first commit
28
.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.env
|
||||
.env.*
|
||||
!.example.env
|
||||
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Vue 3 + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
||||
11
auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const ElMessage: typeof import('element-plus/es').ElMessage
|
||||
const ElMessageBox: typeof import('element-plus/es').ElMessageBox
|
||||
}
|
||||
75
components.d.ts
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// biome-ignore lint: disable
|
||||
// oxlint-disable
|
||||
// ------
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
CommonAside: typeof import('./src/components/CommonAside.vue')['default']
|
||||
CommonHeader: typeof import('./src/components/CommonHeader.vue')['default']
|
||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||
ElAside: typeof import('element-plus/es')['ElAside']
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElBacktop: typeof import('element-plus/es')['ElBacktop']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCascader: typeof import('element-plus/es')['ElCascader']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
||||
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElImage: typeof import('element-plus/es')['ElImage']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||
ElLink: typeof import('element-plus/es')['ElLink']
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElTree: typeof import('element-plus/es')['ElTree']
|
||||
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
export interface GlobalDirectives {
|
||||
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||
}
|
||||
}
|
||||
1
docs/dictionary-usage.md
Normal file
@ -0,0 +1 @@
|
||||
# 字典使用示例
|
||||
393
docs/pinia-dict-guide.md
Normal file
@ -0,0 +1,393 @@
|
||||
# Pinia 字典管理系统使用指南
|
||||
|
||||
## 系统架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ API 接口 (getDictItemsByCode) │
|
||||
│ /api/dict/items/code/{code} │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ Pinia Store (useDictStore) │
|
||||
│ ✅ 自动缓存字典数据 │
|
||||
│ ✅ 避免重复请求 │
|
||||
│ ✅ 支持同步/异步访问 │
|
||||
└──────────────┬──────────────────────┘
|
||||
│
|
||||
┌──────┴──────┐
|
||||
↓ ↓
|
||||
┌────────┐ ┌──────────────┐
|
||||
│组件 │ │Composable │
|
||||
│直接用 │ │useDict Hook │
|
||||
└────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心文件说明
|
||||
|
||||
### 1. **Store**: `src/stores/dict.js`
|
||||
|
||||
字典数据的全局管理器
|
||||
|
||||
**主要方法**:
|
||||
```javascript
|
||||
import { useDictStore } from '@/stores/dict'
|
||||
|
||||
const dictStore = useDictStore()
|
||||
|
||||
// ✅ 异步获取字典(推荐)
|
||||
const items = await dictStore.getDictItems('user_status')
|
||||
|
||||
// ✅ 同步获取字典(已缓存时)
|
||||
const items = dictStore.getDictItemsSync('user_status')
|
||||
|
||||
// ✅ 获取字典值对应的标签
|
||||
const label = dictStore.getDictLabel('user_status', 1)
|
||||
|
||||
// ✅ 预加载多个字典
|
||||
await dictStore.preloadDicts(['user_status', 'user_role'])
|
||||
|
||||
// ✅ 清空缓存
|
||||
dictStore.clearCache('user_status')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **常量**: `src/constants/dictCodes.js`
|
||||
|
||||
集中管理所有字典编码
|
||||
|
||||
**使用示例**:
|
||||
```javascript
|
||||
import { DICT_CODES } from '@/constants/dictCodes'
|
||||
|
||||
// 好处:避免硬编码,IDE 有自动完成
|
||||
const items = await dictStore.getDictItems(DICT_CODES.USER_STATUS)
|
||||
|
||||
// 所有可用的编码:
|
||||
DICT_CODES.USER_STATUS // 用户状态
|
||||
DICT_CODES.USER_GENDER // 用户性别
|
||||
DICT_CODES.USER_ROLE // 用户角色
|
||||
DICT_CODES.DEPT_STATUS // 部门状态
|
||||
DICT_CODES.POSITION_STATUS // 职位状态
|
||||
// ... 更多编码
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. **Composable**: `src/composables/useDict.js`
|
||||
|
||||
简化在组件中使用字典的 Hook
|
||||
|
||||
**基础用法**:
|
||||
```javascript
|
||||
import { useDictionary, useUserStatusDict } from '@/composables/useDict'
|
||||
import { DICT_CODES } from '@/constants/dictCodes'
|
||||
|
||||
// 方式1:使用常量
|
||||
const { statusDict, loading } = useDictionary(DICT_CODES.USER_STATUS)
|
||||
|
||||
// 方式2:使用字符串
|
||||
const { dicts, loading } = useDictionary('user_status')
|
||||
|
||||
// 方式3:使用特化 Hook(推荐)
|
||||
const { user_statusDict, loading } = useUserStatusDict()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景1:在列表页加载字典
|
||||
|
||||
**文件**: `src/views/system/users/index.vue`
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useDictStore } from '@/stores/dict'
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const dictStore = useDictStore()
|
||||
const statusDict = ref([])
|
||||
|
||||
const fetchStatusDict = async () => {
|
||||
statusDict.value = await dictStore.getDictItems('user_status')
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchStatusDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 传给子组件 -->
|
||||
<UserEditDialog :status-dict="statusDict" />
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景2:在编辑对话框使用字典
|
||||
|
||||
**文件**: `src/views/system/users/components/UserEdit.vue`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 状态选择 -->
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="form.status">
|
||||
<el-option
|
||||
v-for="item in statusDict"
|
||||
:key="item.dict_value"
|
||||
:label="item.dict_label"
|
||||
:value="item.dict_value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
statusDict: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景3:快速使用 Composable Hook
|
||||
|
||||
最简单的方式,自动处理加载:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<p v-if="loading">加载中...</p>
|
||||
<el-select v-else v-model="status">
|
||||
<el-option
|
||||
v-for="item in user_statusDict"
|
||||
:key="item.dict_value"
|
||||
:label="item.dict_label"
|
||||
:value="item.dict_value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useUserStatusDict } from '@/composables/useDict'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const status = ref('active')
|
||||
const { user_statusDict, loading } = useUserStatusDict()
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景4:预加载应用启动时需要的字典
|
||||
|
||||
**文件**: `src/main.js`
|
||||
|
||||
```javascript
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import { useDictStore } from '@/stores/dict'
|
||||
import { DICT_CODES } from '@/constants/dictCodes'
|
||||
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
|
||||
app.use(pinia)
|
||||
|
||||
// 在应用启动后预加载常用字典
|
||||
const dictStore = useDictStore()
|
||||
await dictStore.preloadDicts([
|
||||
DICT_CODES.USER_STATUS,
|
||||
DICT_CODES.COMMON_STATUS,
|
||||
DICT_CODES.YES_NO,
|
||||
])
|
||||
|
||||
app.mount('#app')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 字典数据结构
|
||||
|
||||
后端返回的字典数据结构:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"dict_id": 1,
|
||||
"dict_value": "1",
|
||||
"dict_label": "启用",
|
||||
"dict_type": "user_status",
|
||||
"remarks": "用户启用状态",
|
||||
"remark": "用户启用状态"
|
||||
},
|
||||
{
|
||||
"dict_id": 2,
|
||||
"dict_value": "0",
|
||||
"dict_label": "禁用",
|
||||
"dict_type": "user_status",
|
||||
"remarks": "用户禁用状态",
|
||||
"remark": "用户禁用状态"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**关键字段**:
|
||||
- `dict_value`: 字典值(存储在数据库中)
|
||||
- `dict_label`: 字典标签(显示给用户)
|
||||
- `dict_type`: 字典类型编码(如 'user_status')
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### ✅ DO
|
||||
|
||||
1. **使用常量而不是硬编码字符串**
|
||||
```javascript
|
||||
// ✅ 好
|
||||
dictStore.getDictItems(DICT_CODES.USER_STATUS)
|
||||
|
||||
// ❌ 差
|
||||
dictStore.getDictItems('user_status')
|
||||
```
|
||||
|
||||
2. **在父组件加载,通过 props 传给子组件**
|
||||
```javascript
|
||||
// ✅ 父组件负责数据,子组件负责展示
|
||||
// index.vue
|
||||
const statusDict = await dictStore.getDictItems(DICT_CODES.USER_STATUS)
|
||||
|
||||
// UserEdit.vue
|
||||
const props = defineProps({ statusDict: Array })
|
||||
```
|
||||
|
||||
3. **用 Composable 简化组件逻辑**
|
||||
```javascript
|
||||
// ✅ 一行代码搞定
|
||||
const { user_statusDict, loading } = useUserStatusDict()
|
||||
```
|
||||
|
||||
4. **预加载常用字典**
|
||||
```javascript
|
||||
// ✅ 应用启动时预加载,避免页面初始化时加载
|
||||
await dictStore.preloadDicts([...])
|
||||
```
|
||||
|
||||
### ❌ DON'T
|
||||
|
||||
1. **不要在多个地方重复加载同一个字典**
|
||||
```javascript
|
||||
// ❌ 糟糕:重复加载
|
||||
// 页面A
|
||||
const dict1 = await dictStore.getDictItems('user_status')
|
||||
|
||||
// 页面B(Store 会自动缓存,但代码看起来重复)
|
||||
const dict2 = await dictStore.getDictItems('user_status')
|
||||
```
|
||||
|
||||
2. **不要忘记处理加载状态**
|
||||
```javascript
|
||||
// ❌ 可能展示空白
|
||||
const { statusDict } = useUserStatusDict()
|
||||
|
||||
// ✅ 处理加载状态
|
||||
const { statusDict, loading } = useUserStatusDict()
|
||||
if (loading) { /* 显示加载中 */ }
|
||||
```
|
||||
|
||||
3. **不要混用不同的字典访问方式**
|
||||
```javascript
|
||||
// ❌ 混乱
|
||||
const dict1 = await dictStore.getDictItems('user_status')
|
||||
const dict2 = dictStore.getDictItemsSync('user_role')
|
||||
|
||||
// ✅ 统一使用
|
||||
const dict1 = await dictStore.getDictItems('user_status')
|
||||
const dict2 = await dictStore.getDictItems('user_role')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
| 优化项 | 说明 |
|
||||
|------|------|
|
||||
| **缓存** | Store 自动缓存,同一个字典只请求一次 |
|
||||
| **预加载** | 在路由切换前预加载需要的字典 |
|
||||
| **同步访问** | 已加载的字典可用 `getDictItemsSync` 同步获取 |
|
||||
| **避免重复** | 不要在多个组件重复请求同一个字典 |
|
||||
|
||||
---
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 问题1:状态选项为空
|
||||
|
||||
**原因**:字典未加载
|
||||
**解决**:
|
||||
```javascript
|
||||
// ❌ 错误:字典还未加载
|
||||
const statusDict = dictStore.getDictItemsSync('user_status') // 返回 []
|
||||
|
||||
// ✅ 正确:等待异步加载完成
|
||||
const statusDict = await dictStore.getDictItems('user_status')
|
||||
```
|
||||
|
||||
### 问题2:重复加载字典
|
||||
|
||||
**原因**:没有使用 Store 的缓存
|
||||
**解决**:
|
||||
```javascript
|
||||
// 所有调用都会自动使用缓存,只请求一次
|
||||
await dictStore.getDictItems('user_status') // 首次:发送请求
|
||||
await dictStore.getDictItems('user_status') // 第二次:返回缓存
|
||||
```
|
||||
|
||||
### 问题3:字典显示不对
|
||||
|
||||
**原因**:value 类型不匹配(如 1 vs "1")
|
||||
**解决**:
|
||||
```javascript
|
||||
// Store 会自动处理类型匹配
|
||||
const item = items.find(i =>
|
||||
String(i.dict_value) === String(value) || i.dict_value === value
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 集成检清表
|
||||
|
||||
- [ ] 创建 `src/stores/dict.js` - Store
|
||||
- [ ] 创建 `src/constants/dictCodes.js` - 常量
|
||||
- [ ] 创建 `src/composables/useDict.js` - Composable
|
||||
- [ ] 在 `index.vue` 中导入 `useDictStore`
|
||||
- [ ] 在 `UserEdit.vue` 中接收 `statusDict` props
|
||||
- [ ] 测试字典加载和显示
|
||||
- [ ] 验证缓存功能(打开浏览器 DevTools 检查 Network)
|
||||
- [ ] 预加载常用字典(可选)
|
||||
|
||||
---
|
||||
|
||||
## 相关文件修改
|
||||
|
||||
已修改的文件:
|
||||
- ✅ `src/stores/dict.js` - 新建
|
||||
- ✅ `src/constants/dictCodes.js` - 新建
|
||||
- ✅ `src/composables/useDict.js` - 新建
|
||||
- ✅ `src/views/system/users/index.vue` - 使用 `useDictStore`
|
||||
- ✅ `src/views/system/users/components/UserEdit.vue` - 导入字典库
|
||||
|
||||
31
docs/一键复制.md
Normal file
@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<el-button @click="handleCopy">复制数据</el-button>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
//一键复制代码
|
||||
function handleCopy() {
|
||||
if (!props.model) return
|
||||
|
||||
const data = [
|
||||
`客户名称: ${props.model.name || '-'}`,
|
||||
`联系人: ${props.model.contact || '-'}`,
|
||||
`电话: ${props.model.phone || '-'}`,
|
||||
`邮箱: ${props.model.email || '-'}`,
|
||||
`客户类型: ${getLabel(customerTypeOptions.value, props.model.customer_type)}`,
|
||||
`客户等级: ${getLabel(customerLevelOptions.value, props.model.customer_level)}`,
|
||||
`所属行业: ${getLabel(industryOptions.value, props.model.industry)}`,
|
||||
`客户状态: ${getLabel(customerStatusOptions.value, String(props.model.status ?? '')) || ((props.model.status===1||props.model.status==='1') ? '正常' : '停用')}`,
|
||||
`地址: ${props.model.address || '-'}`,
|
||||
`经营范围: ${props.model.business_scope || '-'}`
|
||||
].join('\n')
|
||||
|
||||
navigator.clipboard.writeText(data).then(() => {
|
||||
ElMessage.success('数据已复制到剪贴板')
|
||||
}).catch(() => {
|
||||
ElMessage.error('复制失败')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
11
docs/拼接接口路径.md
Normal file
@ -0,0 +1,11 @@
|
||||
//拼接接口路径
|
||||
const getEnvUrl = (path: string) => {
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
|
||||
return `${API_BASE_URL}${path}`;
|
||||
};
|
||||
|
||||
用例:
|
||||
<img :src="getEnvUrl(module.thumb)" :alt="module.title" />
|
||||
|
||||
|
||||
const url = getEnvUrl('/admin/moduleCenter/modules');
|
||||
12
docs/接口调用.md
Normal file
@ -0,0 +1,12 @@
|
||||
import { onMounted } from "vue";
|
||||
import { getMenus } from "@/api/menu";
|
||||
|
||||
onMounted(async () => {
|
||||
try{
|
||||
const response = await getMenus();
|
||||
} catch (error) {
|
||||
console.error('获取菜单数据失败:', error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
23
docs/获取缓存数据.md
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
// 使用 auth store 获取用户信息
|
||||
const authStore = useAuthStore();
|
||||
|
||||
// 获取租户ID
|
||||
const tenantId = (authStore.user as any)?.tid;
|
||||
|
||||
// 获取用户信息
|
||||
const userInfo = authStore.user;
|
||||
if (userInfo && userInfo.id) {
|
||||
console.log('用户名:', userInfo.username || userInfo.nickname);
|
||||
console.log('用户ID:', userInfo.id);
|
||||
console.log('角色:', userInfo.role);
|
||||
} else {
|
||||
console.log('未找到用户信息或用户未登录');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserInfo();
|
||||
});
|
||||
90
docs/调用图片上传组件.md
Normal file
@ -0,0 +1,90 @@
|
||||
<el-form-item label="默认图片" prop="image">
|
||||
<div class="uploads">
|
||||
<el-upload v-model:file-list="fileList" :action="uploadUrl" list-type="picture-card"
|
||||
:headers="uploadHeaders" :limit="1" :auto-upload="false" :before-upload="beforeImgUpload"
|
||||
:on-success="handleImgSuccess">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
|
||||
<template #file="{ file }">
|
||||
<div>
|
||||
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
||||
<el-icon>
|
||||
<ZoomIn />
|
||||
</el-icon>
|
||||
</span>
|
||||
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||
</el-dialog>
|
||||
|
||||
<div class="upload-tip">
|
||||
<span>建议尺寸:250px × 140px</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
import { uploadFile } from '@/api/file.js';
|
||||
import { ElMessage, ElUpload } from 'element-plus'
|
||||
|
||||
// 上传相关
|
||||
const fileList = ref<any[]>([])
|
||||
const dialogVisible = ref(false)
|
||||
const dialogImageUrl = ref('')
|
||||
|
||||
function beforeImgUpload(file: File) {
|
||||
const isImage = file.type.startsWith('image/')
|
||||
const isLt10M = file.size / 1024 / 1024 < 10
|
||||
if (!isImage) ElMessage.error('仅支持图片格式')
|
||||
if (!isLt10M) ElMessage.error('图片大小不能超过10MB')
|
||||
return isImage && isLt10M
|
||||
}
|
||||
|
||||
function handleImgUpload(file: File) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('cate', 'article')
|
||||
|
||||
uploadFile(formData).then((res: any) => {
|
||||
if (res?.url) {
|
||||
formData.image = res.url
|
||||
fileList.value = [{
|
||||
name: file.name,
|
||||
url: res.url
|
||||
}]
|
||||
}
|
||||
}).catch((error: any) => {
|
||||
ElMessage.error('上传失败:' + (error.msg || '未知错误'))
|
||||
})
|
||||
}
|
||||
|
||||
function handlePictureCardPreview(file: any) {
|
||||
dialogImageUrl.value = file.url
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function handleRemove(file: any) {
|
||||
fileList.value = []
|
||||
formData.image = ''
|
||||
}
|
||||
|
||||
|
||||
.uploads{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.upload-tip {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
27
docs/调用字典.md
Normal file
@ -0,0 +1,27 @@
|
||||
````
|
||||
<template>
|
||||
{{ (xxxxxxxxDict.find(item => item.dict_value == String(model?.status)) || {}).dict_label || '-' }}
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { useDictStore } from '@/stores/dict';
|
||||
|
||||
// 字典store
|
||||
const dictStore = useDictStore();
|
||||
const xxxxxxxxDict = ref<any[]>([]);
|
||||
|
||||
// 获取审核状态字典
|
||||
const fetchxxxxxxxxDict = async () => {
|
||||
try {
|
||||
xxxxxxxxDict.value = await dictStore.getDictItems('article_status');
|
||||
console.log(xxxxxxxxDict.value);
|
||||
} catch (err) {
|
||||
console.error('获取文章状态字典失败:', err);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchxxxxxxxxDict();
|
||||
});
|
||||
</script>
|
||||
````
|
||||
16
index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/assets/svgs/logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<title>后台管理系统</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
4916
package-lock.json
generated
Normal file
38
package.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "pc",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"axios": "^1.13.1",
|
||||
"chart": "^0.1.2",
|
||||
"chart.js": "^4.5.1",
|
||||
"docx-preview": "^0.3.7",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.11.7",
|
||||
"less": "^4.4.2",
|
||||
"marked": "^16.4.1",
|
||||
"os": "^0.1.2",
|
||||
"pinia": "^3.0.3",
|
||||
"vue": "^3.5.22",
|
||||
"vue-img-cutter": "^3.0.7",
|
||||
"vue-router": "^4.6.3",
|
||||
"vue3-pdf-app": "^1.0.3",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.10.7",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"typescript": "^5.9.3",
|
||||
"unplugin-auto-import": "^20.2.0",
|
||||
"unplugin-vue-components": "^30.0.0",
|
||||
"vite": "^7.1.7"
|
||||
}
|
||||
}
|
||||
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
14
src/App.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
18
src/api/analytics.js
Normal file
@ -0,0 +1,18 @@
|
||||
// 数据统计相关API
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 获取内容统计
|
||||
export function getContentStats() {
|
||||
return request({
|
||||
url: "/admin/contentstats",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户统计
|
||||
export function getUserStats() {
|
||||
return request({
|
||||
url: "/admin/usersstats",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
170
src/api/article.js
Normal file
@ -0,0 +1,170 @@
|
||||
// 文章管理相关API
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 获取文章列表
|
||||
export function listArticles(params) {
|
||||
return request({
|
||||
url: `/admin/articlesList`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取文章所有文章
|
||||
export function listAllArticles(params) {
|
||||
return request({
|
||||
url: `/admin/allarticles`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取文章详情
|
||||
export function getArticle(id) {
|
||||
return request({
|
||||
url: `/admin/articles/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 创建文章
|
||||
export function createArticle(data) {
|
||||
return request({
|
||||
url: '/admin/createarticle',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑文章
|
||||
export function editArticle(id, data) {
|
||||
return request({
|
||||
url: `/admin/editarticle/${id}`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除文章
|
||||
export function deleteArticle(id) {
|
||||
return request({
|
||||
url: `/admin/deletearticle/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
// 发布文章
|
||||
export function publishArticle(id,uid) {
|
||||
return request({
|
||||
url: `/admin/publisharticle/${id}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
uid
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 下架文章
|
||||
export function unPublishArticle(id) {
|
||||
return request({
|
||||
url: `/admin/unPublisharticle/${id}`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
// 文章推荐
|
||||
export function articleRecommend(id) {
|
||||
return request({
|
||||
url: `/admin/articleRecommend/${id}`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
// 取消文章推荐
|
||||
export function unArticleRecommend(id) {
|
||||
return request({
|
||||
url: `/admin/unArticleRecommend/${id}`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
// 文章置顶
|
||||
export function articleTop(id) {
|
||||
return request({
|
||||
url: `/admin/articleTop/${id}`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
// 取消文章置顶
|
||||
export function unArticleTop(id) {
|
||||
return request({
|
||||
url: `/admin/unArticleTop/${id}`,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////分类相关////////////////////////////
|
||||
|
||||
// 获取所有分类列表
|
||||
export function allCategories(params) {
|
||||
return request({
|
||||
url: `/admin/allcategories`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取分类列表
|
||||
export function listCategories(params) {
|
||||
return request({
|
||||
url: `/admin/categories`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取分类详情
|
||||
export function getCategory(id) {
|
||||
return request({
|
||||
url: `/admin/categories/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 创建分类
|
||||
export function createCategory(data) {
|
||||
return request({
|
||||
url: `/admin/createCategory`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新分类
|
||||
export function editCategory(id, data) {
|
||||
return request({
|
||||
url: `/admin/editCategory/${id}`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除分类
|
||||
export function deleteCategory(id) {
|
||||
return request({
|
||||
url: `/admin/categories/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
// 更新分类状态
|
||||
export function updateCategoryStatus(id, status) {
|
||||
return request({
|
||||
url: `/admin/categories/${id}/status`,
|
||||
method: "patch",
|
||||
data: { status },
|
||||
});
|
||||
}
|
||||
179
src/api/babyhealth.js
Normal file
@ -0,0 +1,179 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/*************************************************
|
||||
****************** 宝贝相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* 获取宝贝列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getBabyList() {
|
||||
return request({
|
||||
url: '/admin/babys/list',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取宝贝详情
|
||||
* @param {number} id 宝贝ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getBabyDetail(id) {
|
||||
return request({
|
||||
url: `/admin/babys/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建宝贝数据
|
||||
* @param {Object} data 宝贝数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createBaby(data) {
|
||||
return request({
|
||||
url: "/admin/babys",
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更新宝贝信息
|
||||
export function editBaby(id, data) {
|
||||
return request({
|
||||
url: `/admin/baby/update/${id}`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除宝贝数据
|
||||
* @param {number} id 宝贝ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteBaby(id) {
|
||||
return request({
|
||||
url: `/admin/babys/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定父母
|
||||
* @param {number} id 宝贝ID
|
||||
* @param {Object} data 绑定数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function bindParent(id, data) {
|
||||
return request({
|
||||
url: `/admin/babys/bindparents/${id}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父母
|
||||
* @param {number} id 宝贝ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getParents(id) {
|
||||
return request({
|
||||
url: `/admin/babys/getParents/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
****************** 用户相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getUserList() {
|
||||
return request({
|
||||
url: "/admin/babyhealthUser/list",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户详情
|
||||
* @param {number} id 用户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getUserDetail(id) {
|
||||
return request({
|
||||
url: `/admin/babyhealthUser/detail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户数据
|
||||
* @param {Object} data 用户数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createUser(data) {
|
||||
return request({
|
||||
url: "/admin/babyhealthUser/create",
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户数据
|
||||
* @param {number} id 用户ID
|
||||
* @param {Object} data 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateUser(id, data) {
|
||||
return request({
|
||||
url: `/admin/babyhealthUser/update/${id}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户数据
|
||||
* @param {number} id 用户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteUser(id) {
|
||||
return request({
|
||||
url: `/admin/babyhealthUser/delete/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
****************** 仪表盘相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* dashborad总体输出
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getDashborad() {
|
||||
return request({
|
||||
url: "/admin/babyhealthDashborad/dashborad",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
55
src/api/banner.js
Normal file
@ -0,0 +1,55 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取所有Banner
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getBanners() {
|
||||
return request({
|
||||
url: "/admin/allbanners",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Banner
|
||||
* @param {Object} bannerData Banner数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createBanner(formData) {
|
||||
return request({
|
||||
url: "/admin/createbanner",
|
||||
method: "post",
|
||||
data: formData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑Banner
|
||||
* @param {number|string} id Banner ID
|
||||
* @param {Object} bannerData 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editBanner(id, bannerData) {
|
||||
return request({
|
||||
url: `/admin/editbanner/${id}`,
|
||||
method: "post",
|
||||
data: bannerData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Banner
|
||||
* @param {number|string} id Banner ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteBanner(id) {
|
||||
return request({
|
||||
url: `/admin/deletebanner/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
33
src/api/contact.js
Normal file
@ -0,0 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listContacts(params) {
|
||||
return request({
|
||||
url: '/admin/crm/contact/list',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
export function createContact(data) {
|
||||
return request({
|
||||
url: '/admin/crm/contact/add',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export function updateContact(data) {
|
||||
return request({
|
||||
url: '/admin/crm/contact/edit',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteContact(data) {
|
||||
return request({
|
||||
url: '/admin/crm/contact/delete',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
41
src/api/dashboard.js
Normal file
@ -0,0 +1,41 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取平台统计数据(平台用户使用)
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPlatformStats() {
|
||||
return request({
|
||||
url: "/admin/dashboard/platform-stats",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户统计数据(租户员工使用)
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getTenantStats() {
|
||||
return request({
|
||||
url: "/admin/dashboard/tenant-stats",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户活动日志(操作日志和登录日志)
|
||||
* @param {number} pageNum - 页码
|
||||
* @param {number} pageSize - 每页数量
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getActivityLogs(pageNum = 1, pageSize = 10) {
|
||||
return request({
|
||||
url: "/admin/dashboard/user-activity-logs",
|
||||
method: "get",
|
||||
params: {
|
||||
page_num: pageNum,
|
||||
page_size: pageSize,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
51
src/api/demand.js
Normal file
@ -0,0 +1,51 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取需求列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getDemandList() {
|
||||
return request({
|
||||
url: "/admin/demandList",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增需求
|
||||
* @param {Object} data 需求数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addDemand(data) {
|
||||
return request({
|
||||
url: "/admin/addDemand",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑需求
|
||||
* @param {number} id 需求ID
|
||||
* @param {Object} data 需求数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editDemand(id, data) {
|
||||
return request({
|
||||
url: `/admin/editDemand/${id}`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除需求
|
||||
* @param {number} id 需求ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteDemand(id) {
|
||||
return request({
|
||||
url: `/admin/deleteDemand/${id}`,
|
||||
method: "post",
|
||||
});
|
||||
}
|
||||
44
src/api/department.js
Normal file
@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 获取租户下的所有部门
|
||||
export function getTenantDepartments(tenantId) {
|
||||
return request({
|
||||
url: `/admin/departments/tenant/${tenantId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取部门详情
|
||||
export function getDepartmentInfo(departmentId) {
|
||||
return request({
|
||||
url: `/admin/departments/${departmentId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加部门
|
||||
export function addDepartment(data) {
|
||||
return request({
|
||||
url: '/admin/departments',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新部门信息
|
||||
export function editDepartment(departmentId, data) {
|
||||
return request({
|
||||
url: `/admin/departments/${departmentId}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
export function deleteDepartment(departmentId) {
|
||||
return request({
|
||||
url: `/admin/departments/${departmentId}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
114
src/api/dict.js
Normal file
@ -0,0 +1,114 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取字典类型列表
|
||||
export function getDictTypes(params) {
|
||||
return request({
|
||||
url: '/admin/dict/types',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID获取字典类型
|
||||
export function getDictTypeById(id) {
|
||||
return request({
|
||||
url: `/admin/dict/types/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 添加字典类型
|
||||
export function addDictType(data) {
|
||||
return request({
|
||||
url: '/admin/dict/types',
|
||||
method: 'post',
|
||||
data: {
|
||||
...data,
|
||||
is_global: data.is_global !== undefined ? data.is_global : 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 更新字典类型
|
||||
export function updateDictType(id, data) {
|
||||
return request({
|
||||
url: `/admin/dict/types/${id}`,
|
||||
method: 'put',
|
||||
data: {
|
||||
...data,
|
||||
is_global: data.is_global !== undefined ? data.is_global : 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除字典类型
|
||||
export function deleteDictType(id) {
|
||||
return request({
|
||||
url: `/admin/dict/types/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取字典项列表
|
||||
export function getDictItems(params) {
|
||||
return request({
|
||||
url: '/admin/dict/items',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID获取字典项
|
||||
export function getDictItemById(id) {
|
||||
return request({
|
||||
url: `/admin/dict/items/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 添加字典项
|
||||
export function addDictItem(data) {
|
||||
return request({
|
||||
url: '/admin/dict/items',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新字典项
|
||||
export function updateDictItem(id, data) {
|
||||
return request({
|
||||
url: `/admin/dict/items/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除字典项
|
||||
export function deleteDictItem(id) {
|
||||
return request({
|
||||
url: `/admin/dict/items/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据字典编码获取字典项(用于业务查询)
|
||||
export function getDictItemsByCode(code, includeDisabled = false) {
|
||||
return request({
|
||||
url: `/admin/dict/items/code/${code}`,
|
||||
method: 'get',
|
||||
params: {
|
||||
include_disabled: includeDisabled ? '1' : '0'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 批量更新字典项排序
|
||||
export function batchUpdateDictItemSort(data) {
|
||||
return request({
|
||||
url: '/admin/dict/items/sort',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
110
src/api/domain.js
Normal file
@ -0,0 +1,110 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// ==================== 主域名池管理 ====================
|
||||
|
||||
// 获取域名池列表
|
||||
export function getDomainPoolList(params) {
|
||||
return request({
|
||||
url: '/admin/domain/pool/index',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取启用的主域名列表
|
||||
export function getEnabledDomains() {
|
||||
return request({
|
||||
url: '/admin/domain/pool/getEnabledDomains',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 创建主域名
|
||||
export function createDomainPool(data) {
|
||||
return request({
|
||||
url: '/admin/domain/pool/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新主域名
|
||||
export function updateDomainPool(data) {
|
||||
return request({
|
||||
url: '/admin/domain/pool/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除主域名
|
||||
export function deleteDomainPool(id) {
|
||||
return request({
|
||||
url: `/admin/domain/pool/delete/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 切换主域名状态
|
||||
export function toggleDomainPoolStatus(id) {
|
||||
return request({
|
||||
url: '/admin/domain/pool/toggleStatus',
|
||||
method: 'post',
|
||||
data: { id }
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 租户域名管理 ====================
|
||||
|
||||
// 获取租户域名列表(管理员)
|
||||
export function getTenantDomainList(params) {
|
||||
return request({
|
||||
url: '/admin/domain/tenant/index',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前租户的域名列表
|
||||
export function getMyDomains(params) {
|
||||
return request({
|
||||
url: '/admin/domain/tenant/myDomains',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 申请二级域名
|
||||
export function applyTenantDomain(data) {
|
||||
return request({
|
||||
url: '/admin/domain/tenant/apply',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 审核租户域名
|
||||
export function auditTenantDomain(data) {
|
||||
return request({
|
||||
url: '/admin/domain/tenant/audit',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 禁用/启用租户域名
|
||||
export function toggleTenantDomainStatus(id) {
|
||||
return request({
|
||||
url: '/admin/domain/tenant/toggleStatus',
|
||||
method: 'post',
|
||||
data: { id }
|
||||
})
|
||||
}
|
||||
|
||||
// 删除租户域名
|
||||
export function deleteTenantDomain(id) {
|
||||
return request({
|
||||
url: `/admin/domain/tenant/delete/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
36
src/api/email.js
Normal file
@ -0,0 +1,36 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取邮箱信息
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getEmailInfo() {
|
||||
return request({
|
||||
url: "/admin/email/info",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑邮箱信息
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editEmailInfo(data) {
|
||||
return request({
|
||||
url: "/admin/email/editinfo",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送测试邮件
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function sendTestEmail(data) {
|
||||
return request({
|
||||
url: "/admin/email/sendtestemail",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
155
src/api/erp.js
Normal file
@ -0,0 +1,155 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/*************************************************
|
||||
****************** 组织机构相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* 获取组织机构列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOrganizationList() {
|
||||
return request({
|
||||
url: '/admin/erp/getOrganization',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组织机构详情
|
||||
* @param {number} id 组织机构ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOrganizationDetail(id) {
|
||||
return request({
|
||||
url: `/admin/erp/getOrganizationDetail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建组织机构数据
|
||||
* @param {Object} data 组织机构数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createOrganization(data) {
|
||||
return request({
|
||||
url: "/admin/erp/createOrganization",
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更新组织机构信息
|
||||
export function editOrganization(id, data) {
|
||||
return request({
|
||||
url: `/admin/erp/editOrganization/${id}`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组织机构数据
|
||||
* @param {number} id 组织机构ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteOrganization(id) {
|
||||
return request({
|
||||
url: `/admin/erp/deleteOrganization/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业单位列表
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getCompanys() {
|
||||
return request({
|
||||
url: '/admin/erp/getCompanys',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门列表
|
||||
* @param {number} parentId 隶属单位ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getDepartments(parentId) {
|
||||
return request({
|
||||
url: '/admin/erp/getDepartments',
|
||||
method: 'get',
|
||||
params: parentId ? { parent_id: parentId } : {}
|
||||
});
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
****************** 员工相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* 获取员工列表
|
||||
* @param {number} tenantId 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getEmployeeList(tenantId) {
|
||||
return request({
|
||||
url: '/admin/erp/getEmployee',
|
||||
method: 'get',
|
||||
params: { tid: tenantId }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取员工详情
|
||||
* @param {number} id 员工ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getEmployeeDetail(id) {
|
||||
return request({
|
||||
url: `/admin/erp/getEmployeeDetail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建员工数据
|
||||
* @param {Object} data 员工数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createEmployee(data) {
|
||||
return request({
|
||||
url: "/admin/erp/createEmployee",
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更新员工信息
|
||||
export function editEmployee(id, data) {
|
||||
return request({
|
||||
url: `/admin/erp/editEmployee/${id}`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除员工数据
|
||||
* @param {number} id 员工ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteEmployee(id) {
|
||||
return request({
|
||||
url: `/admin/erp/deleteEmployee/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
211
src/api/file.js
Normal file
@ -0,0 +1,211 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取用户分类
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getUserCate() {
|
||||
return request({
|
||||
url: `/admin/usercate`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有文件
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getAllFiles() {
|
||||
return request({
|
||||
url: "/admin/allfiles",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建文件分组
|
||||
* @param {Object} data 文件分组数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createFileCate(data) {
|
||||
return request({
|
||||
url: "/admin/createfilecate",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重命名文件分组
|
||||
* @param {number|string} id 文件分组ID
|
||||
* @param {Object} data 文件分组数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function renameFileCate(id, data) {
|
||||
return request({
|
||||
url: `/admin/renamefilecate/${id}`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件分组
|
||||
* @param {number|string} id 文件分组ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteFileCate(id) {
|
||||
return request({
|
||||
url: `/admin/deletefilecate/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类ID获取文件
|
||||
* @param {number|string} id 分类ID
|
||||
* @param {number} page 页码,默认1
|
||||
* @param {number} pageSize 每页数量,默认24
|
||||
* @param {string} keyword 搜索关键词,可选
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getCateFiles(id, page = 1, pageSize = 24, keyword = "") {
|
||||
const params = {
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
if (keyword) {
|
||||
params.keyword = keyword;
|
||||
}
|
||||
return request({
|
||||
url: `/admin/catefiles/${id}`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID获取文件
|
||||
* @param {number|string} id 文件ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getFileById(id) {
|
||||
return request({
|
||||
url: `/admin/catefiles`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param {FormData} formData 文件数据
|
||||
* @param {Object} options 额外选项
|
||||
* @param {string} [options.cate]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function uploadFile(formData, options = {}) {
|
||||
if (options.cate) {
|
||||
formData.append('cate', options.cate);
|
||||
}
|
||||
|
||||
return request({
|
||||
url: "/admin/uploadfile",
|
||||
method: "post",
|
||||
data: formData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件信息
|
||||
* @param {number|string} id 文件ID
|
||||
* @param {Object} fileData 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateFile(id, fileData) {
|
||||
return request({
|
||||
url: `/admin/updatefile/${id}`,
|
||||
method: "post",
|
||||
data: fileData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param {number|string} id 文件ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteFile(id) {
|
||||
return request({
|
||||
url: `/admin/deletefile/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param {number|string} id 文件ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteFilePermanently(id) {
|
||||
return request({
|
||||
url: `/admin/deleteFilePermanently/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动文件
|
||||
* @param {number|string} id 文件ID
|
||||
* @param {Object} fileData 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function moveFile(id, cate) {
|
||||
return request({
|
||||
url: `/admin/movefile/${id}`,
|
||||
method: "get",
|
||||
params: { cate },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除文件
|
||||
* @param {Array} ids 文件ID数组
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchDeleteFiles(ids) {
|
||||
return request({
|
||||
url: "/admin/batchDeleteFiles",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量彻底删除文件
|
||||
* @param {Array} ids 文件ID数组
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchDeleteFilesPermanently(ids) {
|
||||
return request({
|
||||
url: "/admin/batchDeleteFilesPermanently",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移动文件
|
||||
* @param {Array} ids 文件ID数组
|
||||
* @param {number} cate 目标分类ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchMoveFiles(ids, cate) {
|
||||
return request({
|
||||
url: "/admin/batchMoveFiles",
|
||||
method: "post",
|
||||
data: { ids, cate },
|
||||
});
|
||||
}
|
||||
77
src/api/friendlink.js
Normal file
@ -0,0 +1,77 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取友情链接列表
|
||||
* @param {Object} params - 查询参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getFriendlinkList(params) {
|
||||
return request({
|
||||
url: '/admin/friendlinks',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有友情链接(下拉选择用)
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getAllFriendlinks() {
|
||||
return request({
|
||||
url: '/admin/friendlinks/all',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加友情链接
|
||||
* @param {Object} data - 链接数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addFriendlink(data) {
|
||||
return request({
|
||||
url: '/admin/friendlinks',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新友情链接
|
||||
* @param {number} id - 链接ID
|
||||
* @param {Object} data - 链接数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateFriendlink(id, data) {
|
||||
return request({
|
||||
url: `/admin/friendlinks/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除友情链接
|
||||
* @param {number} id - 链接ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteFriendlink(id) {
|
||||
return request({
|
||||
url: `/admin/friendlinks/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除友情链接
|
||||
* @param {Array} ids - 链接ID数组
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchDeleteFriendlinks(ids) {
|
||||
return request({
|
||||
url: '/admin/friendlinks/batchdelete',
|
||||
method: 'post',
|
||||
data: { ids }
|
||||
})
|
||||
}
|
||||
55
src/api/frontMenu.js
Normal file
@ -0,0 +1,55 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取所有前端导航
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getFrontMenus() {
|
||||
return request({
|
||||
url: "/admin/frontmenus",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建前端导航
|
||||
* @param {Object} frontMenuData 前端导航数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createFrontMenu(formData, options = {}) {
|
||||
return request({
|
||||
url: "/admin/createfrontmenu",
|
||||
method: "post",
|
||||
data: formData,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑前端导航
|
||||
* @param {number|string} id 前端导航ID
|
||||
* @param {Object} frontMenuData 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editFrontMenu(id, frontMenuData) {
|
||||
return request({
|
||||
url: `/admin/editfrontmenu/${id}`,
|
||||
method: "post",
|
||||
data: frontMenuData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除前端导航
|
||||
* @param {number|string} id 前端导航ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteFrontMenu(id) {
|
||||
return request({
|
||||
url: `/admin/deletefrontmenu/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
99
src/api/login.js
Normal file
@ -0,0 +1,99 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 登录(平台端 / 使用租户名称)
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: `/platform/login`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 发送登录验证码(手机号)
|
||||
export function sendLoginCode(data) {
|
||||
return request({
|
||||
url: "/platform/sendLoginCode",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 手机号验证码登录
|
||||
export function loginBySms(data) {
|
||||
return request({
|
||||
url: "/platform/loginBySms",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 登出
|
||||
export function logout(userInfo = null) {
|
||||
// 如果没有传入 userInfo,尝试从 localStorage 获取
|
||||
if (!userInfo) {
|
||||
const cachedUserInfo = localStorage.getItem('userInfo');
|
||||
if (cachedUserInfo) {
|
||||
try {
|
||||
userInfo = JSON.parse(cachedUserInfo);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse userInfo from localStorage:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return request({
|
||||
url: `/platform/logout`,
|
||||
method: "post",
|
||||
data: userInfo ? { userInfo: userInfo } : {},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取极验3.0数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getGeetest3Infos() {
|
||||
return request({
|
||||
url: '/platform/login/getGeetest3Infos',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取极验4.0数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getGeetest4Infos() {
|
||||
return request({
|
||||
url: '/platform/login/getGeetest4Infos',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否开启验证
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOpenVerify() {
|
||||
return request({
|
||||
url: '/platform/login/getOpenVerify',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 忘记密码重置
|
||||
export function resetPassword(data) {
|
||||
return request({
|
||||
url: "/platform/resetPassword",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 发送找回密码验证码
|
||||
export function sendResetCode(data) {
|
||||
return request({
|
||||
url: "/platform/sendResetCode",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
52
src/api/menu.js
Normal file
@ -0,0 +1,52 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 获取所有菜单
|
||||
export function getAllMenus() {
|
||||
return request({
|
||||
url: `/admin/allmenu`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
//获取用户菜单
|
||||
export function getMenus(id){
|
||||
return request({
|
||||
url: `/admin/menu/${parseInt(id)}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 更新菜单状态
|
||||
export function updateMenuStatus(menuId, status) {
|
||||
return request({
|
||||
url: `/admin/menu/status/${menuId}`,
|
||||
method: "patch",
|
||||
data: { status },
|
||||
});
|
||||
}
|
||||
|
||||
// 创建菜单
|
||||
export function createMenu(menuData) {
|
||||
return request({
|
||||
url: `/admin/createmenu`,
|
||||
method: "post",
|
||||
data: menuData,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新菜单
|
||||
export function updateMenu(menuId, menuData) {
|
||||
return request({
|
||||
url: `/admin/updatemenu/${menuId}`,
|
||||
method: "put",
|
||||
data: menuData,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除菜单
|
||||
export function deleteMenu(menuId) {
|
||||
return request({
|
||||
url: `/admin/deletemenu/${menuId}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
57
src/api/moduleCenter.js
Normal file
@ -0,0 +1,57 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取模块中心分类
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getModuleCategory() {
|
||||
return request({
|
||||
url: "/admin/moduleCategory",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模块中心列表
|
||||
* @param {number} cid 分类id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getModules(cid) {
|
||||
return request({
|
||||
url: "/admin/moduleCenter/modules",
|
||||
method: "get",
|
||||
params: { cid }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑模块分类
|
||||
* @param {Object} data 分类数据
|
||||
* @param {number} data.id 分类id(编辑时必填,新增时不填)
|
||||
* @param {string} data.title 分类名称
|
||||
* @param {number} data.status 分类状态
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editModuleCategory(data) {
|
||||
return request({
|
||||
url: "/admin/moduleCenter/editCategory",
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑模块
|
||||
* @param {Object} data 模块数据
|
||||
* @param {number} data.id 模块id(编辑时必填,新增时不填)
|
||||
* @param {string} data.title 模块名称
|
||||
* @param {number} data.status 模块状态
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editModules(data) {
|
||||
return request({
|
||||
url: "/admin/moduleCenter/editModules",
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
68
src/api/modules.js
Normal file
@ -0,0 +1,68 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getModulesList() {
|
||||
return request({
|
||||
url: '/admin/modules/list',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function getTenantList() {
|
||||
return request({
|
||||
url: '/admin/modules/getTenantList',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function getModuleDetail(id) {
|
||||
return request({
|
||||
url: `/admin/modules/${id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function addModule(data) {
|
||||
return request({
|
||||
url: '/admin/modules',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function editModule(id, data) {
|
||||
return request({
|
||||
url: `/admin/modules/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteModule(id) {
|
||||
return request({
|
||||
url: `/admin/modules/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
export function batchDeleteModules(ids) {
|
||||
return request({
|
||||
url: '/admin/modules/batchDelete',
|
||||
method: 'post',
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
|
||||
export function changeModuleStatus(id, status) {
|
||||
return request({
|
||||
url: '/admin/modules/status',
|
||||
method: 'post',
|
||||
data: { id, status },
|
||||
});
|
||||
}
|
||||
|
||||
export function getModulesSelectList() {
|
||||
return request({
|
||||
url: '/admin/modules/select/list',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
64
src/api/onepage.js
Normal file
@ -0,0 +1,64 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取所有单页
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOnePages() {
|
||||
return request({
|
||||
url: "/admin/allonepages",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建单页
|
||||
* @param {Object} onePageData 单页数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createOnePage(formData) {
|
||||
return request({
|
||||
url: "/admin/createonepage",
|
||||
method: "post",
|
||||
data: formData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑单页
|
||||
* @param {number|string} id 单页ID
|
||||
* @param {Object} onePageData 更新的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editOnePage(id, onePageData) {
|
||||
return request({
|
||||
url: `/admin/editonepage/${id}`,
|
||||
method: "post",
|
||||
data: onePageData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单页
|
||||
* @param {number|string} id 单页ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteOnePage(id) {
|
||||
return request({
|
||||
url: `/admin/deleteonepage/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路径获取单页(前端使用)
|
||||
* @param {string} path 路由路径
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOnePageByPath(path) {
|
||||
return request({
|
||||
url: `/index/onepage/${encodeURIComponent(path)}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
70
src/api/operationLog.js
Normal file
@ -0,0 +1,70 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取操作日志列表
|
||||
* @param {Object} params 查询参数
|
||||
* @param {number} params.page 页码
|
||||
* @param {number} params.pageSize 每页数量
|
||||
* @param {string} params.keyword 关键词搜索
|
||||
* @param {string} params.module 模块筛选
|
||||
* @param {string} params.action 操作动作筛选
|
||||
* @param {string} params.status 状态筛选
|
||||
* @param {string} params.startTime 开始时间
|
||||
* @param {string} params.endTime 结束时间
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOperationLogs(params) {
|
||||
return request({
|
||||
url: "/admin/operationLogs",
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作日志详情
|
||||
* @param {number|string} id 日志ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOperationLogDetail(id) {
|
||||
return request({
|
||||
url: `/admin/operationLogs/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除操作日志
|
||||
* @param {number|string} id 日志ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteOperationLog(id) {
|
||||
return request({
|
||||
url: `/admin/operationLogs/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除操作日志
|
||||
* @param {Array} ids 日志ID数组
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchDeleteOperationLogs(ids) {
|
||||
return request({
|
||||
url: "/admin/operationLogs/batchDelete",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作统计信息
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getOperationStatistics() {
|
||||
return request({
|
||||
url: "/admin/operationLogs/statistics",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
24
src/api/permission.js
Normal file
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getAllMenuPermissions(params = {}) {
|
||||
return request({
|
||||
url: '/admin/allmenupermissions',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function getRolePermissions(roleId) {
|
||||
return request({
|
||||
url: `/admin/rolepermissions/${roleId}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function assignRolePermissions(roleId, permissions) {
|
||||
return request({
|
||||
url: `/admin/assignrolepermissions/${roleId}`,
|
||||
method: 'post',
|
||||
data: { permissions }
|
||||
});
|
||||
}
|
||||
52
src/api/position.js
Normal file
@ -0,0 +1,52 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 获取租户下的所有职位
|
||||
export function getTenantPositions(tenantId) {
|
||||
return request({
|
||||
url: `/admin/positions/tenant/${tenantId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 根据部门ID获取职位列表
|
||||
export function getPositionsByDepartment(departmentId) {
|
||||
return request({
|
||||
url: `/admin/positions/department/${departmentId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取职位详情
|
||||
export function getPositionInfo(positionId) {
|
||||
return request({
|
||||
url: `/admin/positions/${positionId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加职位
|
||||
export function addPosition(data) {
|
||||
return request({
|
||||
url: '/admin/positions',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新职位信息
|
||||
export function editPosition(positionId, data) {
|
||||
return request({
|
||||
url: `/admin/positions/${positionId}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除职位
|
||||
export function deletePosition(positionId) {
|
||||
return request({
|
||||
url: `/admin/positions/${positionId}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
105
src/api/products.js
Normal file
@ -0,0 +1,105 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取特色产品列表
|
||||
* @param {Object} params - 查询参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getProductsList(params) {
|
||||
return request({
|
||||
url: '/admin/productsList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加特色产品
|
||||
* @param {Object} data - 产品数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addProducts(data) {
|
||||
return request({
|
||||
url: '/admin/addProducts',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新特色产品
|
||||
* @param {number} id - 产品ID
|
||||
* @param {Object} data - 产品数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateProducts(id, data) {
|
||||
return request({
|
||||
url: `/admin/editProducts/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除特色产品
|
||||
* @param {number} id - 产品ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteProducts(id) {
|
||||
return request({
|
||||
url: `/admin/deleteProducts/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取产品分类列表
|
||||
* @param {Object} params - 查询参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getProductsTypesList(params) {
|
||||
return request({
|
||||
url: '/admin/productsTypesList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加产品分类
|
||||
* @param {Object} data - 分类数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addProductsTypes(data) {
|
||||
return request({
|
||||
url: '/admin/addProductsTypes',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新产品分类
|
||||
* @param {number} id - 分类ID
|
||||
* @param {Object} data - 分类数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateProductsTypes(id, data) {
|
||||
return request({
|
||||
url: `/admin/editProductsTypes/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除产品分类
|
||||
* @param {number} id - 分类ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteProductsTypes(id) {
|
||||
return request({
|
||||
url: `/admin/deleteProductsTypes/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
38
src/api/role.js
Normal file
@ -0,0 +1,38 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getAllRoles() {
|
||||
return request({
|
||||
url: '/admin/allRoles',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getRoleById(id) {
|
||||
return request({
|
||||
url: `/admin/roles/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function createRole(data) {
|
||||
return request({
|
||||
url: '/admin/roles',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateRole(id, data) {
|
||||
return request({
|
||||
url: `/admin/roles/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteRole(id) {
|
||||
return request({
|
||||
url: `/admin/roles/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
53
src/api/services.js
Normal file
@ -0,0 +1,53 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取特色服务列表
|
||||
* @param {Object} params - 查询参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getServiceList(params) {
|
||||
return request({
|
||||
url: '/admin/servicesList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加特色服务
|
||||
* @param {Object} data - 服务数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addService(data) {
|
||||
return request({
|
||||
url: '/admin/addServices',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新特色服务
|
||||
* @param {number} id - 服务ID
|
||||
* @param {Object} data - 服务数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updateService(id, data) {
|
||||
return request({
|
||||
url: `/admin/editServices/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除特色服务
|
||||
* @param {number} id - 服务ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteService(id) {
|
||||
return request({
|
||||
url: `/admin/deleteServices/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
129
src/api/sitesettings.js
Normal file
@ -0,0 +1,129 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取基本信息
|
||||
* @param {number} tid 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getNormalInfos(tid) {
|
||||
return request({
|
||||
url: "/admin/normalInfos",
|
||||
method: "get",
|
||||
params: { tid }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存基本信息
|
||||
* @param {Object} data 要保存的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function saveNormalInfos(data) {
|
||||
return request({
|
||||
url: "/admin/saveNormalInfos",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录验证数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getVerifyInfos() {
|
||||
return request({
|
||||
url: "/admin/loginVerifyInfos",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存登录验证数据
|
||||
* @param {Object} data 要保存的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function saveVerifyInfos(data) {
|
||||
return request({
|
||||
url: "/admin/saveloginVerifyInfos",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取法律声明和隐私条款
|
||||
* @param {number} tid 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getLegalInfos(tid) {
|
||||
return request({
|
||||
url: "/admin/legalInfos",
|
||||
method: "get",
|
||||
params: { tid }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存法律声明和隐私条款
|
||||
* @param {Object} data 要保存的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function saveLegalInfos(data) {
|
||||
return request({
|
||||
url: "/admin/saveLegalInfos",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业信息
|
||||
* @param {number} tid 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getCompanyInfos(tid) {
|
||||
return request({
|
||||
url: "/admin/companyInfos",
|
||||
method: "get",
|
||||
params: { tid }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存企业信息
|
||||
* @param {Object} data 要保存的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function saveCompanyInfos(data) {
|
||||
return request({
|
||||
url: "/admin/saveCompanyInfos",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业SEO
|
||||
* @param {number} tid 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getCompanySeo(tid) {
|
||||
return request({
|
||||
url: "/admin/companySeo",
|
||||
method: "get",
|
||||
params: { tid }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存企业SEO
|
||||
* @param {Object} data 要保存的数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function saveCompanySeo(data) {
|
||||
return request({
|
||||
url: "/admin/saveCompanySeo",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
56
src/api/sms.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取短信网关配置
|
||||
*/
|
||||
export function getSmsInfo() {
|
||||
return request({
|
||||
url: "/admin/sms/info",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑短信网关配置
|
||||
*/
|
||||
export function editSmsInfo(data: any) {
|
||||
return request({
|
||||
url: "/admin/sms/editinfo",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送测试短信(入队任务,等待网关发送)
|
||||
*/
|
||||
export function sendTestSms(data: any) {
|
||||
return request({
|
||||
url: "/admin/sms/sendtest",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信任务列表(租户隔离)
|
||||
*/
|
||||
export function getSmsTaskList(params: { status?: string | number; phone?: string } = {}) {
|
||||
return request({
|
||||
url: "/admin/sms/taskList",
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑短信任务
|
||||
*/
|
||||
export function editSmsTask(id: number | string, data: any) {
|
||||
return request({
|
||||
url: `/admin/sms/taskEdit/${id}`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
84
src/api/tenant.js
Normal file
@ -0,0 +1,84 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/*************************************************
|
||||
****************** 租户相关接口 ******************
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* 获取租户列表
|
||||
* @param {Object} params 包含 page 和 pageSize
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getTenantList(params) {
|
||||
return request({
|
||||
url: "/admin/tenant/getTenant",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户详情
|
||||
* @param {number} id 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getTenantDetail(id) {
|
||||
return request({
|
||||
url: `/admin/tenant/getTenantDetail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建租户数据
|
||||
* @param {Object} data 租户数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function createTenant(data) {
|
||||
return request({
|
||||
url: "/admin/tenant/createTenant",
|
||||
method: "post",
|
||||
data: data,
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新租户数据
|
||||
* @param {Object} data 租户数据
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function editTenant(id, data) {
|
||||
return request({
|
||||
url: `/admin/tenant/editTenant/${id}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除租户数据
|
||||
* @param {number} id 租户ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deleteTenant(id) {
|
||||
return request({
|
||||
url: `/admin/tenant/deleteTenant/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验租户编码是否重复
|
||||
* @param {string} tenant_code 编码
|
||||
* @param {number} id 可选,当前编辑的租户ID
|
||||
*/
|
||||
export function checkTenantCode(tenant_code) {
|
||||
return request({
|
||||
url: '/admin/tenant/findTenantCode',
|
||||
method: 'get',
|
||||
params: { tenant_code }
|
||||
});
|
||||
}
|
||||
36
src/api/theme.js
Normal file
@ -0,0 +1,36 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取模板列表
|
||||
export function getThemeList() {
|
||||
return request({
|
||||
url: '/admin/theme',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 切换模板
|
||||
export function switchTheme(data) {
|
||||
return request({
|
||||
url: '/admin/theme/switch',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取模板数据
|
||||
export function getThemeData(params) {
|
||||
return request({
|
||||
url: '/admin/theme/data',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 保存模板数据
|
||||
export function saveThemeData(data) {
|
||||
return request({
|
||||
url: '/admin/theme/data',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
68
src/api/user.js
Normal file
@ -0,0 +1,68 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
//获取所有用户信息
|
||||
export function getAllUsers() {
|
||||
return request({
|
||||
url: '/admin/getAllUsers',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
//获取租户用户
|
||||
export function getTenantUsers(tenantId) {
|
||||
return request({
|
||||
url: `/admin/getTenantUsers/${tenantId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export function getUserInfo(userId) {
|
||||
return request({
|
||||
url: `/admin/getUserInfo/${userId}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
export function addUser(data) {
|
||||
return request({
|
||||
url: '/admin/addUser',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑用户信息
|
||||
export function editUser(userId, data) {
|
||||
return request({
|
||||
url: `/admin/editUser/${userId}`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新用户信息(编辑用户的别名)
|
||||
export function updateUserInfo(userId, data) {
|
||||
return editUser(userId, data);
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function deleteUser(userId) {
|
||||
return request({
|
||||
url: `/admin/deleteUser/${userId}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function changePassword(userId, data) {
|
||||
return request({
|
||||
url: '/admin/changePassword',
|
||||
method: 'post',
|
||||
data: {
|
||||
id: userId,
|
||||
password: data.newPassword
|
||||
},
|
||||
});
|
||||
}
|
||||
11
src/api/workbench.js
Normal file
@ -0,0 +1,11 @@
|
||||
// 文章管理相关API
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 获取文章列表
|
||||
export function GetCRMWorkbench(params) {
|
||||
return request({
|
||||
url: `/admin/workbench/crm`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
9
src/assets/css/all.min.css
vendored
Normal file
BIN
src/assets/images/default_avatar.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
6
src/assets/js/all.min.js
vendored
Normal file
353
src/assets/js/gt.0.5.0.js
Normal file
@ -0,0 +1,353 @@
|
||||
"v0.5.0 Geetest Inc.";
|
||||
|
||||
(function (window) {
|
||||
"use strict";
|
||||
if (typeof window === 'undefined') {
|
||||
throw new Error('Geetest requires browser environment');
|
||||
}
|
||||
|
||||
var document = window.document;
|
||||
var Math = window.Math;
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
|
||||
function _Object(obj) {
|
||||
this._obj = obj;
|
||||
}
|
||||
|
||||
_Object.prototype = {
|
||||
_each: function (process) {
|
||||
var _obj = this._obj;
|
||||
for (var k in _obj) {
|
||||
if (_obj.hasOwnProperty(k)) {
|
||||
process(k, _obj[k]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
function Config(config) {
|
||||
var self = this;
|
||||
new _Object(config)._each(function (key, value) {
|
||||
self[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
Config.prototype = {
|
||||
api_server: 'api.geetest.com',
|
||||
protocol: 'http://',
|
||||
typePath: '/gettype.php',
|
||||
fallback_config: {
|
||||
slide: {
|
||||
static_servers: ["static.geetest.com", "static.geevisit.com"],
|
||||
type: 'slide',
|
||||
slide: '/static/js/geetest.0.0.0.js'
|
||||
},
|
||||
fullpage: {
|
||||
static_servers: ["static.geetest.com", "static.geevisit.com"],
|
||||
type: 'fullpage',
|
||||
fullpage: '/static/js/fullpage.0.0.0.js'
|
||||
}
|
||||
},
|
||||
_get_fallback_config: function () {
|
||||
var self = this;
|
||||
if (isString(self.type)) {
|
||||
return self.fallback_config[self.type];
|
||||
} else if (self.new_captcha) {
|
||||
return self.fallback_config.fullpage;
|
||||
} else {
|
||||
return self.fallback_config.slide;
|
||||
}
|
||||
},
|
||||
_extend: function (obj) {
|
||||
var self = this;
|
||||
new _Object(obj)._each(function (key, value) {
|
||||
self[key] = value;
|
||||
})
|
||||
}
|
||||
};
|
||||
var isNumber = function (value) {
|
||||
return (typeof value === 'number');
|
||||
};
|
||||
var isString = function (value) {
|
||||
return (typeof value === 'string');
|
||||
};
|
||||
var isBoolean = function (value) {
|
||||
return (typeof value === 'boolean');
|
||||
};
|
||||
var isObject = function (value) {
|
||||
return (typeof value === 'object' && value !== null);
|
||||
};
|
||||
var isFunction = function (value) {
|
||||
return (typeof value === 'function');
|
||||
};
|
||||
var MOBILE = /Mobi/i.test(navigator.userAgent);
|
||||
var pt = MOBILE ? 3 : 0;
|
||||
|
||||
var callbacks = {};
|
||||
var status = {};
|
||||
|
||||
var nowDate = function () {
|
||||
var date = new Date();
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
var hours = date.getHours();
|
||||
var minutes = date.getMinutes();
|
||||
var seconds = date.getSeconds();
|
||||
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = '0' + month;
|
||||
}
|
||||
if (day >= 0 && day <= 9) {
|
||||
day = '0' + day;
|
||||
}
|
||||
if (hours >= 0 && hours <= 9) {
|
||||
hours = '0' + hours;
|
||||
}
|
||||
if (minutes >= 0 && minutes <= 9) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
if (seconds >= 0 && seconds <= 9) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
var currentdate = year + '-' + month + '-' + day + " " + hours + ":" + minutes + ":" + seconds;
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
var random = function () {
|
||||
return parseInt(Math.random() * 10000) + (new Date()).valueOf();
|
||||
};
|
||||
|
||||
var loadScript = function (url, cb) {
|
||||
var script = document.createElement("script");
|
||||
script.charset = "UTF-8";
|
||||
script.async = true;
|
||||
|
||||
// 对geetestçš„é™æ€èµ„æºæ·»åŠ crossOrigin
|
||||
if ( /static\.geetest\.com/g.test(url)) {
|
||||
script.crossOrigin = "anonymous";
|
||||
}
|
||||
|
||||
script.onerror = function () {
|
||||
cb(true);
|
||||
};
|
||||
var loaded = false;
|
||||
script.onload = script.onreadystatechange = function () {
|
||||
if (!loaded &&
|
||||
(!script.readyState ||
|
||||
"loaded" === script.readyState ||
|
||||
"complete" === script.readyState)) {
|
||||
|
||||
loaded = true;
|
||||
setTimeout(function () {
|
||||
cb(false);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
script.src = url;
|
||||
head.appendChild(script);
|
||||
};
|
||||
|
||||
var normalizeDomain = function (domain) {
|
||||
// special domain: uems.sysu.edu.cn/jwxt/geetest/
|
||||
// return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
|
||||
return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest
|
||||
};
|
||||
var normalizePath = function (path) {
|
||||
path = path.replace(/\/+/g, '/');
|
||||
if (path.indexOf('/') !== 0) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
};
|
||||
var normalizeQuery = function (query) {
|
||||
if (!query) {
|
||||
return '';
|
||||
}
|
||||
var q = '?';
|
||||
new _Object(query)._each(function (key, value) {
|
||||
if (isString(value) || isNumber(value) || isBoolean(value)) {
|
||||
q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
|
||||
}
|
||||
});
|
||||
if (q === '?') {
|
||||
q = '';
|
||||
}
|
||||
return q.replace(/&$/, '');
|
||||
};
|
||||
var makeURL = function (protocol, domain, path, query) {
|
||||
domain = normalizeDomain(domain);
|
||||
|
||||
var url = normalizePath(path) + normalizeQuery(query);
|
||||
if (domain) {
|
||||
url = protocol + domain + url;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
var load = function (config, send, protocol, domains, path, query, cb) {
|
||||
var tryRequest = function (at) {
|
||||
|
||||
var url = makeURL(protocol, domains[at], path, query);
|
||||
loadScript(url, function (err) {
|
||||
if (err) {
|
||||
if (at >= domains.length - 1) {
|
||||
cb(true);
|
||||
// report gettype error
|
||||
if (send) {
|
||||
config.error_code = 508;
|
||||
var url = protocol + domains[at] + path;
|
||||
reportError(config, url);
|
||||
}
|
||||
} else {
|
||||
tryRequest(at + 1);
|
||||
}
|
||||
} else {
|
||||
cb(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
tryRequest(0);
|
||||
};
|
||||
|
||||
|
||||
var jsonp = function (domains, path, config, callback) {
|
||||
if (isObject(config.getLib)) {
|
||||
config._extend(config.getLib);
|
||||
callback(config);
|
||||
return;
|
||||
}
|
||||
if (config.offline) {
|
||||
callback(config._get_fallback_config());
|
||||
return;
|
||||
}
|
||||
|
||||
var cb = "geetest_" + random();
|
||||
window[cb] = function (data) {
|
||||
if (data.status == 'success') {
|
||||
callback(data.data);
|
||||
} else if (!data.status) {
|
||||
callback(data);
|
||||
} else {
|
||||
callback(config._get_fallback_config());
|
||||
}
|
||||
window[cb] = undefined;
|
||||
try {
|
||||
delete window[cb];
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
load(config, true, config.protocol, domains, path, {
|
||||
gt: config.gt,
|
||||
callback: cb
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
callback(config._get_fallback_config());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var reportError = function (config, url) {
|
||||
load(config, false, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
|
||||
time: nowDate(),
|
||||
captcha_id: config.gt,
|
||||
challenge: config.challenge,
|
||||
pt: pt,
|
||||
exception_url: url,
|
||||
error_code: config.error_code
|
||||
}, function (err) {})
|
||||
}
|
||||
|
||||
var throwError = function (errorType, config) {
|
||||
var errors = {
|
||||
networkError: '网络错误',
|
||||
gtTypeError: 'gtå—æ®µä¸æ˜¯å—符串类型'
|
||||
};
|
||||
if (typeof config.onError === 'function') {
|
||||
config.onError(errors[errorType]);
|
||||
} else {
|
||||
throw new Error(errors[errorType]);
|
||||
}
|
||||
};
|
||||
|
||||
var detect = function () {
|
||||
return window.Geetest || document.getElementById("gt_lib");
|
||||
};
|
||||
|
||||
if (detect()) {
|
||||
status.slide = "loaded";
|
||||
}
|
||||
|
||||
window.initGeetest = function (userConfig, callback) {
|
||||
|
||||
var config = new Config(userConfig);
|
||||
|
||||
if (userConfig.https) {
|
||||
config.protocol = 'https://';
|
||||
} else if (!userConfig.protocol) {
|
||||
config.protocol = window.location.protocol + '//';
|
||||
}
|
||||
|
||||
// for KFC
|
||||
if (userConfig.gt === '050cffef4ae57b5d5e529fea9540b0d1' ||
|
||||
userConfig.gt === '3bd38408ae4af923ed36e13819b14d42') {
|
||||
config.apiserver = 'yumchina.geetest.com/'; // for old js
|
||||
config.api_server = 'yumchina.geetest.com';
|
||||
}
|
||||
|
||||
if(userConfig.gt){
|
||||
window.GeeGT = userConfig.gt
|
||||
}
|
||||
|
||||
if(userConfig.challenge){
|
||||
window.GeeChallenge = userConfig.challenge
|
||||
}
|
||||
|
||||
if (isObject(userConfig.getType)) {
|
||||
config._extend(userConfig.getType);
|
||||
}
|
||||
jsonp((config.api_server_v3 || [config.api_server || config.apiserver]), config.typePath, config, function (newConfig) {
|
||||
var type = newConfig.type;
|
||||
var init = function () {
|
||||
config._extend(newConfig);
|
||||
callback(new window.Geetest(config));
|
||||
};
|
||||
|
||||
callbacks[type] = callbacks[type] || [];
|
||||
var s = status[type] || 'init';
|
||||
if (s === 'init') {
|
||||
status[type] = 'loading';
|
||||
|
||||
callbacks[type].push(init);
|
||||
|
||||
load(config, true, config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) {
|
||||
if (err) {
|
||||
status[type] = 'fail';
|
||||
throwError('networkError', config);
|
||||
} else {
|
||||
status[type] = 'loaded';
|
||||
var cbs = callbacks[type];
|
||||
for (var i = 0, len = cbs.length; i < len; i = i + 1) {
|
||||
var cb = cbs[i];
|
||||
if (isFunction(cb)) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
callbacks[type] = [];
|
||||
}
|
||||
});
|
||||
} else if (s === "loaded") {
|
||||
init();
|
||||
} else if (s === "fail") {
|
||||
throwError('networkError', config);
|
||||
} else if (s === "loading") {
|
||||
callbacks[type].push(init);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
})(window);
|
||||
487
src/assets/js/gt4.js
Normal file
@ -0,0 +1,487 @@
|
||||
"v4.2.0 Geetest Inc.";
|
||||
|
||||
(function (window) {
|
||||
"use strict";
|
||||
if (typeof window === 'undefined') {
|
||||
throw new Error('Geetest requires browser environment');
|
||||
}
|
||||
|
||||
var document = window.document;
|
||||
var Math = window.Math;
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
var TIMEOUT = 10000;
|
||||
|
||||
function _Object(obj) {
|
||||
this._obj = obj;
|
||||
}
|
||||
|
||||
_Object.prototype = {
|
||||
_each: function (process) {
|
||||
var _obj = this._obj;
|
||||
for (var k in _obj) {
|
||||
if (_obj.hasOwnProperty(k)) {
|
||||
process(k, _obj[k]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
_extend: function (obj){
|
||||
var self = this;
|
||||
new _Object(obj)._each(function (key, value){
|
||||
self._obj[key] = value;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
var uuid = function () {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0;
|
||||
var v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
};
|
||||
|
||||
function Config(config) {
|
||||
var self = this;
|
||||
new _Object(config)._each(function (key, value) {
|
||||
self[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
Config.prototype = {
|
||||
apiServers: ['gcaptcha4.geetest.com','gcaptcha4.geevisit.com','gcaptcha4.gsensebot.com'],
|
||||
staticServers: ["static.geetest.com",'static.geevisit.com'],
|
||||
protocol: 'http://',
|
||||
typePath: '/load',
|
||||
fallback_config: {
|
||||
bypass: {
|
||||
staticServers: ["static.geetest.com",'static.geevisit.com'],
|
||||
type: 'bypass',
|
||||
bypass: '/v4/bypass.js'
|
||||
}
|
||||
},
|
||||
_get_fallback_config: function () {
|
||||
var self = this;
|
||||
if (isString(self.type)) {
|
||||
return self.fallback_config[self.type];
|
||||
} else {
|
||||
return self.fallback_config.bypass;
|
||||
}
|
||||
},
|
||||
_extend: function (obj) {
|
||||
var self = this;
|
||||
new _Object(obj)._each(function (key, value) {
|
||||
self[key] = value;
|
||||
})
|
||||
}
|
||||
};
|
||||
var isNumber = function (value) {
|
||||
return (typeof value === 'number');
|
||||
};
|
||||
var isString = function (value) {
|
||||
return (typeof value === 'string');
|
||||
};
|
||||
var isBoolean = function (value) {
|
||||
return (typeof value === 'boolean');
|
||||
};
|
||||
var isObject = function (value) {
|
||||
return (typeof value === 'object' && value !== null);
|
||||
};
|
||||
var isFunction = function (value) {
|
||||
return (typeof value === 'function');
|
||||
};
|
||||
var MOBILE = /Mobi/i.test(navigator.userAgent);
|
||||
|
||||
var callbacks = {};
|
||||
var status = {};
|
||||
|
||||
var random = function () {
|
||||
return parseInt(Math.random() * 10000) + (new Date()).valueOf();
|
||||
};
|
||||
|
||||
// bind 函数polify, ä¸å¸¦new功能的bind
|
||||
|
||||
var bind = function(target,context){
|
||||
if(typeof target !== 'function'){
|
||||
return;
|
||||
}
|
||||
var args = Array.prototype.slice.call(arguments,2);
|
||||
|
||||
if(Function.prototype.bind){
|
||||
return target.bind(context, args);
|
||||
}else {
|
||||
return function(){
|
||||
var _args = Array.prototype.slice.call(arguments);
|
||||
return target.apply(context,args.concat(_args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var toString = Object.prototype.toString;
|
||||
|
||||
var _isFunction = function(obj) {
|
||||
return typeof(obj) === 'function';
|
||||
};
|
||||
var _isObject = function(obj) {
|
||||
return obj === Object(obj);
|
||||
};
|
||||
var _isArray = function(obj) {
|
||||
return toString.call(obj) == '[object Array]';
|
||||
};
|
||||
var _isDate = function(obj) {
|
||||
return toString.call(obj) == '[object Date]';
|
||||
};
|
||||
var _isRegExp = function(obj) {
|
||||
return toString.call(obj) == '[object RegExp]';
|
||||
};
|
||||
var _isBoolean = function(obj) {
|
||||
return toString.call(obj) == '[object Boolean]';
|
||||
};
|
||||
|
||||
|
||||
function resolveKey(input){
|
||||
return input.replace(/(\S)(_([a-zA-Z]))/g, function(match, $1, $2, $3){
|
||||
return $1 + $3.toUpperCase() || "";
|
||||
})
|
||||
}
|
||||
|
||||
function camelizeKeys(input, convert){
|
||||
if(!_isObject(input) || _isDate(input) || _isRegExp(input) || _isBoolean(input) || _isFunction(input)){
|
||||
return convert ? resolveKey(input) : input;
|
||||
}
|
||||
|
||||
if(_isArray(input)){
|
||||
var temp = [];
|
||||
for(var i = 0; i < input.length; i++){
|
||||
temp.push(camelizeKeys(input[i]));
|
||||
}
|
||||
|
||||
}else {
|
||||
var temp = {};
|
||||
for(var prop in input){
|
||||
if(input.hasOwnProperty(prop)){
|
||||
temp[camelizeKeys(prop, true)] = camelizeKeys(input[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
var loadScript = function (url, cb, timeout) {
|
||||
var script = document.createElement("script");
|
||||
script.charset = "UTF-8";
|
||||
script.async = true;
|
||||
|
||||
// 对geetestçš„é™æ€èµ„æºæ·»åŠ crossOrigin
|
||||
if ( /static\.geetest\.com/g.test(url)) {
|
||||
script.crossOrigin = "anonymous";
|
||||
}
|
||||
|
||||
script.onerror = function () {
|
||||
cb(true);
|
||||
// 错误触å‘了,超时逻辑就ä¸ç”¨äº†
|
||||
loaded = true;
|
||||
};
|
||||
var loaded = false;
|
||||
script.onload = script.onreadystatechange = function () {
|
||||
if (!loaded &&
|
||||
(!script.readyState ||
|
||||
"loaded" === script.readyState ||
|
||||
"complete" === script.readyState)) {
|
||||
|
||||
loaded = true;
|
||||
setTimeout(function () {
|
||||
cb(false);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
script.src = url;
|
||||
head.appendChild(script);
|
||||
|
||||
setTimeout(function () {
|
||||
if (!loaded) {
|
||||
script.onerror = script.onload = null;
|
||||
script.remove && script.remove();
|
||||
cb(true);
|
||||
}
|
||||
}, timeout || TIMEOUT);
|
||||
};
|
||||
|
||||
var normalizeDomain = function (domain) {
|
||||
// special domain: uems.sysu.edu.cn/jwxt/geetest/
|
||||
// return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
|
||||
return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest
|
||||
};
|
||||
var normalizePath = function (path) {
|
||||
|
||||
path = path && path.replace(/\/+/g, '/');
|
||||
if (path.indexOf('/') !== 0) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
};
|
||||
var normalizeQuery = function (query) {
|
||||
if (!query) {
|
||||
return '';
|
||||
}
|
||||
var q = '?';
|
||||
new _Object(query)._each(function (key, value) {
|
||||
if (isString(value) || isNumber(value) || isBoolean(value)) {
|
||||
q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
|
||||
}
|
||||
});
|
||||
if (q === '?') {
|
||||
q = '';
|
||||
}
|
||||
return q.replace(/&$/, '');
|
||||
};
|
||||
var makeURL = function (protocol, domain, path, query) {
|
||||
domain = normalizeDomain(domain);
|
||||
|
||||
var url = normalizePath(path) + normalizeQuery(query);
|
||||
if (domain) {
|
||||
url = protocol + domain + url;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
var load = function (config, protocol, domains, path, query, cb, handleCb) {
|
||||
var tryRequest = function (at) {
|
||||
// 处ç†jsonp回调,这里为了ä¿è¯æ¯ä¸ªä¸åŒjsonp都有唯一的回调函数
|
||||
if(handleCb){
|
||||
var cbName = "geetest_" + random();
|
||||
// 需è¦ä¸Žé¢„先定义好cbname傿•°ï¼Œåˆ 除对象
|
||||
window[cbName] = bind(handleCb, null, cbName);
|
||||
query.callback = cbName;
|
||||
}
|
||||
var url = makeURL(protocol, domains[at], path, query);
|
||||
loadScript(url, function (err) {
|
||||
if (err) {
|
||||
// 超时或者出错的时候 移除回调
|
||||
if(cbName){
|
||||
try {
|
||||
window[cbName] = function(){
|
||||
window[cbName] = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (at >= domains.length - 1) {
|
||||
cb(true);
|
||||
// report gettype error
|
||||
} else {
|
||||
tryRequest(at + 1);
|
||||
}
|
||||
} else {
|
||||
cb(false);
|
||||
}
|
||||
}, config.timeout);
|
||||
};
|
||||
tryRequest(0);
|
||||
};
|
||||
|
||||
|
||||
var jsonp = function (domains, path, config, callback) {
|
||||
|
||||
var handleCb = function (cbName, data) {
|
||||
|
||||
// ä¿è¯åªæ‰§è¡Œä¸€æ¬¡ï¼Œå…¨éƒ¨è¶…时的情况下ä¸ä¼šå†è§¦å‘;
|
||||
|
||||
if (data.status == 'success') {
|
||||
callback(data.data);
|
||||
} else if (!data.status) {
|
||||
callback(data);
|
||||
} else {
|
||||
//æŽ¥å£æœ‰è¿”回,但是返回了错误状æ€ï¼Œè¿›å…¥æŠ¥é”™é€»è¾‘
|
||||
callback(data);
|
||||
}
|
||||
window[cbName] = undefined;
|
||||
try {
|
||||
delete window[cbName];
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
load(config, config.protocol, domains, path, {
|
||||
callback: '',
|
||||
captcha_id: config.captchaId,
|
||||
challenge: config.challenge || uuid(),
|
||||
client_type: config.clientType ? config.clientType : (MOBILE? 'h5':'web'),
|
||||
risk_type: config.riskType,
|
||||
user_info: config.userInfo,
|
||||
call_type: config.callType,
|
||||
lang: config.language? config.language : navigator.appName === 'Netscape' ? navigator.language.toLowerCase() : navigator.userLanguage.toLowerCase()
|
||||
}, function (err) {
|
||||
// ç½‘ç»œé—®é¢˜æŽ¥å£æ²¡æœ‰è¿”回,直接使用本地验è¯ç ,走宕机模å¼
|
||||
// 这里å¯ä»¥æ·»åŠ ç”¨æˆ·çš„é€»è¾‘
|
||||
if(err && typeof config.offlineCb === 'function'){
|
||||
// 执行自己的宕机
|
||||
config.offlineCb();
|
||||
return;
|
||||
}
|
||||
if(err){
|
||||
callback(config._get_fallback_config());
|
||||
}
|
||||
}, handleCb);
|
||||
};
|
||||
|
||||
var reportError = function (config, url) {
|
||||
load(config, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
|
||||
time: Date.now().getTime(),
|
||||
captcha_id: config.gt,
|
||||
challenge: config.challenge,
|
||||
exception_url: url,
|
||||
error_code: config.error_code
|
||||
}, function (err) {})
|
||||
}
|
||||
|
||||
var throwError = function (errorType, config, errObj) {
|
||||
var errors = {
|
||||
networkError: '网络错误',
|
||||
gtTypeError: 'gtå—æ®µä¸æ˜¯å—符串类型'
|
||||
};
|
||||
if (typeof config.onError === 'function') {
|
||||
config.onError({
|
||||
desc: errObj.desc,
|
||||
msg: errObj.msg,
|
||||
code: errObj.code
|
||||
});
|
||||
} else {
|
||||
throw new Error(errors[errorType]);
|
||||
}
|
||||
};
|
||||
|
||||
var detect = function () {
|
||||
return window.Geetest || document.getElementById("gt_lib");
|
||||
};
|
||||
|
||||
if (detect()) {
|
||||
status.slide = "loaded";
|
||||
}
|
||||
var GeetestIsLoad = function (fname) {
|
||||
var GeetestIsLoad = false;
|
||||
var tags = { js: 'script', css: 'link' };
|
||||
var tagname = fname && tags[fname.split('.').pop()];
|
||||
if (tagname !== undefined) {
|
||||
var elts = document.getElementsByTagName(tagname);
|
||||
for (var i in elts) {
|
||||
if ((elts[i].href && elts[i].href.toString().indexOf(fname) > 0)
|
||||
|| (elts[i].src && elts[i].src.toString().indexOf(fname) > 0)) {
|
||||
GeetestIsLoad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GeetestIsLoad;
|
||||
};
|
||||
window.initGeetest4 = function (userConfig,callback) {
|
||||
|
||||
var config = new Config(userConfig);
|
||||
if (userConfig.https) {
|
||||
config.protocol = 'https://';
|
||||
} else if (!userConfig.protocol) {
|
||||
config.protocol = window.location.protocol + '//';
|
||||
}
|
||||
|
||||
|
||||
if (isObject(userConfig.getType)) {
|
||||
config._extend(userConfig.getType);
|
||||
}
|
||||
|
||||
jsonp(config.apiServers , config.typePath, config, function (newConfig) {
|
||||
//错误æ•获,第一个load请求å¯èƒ½ç›´æŽ¥æŠ¥é”™
|
||||
var newConfig = camelizeKeys(newConfig);
|
||||
|
||||
if(newConfig.status === 'error'){
|
||||
return throwError('networkError', config, newConfig);
|
||||
}
|
||||
|
||||
var type = newConfig.type;
|
||||
if(config.debug){
|
||||
new _Object(newConfig)._extend(config.debug)
|
||||
}
|
||||
var init = function () {
|
||||
config._extend(newConfig);
|
||||
callback(new window.Geetest4(config));
|
||||
};
|
||||
|
||||
callbacks[type] = callbacks[type] || [];
|
||||
|
||||
var s = status[type] || 'init';
|
||||
if (s === 'init') {
|
||||
status[type] = 'loading';
|
||||
|
||||
callbacks[type].push(init);
|
||||
|
||||
if(newConfig.gctPath){
|
||||
load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
|
||||
if(err){
|
||||
throwError('networkError', config, {
|
||||
code: '60205',
|
||||
msg: 'Network failure',
|
||||
desc: {
|
||||
detail: 'gct resource load timeout'
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers : newConfig.staticServers || config.staticServers, newConfig.bypass || (newConfig.staticPath + newConfig.js), null, function (err) {
|
||||
if (err) {
|
||||
status[type] = 'fail';
|
||||
throwError('networkError', config, {
|
||||
code: '60204',
|
||||
msg: 'Network failure',
|
||||
desc: {
|
||||
detail: 'js resource load timeout'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
status[type] = 'loaded';
|
||||
var cbs = callbacks[type];
|
||||
for (var i = 0, len = cbs.length; i < len; i = i + 1) {
|
||||
var cb = cbs[i];
|
||||
if (isFunction(cb)) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
callbacks[type] = [];
|
||||
status[type] = 'init';
|
||||
}
|
||||
});
|
||||
} else if (s === "loaded") {
|
||||
// 判æ–gct是å¦éœ€è¦é‡æ–°åŠ è½½
|
||||
if(newConfig.gctPath && !GeetestIsLoad(newConfig.gctPath)){
|
||||
load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
|
||||
if(err){
|
||||
throwError('networkError', config, {
|
||||
code: '60205',
|
||||
msg: 'Network failure',
|
||||
desc: {
|
||||
detail: 'gct resource load timeout'
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
return init();
|
||||
} else if (s === "fail") {
|
||||
throwError('networkError', config, {
|
||||
code: '60204',
|
||||
msg: 'Network failure',
|
||||
desc: {
|
||||
detail: 'js resource load timeout'
|
||||
}
|
||||
});
|
||||
} else if (s === "loading") {
|
||||
callbacks[type].push(init);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
})(window);
|
||||
2
src/assets/less/index.less
Normal file
@ -0,0 +1,2 @@
|
||||
@import './reset.less';
|
||||
@import './style.less';
|
||||
192
src/assets/less/reset.less
Normal file
@ -0,0 +1,192 @@
|
||||
// reset.less - 现代 CSS 样式重置
|
||||
// 统一盒模型为 border-box
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// 基础字体与颜色设置
|
||||
html {
|
||||
// 基础字体大小 (1rem = 16px)
|
||||
font-size: 16px;
|
||||
// 平滑滚动
|
||||
scroll-behavior: smooth;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
// 继承父级字体设置
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5; // 舒适行高
|
||||
color: #333; // 基础文本色
|
||||
// background-color: #fff; // 基础背景色
|
||||
-webkit-text-size-adjust: 100%; // 防止iOS横屏字体放大
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// 移除默认边框
|
||||
img,
|
||||
iframe,
|
||||
embed,
|
||||
object,
|
||||
video {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// 图片与媒体元素自适应
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// 表格重置
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// 列表样式重置
|
||||
ul,
|
||||
ol,
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// 文本元素重置
|
||||
a {
|
||||
color: inherit; // 继承父级颜色
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// 标题元素重置
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// 表单元素重置
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
// 按钮样式重置
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// 输入框聚焦样式
|
||||
input:focus,
|
||||
select:focus,
|
||||
textarea:focus,
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// 文本区域不允许拖拽调整大小
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical; // 仅允许垂直调整
|
||||
}
|
||||
|
||||
// 移除占位符默认样式
|
||||
::-webkit-input-placeholder {
|
||||
color: #999;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #999;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #999;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #999;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// 清除浮动
|
||||
.clearfix::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
// 隐藏元素(屏幕阅读器可见)
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
432
src/assets/less/style.less
Normal file
@ -0,0 +1,432 @@
|
||||
// Element Plus Message z-index
|
||||
:root {
|
||||
--el-message-z-index: 9999;
|
||||
}
|
||||
|
||||
// body 样式
|
||||
body {
|
||||
// background-color: #f5f7fa;
|
||||
color: #303133;
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
}
|
||||
|
||||
// container-box 样式
|
||||
.container-box {
|
||||
// background-color: #ffffff;
|
||||
// border: 1px solid #ebeef5;
|
||||
padding: 24px;
|
||||
background-color: var(--el-bg-color);
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.04);
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
transition: background-color 0.3s, border-color 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.header-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pagination-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 14px 0 0 0;
|
||||
}
|
||||
|
||||
// 修复 ElMessage 显示问题
|
||||
// 只修复定位,保持 Element Plus 官方样式
|
||||
.el-message {
|
||||
// 确保消息固定在页面顶部中央,不受父容器影响
|
||||
position: fixed !important;
|
||||
z-index: var(--el-message-z-index, 9999) !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.wang-editor-wrapper{
|
||||
border: 1px solid #dcdfe6 !important;
|
||||
|
||||
.toolbar-container{
|
||||
border-bottom: 1px solid #dcdfe6 !important;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
:deep(.w-e-text),
|
||||
:deep(.w-e-text-container) {
|
||||
background-color: transparent !important;
|
||||
|
||||
* {
|
||||
color: #1a1a2e !important;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #1a1a2e !important;
|
||||
margin: 8px 0 !important;
|
||||
line-height: 1.8 !important;
|
||||
font-size: 14px !important;
|
||||
text-indent: 0 !important;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: 600 !important;
|
||||
color: #1a1a2e !important;
|
||||
}
|
||||
|
||||
em, i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
u {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
s, del {
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 28px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 24px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 18px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h6 {
|
||||
color: #1a1a2e !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3973ff !important;
|
||||
text-decoration: underline !important;
|
||||
|
||||
&:hover {
|
||||
color: #3973ff !important;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #f5f7fa !important;
|
||||
color: #1a1a2e !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
border-radius: 3px !important;
|
||||
padding: 2px 6px !important;
|
||||
font-family: 'Consolas', 'Monaco', monospace !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f5f7fa !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
border-radius: 4px !important;
|
||||
color: #1a1a2e !important;
|
||||
padding: 12px 16px !important;
|
||||
margin: 12px 0 !important;
|
||||
overflow-x: auto;
|
||||
|
||||
code {
|
||||
background-color: transparent !important;
|
||||
border: none !important;
|
||||
padding: 0 !important;
|
||||
color: #1a1a2e !important;
|
||||
font-size: 13px !important;
|
||||
line-height: 1.6 !important;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #3973ff !important;
|
||||
background-color: #f5f7fa !important;
|
||||
color: #606266 !important;
|
||||
padding: 8px 16px !important;
|
||||
margin: 12px 0 !important;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
width: 100% !important;
|
||||
|
||||
th, td {
|
||||
border: 1px solid #e4e7ed !important;
|
||||
background-color: #ffffff !important;
|
||||
color: #1a1a2e !important;
|
||||
padding: 8px 12px !important;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f5f7fa !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc !important;
|
||||
color: #1a1a2e !important;
|
||||
padding-left: 24px !important;
|
||||
margin: 8px 0 !important;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal !important;
|
||||
color: #1a1a2e !important;
|
||||
padding-left: 24px !important;
|
||||
margin: 8px 0 !important;
|
||||
}
|
||||
|
||||
li {
|
||||
color: #1a1a2e !important;
|
||||
line-height: 1.8 !important;
|
||||
margin: 4px 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid #e4e7ed !important;
|
||||
margin: 16px 0 !important;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
border-radius: 4px !important;
|
||||
margin: 8px 0 !important;
|
||||
}
|
||||
|
||||
video {
|
||||
max-width: 100% !important;
|
||||
border-radius: 4px !important;
|
||||
margin: 8px 0 !important;
|
||||
}
|
||||
|
||||
.w-e-panel-tab-content {
|
||||
color: #1a1a2e !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html.dark {
|
||||
.wang-editor-wrapper {
|
||||
border-color: #3d3d3d !important;
|
||||
background-color: #1a1a1a !important;
|
||||
|
||||
.toolbar-container {
|
||||
background-color: #2d2d2d !important;
|
||||
border-color: #3d3d3d !important;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
background-color: #1a1a1a !important;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #4d4d4d !important;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #2d2d2d !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.w-e-text),
|
||||
:deep(.w-e-text-container) {
|
||||
background-color: transparent !important;
|
||||
|
||||
* {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #e0e0e0 !important;
|
||||
margin: 8px 0 !important;
|
||||
line-height: 1.8 !important;
|
||||
font-size: 14px !important;
|
||||
text-indent: 0 !important;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: 600 !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
em, i {
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
u {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
s, del {
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 28px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 24px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 18px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
h6 {
|
||||
color: #e0e0e0 !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 16px 0 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4f84ff !important;
|
||||
text-decoration: underline !important;
|
||||
|
||||
&:hover {
|
||||
color: #4f84ff !important;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #2d2d2d !important;
|
||||
color: #e0e0e0 !important;
|
||||
border-color: #3d3d3d !important;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #2d2d2d !important;
|
||||
border-color: #3d3d3d !important;
|
||||
color: #e0e0e0 !important;
|
||||
|
||||
code {
|
||||
background-color: transparent !important;
|
||||
border: none !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left-color: #4f84ff !important;
|
||||
background-color: #2d2d2d !important;
|
||||
color: #b0b0b0 !important;
|
||||
}
|
||||
|
||||
table {
|
||||
border-color: #3d3d3d !important;
|
||||
|
||||
th, td {
|
||||
border-color: #3d3d3d !important;
|
||||
background-color: #1a1a1a !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #2d2d2d !important;
|
||||
}
|
||||
}
|
||||
|
||||
ul, ol, li {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top-color: #3d3d3d !important;
|
||||
}
|
||||
|
||||
img, video {
|
||||
max-width: 100% !important;
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
.w-e-panel-tab-content {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-form-item__label{
|
||||
min-width: 80px !important;
|
||||
}
|
||||
1
src/assets/svgs/brands/11ty.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M615.3 168.5c2.3 0 4.6 .7 6.6 2.2 1.9 1.4 3.1 3.3 3.8 5 1.4 3.3 1.8 7.3 1.8 11.3 0 2.2-.3 4.9-.7 7.6l0 .4-50.9 264.9 0 0c-4 22.1-8.5 39.4-13.6 51.7-5 12.1-10.9 21.6-18.6 27l0 0c-7.5 5.3-16.9 7.7-27.6 8l-3 0c-16 0-29.3-4.2-36.9-14.8-.1-.1-.1-.1-.2-.2-.1-.2-.3-.4-.5-.6l0 0c-1.8-2.4-2.5-5.2-2.9-7.4-.5-2.8-.7-6.1-.7-9.8 0-7.3 .6-13.5 2.1-18.2 1.4-4.4 4.8-10.4 12.2-10.4l1.3 .1c.2 0 .4 .1 .5 .1 .3 .1 .6 .1 .8 .2 .6 .1 1.3 .3 2.2 .6l7.6 2.2 .1 0 7.6 2.1c.9 .2 1.7 .4 2.2 .5 .4 .1 .6 .1 .7 .1 0 0 .1 0 .2-.1 .1-.1 .4-.2 .8-.6 .9-.9 2.2-2.6 3.6-5.7 2.6-5.8 4.2-14.7 4.2-27.4 0-.7-.3-3.4-1.3-8.9-.9-5.1-2.3-12.2-4.2-21.1l-56-232.9-.1-.4 0-.3c-.4-2.7-.7-5.3-.7-7.3 0-3.7 .4-7.5 1.7-10.6 .7-1.6 1.8-3.4 3.5-4.9 1.9-1.5 4.2-2.3 6.5-2.3l34.6 0c4.6 0 8.7 1.7 11.9 5l1.3 1.5c1.2 1.6 2 3.4 2.7 5.2 .9 2.4 1.5 5.1 2 8.1l30.4 161.2 23.8-160c.8-5.8 2.2-11.4 5.1-15.1 3-3.8 7.2-5.8 12-5.8l24 0zM375.1 34.6c2.6 0 5.1 .7 7.4 2.3 2.2 1.5 3.7 3.6 4.7 5.7 1.9 4 2.5 9.1 2.5 14.5l0 111.2c0 .1 0 .2 0 .3l32.4 0c2.5 0 5 .6 7.2 2.1 2.2 1.4 3.7 3.4 4.8 5.5 2 3.9 2.6 8.8 2.6 13.9l0 15.4c0 5-.6 9.8-2.6 13.7-1.1 2-2.6 4-4.8 5.4-2.2 1.4-4.7 2-7.1 2l-32.5 0 0 145.8c0 10.8 .7 19.5 2 26.2 1.4 6.9 3.1 10.9 4.7 12.9 1.2 1.5 2.2 2.5 3.1 3.2l2.2 1.4 .1 .1 2.9 .8c1.2 .2 2.6 .3 4.3 .3l20.3 0c4.5 0 8.9 1.7 11.8 5.8 2.6 3.6 3.3 8.1 3.3 12.2l0 17.2c0 4.5-.8 9.3-3.4 13.1-3 4.2-7.5 6-12.3 6l0 0-29.1 .1c-8 0-15-.6-21.2-1.7-6.7-1.3-13.4-4.1-20.1-8.1-7.2-4.4-13-10.3-17.5-17.8-4.5-7.5-7.9-17.5-10.5-29.5-2.6-12.2-3.9-26.6-3.9-43l0-144.9-13.4 0c-2.4 0-4.9-.6-7.1-2-2.2-1.4-3.7-3.4-4.8-5.4-2-3.9-2.6-8.7-2.6-13.7l0-15.4c0-5.1 .6-10 2.6-13.9 1.1-2.1 2.6-4 4.8-5.5 2.2-1.5 4.7-2.1 7.2-2.1l13.4 0 0-.6 5.2-111.2 0-.1 .3-3.9c.5-3.8 1.3-7.4 2.7-10.3 2.1-4.2 6-7.9 11.8-7.9l28.6 0zm-268 11.7c1.8 .3 3.6 .9 5.3 2.1 2.1 1.5 3.5 3.5 4.4 5.4 1.7 3.7 2.3 8.4 2.3 13.2l0 377.8c0 6.7-.6 12.6-2.4 17.1-.9 2.3-2.3 4.7-4.4 6.5-2.3 2-5.1 3-8.1 3l-43.7 0c-3 0-5.8-1.1-8.1-3.1-2.1-1.9-3.4-4.3-4.2-6.5-1.7-4.5-2.3-10.3-2.3-17l0-315.8c-4.8 1.2-8.7 2.2-11.5 2.9-1.9 .5-3.4 .8-4.4 1.1-.5 .1-.9 .2-1.2 .3-.1 0-.3 .1-.5 .1-.1 0-.2 0-.3 .1 0 0-.2 0-.3 0 0 0-.2 0-.4 0l0 0c-.1 0-.3 0-.4 0-.1 0-.2 0-.2 0-2.2 .1-4.5-.4-6.6-1.7-2.3-1.4-3.8-3.4-4.7-5.3-1.8-3.7-2.3-8.4-2.3-13l0-27.4c0-4.4 .7-8.8 2.6-12.4 2.1-3.9 5.5-6.6 9.8-7.6l75.5-19.5c1.4-.4 2.9-.5 4.4-.5l1.8 .1zm143.8-.5c1.8 .3 3.6 .9 5.2 2.1 2.1 1.5 3.5 3.5 4.4 5.4 1.7 3.7 2.2 8.4 2.2 13.2l0 377.8c0 6.7-.6 12.6-2.4 17.1-.9 2.3-2.3 4.7-4.4 6.5-2.3 2-5.1 3-8.1 3l-43.7 0c-3 0-5.8-1.1-8.1-3.1-2.1-1.9-3.4-4.3-4.2-6.5-1.7-4.5-2.3-10.3-2.3-17l0-315.8c-4.8 1.2-8.7 2.2-11.5 2.9-1.9 .5-3.4 .8-4.4 1.1-.5 .1-.9 .2-1.2 .3-.1 0-.3 .1-.5 .1-.1 0-.2 0-.3 .1-.1 0-.2 0-.3 0 0 0-.2 0-.4 0l0 0c-.1 0-.2 0-.3 0-.1 0-.2 0-.3 0-2.2 .1-4.5-.4-6.6-1.7-2.3-1.4-3.8-3.4-4.7-5.3-1.8-3.7-2.3-8.3-2.3-13l0-27.4c0-4.4 .7-8.7 2.6-12.4 2.1-3.9 5.5-6.6 9.8-7.6l75.4-19.4c1.4-.4 2.9-.5 4.4-.5l1.8 .1z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
src/assets/svgs/brands/42-group.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M320 96l0 320c21 0 41.8-4.1 61.2-12.2s37-19.8 51.9-34.7 26.6-32.5 34.7-51.9 12.2-40.2 12.2-61.2-4.1-41.8-12.2-61.2-19.8-37.1-34.7-51.9-32.5-26.6-51.9-34.7-40.2-12.2-61.2-12.2zM0 256L160 416 320 256 160 96 0 256zm480 0c0 21 4.1 41.8 12.2 61.2s19.8 37 34.7 51.9 32.5 26.6 51.9 34.7 40.2 12.2 61.2 12.2l0-320c-42.4 0-83.1 16.9-113.1 46.9S480 213.6 480 256z"/></svg>
|
||||
|
After Width: | Height: | Size: 664 B |
1
src/assets/svgs/brands/500px.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M71.8 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2l.3 0 0-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5S151 163.3 126.3 188c-.3 .3-16 16.5-21.2 23.9l-.5 .6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8L70.2 20c0-5 3.9-10.5 10.5-10.5L322 9.5c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1l-223.2 0 0 132.9 .3 0c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zM135.1 83.5c-.5 4.2 4.6 24.5 14.6 20.6 124.8-47.5 202.8 40.4 209.4 40.4 4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM361.5 414.7c-110 109.9-299 60.8-332-104.2 0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM182.1 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6 .2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2l-17.3-17.3 18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L218.2 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L202.5 284c-18.1 17.9-20.4 19.2-20.4 22.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/svgs/brands/accessible-icon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46C105.5 165.3 64.9 120 95 93.1l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6l-58.4 66.5 106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zM359 101.8A50.9 50.9 0 1 0 359 0 50.9 50.9 0 1 0 359 101.8zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1L57.2 260.7C36.4 287 24 320.3 24 356.4 24 487.1 174.7 557.8 275.4 478.9l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 949 B |
1
src/assets/svgs/brands/accusoft.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M322.1 252l0-1-51.2-65.8s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7 .8 0 114.5-36.6 114.5-36.6 .5-.6-.1-.1 .6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3zM482.2 372.1c13.3 16.1 20.7 13.3 30.8 9.3 3.2-1.2 115.4-47.6 117.8-48.9 8-4.3-1.7-16.7-7.2-23.4-2.1-2.5-205.1-245.6-207.2-248.3-9.7-12.2-14.3-12.9-38.4-12.8-10.2 0-106.8 .5-116.5 .6-19.2 .1-32.9-.3-19.2 16.9 7.7 9.5 234.2 299.7 239.9 306.6zm152.7 1.6c-2.3-.3-24.6-4.7-38-7.2 0 0-115 50.4-117.5 51.6-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1 .2-9.6 .8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6 .2 2.5 2 2.6 4.6 3.5 2.7 .8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/svgs/brands/adn.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M256 167.5l64.9 98.8-129.8 0 64.9-98.8zM8 256a248 248 0 1 1 496 0 248 248 0 1 1 -496 0zm396.2 82.7l-148.2-223.2-148.2 223.2 30.4 0 33.6-51.7 168.6 0 33.6 51.7 30.2 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 477 B |
1
src/assets/svgs/brands/adversal.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M482.1 32L28.7 32C5.8 32 0 37.9 0 60.9L0 451.1C0 474.4 5.8 480 28.7 480l453.4 0c24.4 0 29.9-5.2 29.9-29.7l0-388.1c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4 .4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9l-394.9 0c-7.4 0-18.2 4.8-17.8-10.7 .4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5l0 291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5l0-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6 .4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1 .2-.1 .3-.1 .5zM417.4 334.1c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2 .4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zM122.6 369.4c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/svgs/brands/affiliatetheme.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1 105.5 88.2 170.8 48.3 199.9 69.9s11.1 96.6-40.2 167.5zm351.2-57.3c-73.8 123.4-191.9 187.7-264.5 143.6-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9 .1-8.5-.3-16.8-1-25z"/></svg>
|
||||
|
After Width: | Height: | Size: 627 B |
1
src/assets/svgs/brands/airbnb.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M224.5 373.1c-25.2-31.7-40.1-59.4-45-83.2-22.5-88 112.6-88 90.1 0-5.4 24.2-20.3 52-45 83.2l-.1 0zm138.2 73.2c-42.1 18.3-83.7-10.9-119.3-50.5 103.9-130.1 46.1-200-18.8-200-54.9 0-85.2 46.5-73.3 100.5 6.9 29.2 25.2 62.4 54.4 99.5-32.5 36-60.5 52.7-85.2 54.9-50 7.4-89.1-41.1-71.3-91.1 15.1-39.2 111.7-231.2 115.9-241.6 15.8-30.1 25.6-57.4 59.4-57.4 32.3 0 43.4 25.9 60.4 59.9 36 70.6 89.4 177.5 114.8 239.1 13.2 33.1-1.4 71.3-37 86.6zm47-136.1c-128.9-274.3-136-278.2-185.1-278.2-45.5 0-64.9 31.7-84.7 72.8-106.2 212.3-116.4 242.4-117.3 245-25.2 69.3 26.7 130.2 89.6 130.2 21.7 0 60.6-6.1 112.4-62.4 58.7 63.8 101.3 62.4 112.4 62.4 62.9 .1 114.9-60.9 89.6-130.2 0-3.9-16.8-38.9-16.8-39.6l0 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 1000 B |
1
src/assets/svgs/brands/algolia.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M256 0c-139.9 0-254 112.7-256 252.1-2 141.5 112.9 258.7 254.5 259.5 43.7 .3 85.9-10.4 123.3-30.7 3.6-2 4.2-7 1.1-9.7l-24-21.2c-4.9-4.3-11.8-5.5-17.8-3-26.1 11.1-54.5 16.8-83.7 16.4-114.4-1.5-206.9-96.6-205.1-211 1.8-112.9 94.3-204.2 207.7-204.2l207.7 0 0 369-117.8-104.7c-3.8-3.4-9.7-2.7-12.7 1.3-18.9 25-49.7 40.6-83.9 38.2-47.5-3.3-85.9-41.5-89.5-88.9-4.2-56.6 40.6-103.9 96.3-103.9 50.4 0 91.9 38.8 96.2 88 .4 4.4 2.4 8.5 5.7 11.4l30.7 27.2c3.5 3.1 9 1.2 9.9-3.4 2.2-11.8 3-24.2 2.1-36.8-4.9-72-63.3-130-135.4-134.4-82.7-5.1-151.8 59.5-154 140.6-2.1 78.9 62.6 147 141.6 148.7 33 .7 63.6-9.6 88.3-27.6L495 509.4c6.6 5.8 17 1.2 17-7.7l0-492c0-5.4-4.4-9.7-9.7-9.7L256 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 981 B |
1
src/assets/svgs/brands/alipay.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M377.7 32L70.3 32C31.4 32 0 63.4 0 102.3L0 409.7C0 448.6 31.4 480 70.3 480l307.5 0c38.5 0 69.8-31.1 70.3-69.6-46-25.6-110.6-60.3-171.6-88.4-32.1 44-84.1 81-148.6 81-70.6 0-93.7-45.3-97-76.4-4-39 14.9-81.5 99.5-81.5 35.4 0 79.4 10.2 127.1 25 16.5-30.1 26.5-60.3 26.5-60.3l-178.2 0 0-16.7 92.1 0 0-31.2-109.4 0 0-19 109.4 0 0-50.4 50.9 0 0 50.4 109.4 0 0 19-109.4 0 0 31.2 88.8 0s-15.2 46.6-38.3 90.9c48.9 16.7 100 36 148.6 52.7l0-234.4c.2-38.7-31.2-70.3-69.9-70.3zM47.3 323c1 20.2 10.2 53.7 69.9 53.7 52.1 0 92.6-39.7 117.9-72.9-44.6-18.7-84.5-31.4-109.4-31.4-67.4 0-79.4 33.1-78.4 50.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 897 B |
1
src/assets/svgs/brands/amazon-pay.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M14 325.3c2.3-4.2 5.2-4.9 9.7-2.5 10.4 5.6 20.6 11.4 31.2 16.7 40.6 20.2 83.3 35.8 127.4 46.3 20.8 5 41.9 9 63.2 11.8 31.5 4.2 63.2 6 95 5.2 17.4-.4 34.8-1.8 52.1-3.8 56.2-6.6 111.1-21 163.3-42.8 2.9-1.2 5.9-2 9.1-1.2 6.7 1.8 9 9 4.1 13.9-3 2.7-6.2 5.2-9.6 7.4-30.7 21.1-64.2 36.4-99.6 47.9-24.5 7.9-49.6 13.8-75.1 17.6-17.6 2.7-35.4 4.3-53.2 4.8-.8 0-1.7 .2-2.5 .3l-21.1 0c-.8-.1-1.7-.2-2.5-.3-3.6-.2-7.2-.3-10.7-.4-16.9-.8-33.7-2.5-50.4-5.3-27.4-4.5-54.3-11.5-80.4-20.9-53.7-19.4-103.1-48.9-145.6-87-1.8-1.6-3-3.8-4.4-5.7l0-2zM172 65.1l-4.3 .6c-13.8 1.7-26.8 6.9-38 15.1-2.4 1.7-4.6 3.5-7.1 5.4-.2-.4-.3-.9-.4-1.4-.4-2.7-.8-5.5-1.3-8.2-.7-4.6-3-6.6-7.6-6.6l-11.5 0c-6.9 0-8.2 1.3-8.2 8.2l0 209.3c0 1 0 2 .1 3 .2 3 2 4.9 4.9 5 7 .1 14.1 .1 21.1 0 2.9 0 4.7-2 5-5 .1-1 .1-2 .1-3l0-72.4c1.1 .9 1.7 1.4 2.2 1.9 17.9 14.9 38.5 19.8 61 15.4 20.4-4 34.6-16.5 43.8-34.9 7-13.9 9.9-28.7 10.3-44.1 .5-17.1-1.2-33.9-8.1-49.8-8.5-19.6-22.6-32.5-43.9-36.9-3.2-.7-6.5-1-9.8-1.5-2.8-.1-5.5-.1-8.3-.1zM124.6 107c-.1-.7 .1-1.3 .4-1.9s.8-1.1 1.3-1.4c13.7-9.5 28.8-14.5 45.6-13.2 14.9 1.1 27.1 8.4 33.5 25.9 3.9 10.7 4.9 21.8 4.9 33 0 10.4-.8 20.6-4 30.6-6.8 21.3-22.4 29.4-42.6 28.5-14-.6-26.2-6-37.4-13.9-.6-.3-1-.8-1.3-1.4s-.4-1.2-.4-1.9c.1-14.1 0-28.1 0-42.2s.1-28 0-42.1zM330.3 65.1c-1 .1-2 .3-2.9 .4-9.7 .4-19.4 1.8-28.9 4.1-6.1 1.6-12 3.8-17.9 5.8-3.6 1.2-5.4 3.8-5.3 7.7 .1 3.3-.1 6.6 0 9.9 .1 4.8 2.1 6.1 6.8 4.9 7.8-2 15.6-4.2 23.5-5.7 12.3-2.3 24.7-3.3 37.2-1.4 6.5 1 12.6 2.9 16.8 8.4 3.7 4.8 5.1 10.5 5.3 16.4 .3 8.3 .2 16.6 .3 24.9 0 .5-.1 .9-.2 1.4-.5-.1-.9 0-1.3-.1-10.5-2.6-21.2-4.2-32-4.9-11.3-.6-22.5 .1-33.3 3.9-12.9 4.5-23.3 12.3-29.4 24.9-4.7 9.8-5.4 20.2-3.9 30.7 2 14 9 24.8 21.4 31.7 11.9 6.6 24.8 7.4 37.9 5.4 15.1-2.3 28.5-8.7 40.3-18.4 .5-.4 1-.8 1.6-1.1 .6 3.8 1.1 7.4 1.8 11 .6 3.1 2.5 5.1 5.4 5.2 5.4 .1 10.9 .1 16.3 0 1.3 0 2.5-.5 3.4-1.4s1.4-2.1 1.5-3.3c.1-.9 .1-1.9 .1-2.8l0-106c0-4.3-.3-8.6-.9-12.9-1.9-12.9-7.4-23.5-19-30.4-6.7-4-14.1-6-21.8-7.1-3.6-.5-7.2-.8-10.8-1.3-3.9 .1-7.9 .1-11.9 .1zm35 127.7c0 .6-.1 1.2-.3 1.7s-.7 1-1.2 1.3c-11.2 8.1-23.5 13.5-37.4 14.9-5.7 .6-11.4 .4-16.8-1.8-3-1.1-5.6-2.9-7.8-5.2s-3.7-5.1-4.6-8.1c-2-6.3-2-13.1-.1-19.4 2.5-8.3 8.4-13 16.4-15.6 8-2.4 16.5-3.2 24.8-2.2 8.4 .7 16.6 2.3 25 3.4 1.6 .2 2.1 1 2.1 2.6-.1 4.8 0 9.5 0 14.3s-.2 9.4-.1 14.1zM625.2 322.2c-1-5-4.8-6.9-9.1-8.3-6.8-2.1-13.9-3.5-21-3.9-13.1-1.1-26.3-.5-39.2 1.9-14.3 2.7-27.9 7.3-40 15.6-1.4 .9-2.7 2.1-3.7 3.5-.4 .6-.6 1.3-.7 1.9s0 1.4 .2 2.1c.4 1.5 2.1 1.9 3.6 1.8 .7 0 1.5 0 2.2-.1 7.8-.8 15.5-1.7 23.3-2.5 11.4-1.1 22.9-1.8 34.3-.9 4.9 .4 9.7 1.3 14.4 2.7 5.1 1.4 7.4 5.2 7.6 10.4 .4 8-1.4 15.7-3.5 23.3-4.1 15.4-10 30.3-15.8 45.1-.4 1-.8 2-1 3-.5 2.9 1.2 4.8 4.1 4.1 1.8-.4 3.4-1.3 4.8-2.5 4.5-4.2 8.8-8.7 12.7-13.4 12.8-16.4 20.3-35.3 24.7-55.6 .8-3.6 1.4-7.3 2.1-10.9l0-17.3zM493.1 199c-12.9-35.7-25.8-71.4-38.7-107.2-2-5.7-4.2-11.3-6.3-16.9-1.1-2.9-3.2-4.8-6.4-4.8-7.6-.1-15.2-.2-22.9-.1-2.5 0-3.7 2-3.2 4.5 .5 2.1 1.1 4.1 1.9 6.1 19.6 48.5 39.3 97 59.1 145.5 1.7 4.1 2.1 7.6 .2 11.8-3.3 7.3-5.9 15-9.3 22.3-3 6.5-8 11.4-15.2 13.3-5 1.3-10.2 1.7-15.4 1.1-2.5-.2-5-.8-7.5-1-3.4-.2-5.1 1.3-5.2 4.8-.1 3.3-.1 6.6 0 9.9 .1 5.5 2 8 7.4 8.9 5.6 1.1 11.2 1.8 16.9 2 17.1 .4 30.7-6.5 39.5-21.4 3.5-5.9 6.6-12 9.2-18.4 23.7-59.8 47.2-119.7 70.6-179.6 .7-1.8 1.3-3.6 1.6-5.5 .4-2.8-.9-4.4-3.7-4.4-6.6-.1-13.3 0-19.9 0-1.7-.1-3.4 .3-4.7 1.3s-2.4 2.3-3 3.9c-.5 1.4-1.1 2.7-1.6 4.1l-34.8 100c-2.5 7.2-5.1 14.5-7.7 22.2-.4-1.1-.6-1.7-.9-2.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
1
src/assets/svgs/brands/amazon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M257.7 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56s-32.3-25.3-32.3-52.8l0-147.1C341.5 89 317 32 229.2 32 141.2 32 94.5 87 94.5 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8l0 40.6zM393.7 413c-7.7 10-70 67-174.5 67S34.7 408.5 10.2 379c-6.8-7.7 1-11.3 5.5-8.3 73.3 44.5 187.8 117.8 372.5 30.3 7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z"/></svg>
|
||||
|
After Width: | Height: | Size: 963 B |
1
src/assets/svgs/brands/amilia.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M240.2 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1l0 38.5C203.1 227.7 78.3 251 46.8 264.2 11.3 280.5 16.4 357.7 16.4 376S31.6 480 141.3 480c47.8 0 113.7-20.7 153.3-42.1l0 25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5 .3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1l0-296.6c-.1-80.3-57.9-136-192-136zm50.2 348c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7 0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5l0 106.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 855 B |
1
src/assets/svgs/brands/android.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M420.5 253.9a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm-265.1 0a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm273.7-96.5l47.9-83c.8-1.1 1.3-2.4 1.5-3.8s.2-2.7-.1-4.1-.9-2.6-1.7-3.7-1.8-2-3-2.7-2.5-1.1-3.9-1.3-2.7 0-4 .4-2.5 1.1-3.6 1.9-1.9 2-2.5 3.2l-48.5 84.1c-38.8-17.4-80.8-26.4-123.3-26.4s-84.5 9-123.3 26.4L116.2 64.4c-.6-1.2-1.5-2.3-2.5-3.2s-2.3-1.5-3.6-1.9-2.7-.5-4-.4-2.7 .6-3.9 1.3-2.2 1.6-3 2.7-1.4 2.4-1.7 3.7-.3 2.7-.1 4.1 .8 2.6 1.5 3.8l47.9 83C64.5 202.2 8.2 285.5 0 384l576 0c-8.2-98.5-64.5-181.8-146.9-226.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 817 B |
1
src/assets/svgs/brands/angellist.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M315.6 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1-9.7-28.5-55.1-172.5-95.1-172.5-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7-.1 72.2 68.3 148.6 164.5 148.6 118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM280.2 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM110.8 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM108.5 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7 .1-7.7 12.7-21.1 20.4-21.1zM292.8 430.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3 .3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7 .1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
src/assets/svgs/brands/angrycreative.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2-47.3 115.4-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8 12.9-120.1-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8-32.8 2-59.7-20.9-56.4-58.2 2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6 32.1 110.6 8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7c-6.7-12.4-14.4-16.6-26.3-15.8-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4L145 326.3c14.2-.9 27.5-2.1 28.8-16.1zM194.9 381l5.8-60c-5 13.5-14.7 21.1-27.9 26.6L194.9 381zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zM160.2 261.4l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8 .3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1 .6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
src/assets/svgs/brands/angular.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M185.7 268.1l76.2 0-38.1-91.6-38.1 91.6zM223.8 32L16 106.4 47.8 382.1 223.8 480 399.8 382.1 431.6 106.4 223.8 32zM354 373.8l-48.6 0-26.2-65.4-110.6 0-26.2 65.4-48.7 0 130.1-292.3 130.2 292.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 502 B |
1
src/assets/svgs/brands/app-store-ios.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M400 32L48 32C21.5 32 0 53.5 0 80L0 432c0 26.5 21.5 48 48 48l352 0c26.5 0 48-21.5 48-48l0-352c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9L84 330.6c-11 0-20-9-20-20s9-20 20-20l51 0 65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6 62.1 0c20.2 0 31.5 23.7 22.7 40zm98.1 0l-29 0 19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102l52 0c11 0 20 9 20 20 0 11.1-9 20-20 20z"/></svg>
|
||||
|
After Width: | Height: | Size: 981 B |
1
src/assets/svgs/brands/app-store.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5s13.1 18.1 7.5 27.9l-87.5 151.5 63.3 0c20.5 0 32 24.1 23.1 40.8l-185.5 0c-11.3 0-20.4-9.1-20.4-20.4s9.1-20.4 20.4-20.4l52 0 66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5s-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7l53.1 0c11.3 0 20.4 9.1 20.4 20.4S410.5 318 399.2 318l-29.5 0 19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8a248 248 0 1 0 0 496 248 248 0 1 0 0-496zM40 256a216 216 0 1 1 432 0 216 216 0 1 1 -432 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 990 B |
1
src/assets/svgs/brands/apper.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M42.1 239.1c22.2 0 29 2.8 33.5 14.6l.8 0 0-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8l-38.6 0c.3-13.9 1.5-19.1 5.8-24.4 7.3-8.8 18.9-11.8 46.1-11.8 33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7l0 76.3-38.3 0 1.3-19.1-1 0c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zM137 192.3l38.3 0-1.5 20.6 .8 0c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2l-.8 0 0 70.3-39.5 0 0-169zM217.9 253c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7l38.3 0-1.5 20.6 .8 0c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2l-.8 0 0 70.3-39.5 0 0-169 .1 0zM356.7 253c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7l0 11.1-75.3 0c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9l37.5 0 0 2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3 38.3 0zm55.6-45.3l38.3 0-1.8 19.9 .7 0c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3l-35 0c.3-1.8 .3-3.3 .3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3l0 68-38.3 0 0-118.5 .1 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
src/assets/svgs/brands/apple-pay.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8zm10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9 .3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1zm100.4-36.2l0 194.9 30.3 0 0-66.6 41.9 0c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64l-73.2 0zM258.5 165l34.9 0c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8l-34.8 0 0-77.4zM420.7 335.9c19 0 36.6-9.6 44.6-24.9l.6 0 0 23.4 28 0 0-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6l27.3 0c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5l0 10.8-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5 .1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1 0 11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4l53.1-149-30.8 0-35.6 115.1-.6 0-35.6-115.1-31.6 0 51.2 141.9-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5l0 23.4c1.8 .4 9.3 .7 11.6 .7z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/svgs/brands/apple.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M319.1 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7-55.8 .9-115.1 44.5-115.1 133.2 0 26.2 4.8 53.3 14.4 81.2 12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zM262.5 104.5c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 759 B |
1
src/assets/svgs/brands/artstation.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M2.1 377.4l43 74.3c4.3 8.5 10.8 15.7 18.9 20.7s17.4 7.6 27 7.6l285.4 0-59.2-102.6-315.1 0zM501.9 350L335.7 59.3c-4.4-8.2-10.9-15.1-18.9-20S299.7 32 290.4 32l-88.4 0 257.3 447.6 40.7-70.5c1.9-3.2 21-29.7 2-59.1zM275.2 304.5l-115.5-200-115.5 200 231 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 561 B |
1
src/assets/svgs/brands/asymmetrik.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M517.5 309.2c38.8-40 58.1-80 58.5-116.1 .8-65.5-59.4-118.2-169.4-135-128.7-19.7-288.5 15.5-406.6 82.4 52-26.5 110.6-48.2 170.7-58.2 74.5-20.5 153-25.4 221.3-14.8 152.5 23.8 196.8 127.5 98.8 231.7-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7 101.6 0 22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1 135.5 0-32.6-53.1c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8 101.6 0-73.4-110.4c18.5-12.1 35-25.5 48.9-39.8zM329.9 389.7l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 1009 B |
1
src/assets/svgs/brands/atlassian.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M152.2 236.4c-7.7-8.2-19.7-7.7-24.8 2.8L1.6 490.2c-5 10 2.4 21.7 13.4 21.7l175 0c5.8 .1 11-3.2 13.4-8.4 37.9-77.8 15.1-196.3-51.2-267.1zM244.4 8.1c-122.3 193.4-8.5 348.6 65 495.5 2.5 5.1 7.7 8.4 13.4 8.4L497 512c11.2 0 18.4-11.8 13.4-21.7 0 0-234.5-470.6-240.4-482.3-5.3-10.6-18.8-10.8-25.6 .1z"/></svg>
|
||||
|
After Width: | Height: | Size: 605 B |
1
src/assets/svgs/brands/audible.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M640 199.9l0 54-320 200-320-199.9 0-54 320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6s-135.5 36.7-172.6 92.4l.3 0c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zM225.4 290.7c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1C235.4 56.8 421.8 84.7 521.1 223.2l.7 1 48.8-30.4c-53.5-81.7-145.8-135.7-250.7-135.7-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 799 B |
1
src/assets/svgs/brands/autoprefixer.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M318.4 16l-161 480 77.5 0 25.4-81.4 119.5 0 25.2 81.4 77.5 0-164.1-480zM278.1 357.9l41.2-130.4 1.5 0 40.9 130.4-83.6 0zM640 405L630 373.6 462.1 358 481.5 414.5 640 405zM177.9 358L10 373.7 0 405 158.5 414.4 177.9 358z"/></svg>
|
||||
|
After Width: | Height: | Size: 527 B |
1
src/assets/svgs/brands/avianex.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M453.2 32l-312 0C102.3 32 65 63.2 57.9 101.7L1.3 410.3C-5.8 448.8 20 480 59 480l312 0c38.9 0 76.2-31.2 83.3-69.7L511 101.8C518 63.2 492.2 32 453.2 32zM395 379.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9l-20.5-29.6-68.8-99.8 18.8-28.9 8.9-4.8 103.1 112.4 4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z"/></svg>
|
||||
|
After Width: | Height: | Size: 801 B |
1
src/assets/svgs/brands/aviato.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M107.2 283.5l-19-41.8-52.1 0-19 41.8-17.1 0 62.2-131.4 62.2 131.4-17.2 0zm-45-98.1l-19.6 42.5 39.2 0-19.6-42.5zM174.9 287.8l-62.2-131.4 17.1 0 45.1 96 45.1-96 17 0-62.1 131.4zm80.6-4.3l0-127.1 15.5 0 0 127.1-15.5 0zM464.6 167.9l0 115.6-17.3 0 0-115.6-41.2 0 0-11.5 99.6 0 0 11.5-41.1 0zM640 218.8c0 9.2-1.7 17.8-5.1 25.8s-8.2 15.1-14.2 21.1-13.1 10.8-21.1 14.2-16.6 5.1-25.8 5.1-17.8-1.7-25.8-5.1-15.1-8.2-21.1-14.2-10.8-13-14.2-21.1c-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8 8.2-15.1 14.2-21.1 13-8.4 21.1-11.9c8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1 15.1 5.8 21.1 11.9c6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3s-6.2-11.7-10.8-16.3-10-8.2-16.2-10.9-12.8-4-19.8-4-13.6 1.3-19.8 4-11.6 6.3-16.2 10.9-8.2 10-10.8 16.3-3.9 13.1-3.9 20.3c0 7.3 1.3 14 3.9 20.3s6.2 11.7 10.8 16.3 10 8.2 16.2 10.9 12.8 4 19.8 4 13.6-1.3 19.8-4 11.6-6.3 16.2-10.9 8.2-10 10.8-16.3 3.9-13.1 3.9-20.3zm-94.8 96.7l0-6.3 88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2 .3-2 .5-4.2 .6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3 23.8 0 19 41.8 17.1 0-62.2-131.4-62.2 131.4 17.1 0 19-41.8 23.6 0-1.1 26.4s-22.7 6.5-25.5 23.7c-.1 .3-.1 .7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3 .3 4.4 .6 6.5 .3 2.6 .8 5 1.4 7.2l-242.9-13.5 88.9 10 0 6.3c-5.9 .9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4s12.4-5.6 12.4-12.4c0-6.2-4.6-11.3-10.5-12.2l0-5.8 80.3 9 0 5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2s12.4-3.4 12.4-10.2c0-6-4.3-11-9.9-12.1l0-4.9 28.4 3.2 0 23.7-5.9 0 0 13.9 5.9 0 0-6.6 5 0 0 6.6 5.9 0 0-13.8-5.9 0 0-23.2 38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1 .2-.1 12.1 4.1 0 .1-5 5.2 0 .1 5 4.1 0-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3 0 23.2-5.9 0 0 13.8 5.9 0 0-6.6 5 0 0 6.6 5.9 0 0-13.8-5.9 0 0-23.7 28.4-3.2 0 4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2s12.4-3.4 12.4-10.2c0-6-4.3-11-9.9-12.1l0-5.4 80.3-9 0 5.8c-5.9 .9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4s12.4-5.6 12.4-12.4c-.2-6.3-4.7-11.4-10.7-12.3zM328.9 227.9l19.6-42.5 19.6 42.5-17.9 0-1.7-40.3-1.7 40.3-17.9 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
1
src/assets/svgs/brands/aws.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M180.4 203c-.7 22.6 10.6 32.7 10.9 39-.1 1.3-.6 2.5-1.3 3.6s-1.7 2-2.8 2.6l-12.8 9c-1.7 1.2-3.6 1.8-5.6 1.9-.4 0-8.2 1.8-20.5-25.6-7.5 9.4-17 16.9-27.9 22s-22.7 7.7-34.7 7.5c-16.3 .9-60.4-9.2-58.1-56.2-1.6-38.3 34.1-62.1 70.9-60 7.1 0 21.6 .4 47 6.3l0-15.6c2.7-26.5-14.7-47-44.8-43.9-2.4 0-19.4-.5-45.8 10.1-7.4 3.4-8.3 2.8-10.8 2.8-7.4 0-4.4-21.5-2.9-24.2 5.2-6.4 35.9-18.4 65.9-18.2 20.1-1.8 40.1 4.4 55.7 17.3 6.3 7.1 11.2 15.4 14.2 24.4s4.2 18.5 3.5 28l0 69.3zM94 235.4c32.4-.5 46.2-20 49.3-30.5 2.5-10.1 2.1-16.4 2.1-27.4-9.7-2.3-23.6-4.9-39.6-4.9-15.2-1.1-42.8 5.6-41.7 32.3-1.2 16.8 11.1 31.4 30 30.5zm170.9 23.1c-7.9 .7-11.5-4.9-12.7-10.4L202.4 83.4c-1-2.8-1.6-5.6-1.9-8.6-.2-1.2 .1-2.4 .8-3.4s1.8-1.6 3-1.8c.2 0-2.1 0 22.2 0 8.8-.9 11.6 6 12.6 10.4L274.9 220.8 308.1 80c.5-3.2 2.9-11.1 12.8-10.2l17.2 0c2.2-.2 11.1-.5 12.7 10.4L384.1 222.7 421 80.1c.5-2.2 2.7-11.4 12.7-10.4l19.7 0c.9-.1 6.2-.8 5.3 8.6-.4 1.8 3.4-10.7-52.8 169.9-1.1 5.5-4.8 11.1-12.7 10.4l-18.7 0c-10.9 1.2-12.5-9.7-12.7-10.7l-33.2-137.1-32.8 137c-.2 1.1-1.7 11.9-12.7 10.7l-18.3 0 0 0zm273.5 5.6c-5.9 0-33.9-.3-57.4-12.3-2.3-1-4.3-2.6-5.7-4.8s-2.1-4.6-2.1-7.1l0-10.7c0-8.5 6.2-6.9 8.8-5.9 10 4.1 16.5 7.1 28.8 9.6 36.7 7.5 52.8-2.3 56.7-4.5 13.2-7.8 14.2-25.7 5.3-34.9-10.5-8.8-15.5-9.1-53.1-21-4.6-1.3-43.7-13.6-43.8-52.4-.6-28.2 25-56.2 69.5-56 12.7 0 46.4 4.1 55.6 15.6 1.4 2.1 2 4.6 1.9 7l0 10.1c0 4.4-1.6 6.7-4.9 6.7-7.7-.9-21.4-11.2-49.2-10.8-6.9-.4-39.9 .9-38.4 25-.4 19 26.6 26.1 29.7 26.9 36.5 11 48.6 12.8 63.1 29.6 17.1 22.2 7.9 48.3 4.3 55.4-19.1 37.5-68.4 34.4-69.3 34.4zm40.2 104.9c-70 51.7-171.7 79.2-258.5 79.2-117.1 .8-230.3-42.3-317.3-120.7-6.5-5.9-.8-14 7.2-9.5 96.5 55.2 205.7 84.2 316.9 84.1 83-.4 165.1-17.3 241.6-49.5 11.8-5 21.8 7.8 10.1 16.4zm29.2-33.3c-9-11.5-59.3-5.4-81.8-2.7-6.8 .8-7.9-5.1-1.8-9.5 40.1-28.2 105.9-20.1 113.4-10.6 7.5 9.5-2.1 75.4-39.6 106.9-5.8 4.9-11.3 2.3-8.7-4.1 8.4-21.3 27.4-68.5 18.4-80z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
src/assets/svgs/brands/bandcamp.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M256 8a248 248 0 1 0 0 496 248 248 0 1 0 0-496zm48.2 326.1l-181 0 84.7-156.1 181 0-84.7 156.1z"/></svg>
|
||||
|
After Width: | Height: | Size: 405 B |
1
src/assets/svgs/brands/battle-net.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M448.8 225.6c26.9 .2 35.6-7.4 38.9-12.4 12.5-16.3-7.1-47.6-52.8-71.3 17.8-33.6 30.1-63.7 36.3-85.3 3.4-11.8 1.1-19 .5-20.3-1.7 10.5-15.8 48.5-48.2 100-25-11.2-56.5-20.1-93.8-23.8-8.9-16.9-34.9-63.9-60.5-88.9-16.8-16.5-30.3-22.6-40.8-23.5l0 0c-13.8-1.6-22.7 5.8-27.4 11-17.2 18.5-24.3 48.9-25 84.1-7.2-12.3-17.2-24.6-28.5-25.9l-.2 0c-20.7-3.5-38.4 29.2-36 81.3-38.4 1.4-71 5.8-93 11.2-9.9 2.4-16.2 7.3-17.8 9.7 1-.4 22.4-9.2 111.6-9.2 5.2 53 29.8 101.8 26 93.2-9.7 15.4-38.2 62.4-47.3 97.7-5.9 22.9-4.4 37.6 .2 47.1 5.6 12.8 16.4 16.7 23.2 18.3 25 5.7 55.4-3.6 86.7-21.1-7.5 12.8-13.9 28.5-9.1 39.3 7.3 19.6 44.5 18.7 88.4-9.4 20.2 32.2 40.1 57.9 55.7 74.1 2.6 2.8 5.5 5.2 8.8 7.1 5.1 3.2 8.6 3.4 8.6 3.4-8.2-6.7-34-38-62.5-91.8 22.2-16 45.7-38.9 67.5-69.3 122.8 4.6 143.3-24.8 148-31.6 14.7-19.9 3.4-57.4-57.3-93.7zM371 331.8c23.8-37.7 30.3-67.8 29.4-92.3 27.9 17.6 47.2 37.6 49.1 58.8 1.1 12.9-8.1 29.1-78.5 33.5zM217.1 387.7c9.8-6.2 19.5-13.1 29.2-20.5 6.7 13.3 13.6 26.1 20.6 38.2-40.6 21.9-68.8 12.8-49.8-17.7zm215-171.3c-10.3-5.3-21.2-10.3-32.4-15 7.9-12.1 15.5-24.4 22.7-36.9 39.1 24.1 45.9 53.2 9.6 51.9zM279.4 398c-5.5-11.4-11-23.5-16.5-36.4 43.2 1.3 62.4-18.7 63.3-20.4 0 .1-25 15.6-62.5 12.2 30.6-25.6 59.1-53.7 85.1-84 8.7-10.2 17-20.6 24.9-31.1-.4-.3-1.5-3-16.5-12-51.7 60.3-102.3 98-132.8 115.9-20.6-11.2-40.8-31.8-55.7-61.5-20-39.9-30-82.4-31.6-116.1 12.3 .9 25.3 2.2 38.8 3.9-22.3 36.8-14.4 63-13.5 64.2 0-.1-1-29.2 20.1-59.6 9 52.5 24 103.8 44.7 152.8 .9-.4 1.8 .9 18.7-8.2-26.3-74.5-33.8-138.2-34-173.4 20-12.4 48.2-19.8 81.6-17.8 44.6 2.7 86.4 15.2 116.3 30.7-7.1 10.4-14.9 21.3-23.3 32.5-20.7-37.7-47.3-43.9-48.9-43.7 .1 0 25.9 14.1 41.5 47.2-37.5-13.8-76.1-24.4-115.3-31.7-13.1-2.4-26.2-4.4-39.4-6-.1 .4-1.8 1.8-2.2 20.3 77.9 14.5 136.6 39.9 167.2 57.2 .7 23.6-7 51.6-25.4 79.6-24.6 37.3-56.4 67.2-84.8 85.4zm27.4-287c-44.6-1.7-73.6 7.4-94.7 20.7 2-52.3 21.3-76.4 38.2-75.3 16.9-4.2 54.9 52.2 56.5 54.6zm-130.7 3.1c.5 12.1 1.6 24.6 3.2 37.3-14.6-.9-28.7-1.3-42.4-1.3-.1 3.2-.1-51 24.7-49.6l.1 0c5.8 1.1 10.6 6.9 14.4 13.6zm-28.1 162c20.8 39.7 43.3 60.6 65.3 72.3-46.8 24.8-77.5 20-84.9 4.5-.2-.2-11.1-15.3 19.7-76.8l0 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
1
src/assets/svgs/brands/behance-square.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M155.3 318.4c17.2 0 31.2-6.1 31.2-25.4 0-19.7-11.7-27.4-30.3-27.5l-46 0 0 52.9 45.1 0zm-5.4-129.6l-39.6 0 0 44.8 42.7 0c15.1 0 25.8-6.6 25.8-22.9 0-17.7-13.7-21.9-28.9-21.9zm129.5 74.8l62.2 0c-1.7-18.5-11.3-29.7-30.5-29.7-18.3 0-30.5 11.4-31.7 29.7zM384 32L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64zM349.5 185l-77.8 0 0-18.9 77.8 0 0 18.9zM193.7 243.7c23.6 6.7 35 27.5 35 51.6 0 39-32.7 55.7-67.6 55.9l-93.1 0 0-192 90.5 0c32.9 0 61.4 9.3 61.4 47.5 0 19.3-9 28.8-26.2 37zm118.7-38.6c43.5 0 67.6 34.3 67.6 75.4 0 1.6-.1 3.3-.2 5 0 .8-.1 1.5-.1 2.2l-100.2 0c0 22.2 11.7 35.3 34.1 35.3 11.6 0 26.5-6.2 30.2-18.1l33.7 0c-10.4 31.9-31.9 46.8-65.1 46.8-43.8 0-71.1-29.7-71.1-73 0-41.8 28.7-73.6 71.1-73.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
src/assets/svgs/brands/behance.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8l-167.1 0 0 354.4 171.8 0c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9l73.1 0c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2l-79 0 0-82.7zm83.3 233.7l-83.3 0 0-97.6 84.9 0c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zM519.7 128.9l-143.7 0 0-34.9 143.7 0 0 34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3l-62.2 0c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3l185.1 0c.3-4.2 .6-8.7 .6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8l-114.7 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 964 B |
1
src/assets/svgs/brands/bilibili.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M488.6 104.1c16.7 18.1 24.4 39.7 23.3 65.7l0 202.4c-.4 26.4-9.2 48.1-26.5 65.1-17.2 17-39.1 25.9-65.5 26.7L92 464c-26.4-.8-48.2-9.8-65.3-27.2-17.1-17.4-26-40.3-26.7-68.6L0 169.8c.8-26 9.7-47.6 26.7-65.7 17.1-16.3 38.8-25.3 65.3-26.1l29.4 0-25.4-25.8c-5.7-5.7-8.6-13-8.6-21.8s2.9-16.1 8.6-21.8 13-8.6 21.9-8.6 16.1 2.9 21.9 8.6l73.3 69.4 88 0 74.5-69.4C381.7 2.9 389.2 0 398 0s16.1 2.9 21.9 8.6c5.7 5.7 8.6 13 8.6 21.8s-2.9 16.1-8.6 21.8L394.6 78 423.9 78c26.4 .8 48 9.8 64.7 26.1zm-38.8 69.7c-.4-9.6-3.7-17.4-10.7-23.5-5.2-6.1-14-9.4-22.7-9.8l-320.4 0c-9.6 .4-17.4 3.7-23.6 9.8-6.1 6.1-9.4 13.9-9.8 23.5l0 194.4c0 9.2 3.3 17 9.8 23.5s14.4 9.8 23.6 9.8l320.4 0c9.2 0 17-3.3 23.3-9.8s9.7-14.3 10.1-23.5l0-194.4zM185.5 216.5c6.3 6.3 9.7 14.1 10.1 23.2l0 33.3c-.4 9.2-3.7 16.9-9.8 23.2-6.2 6.3-14 9.5-23.6 9.5s-17.5-3.2-23.6-9.5-9.4-14-9.8-23.2l0-33.3c.4-9.1 3.8-16.9 10.1-23.2s13.2-9.6 23.3-10c9.2 .4 17 3.7 23.3 10zm191.5 0c6.3 6.3 9.7 14.1 10.1 23.2l0 33.3c-.4 9.2-3.7 16.9-9.8 23.2s-14 9.5-23.6 9.5-17.4-3.2-23.6-9.5c-7-6.3-9.4-14-9.7-23.2l0-33.3c.3-9.1 3.7-16.9 10-23.2s14.1-9.6 23.3-10c9.2 .4 17 3.7 23.3 10z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/svgs/brands/bimobject.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M416 32L32 32C14.4 32 0 46.4 0 64L0 448c0 17.6 14.4 32 32 32l384 0c17.6 0 32-14.4 32-32l0-384c0-17.6-14.4-32-32-32zM352 289.4c0 49.4-11.4 82.6-103.8 82.6l-16.9 0c-44.1 0-62.4-14.9-70.4-38.8l-.9 0 0 34.8-64 0 0-232 64 0 0 74.7 1.1 0c4.6-30.5 39.7-38.8 69.7-38.8l17.3 0c92.4 0 103.8 33.1 103.8 82.5l0 35 .1 0zm-64-28.9l0 22.9c0 21.7-3.4 33.8-38.4 33.8l-45.3 0c-28.9 0-44.1-6.5-44.1-35.7l0-19c0-29.3 15.2-35.7 44.1-35.7l45.3 0c35-.2 38.4 12 38.4 33.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 759 B |
1
src/assets/svgs/brands/bitbucket.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M22.2 32c-2.1 0-4.2 .4-6.1 1.1s-3.7 1.9-5.2 3.4-2.7 3.2-3.5 5.1-1.3 4-1.3 6.1c0 .9 .1 1.9 .2 2.8L74.1 462.7c.8 5.1 3.4 9.7 7.3 13s8.8 5.2 14 5.2l325.7 0c3.8 .1 7.5-1.3 10.5-3.7s4.9-5.9 5.5-9.7L505 50.7c.7-4.2-.3-8.4-2.8-11.9s-6.2-5.7-10.4-6.4c-.9-.1-1.9-.2-2.8-.2L22.2 32zM308.1 329.8l-104 0-28.1-147 157.3 0-25.2 147z"/></svg>
|
||||
|
After Width: | Height: | Size: 629 B |
1
src/assets/svgs/brands/bitcoin.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M8 256a248 248 0 1 1 496 0 248 248 0 1 1 -496 0zm354.3-35.3c4.9-33-20.2-50.7-54.6-62.6l11.1-44.7-27.2-6.8-10.9 43.5c-7.2-1.8-14.5-3.5-21.8-5.1l10.9-43.8-27.2-6.8-11.2 44.7c-5.9-1.3-11.7-2.7-17.4-4.1l0-.1-37.5-9.4-7.2 29.1s20.2 4.6 19.8 4.9c11 2.8 13 10 12.7 15.8l-12.7 50.9c.8 .2 1.7 .5 2.8 .9-.9-.2-1.9-.5-2.9-.7l-17.8 71.3c-1.3 3.3-4.8 8.4-12.5 6.5 .3 .4-19.8-4.9-19.8-4.9l-13.5 31.1 35.4 8.8c6.6 1.7 13 3.4 19.4 5l-11.3 45.2 27.2 6.8 11.2-44.7c7.2 2 14.4 3.8 21.7 5.6l-11.1 44.5 27.2 6.8 11.3-45.1c46.4 8.8 81.3 5.2 96-36.7 11.8-33.8-.6-53.3-25-66 17.8-4.1 31.2-15.8 34.7-39.9zm-62.2 87.2c-8.4 33.8-65.3 15.5-83.8 10.9l14.9-59.9c18.4 4.6 77.6 13.7 68.8 49zm8.4-87.7c-7.7 30.7-55 15.1-70.4 11.3l13.5-54.3c15.4 3.8 64.8 11 56.8 43z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
src/assets/svgs/brands/bity.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M86.5 67.2c95.4-89.2 246.1-91.2 343.1 3.8 14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30-112.2-33.9-175.8-149.7-147.5-261 5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8s-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0l0 71.6c0 69.3 60.7 90.9 118 90.1 57.3 .8 118-20.8 118-90.1l0-71.6c0-19.6-32.5-21.8-32.5 0z"/></svg>
|
||||
|
After Width: | Height: | Size: 996 B |
1
src/assets/svgs/brands/black-tie.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M0 32l0 448 448 0 0-448-448 0zM316.5 357.2l-92.5 88.7-92.5-88.7 64.5-184-64.5-86.6 184.9 0-64.4 86.6 64.5 184z"/></svg>
|
||||
|
After Width: | Height: | Size: 421 B |
1
src/assets/svgs/brands/blackberry.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M166 116.9c0 23.4-16.4 49.1-72.5 49.1l-70.1 0 21-88.8 67.8 0c42.1 0 53.8 23.3 53.8 39.7zM292.2 77.2l-67.8 0-18.7 88.8 70.1 0c53.8 0 70.1-25.7 70.1-49.1 .1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1l-67.8 0-21 88.8 70.1 0c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0l-67.8 0-18.7 88.8 70.1 0c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8l-67.8 0-18.7 88.8 70.1 0c53.8 0 70.1-23.4 70.1-49.1 .1-16.3-11.6-39.7-53.7-39.7zm-28 137.9l-67.8 0-18.7 88.8 70.1 0c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346l-67.8 0-18.7 88.8 70.1 0c56.1 0 70.1-25.7 70.1-49.1 .1-16.3-11.6-39.7-53.7-39.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 941 B |
1
src/assets/svgs/brands/blogger-b.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8 .6-108.4 10-43.5 17.2-74.7 53.8-86.1 100.6-2.1 8.8-2.6 22.9-3.1 103.9-.6 101.5 .1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zM124.5 159.1c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4 .1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5 .2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zM316.3 358.9l-14.9 2.4-77.5 .9c-68.1 .8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |