first commit
14
.editorconfig
Normal file
@ -0,0 +1,14 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
36
.eslintrc.cjs
Normal file
@ -0,0 +1,36 @@
|
||||
/* eslint-env node */
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require('@rushstack/eslint-patch/modern-module-resolution');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier',
|
||||
'alloy',
|
||||
'alloy/vue',
|
||||
'alloy/typescript',
|
||||
'./config/unplugin/.eslintrc-auto-import.json',
|
||||
],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
parser: {
|
||||
js: '@babel/eslint-parser',
|
||||
jsx: '@babel/eslint-parser',
|
||||
ts: '@typescript-eslint/parser',
|
||||
tsx: '@typescript-eslint/parser',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/prefer-optional-chain': 'off',
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'prettier/prettier': ['error', { endOfLine: 'auto' }],
|
||||
},
|
||||
globals: {
|
||||
defineOptions: 'readonly',
|
||||
},
|
||||
};
|
||||
35
.gitignore
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
*.js.map
|
||||
*.js
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
config/unplugin/*.d.ts
|
||||
config/unplugin/.eslintrc*
|
||||
|
||||
analyzer.html
|
||||
41
.prettierrc.cjs
Normal file
@ -0,0 +1,41 @@
|
||||
module.exports = {
|
||||
// 一行最多 120 字符
|
||||
printWidth: 120,
|
||||
// 使用 2 个空格缩进
|
||||
tabWidth: 2,
|
||||
// 不使用缩进符,而使用空格
|
||||
useTabs: false,
|
||||
// 行尾需要有分号
|
||||
semi: true,
|
||||
// 使用单引号
|
||||
singleQuote: true,
|
||||
// 对象的 key 仅在必要时用引号
|
||||
quoteProps: 'as-needed',
|
||||
// jsx 不使用单引号,而使用双引号
|
||||
jsxSingleQuote: false,
|
||||
// 末尾需要有逗号
|
||||
trailingComma: 'all',
|
||||
// 大括号内的首尾需要空格
|
||||
bracketSpacing: true,
|
||||
// jsx 标签的反尖括号需要换行
|
||||
bracketSameLine: false,
|
||||
// 箭头函数,只有一个参数的时候,也需要括号
|
||||
arrowParens: 'always',
|
||||
// 每个文件格式化的范围是文件的全部内容
|
||||
rangeStart: 0,
|
||||
rangeEnd: Infinity,
|
||||
// 不需要写文件开头的 @prettier
|
||||
requirePragma: false,
|
||||
// 不需要自动在文件开头插入 @prettier
|
||||
insertPragma: false,
|
||||
// 使用默认的折行标准
|
||||
proseWrap: 'preserve',
|
||||
// 根据显示样式决定 html 要不要折行
|
||||
htmlWhitespaceSensitivity: 'css',
|
||||
// vue 文件中的 script 和 style 内不用缩进
|
||||
vueIndentScriptAndStyle: false,
|
||||
// 换行符使用 lf
|
||||
endOfLine: 'lf',
|
||||
// 格式化内嵌代码
|
||||
embeddedLanguageFormatting: 'auto',
|
||||
};
|
||||
189
README.md
Normal file
@ -0,0 +1,189 @@
|
||||
## template-admin-ts
|
||||
|
||||
基于 Arco Design Pro 的中后台管理模板
|
||||
|
||||
- vite 4.x
|
||||
- vue 3.x
|
||||
- vue-router 4.x
|
||||
- pinia
|
||||
- vueuse
|
||||
- axios
|
||||
- dayjs
|
||||
- lodash
|
||||
- arco-design
|
||||
- less
|
||||
- eslint + prettier
|
||||
|
||||
### 项目启动
|
||||
|
||||
```shell
|
||||
# 新开仓库
|
||||
git init
|
||||
# 未安装 pnpm
|
||||
npm add -g pnpm
|
||||
# 项目运行
|
||||
pnpm i
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### 项目部署
|
||||
|
||||
- 本地预览
|
||||
|
||||
```shell
|
||||
# 打包
|
||||
pnpm build --mode preview
|
||||
# 本地运行
|
||||
pnpm preview
|
||||
```
|
||||
|
||||
- 预发布/测试环境
|
||||
|
||||
```shell
|
||||
pnpm build --mode staging
|
||||
```
|
||||
|
||||
- 生产环境
|
||||
|
||||
```shell
|
||||
pnpm build --mode production
|
||||
```
|
||||
|
||||
### git 提交规范
|
||||
|
||||
项目未安装依赖限制 `git commit`, 但需在**代码评审**阶段检查
|
||||
|
||||
##### 示例:
|
||||
|
||||
```git
|
||||
✨ feat: 新功能
|
||||
```
|
||||
|
||||
```git
|
||||
🐛 fix: 修复bug
|
||||
```
|
||||
|
||||
更多功能:[提交规范](https://www.conventionalcommits.org/zh-hans/v1.0.0/),[`gitmoji`](https://gitmoji.dev/)
|
||||
|
||||
##### 插件安装
|
||||
|
||||
- `vscode`
|
||||
|
||||
- Commit Message Editor
|
||||
- Gitmoji
|
||||
|
||||
- `webstorm`
|
||||
|
||||
- Git Commit Template
|
||||
- Gitmoji Plus: Commit Button
|
||||
|
||||
### `vite` 插件
|
||||
|
||||
#### `unocss`
|
||||
|
||||
- [配置](https://github.com/unocss/unocss)
|
||||
- [文档](https://uno.antfu.me/)
|
||||
|
||||
示例:
|
||||
|
||||
```html
|
||||
<div class="ml-2 px-2 text-2"></div>
|
||||
```
|
||||
|
||||
#### 自动导入 `api`
|
||||
|
||||
- [配置](https://github.com/antfu/unplugin-auto-import)
|
||||
|
||||
已安装 `vue`, `vue-router`, `pinia`, `@vueuse/core`, `dayjs`, `lodash-es`
|
||||
|
||||
> `lodash-es` 为部分安装;若需更多功能函数,可新增在 `['cloneDeep']`, 以数组形式。
|
||||
|
||||
示例:
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
const route = useRoute();
|
||||
|
||||
const year = ref<string | number>('2023');
|
||||
year.value = 2023;
|
||||
|
||||
const str: string = join(['a', 'b', 'c'], '~');
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 自动导入组件
|
||||
|
||||
##### `src/components` 目录下的组件
|
||||
|
||||
| 模式 | 描述 |
|
||||
| ---------------- | --------------------- |
|
||||
| `Comp.vue` | - |
|
||||
| `Comp/Index.vue` | - |
|
||||
| `Comp/Comp.vue` | - |
|
||||
| `Comp/Index.js` | 支持默认导出\命名导出 |
|
||||
|
||||
> 默认导出: `Comp.vue`, `Comp/Index.vue`, `Comp/Comp.vue`, `Comp/Index.js`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<eo-comp />
|
||||
</template>
|
||||
```
|
||||
|
||||
> 命名导出: `Comp/Index.js`
|
||||
|
||||
```js
|
||||
// Comp/Index.js
|
||||
export { CompA, CompB, CompC };
|
||||
```
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<eos-comp-a />
|
||||
<eos-comp-b />
|
||||
<eos-comp-c />
|
||||
</template>
|
||||
```
|
||||
|
||||
##### `src/views/**/components` 业务组件
|
||||
|
||||
页面内的业务组件直接使用
|
||||
|
||||
`src/views/pageA/components/Comp.vue`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<comp />
|
||||
</template>
|
||||
```
|
||||
|
||||
##### `src/components/_base` 基础组件
|
||||
|
||||
> 需在 `index.ts` 中命名导出
|
||||
|
||||
```ts
|
||||
export { default as Comp } from './comp/index.vue';
|
||||
```
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<base-comp />
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 自动导入 `svg` 图标
|
||||
|
||||
- `src/assets/icon.svg`
|
||||
- `src/assets/iconA.svg`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<i-icon />
|
||||
<i-icon-a />
|
||||
</template>
|
||||
```
|
||||
|
||||
### `ui` 框架 [`ArcoVue`](https://arco.design/vue/docs/start)
|
||||
|
||||
- 自动导入组件,无需再次导入
|
||||
- 图标库已配置,同组件使用
|
||||
19
config/index.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { configUnocss } from './plugins';
|
||||
import { configAutoImport, configComponents, configIcons } from './unplugin';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
import progress from 'vite-plugin-progress';
|
||||
import defineOptions from 'unplugin-vue-define-options/vite';
|
||||
|
||||
export * from './utils';
|
||||
|
||||
export const pluginsConfig = [
|
||||
configUnocss(),
|
||||
configAutoImport(),
|
||||
configComponents(),
|
||||
configIcons(),
|
||||
viteCompression(),
|
||||
progress(),
|
||||
defineOptions({
|
||||
include: [/\.vue$/, /\.vue\?vue/],
|
||||
}),
|
||||
];
|
||||
1
config/plugins/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './unocss';
|
||||
61
config/plugins/unocss.ts
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:14:16
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:23:48
|
||||
* @Description:
|
||||
*/
|
||||
import Unocss from 'unocss/vite';
|
||||
import {
|
||||
presetUno,
|
||||
presetIcons,
|
||||
presetAttributify,
|
||||
transformerDirectives,
|
||||
transformerCompileClass,
|
||||
transformerVariantGroup,
|
||||
transformerAttributifyJsx,
|
||||
} from 'unocss';
|
||||
import presetRemToPx from '@unocss/preset-rem-to-px';
|
||||
|
||||
export const configUnocss = () =>
|
||||
Unocss({
|
||||
presets: [presetUno(), presetIcons(), presetAttributify(), presetRemToPx()],
|
||||
transformers: [
|
||||
transformerDirectives(),
|
||||
transformerCompileClass(),
|
||||
transformerVariantGroup(),
|
||||
transformerAttributifyJsx(),
|
||||
],
|
||||
shortcuts: [
|
||||
// 垂直水平居中
|
||||
['flex-center', 'flex justify-center items-center'],
|
||||
],
|
||||
rules: [
|
||||
[/^mgl-(\d+)$/, ([, d]) => ({ 'margin-left': `${d}px !important` })],
|
||||
[/^mgr-(\d+)$/, ([, d]) => ({ 'margin-right': `${d}px !important` })],
|
||||
[/^mgt-(\d+)$/, ([, d]) => ({ 'margin-top': `${d}px !important` })],
|
||||
[/^mgb-(\d+)$/, ([, d]) => ({ 'margin-bottom': `${d}px !important` })],
|
||||
[/^pd-(\d+)$/, ([, d]) => ({ padding: `${d}px !important` })],
|
||||
[/^flex-(\d+)$/, ([, d]) => ({ flex: `${d} !important` })],
|
||||
[/^w(\d+)$/, ([, d]) => ({ width: `${d}% !important` })],
|
||||
[/^w-(\d+)$/, ([, d]) => ({ width: `${d}px !important` })],
|
||||
[/^h-(\d+)$/, ([, d]) => ({ height: `${d}px !important` })],
|
||||
[/^ft-(\d+)$/, ([, d]) => ({ 'font-size': `${d}px !important` })],
|
||||
[
|
||||
'box-container',
|
||||
{
|
||||
'border-radius': '2px',
|
||||
padding: '20px',
|
||||
margin: '8px',
|
||||
'background-color': '#fff',
|
||||
},
|
||||
],
|
||||
[
|
||||
'justify-between',
|
||||
{
|
||||
'justify-content': 'space-between',
|
||||
},
|
||||
],
|
||||
['align-center', { 'text-align': 'center' }],
|
||||
],
|
||||
});
|
||||
41
config/unplugin/auto-import.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 自动引入API
|
||||
* */
|
||||
import AutoImport from 'unplugin-auto-import/vite';
|
||||
|
||||
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
|
||||
import IconsResolver from 'unplugin-icons/resolver';
|
||||
|
||||
import { layoutsResolver } from '../utils';
|
||||
|
||||
export function configAutoImport() {
|
||||
return AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'pinia',
|
||||
'@vueuse/core',
|
||||
{
|
||||
dayjs: [['default', 'dayjs']],
|
||||
'lodash-es': ['cloneDeep', 'omit', 'pick'],
|
||||
'@/hooks': ['useModal'],
|
||||
},
|
||||
],
|
||||
resolvers: [
|
||||
ArcoResolver({
|
||||
resolveIcons: {
|
||||
enable: true,
|
||||
},
|
||||
}),
|
||||
IconsResolver({
|
||||
enabledCollections: [],
|
||||
}),
|
||||
layoutsResolver(),
|
||||
],
|
||||
eslintrc: {
|
||||
enabled: true,
|
||||
filepath: './config/unplugin/.eslintrc-auto-import.json',
|
||||
},
|
||||
dts: './config/unplugin/auto-imports.d.ts',
|
||||
});
|
||||
}
|
||||
57
config/unplugin/component.ts
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 自动引入组件
|
||||
* */
|
||||
import { kebabCase } from 'unplugin-vue-components';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
|
||||
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
|
||||
import IconsResolver from 'unplugin-icons/resolver';
|
||||
|
||||
import { getSep, getPath, setResolve, layoutsResolver } from '../utils';
|
||||
|
||||
export function configComponents() {
|
||||
return Components({
|
||||
dirs: ['src/components'],
|
||||
extensions: ['vue'],
|
||||
resolvers: [
|
||||
ArcoResolver({
|
||||
resolveIcons: {
|
||||
enable: true,
|
||||
},
|
||||
sideEffect: true,
|
||||
}),
|
||||
IconsResolver({
|
||||
prefix: false,
|
||||
customCollections: ['i'],
|
||||
enabledCollections: [],
|
||||
}),
|
||||
layoutsResolver(),
|
||||
{
|
||||
type: 'component',
|
||||
resolve: (name) => {
|
||||
const [prefix, folder] = kebabCase(name).split('-');
|
||||
|
||||
// 命名导出组件
|
||||
if (prefix === 'eos') {
|
||||
return {
|
||||
name: name.slice(3),
|
||||
from: getPath(`${getSep('src')}/components`, { folder }),
|
||||
};
|
||||
}
|
||||
// 默认导出组件
|
||||
if (prefix === 'eo') {
|
||||
return setResolve(name);
|
||||
}
|
||||
if (prefix === 'base') {
|
||||
return {
|
||||
name: name.slice(4),
|
||||
from: `${getSep('src')}/components/_base`,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
directoryAsNamespace: true,
|
||||
dts: './config/unplugin/components.d.ts',
|
||||
});
|
||||
}
|
||||
14
config/unplugin/icons.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 自动引入 svg 图标
|
||||
* */
|
||||
import Icons from 'unplugin-icons/vite';
|
||||
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
|
||||
|
||||
export function configIcons() {
|
||||
return Icons({
|
||||
compiler: 'vue3',
|
||||
customCollections: {
|
||||
i: FileSystemIconLoader('./src/assets', (svg) => svg.replace(/^<svg /, '<svg class="eo-i" ')),
|
||||
},
|
||||
});
|
||||
}
|
||||
3
config/unplugin/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './auto-import';
|
||||
export * from './component';
|
||||
export * from './icons';
|
||||
73
config/utils.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { sep } from 'node:path';
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import { accessSync, readdirSync } from 'node:fs';
|
||||
|
||||
export const resolve = (src: string) => fileURLToPath(new URL(`../${src}`, import.meta.url));
|
||||
|
||||
export const getSep = (src: string) => resolve(src).split(sep).join('/');
|
||||
|
||||
interface AccessType {
|
||||
name: string;
|
||||
dir: string;
|
||||
extensions: string[];
|
||||
}
|
||||
const access = ({ name, dir, extensions }: AccessType) => {
|
||||
const paths = ['/Index', '/index', `/${name}`].reduce(
|
||||
(t: string[], o: string) => [...t, ...extensions.map((r) => `${o}.${r}`)],
|
||||
[],
|
||||
);
|
||||
|
||||
for (const path of paths) {
|
||||
try {
|
||||
accessSync(`${getSep('src')}/${dir}/${name}${path}`);
|
||||
return path;
|
||||
} catch {}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// 解决 nodejs 大小写不敏感不能正确读取路径,vite 的自动导入组件不能热更新
|
||||
interface PathParams {
|
||||
folder: string;
|
||||
}
|
||||
export const getPath = (parentPath: string, { folder }: PathParams) => {
|
||||
try {
|
||||
const files = readdirSync(parentPath);
|
||||
for (const file of files) {
|
||||
if (file.toLowerCase() === folder) {
|
||||
return `${parentPath}/${file}`;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
throw new Error(`${parentPath}/${folder} is exist?`);
|
||||
};
|
||||
|
||||
export const setResolve = (name: string, { prefix = 'Eo', dir = 'components' } = {}) => {
|
||||
const partialName = name.slice(prefix.length);
|
||||
const path = access({ name: partialName, dir, extensions: ['vue', 'js'] }) || '.vue';
|
||||
return `${getSep('src')}/${dir}/${partialName}${path}`;
|
||||
};
|
||||
|
||||
// resolver
|
||||
export const layoutsResolver = () => (name: string) => {
|
||||
if (name.startsWith('Layout')) {
|
||||
return setResolve(name, { prefix: 'Layout', dir: 'layouts' });
|
||||
}
|
||||
};
|
||||
|
||||
// 本地服务器配置
|
||||
export const setServerConfig =
|
||||
({ env }: { env: Record<string, string> }) =>
|
||||
(opts = {}): Record<string, any> => {
|
||||
return {
|
||||
port: Number(env.APP_PORT),
|
||||
proxy: {
|
||||
[env.EO_API_URL]: {
|
||||
target: env.API_PROXY,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(env.EO_API_URL, ''),
|
||||
},
|
||||
},
|
||||
...opts,
|
||||
};
|
||||
};
|
||||
19
env/.env
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# 环境变量前缀
|
||||
# 此前缀开头的变量通过 import.meta.env 暴露出去
|
||||
ENV_PREFIX=EO_
|
||||
|
||||
APP_TITLE=${APP_TITLE}
|
||||
|
||||
# router base
|
||||
EO_BASE=/
|
||||
|
||||
# 协议
|
||||
APP_PROTOCOL=https://
|
||||
|
||||
# 接口地址
|
||||
EO_API_URL=${APP_PROTOCOL}${API_PATH}
|
||||
OSS_API_URL=${APP_PROTOCOL}${OSS_API_PATH}
|
||||
|
||||
# 接口代理地址
|
||||
API_PROXY=${APP_PROTOCOL}${API_PATH}
|
||||
OSS_API_PROXY=${APP_PROTOCOL}${OSS_API_PATH}
|
||||
15
env/.env.development
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# 开发环境
|
||||
APP_TITLE='development'
|
||||
# 端口
|
||||
APP_PORT=48438
|
||||
|
||||
# 协议
|
||||
APP_PROTOCOL=http://
|
||||
|
||||
# 接口路径
|
||||
API_PATH=192.168.40.5
|
||||
|
||||
# 接口地址
|
||||
EO_API_URL=/api
|
||||
|
||||
VITE_ENV='development'
|
||||
8
env/.env.production
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 生产环境
|
||||
APP_TITLE='production | eyo'
|
||||
|
||||
# 接口路径
|
||||
API_PATH=zzz
|
||||
|
||||
# 接口地址
|
||||
EO_API_URL=http://lingjiapi.lvfunai.com/api
|
||||
16
env/.env.test
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# 测试环境
|
||||
APP_TITLE='test'
|
||||
# 端口
|
||||
APP_PORT=48438
|
||||
|
||||
# 协议
|
||||
APP_PROTOCOL=http://
|
||||
|
||||
# 接口路径
|
||||
|
||||
API_PATH=xxxx
|
||||
|
||||
# 接口地址
|
||||
EO_API_URL=https://lingjiapi.lvfunai.com/api
|
||||
|
||||
VITE_ENV='test'
|
||||
31
env/README.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
### 环境变量和模式
|
||||
|
||||
| 模式 | 环境 | 描述 |
|
||||
| ----------------- | ------------------- | ------------ |
|
||||
| `env` | - | 通用设置 |
|
||||
| `env.development` | 开发环境 | - |
|
||||
| `env.preview` | 预览环境 | 本地预览使用 |
|
||||
| `env.production` | 生产环境 | - |
|
||||
| `env.staging` | 预发布环境/测试环境 | - |
|
||||
|
||||
#### 参数说明
|
||||
|
||||
| 参数 | 描述 | 环境 | 说明 |
|
||||
| -------------- | ------------------------ | ------------- | -------------------------------------------------------- |
|
||||
| `EO_BASE` | `vue-router` 路由 `base` | - | - |
|
||||
| `APP_TITLE` | 文档标题 | - | - |
|
||||
| `APP_PROTOCOL` | 协议 | - | 区别 `webSocket` |
|
||||
| `APP_PORT` | 端口 | `开发`,`预览` | - |
|
||||
| `EO_API_URL` | 接口地址 | `开发`,`预览` | - |
|
||||
| `API_PROXY` | 代理接口地址 | - | - |
|
||||
| `API_PATH` | 实际接口地址 | - | 开发中只需修改 `API_PATH` 参数,其他参数根据实际情况修改 |
|
||||
|
||||
#### 示例
|
||||
|
||||
```dotenv
|
||||
API_PATH=192.168.0.1:48438
|
||||
```
|
||||
|
||||
```dotenv
|
||||
API_PATH=192.168.0.1:48438/api
|
||||
```
|
||||
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
9069
package-lock.json
generated
Normal file
73
package.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "template-admin-ts",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p build-only",
|
||||
"build:test": "vite build --mode test && tar -czvf dist-test.tar.gz dist",
|
||||
"build-only": "vite build -- mode development",
|
||||
"test": "vite build --mode test",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@arco-design/web-vue": "^2.42.0",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@vueuse/core": "^9.12.0",
|
||||
"ali-oss": "^6.17.1",
|
||||
"axios": "^1.3.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"echarts": "^5.6.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mitt": "^3.0.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^2.0.29",
|
||||
"swiper": "^11.2.8",
|
||||
"vue": "^3.2.45",
|
||||
"vue-echarts": "^7.0.3",
|
||||
"vue-router": "^4.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/eslint-parser": "^7.19.1",
|
||||
"@rushstack/eslint-patch": "^1.2.0",
|
||||
"@types/mockjs": "^1.0.7",
|
||||
"@types/node": "^18.11.18",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@unocss/preset-rem-to-px": "^0.49.2",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.2",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-config-alloy": "^4.9.0",
|
||||
"eslint-plugin-vue": "^9.9.0",
|
||||
"husky": "^8.0.3",
|
||||
"jsencrypt": "^3.3.1",
|
||||
"less": "^4.1.3",
|
||||
"lint-staged": "^13.1.0",
|
||||
"mockjs": "^1.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nprogress": "0.2.0",
|
||||
"prettier": "^2.8.3",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"typescript": "~4.9.5",
|
||||
"unocss": "^0.49.2",
|
||||
"unplugin-auto-import": "^0.13.0",
|
||||
"unplugin-icons": "^0.15.2",
|
||||
"unplugin-vue-components": "^0.23.0",
|
||||
"unplugin-vue-define-options": "^1.2.4",
|
||||
"vite": "^4.0.4",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-progress": "^0.0.6",
|
||||
"vue-eslint-parser": "^9.1.0",
|
||||
"vue-tsc": "^1.0.24"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*": "prettier --write --ignore-unknown --ignore-path .gitignore",
|
||||
"src/*": "eslint --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
}
|
||||
}
|
||||
6130
pnpm-lock.yaml
generated
Normal file
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
25
src/App.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<a-config-provider :locale="zhCN" size="small" :theme="redTheme">
|
||||
<LayoutBasic>
|
||||
<router-view />
|
||||
</LayoutBasic>
|
||||
</a-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import zhCN from '@arco-design/web-vue/es/locale/lang/zh-cn';
|
||||
onMounted(() => {
|
||||
// 监听全局未处理错误
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
event.preventDefault();
|
||||
console.log(event);
|
||||
console.error(`发现catch报错:${event.reason}`);
|
||||
});
|
||||
});
|
||||
const redTheme = {
|
||||
token: {
|
||||
colorPrimary: '#6d4cfe', // 主色
|
||||
colorLink: '#f5222d', // 链接色
|
||||
},
|
||||
};
|
||||
</script>
|
||||
111
src/api/all/index.ts
Normal file
@ -0,0 +1,111 @@
|
||||
import Http from '@/api';
|
||||
|
||||
// 导出一个函数,用于获取行业树
|
||||
export const fetchIndustriesTree = (params = {}) => {
|
||||
// 发送GET请求,获取行业树
|
||||
return Http.get('/v1/industries/tree', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取菜单树
|
||||
export const fetchMenusTree = (params = {}) => {
|
||||
// 使用Http.get方法,发送GET请求,获取菜单树
|
||||
return Http.get('/v1/menus/tree', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取行业话题列表
|
||||
export const fetchIndustryTopics = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-topics/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取行业话题详情
|
||||
export const fetchIndustryTopicDetail = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-topics/' + params, {});
|
||||
};
|
||||
|
||||
export const fetchindustryTerms = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-terms/list', params);
|
||||
};
|
||||
|
||||
|
||||
// 导出一个函数fetchKeywordTrendsList,用于获取行业话题列表
|
||||
export const fetchKeywordTrendsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-keyword-trends/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取行业话题列表
|
||||
export const fetchIndustryEmotions = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-emotions', params);
|
||||
};
|
||||
|
||||
export const fetchNewKeywordList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/industry-new-keywords/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数fetchUserPainPointsList,用于获取用户痛点列表
|
||||
export const fetchUserPainPointsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/user-pain-points/list', params);
|
||||
};
|
||||
|
||||
|
||||
// 导出一个函数fetchUserPainPointsDetail,用于获取用户痛点详情
|
||||
export const fetchUserPainPointsDetail = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/user-pain-points/' + params, {});
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 导出一个函数fetchFocusBrandsList,用于获取行业话题列表
|
||||
export const fetchFocusBrandsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/focus-brands/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数fetchFocusBrandsList,用于获取行业话题列表
|
||||
// 导出一个函数,用于获取行业话题列表
|
||||
export const fetchEventDynamicsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取行业话题列表
|
||||
return Http.get('/v1/event-dynamics/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取年龄分布列表
|
||||
export const fetchAgeDistributionsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取年龄分布列表
|
||||
return Http.get('/v1/age-distributions/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取地理分布列表
|
||||
export const fetchGeoDistributionsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取地理分布列表
|
||||
return Http.get('/v1/geo-distributions/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取性别分布列表
|
||||
export const fetchGenderDistributionsList = (params: any) => {
|
||||
// 使用Http.get方法,发送GET请求,获取性别分布列表
|
||||
return Http.get('/v1/gender-distributions/list', params);
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取产品列表
|
||||
export const fetchProductList = () => {
|
||||
// 使用Http.get方法,发送GET请求,获取产品列表
|
||||
return Http.get('/v1/products/list', {}, { headers: { 'enterprise-id': 1 } });
|
||||
};
|
||||
|
||||
// 导出一个函数,用于获取成功案例列表
|
||||
export const fetchSuccessCaseList = () => {
|
||||
// 使用Http.get方法,发送GET请求,获取成功案例列表
|
||||
return Http.get('/v1/success-cases/list');
|
||||
};
|
||||
|
||||
// 试用产品
|
||||
export const trialProduct = (id: number) => {
|
||||
return Http.post(`/v1/products/${id}/try`, {}, { headers: { 'enterprise-id': 1 } });
|
||||
};
|
||||
36
src/api/apiCodes.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-17 11:15:23
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-21 16:25:32
|
||||
* @Description: API状态码
|
||||
*/
|
||||
|
||||
export enum API_STATUS_CODE {
|
||||
/** 正常响应 */
|
||||
SUCCESS = 200,
|
||||
/** 会话失效,请重新登录 */
|
||||
SESSION_FAILUIRE = 1000,
|
||||
/** 认证失败,无法访问系统资源 */
|
||||
AUTH_FAILED = 1001,
|
||||
/** 未授权,无法访问系统资源 */
|
||||
RESOURCE_FORBIDDEN = 1002,
|
||||
/** 黑名单用户 */
|
||||
BLACK_LIST_USER = 1003,
|
||||
/** 非法IP地址 */
|
||||
ILLEGAL_IP = 1004,
|
||||
/** 网关访问受限 */
|
||||
GATEWAY_FORBIDDEN = 1005,
|
||||
/** 网关访问异常,请稍后重试 */
|
||||
GATEWAY_ERROR = 1006,
|
||||
/** 流控异常 */
|
||||
TRAFFIC_CONTROL_ERROR = 1007,
|
||||
/** 资源找不到服务 */
|
||||
RESOURCE_NOT_FOUND = 1008,
|
||||
/** 资源请求超时 */
|
||||
FETCH_TIMEOUT = 1009,
|
||||
/** 资源响应异常 */
|
||||
RESOURCE_RESPONSE_ERROR = 1010,
|
||||
/** 请求路径不符合规范 */
|
||||
ILLEGAL_PATH = 1011,
|
||||
}
|
||||
32
src/api/axiosHandler.ts
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-21 16:34:47
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-21 16:59:10
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
import router from '@/router';
|
||||
import { clearToken } from '@/utils/auth';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
/**
|
||||
* 处理业务逻辑定义的错误code
|
||||
* @param errStatus
|
||||
*/
|
||||
export const handleCodeError = (error: any) => {
|
||||
let errMessage = '未知错误';
|
||||
console.log(error);
|
||||
errMessage = error.msg;
|
||||
switch (error.code) {
|
||||
case 1000:
|
||||
router.replace({
|
||||
name: '/login/password',
|
||||
});
|
||||
clearToken();
|
||||
break;
|
||||
default:
|
||||
errMessage = error.msg || `未知错误-${error.code}`;
|
||||
}
|
||||
Message.error(errMessage);
|
||||
};
|
||||
24
src/api/example/index.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:42:52
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:06:13
|
||||
* @Description: 示例api
|
||||
*/
|
||||
|
||||
import Http from '@/api';
|
||||
|
||||
export declare namespace IExample {
|
||||
interface ITableResponse {
|
||||
id: string;
|
||||
column1: string;
|
||||
column2: string;
|
||||
column3: string;
|
||||
column4: string;
|
||||
column5: string;
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchTableData = (params = {}) => {
|
||||
return Http.get<IExample.ITableResponse[]>('/api/example-table', params);
|
||||
};
|
||||
83
src/api/index.ts
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-17 11:58:44
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:17:29
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
import axios from 'axios';
|
||||
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
|
||||
//* 导出Request类,可以用来自定义传递配置来创建实例
|
||||
export class Request {
|
||||
//* axios 实例
|
||||
private instance: AxiosInstance;
|
||||
//* 基础配置
|
||||
private baseConfig: AxiosRequestConfig = { baseURL: import.meta.env.EO_API_URL, timeout: 60000 };
|
||||
|
||||
public constructor(config: AxiosRequestConfig) {
|
||||
this.instance = axios.create(Object.assign(this.baseConfig, config));
|
||||
|
||||
this.instance.interceptors.request.use(
|
||||
(config: AxiosRequestConfig) => {
|
||||
const token = localStorage.getItem('token') as string;
|
||||
if (token) {
|
||||
config.headers!.Authorization = token;
|
||||
} else {
|
||||
config.headers!.satoken = '123';
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(err: any) => {
|
||||
return Promise.reject(err);
|
||||
},
|
||||
);
|
||||
|
||||
this.instance.interceptors.response.use(
|
||||
(res: AxiosResponse) => {
|
||||
//* http请求成功
|
||||
//* 存入通用response header
|
||||
let tenanttype = localStorage.getItem('tenanttype') as string;
|
||||
if (!tenanttype) {
|
||||
tenanttype = res.headers!.tenanttype;
|
||||
localStorage.setItem('tenanttype', tenanttype);
|
||||
}
|
||||
if (res.data.code === 200) {
|
||||
return res.data.data;
|
||||
}
|
||||
AMessage.error(res.data!.msg);
|
||||
return Promise.reject(res.data);
|
||||
},
|
||||
(err: any) => {
|
||||
// AMessage.error(err.message);
|
||||
// 这里用来处理http常见错误,进行全局提示
|
||||
return Promise.reject(err.response);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
//* 定义请求方法
|
||||
public request<T = any>(config: AxiosRequestConfig): Promise<T> {
|
||||
return this.instance.request(config);
|
||||
}
|
||||
|
||||
public get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||
return this.instance.get(url, { params, ...config });
|
||||
}
|
||||
|
||||
public post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||
return this.instance.post(url, data, config);
|
||||
}
|
||||
|
||||
public put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
|
||||
return this.instance.put(url, data, config);
|
||||
}
|
||||
|
||||
public delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
|
||||
return this.instance.delete(url, config);
|
||||
}
|
||||
}
|
||||
|
||||
//* 默认导出Request实例
|
||||
export default new Request({});
|
||||
19
src/api/types.d.ts
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-19 21:52:10
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-21 16:59:27
|
||||
* @Description:
|
||||
*/
|
||||
import 'axios';
|
||||
|
||||
import { API_STATUS_CODE } from './apiCodes';
|
||||
declare module 'axios' {
|
||||
export interface IWygResponse<T> {
|
||||
success: boolean;
|
||||
msg: string;
|
||||
code: API_STATUS_CODE;
|
||||
data: T;
|
||||
timestamp: number;
|
||||
}
|
||||
}
|
||||
3
src/assets/LOGO.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="148" height="32" viewBox="0 0 148 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.082 15.38L13.342 13.17H28.188L28.396 11.428H14.694L15.006 9.244H28.682L28.916 7.528H14.278L14.538 5.292H29.28C30.06 5.292 30.6407 5.49133 31.022 5.89C31.4033 6.27133 31.5507 6.83467 31.464 7.58L30.502 15.38H13.082ZM30.71 27.262C28.6647 26.3433 27.0007 25.4333 25.718 24.532C24.2273 23.492 22.91 22.2787 21.766 20.892C20.778 22.3653 19.3913 23.6307 17.606 24.688C16.15 25.5547 14.304 26.4127 12.068 27.262L10.274 25.442C11.9727 24.7487 13.316 24.1767 14.304 23.726C15.292 23.258 16.202 22.738 17.034 22.166C18.0047 21.5073 18.802 20.7707 19.426 19.956C20.0673 19.124 20.5093 18.1707 20.752 17.096L20.934 15.978H23.56L23.326 17.148C23.1873 17.7373 23.04 18.2313 22.884 18.63C24.1147 20.242 25.4927 21.542 27.018 22.53C27.7633 23.0153 28.5867 23.466 29.488 23.882C30.4067 24.2807 31.49 24.7053 32.738 25.156L30.71 27.262ZM28.942 16.732H31.49L28.63 20.944H25.978L28.942 16.732ZM17.684 20.944H15.11L12.77 16.914H15.24L17.684 20.944ZM40.98 15.926C39.9747 17.8327 38.9347 19.4793 37.86 20.866L35.884 19.722C37.8253 17.2607 39.5847 14.3833 41.162 11.09H37.808L38.068 8.802H41.864L42.41 4.46H44.828L44.282 8.802H47.09L46.856 11.09H43.996L43.918 11.688C44.802 13.1267 45.738 14.912 46.726 17.044L44.828 18.214C44.412 17.174 43.97 16.1427 43.502 15.12L42.046 26.82H39.628L40.98 15.926ZM55.046 7.996H50.99L49.976 16.342C49.404 21.1433 48.1647 24.714 46.258 27.054L43.866 26.144C44.8887 24.8267 45.686 23.3793 46.258 21.802C46.83 20.2073 47.246 18.37 47.506 16.29L48.546 7.554C48.6327 6.89533 48.8147 6.41867 49.092 6.124C49.3867 5.812 49.8373 5.656 50.444 5.656H55.774C56.3633 5.656 56.814 5.80333 57.126 6.098C57.438 6.39267 57.594 6.81733 57.594 7.372C57.594 7.56267 57.5853 7.71 57.568 7.814L55.748 23.622C55.7307 23.674 55.722 23.752 55.722 23.856C55.722 24.012 55.7653 24.116 55.852 24.168C55.9387 24.22 56.086 24.246 56.294 24.246C57.1953 24.246 58.114 23.9947 59.05 23.492L58.764 26.118C58.0533 26.4647 57.1607 26.638 56.086 26.638H55.124C53.824 26.638 53.174 26.0053 53.174 24.74C53.174 24.532 53.1827 24.3673 53.2 24.246L55.046 7.996ZM73.922 6.41C74.8927 6.41 75.456 6.878 75.612 7.814L78.576 25.936H75.326L74.468 20.294H66.07L63.808 25.936H60.454L67.942 7.606C68.2713 6.80867 68.878 6.41 69.762 6.41H73.922ZM70.516 9.27L67.214 17.434H74.026L72.778 9.27H70.516ZM83.2706 6.41H86.3386L83.9466 25.936H80.8786L83.2706 6.41ZM103.385 4.486H105.855L105.621 5.994H111.133L110.821 8.23H105.309L105.153 9.426H102.735L102.891 8.23H97.7169L97.5609 9.426H95.1169L95.2729 8.23H89.7869L90.0989 5.994H95.5589L95.7669 4.486H98.2369L98.0289 5.994H103.177L103.385 4.486ZM107.961 9.92C108.793 9.92 109.382 10.0587 109.729 10.336C110.093 10.6133 110.275 11.038 110.275 11.61C110.275 11.818 110.266 11.9827 110.249 12.104L109.989 14.626H107.493L107.805 11.974H92.5689L92.2569 14.626H89.7089L90.0209 12.052C90.1249 11.3067 90.3589 10.7693 90.7229 10.44C91.0869 10.0933 91.6589 9.92 92.4389 9.92H107.961ZM106.479 18.942H92.6209L93.0369 15.068C93.1235 14.3573 93.3229 13.8807 93.6349 13.638C93.9642 13.3953 94.5275 13.274 95.3249 13.274H104.919C105.664 13.274 106.202 13.456 106.531 13.82C106.878 14.1667 107.016 14.6173 106.947 15.172L106.479 18.942ZM95.3769 16.966H104.295L104.529 15.25H95.5329L95.3769 16.966ZM107.519 26.664H90.3849L90.9309 22.27C91.1215 20.8313 91.9882 20.112 93.5309 20.112H105.959C107.519 20.112 108.221 20.8227 108.065 22.244L107.519 26.664ZM93.2709 24.506H105.205L105.491 22.244H93.5569L93.2709 24.506ZM132.583 4.564L131.829 10.7H134.481C135.989 10.7 136.674 11.4453 136.535 12.936L135.157 25.13C135.07 25.6673 134.854 26.0833 134.507 26.378C134.178 26.6727 133.762 26.82 133.259 26.82C132.167 26.82 130.884 26.6727 129.411 26.378L129.645 24.168C130.616 24.376 131.56 24.4973 132.479 24.532H132.609C132.73 24.532 132.808 24.506 132.843 24.454C132.878 24.402 132.904 24.2893 132.921 24.116L133.207 21.62H125.927L125.329 26.716H123.015L124.627 12.806C124.696 12.1473 124.922 11.636 125.303 11.272C125.702 10.8907 126.239 10.7 126.915 10.7H129.437L130.165 4.564H132.583ZM124.211 6.826L123.769 9.088H117.373C116.801 9.088 116.515 8.88 116.515 8.464C116.515 8.308 116.558 8.11733 116.645 7.892L117.893 4.616H120.441L119.661 6.826H124.211ZM127.409 5.474L128.475 9.686H126.057L125.043 5.474H127.409ZM137.211 5.552L135.625 9.712H133.233L134.819 5.552H137.211ZM123.067 16.628L122.807 18.89H119.791L119.297 22.894V22.972C119.297 23.2147 119.375 23.336 119.531 23.336L119.739 23.284C120.779 22.92 121.689 22.556 122.469 22.192L122.183 24.766C120.952 25.286 119.73 25.702 118.517 26.014C118.344 26.066 118.17 26.092 117.997 26.092C117.564 26.092 117.226 25.9273 116.983 25.598C116.758 25.286 116.68 24.8527 116.749 24.298L117.399 18.89H114.851L115.111 16.628H117.685L118.023 13.846H115.631L115.891 11.61H123.223L122.963 13.846H120.415L120.051 16.628H123.067ZM134.195 12.884H126.967L126.707 15.068H133.935L134.195 12.884ZM133.701 17.2H126.447L126.187 19.488H133.441L133.701 17.2Z" fill="#6D4CFE"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
3
src/assets/customer-service.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="74" height="80" viewBox="0 0 74 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M45.3172 2.32014L65.8207 14.7368C68.1655 16.1566 70.1036 18.1528 71.4485 20.5334C72.7934 22.9139 73.4999 25.5987 73.5 28.3295V51.4893C73.4999 54.2201 72.7934 56.9049 71.4485 59.2854C70.1036 61.666 68.1655 63.6622 65.8207 65.0821L45.0173 77.6802C42.5864 79.1521 39.8048 79.9521 36.9594 79.9979C34.114 80.0437 31.3079 79.3336 28.8303 77.9407L8.62522 66.5803C6.15918 65.1936 4.1075 63.1804 2.67992 60.7464C1.25234 58.3125 0.500067 55.545 0.5 52.727V28.3295C0.500098 25.5987 1.20658 22.9139 2.55149 20.5334C3.8964 18.1528 5.83448 16.1566 8.17928 14.7368L28.6828 2.32014C31.1888 0.802647 34.0662 0 37 0C39.9338 0 42.8112 0.802647 45.3172 2.32014ZM28.6304 15.1772L28.5066 15.0446C27.7623 14.3026 24.9772 12.184 23.641 14.1021C21.8842 16.6202 25.7564 19.8044 28.1051 20.2512L28.2924 20.2828L28.3876 20.3017V23.2587C28.1448 23.5018 27.9893 24.0165 28.1226 24.6006C20.7242 29.0289 16.3807 34.7281 16.6044 43.2736C16.8758 54.4447 25.8834 61.9562 36.8445 62.0335C48.1738 62.1062 57.4035 54.2694 57.4035 42.7448C57.4035 34.586 52.6204 29.0084 45.9869 24.8832L45.5315 24.6037L45.5585 19.5029L45.7299 19.6292C46.4979 20.1549 48.2261 20.8274 48.7498 20.9095L49.2465 20.9837C50.459 21.14 52.2776 21.189 52.5712 19.6545C52.8521 18.1736 51.2223 17.2043 50.0384 16.8917C48.7165 16.5444 47.3247 16.1971 46.052 16.3739C44.0175 16.6565 43.7192 18.2857 43.6319 19.4177L43.6208 19.5755C43.6113 19.7255 43.6097 20.2449 43.6113 20.9222V23.5113L42.3671 22.8672L41.6339 22.5056C40.3215 21.8757 38.9631 20.9111 38.1267 20.2765L37.3158 19.6324C37.1336 19.4574 36.895 19.3523 36.6423 19.3355C36.3896 19.3188 36.1391 19.3915 35.9352 19.5408L35.4115 20.0049C34.6577 20.6506 32.9818 22.0257 31.6123 22.7045L30.9934 23.014L30.3951 23.3266L30.3983 20.1975H30.3919V18.9788L30.3792 18.7641L30.3475 18.3789C30.2412 17.4427 29.9301 16.6691 28.6304 15.1772ZM38.8679 36.692V41.0556H44.5015V43.1442H38.8679V49.4054H46.3773V51.2083H26.7975V49.4054H29.6587V39.9173H32.4312V49.4054H35.9177V36.692H38.8679ZM39.1535 30.1592L39.4185 30.6486C41.061 33.5551 43.6557 35.901 47.2025 37.6866L47.8024 37.9786V39.9583C43.3907 38.5059 39.9486 36.2957 37.4777 33.3277C35.1369 36.1394 31.9249 38.2707 27.8433 39.7215L27.1545 39.9583V37.9786L27.7544 37.6866C31.3012 35.9026 33.8959 33.5551 35.5368 30.6486L35.8018 30.1592H39.1551H39.1535Z" fill="#ABABAB"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
3
src/assets/enterprise-nothing.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="74" height="80" viewBox="0 0 74 80" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Vector" d="M45.3172 2.32014L65.8207 14.7368C68.1655 16.1566 70.1036 18.1528 71.4485 20.5334C72.7934 22.9139 73.4999 25.5987 73.5 28.3295V51.4893C73.4999 54.2201 72.7934 56.9049 71.4485 59.2854C70.1036 61.666 68.1655 63.6622 65.8207 65.0821L45.0173 77.6802C42.5864 79.1521 39.8048 79.9521 36.9594 79.9979C34.114 80.0437 31.3079 79.3336 28.8303 77.9407L8.62522 66.5803C6.15918 65.1936 4.1075 63.1804 2.67992 60.7464C1.25234 58.3125 0.500067 55.545 0.5 52.727V28.3295C0.500098 25.5987 1.20658 22.9139 2.55149 20.5334C3.8964 18.1528 5.83448 16.1566 8.17928 14.7368L28.6828 2.32014C31.1888 0.802647 34.0662 0 37 0C39.9338 0 42.8112 0.802647 45.3172 2.32014ZM28.6304 15.1772L28.5066 15.0446C27.7623 14.3026 24.9772 12.184 23.641 14.1021C21.8842 16.6202 25.7564 19.8044 28.1051 20.2512L28.2924 20.2828L28.3876 20.3017V23.2587C28.1448 23.5018 27.9893 24.0165 28.1226 24.6006C20.7242 29.0289 16.3807 34.7281 16.6044 43.2736C16.8758 54.4447 25.8834 61.9562 36.8445 62.0335C48.1738 62.1062 57.4035 54.2694 57.4035 42.7448C57.4035 34.586 52.6204 29.0084 45.9869 24.8832L45.5315 24.6037L45.5585 19.5029L45.7299 19.6292C46.4979 20.1549 48.2261 20.8274 48.7498 20.9095L49.2465 20.9837C50.459 21.14 52.2776 21.189 52.5712 19.6545C52.8521 18.1736 51.2223 17.2043 50.0384 16.8917C48.7165 16.5444 47.3247 16.1971 46.052 16.3739C44.0175 16.6565 43.7192 18.2857 43.6319 19.4177L43.6208 19.5755C43.6113 19.7255 43.6097 20.2449 43.6113 20.9222V23.5113L42.3671 22.8672L41.6339 22.5056C40.3215 21.8757 38.9631 20.9111 38.1267 20.2765L37.3158 19.6324C37.1336 19.4574 36.895 19.3523 36.6423 19.3355C36.3896 19.3188 36.1391 19.3915 35.9352 19.5408L35.4115 20.0049C34.6577 20.6506 32.9818 22.0257 31.6123 22.7045L30.9934 23.014L30.3951 23.3266L30.3983 20.1975H30.3919V18.9788L30.3792 18.7641L30.3475 18.3789C30.2412 17.4427 29.9301 16.6691 28.6304 15.1772ZM38.8679 36.692V41.0556H44.5015V43.1442H38.8679V49.4054H46.3773V51.2083H26.7975V49.4054H29.6587V39.9173H32.4312V49.4054H35.9177V36.692H38.8679ZM39.1535 30.1592L39.4185 30.6486C41.061 33.5551 43.6557 35.901 47.2025 37.6866L47.8024 37.9786V39.9583C43.3907 38.5059 39.9486 36.2957 37.4777 33.3277C35.1369 36.1394 31.9249 38.2707 27.8433 39.7215L27.1545 39.9583V37.9786L27.7544 37.6866C31.3012 35.9026 33.8959 33.5551 35.5368 30.6486L35.8018 30.1592H39.1551H39.1535Z" fill="#ABABAB"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/img/captcha/bg1.png
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
src/assets/img/captcha/bg2.png
Normal file
|
After Width: | Height: | Size: 391 KiB |
BIN
src/assets/img/captcha/bg3.png
Normal file
|
After Width: | Height: | Size: 337 KiB |
BIN
src/assets/img/captcha/bg4.png
Normal file
|
After Width: | Height: | Size: 390 KiB |
BIN
src/assets/img/captcha/bg5.png
Normal file
|
After Width: | Height: | Size: 262 KiB |
BIN
src/assets/img/captcha/icons-sprite.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
365
src/assets/img/captcha/top1.svg
Normal file
@ -0,0 +1,365 @@
|
||||
<svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25.084 1.77441L20.1682 5.51069L20.7939 8.63189C24.6015 5.94241 25.0839 4.43137 25.084 1.77441Z" fill="url(#paint0_linear_256_676)" stroke="url(#paint1_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 1.74219L19.5271 4.19773L20.126 7.28362C23.4547 6.06964 24.9557 2.90886 25.1108 1.74219Z" fill="url(#paint2_linear_256_676)" stroke="url(#paint3_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M25.0747 6.11915L19.1994 8.01789L18.7569 11.1703C23.24 9.89256 24.1953 8.62633 25.0747 6.11915Z" fill="url(#paint4_linear_256_676)" stroke="url(#paint5_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 6.09705L19.0291 6.56618L18.5729 9.67637C22.1158 9.63249 24.5783 7.14664 25.1108 6.09705Z" fill="url(#paint6_linear_256_676)" stroke="url(#paint7_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M25.072 9.44796L18.9882 10.5026L18.1072 13.5616C22.7254 12.9262 23.849 11.8067 25.072 9.44796Z" fill="url(#paint8_linear_256_676)" stroke="url(#paint9_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M25.1107 9.43114L19.0234 9.04135L18.1349 12.0566C21.6488 12.5108 24.4361 10.3955 25.1107 9.43114Z" fill="url(#paint10_linear_256_676)" stroke="url(#paint11_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M23.53 12.4864L17.3933 11.8043L15.695 14.4966C20.3072 15.1732 21.6983 14.4111 23.53 12.4864Z" fill="url(#paint12_linear_256_676)" stroke="url(#paint13_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M23.572 12.481L17.8343 10.4107L16.1409 13.059C19.3891 14.4742 22.6554 13.2193 23.572 12.481Z" fill="url(#paint14_linear_256_676)" stroke="url(#paint15_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.916275 1.77441L5.83203 5.51069L5.20633 8.63189C1.39875 5.94241 0.91639 4.43137 0.916275 1.77441Z" fill="url(#paint16_linear_256_676)" stroke="url(#paint17_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.889464 1.74219L6.47314 4.19773L5.87423 7.28362C2.54558 6.06964 1.04452 2.90886 0.889464 1.74219Z" fill="url(#paint18_linear_256_676)" stroke="url(#paint19_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.92574 6.11915L6.80104 8.01789L7.24362 11.1703C2.7605 9.89256 1.80522 8.62633 0.92574 6.11915Z" fill="url(#paint20_linear_256_676)" stroke="url(#paint21_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.889697 6.09705L6.9714 6.56618L7.42757 9.67637C3.88472 9.63249 1.42215 7.14664 0.889697 6.09705Z" fill="url(#paint22_linear_256_676)" stroke="url(#paint23_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.928288 9.44796L7.01205 10.5026L7.89304 13.5616C3.27489 12.9262 2.15122 11.8067 0.928288 9.44796Z" fill="url(#paint24_linear_256_676)" stroke="url(#paint25_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M0.889507 9.43114L6.97681 9.04135L7.86533 12.0566C4.35145 12.5108 1.56411 10.3955 0.889507 9.43114Z" fill="url(#paint26_linear_256_676)" stroke="url(#paint27_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M2.47021 12.4864L8.60691 11.8043L10.3053 14.4966C5.693 15.1732 4.30191 14.4111 2.47021 12.4864Z" fill="url(#paint28_linear_256_676)" stroke="url(#paint29_linear_256_676)" stroke-width="0.05"/>
|
||||
<path d="M2.42825 12.481L8.16592 10.4107L9.85936 13.059C6.61116 14.4742 3.34484 13.2193 2.42825 12.481Z" fill="url(#paint30_linear_256_676)" stroke="url(#paint31_linear_256_676)" stroke-width="0.05"/>
|
||||
<circle cx="13.0463" cy="8.63179" r="8.10445" fill="#FCBD35"/>
|
||||
<circle cx="13.0463" cy="8.63171" r="7.74538" fill="url(#paint32_linear_256_676)" stroke="url(#paint33_linear_256_676)" stroke-width="0.05"/>
|
||||
<circle cx="13.0463" cy="8.63225" r="6.15764" fill="#FBD371"/>
|
||||
<circle cx="13.0463" cy="8.63225" r="6.10764" stroke="#FFFCED" stroke-opacity="0.8" stroke-width="0.1"/>
|
||||
<g filter="url(#filter0_d_256_676)">
|
||||
<circle cx="13.0463" cy="8.63174" r="5.34952" fill="#FFF8D5"/>
|
||||
<circle cx="13.0463" cy="8.63174" r="5.29952" stroke="#FFFCED" stroke-opacity="0.8" stroke-width="0.1"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_256_676)">
|
||||
<circle cx="13.0461" cy="1.70335" r="0.44749" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="13.0465" cy="1.70351" r="0.364642" fill="url(#paint34_linear_256_676)"/>
|
||||
<g filter="url(#filter2_d_256_676)">
|
||||
<circle cx="13.0466" cy="15.5598" r="0.44749" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="13.0468" cy="15.56" r="0.364642" fill="url(#paint35_linear_256_676)"/>
|
||||
<circle cx="13.0468" cy="15.56" r="0.364642" fill="url(#paint36_linear_256_676)"/>
|
||||
<g filter="url(#filter3_d_256_676)">
|
||||
<circle cx="17.9453" cy="3.73246" r="0.44749" transform="rotate(45 17.9453 3.73246)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="17.9453" cy="3.73248" r="0.364642" transform="rotate(45 17.9453 3.73248)" fill="url(#paint37_linear_256_676)"/>
|
||||
<g filter="url(#filter4_d_256_676)">
|
||||
<circle cx="8.14746" cy="13.5313" r="0.44749" transform="rotate(45 8.14746 13.5313)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="8.14746" cy="13.5313" r="0.364642" transform="rotate(45 8.14746 13.5313)" fill="url(#paint38_linear_256_676)"/>
|
||||
<circle cx="8.14746" cy="13.5313" r="0.364642" transform="rotate(45 8.14746 13.5313)" fill="url(#paint39_linear_256_676)"/>
|
||||
<g filter="url(#filter5_d_256_676)">
|
||||
<circle cx="19.9749" cy="8.63108" r="0.44749" transform="rotate(90 19.9749 8.63108)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="19.9745" cy="8.63124" r="0.364642" transform="rotate(90 19.9745 8.63124)" fill="url(#paint40_linear_256_676)"/>
|
||||
<g filter="url(#filter6_d_256_676)">
|
||||
<circle cx="6.11794" cy="8.63108" r="0.44749" transform="rotate(90 6.11794 8.63108)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="6.11778" cy="8.63124" r="0.364642" transform="rotate(90 6.11778 8.63124)" fill="url(#paint41_linear_256_676)"/>
|
||||
<circle cx="6.11778" cy="8.63124" r="0.364642" transform="rotate(90 6.11778 8.63124)" fill="url(#paint42_linear_256_676)"/>
|
||||
<g filter="url(#filter7_d_256_676)">
|
||||
<circle cx="17.9458" cy="13.5303" r="0.44749" transform="rotate(135 17.9458 13.5303)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="17.9455" cy="13.5303" r="0.364642" transform="rotate(135 17.9455 13.5303)" fill="url(#paint43_linear_256_676)"/>
|
||||
<g filter="url(#filter8_d_256_676)">
|
||||
<circle cx="8.14743" cy="3.73242" r="0.44749" transform="rotate(135 8.14743 3.73242)" fill="#FFF3CE"/>
|
||||
</g>
|
||||
<circle cx="8.14716" cy="3.73242" r="0.364642" transform="rotate(135 8.14716 3.73242)" fill="url(#paint44_linear_256_676)"/>
|
||||
<circle cx="8.14716" cy="3.73242" r="0.364642" transform="rotate(135 8.14716 3.73242)" fill="url(#paint45_linear_256_676)"/>
|
||||
<g filter="url(#filter9_d_256_676)">
|
||||
<path d="M12.2692 5.33496C11.6318 5.97235 10.9153 6.17047 10.6367 6.18985V8.23681C11.3389 8.03308 11.7011 7.82274 12.1267 7.2652V10.3614H10.6367V11.9289H15.4561V10.3614H14.2772V5.33496H12.2692Z" fill="#FFA028"/>
|
||||
<path d="M14.2275 5.38477V10.4111H15.4062V11.8789H10.6865V10.4111H12.1768V7.11719L12.0869 7.23535C11.8768 7.51066 11.6841 7.69813 11.459 7.8418C11.2474 7.97684 11.0038 8.07275 10.6865 8.16797V6.23242C10.9999 6.19558 11.679 5.98727 12.2891 5.38477H14.2275Z" stroke="#FFFEFA" stroke-opacity="0.7" stroke-width="0.1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_256_676" x="7.49678" y="3.08223" width="11.099" height="11.0992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="0.1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.992157 0 0 0 0 0.631373 0 0 0 0 0.0862745 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_256_676" x="12.5086" y="1.22586" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d_256_676" x="12.5091" y="15.0823" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d_256_676" x="17.4078" y="3.25516" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter4_d_256_676" x="7.60995" y="13.054" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter5_d_256_676" x="19.4373" y="8.15359" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter6_d_256_676" x="5.58041" y="8.15359" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter7_d_256_676" x="17.4083" y="13.053" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter8_d_256_676" x="7.60995" y="3.25516" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.920673 0 0 0 0 0.659342 0 0 0 0 0.13668 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter9_d_256_676" x="10.4367" y="5.13496" width="5.21934" height="6.99375" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="0.1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.992157 0 0 0 0 0.631373 0 0 0 0 0.0862745 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_676"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_676" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_256_676" x1="24.4895" y1="2.15758" x2="21.4798" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_256_676" x1="23.5584" y1="2.26682" x2="13.706" y2="7.62766" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_256_676" x1="24.4141" y1="2.055" x2="22.3051" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_256_676" x1="23.3464" y1="2.13492" x2="16.9053" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_256_676" x1="24.387" y1="6.28398" x2="19.2304" y2="10.1602" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_256_676" x1="23.4722" y1="6.07887" x2="12.4007" y2="7.87675" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_256_676" x1="24.3499" y1="6.16166" x2="20.7919" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_256_676" x1="23.3158" y1="5.88369" x2="14.6362" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_256_676" x1="24.3679" y1="9.51454" x2="18.718" y2="12.628" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_256_676" x1="23.4909" y1="9.18297" x2="12.2767" y2="9.40788" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_256_676" x1="24.3483" y1="9.38823" x2="20.2957" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_256_676" x1="23.3636" y1="8.96777" x2="14.0275" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_256_676" x1="22.8353" y1="12.3542" x2="16.5416" y2="13.7702" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_256_676" x1="22.0854" y1="11.7914" x2="11.2526" y2="8.88297" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_256_676" x1="22.8517" y1="12.2274" x2="18.0583" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_256_676" x1="22.0231" y1="11.5492" x2="11.9384" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_256_676" x1="1.51073" y1="2.15758" x2="4.52046" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_256_676" x1="2.44188" y1="2.26682" x2="12.2943" y2="7.62766" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_256_676" x1="1.58611" y1="2.055" x2="3.69514" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_256_676" x1="2.65386" y1="2.13492" x2="9.09494" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint20_linear_256_676" x1="1.61351" y1="6.28398" x2="6.77006" y2="10.1602" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint21_linear_256_676" x1="2.52833" y1="6.07887" x2="13.5997" y2="7.87675" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint22_linear_256_676" x1="1.65061" y1="6.16166" x2="5.20862" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint23_linear_256_676" x1="2.68464" y1="5.88369" x2="11.3643" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint24_linear_256_676" x1="1.63239" y1="9.51454" x2="7.28229" y2="12.628" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint25_linear_256_676" x1="2.50933" y1="9.18297" x2="13.7235" y2="9.40788" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint26_linear_256_676" x1="1.65195" y1="9.38823" x2="5.70454" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint27_linear_256_676" x1="2.63669" y1="8.96777" x2="11.9727" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint28_linear_256_676" x1="3.16499" y1="12.3542" x2="9.45862" y2="13.7702" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCA36"/>
|
||||
<stop offset="1" stop-color="#FF8E14"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint29_linear_256_676" x1="3.91482" y1="11.7914" x2="14.7476" y2="8.88297" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint30_linear_256_676" x1="3.14855" y1="12.2274" x2="7.94198" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFF1BC"/>
|
||||
<stop offset="1" stop-color="#FFCA3F"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint31_linear_256_676" x1="3.97715" y1="11.5492" x2="14.0619" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FFBF28"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint32_linear_256_676" x1="5.27588" y1="0.861328" x2="15.9246" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.242116" stop-color="#FFF0C9"/>
|
||||
<stop offset="0.557692" stop-color="#FFE6AD"/>
|
||||
<stop offset="1" stop-color="#FDA118"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint33_linear_256_676" x1="13.0463" y1="0.861328" x2="13.0463" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint34_linear_256_676" x1="13.0465" y1="1.33887" x2="13.0465" y2="2.06815" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint35_linear_256_676" x1="13.0468" y1="15.1953" x2="13.0468" y2="15.9246" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#E97F33"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint36_linear_256_676" x1="13.0468" y1="15.1953" x2="13.0468" y2="15.9246" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint37_linear_256_676" x1="17.9453" y1="3.36784" x2="17.9453" y2="4.09712" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint38_linear_256_676" x1="8.14746" y1="13.1667" x2="8.14746" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#E97F33"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint39_linear_256_676" x1="8.14746" y1="13.1667" x2="8.14746" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint40_linear_256_676" x1="19.9745" y1="8.2666" x2="19.9745" y2="8.99588" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint41_linear_256_676" x1="6.11778" y1="8.2666" x2="6.11778" y2="8.99588" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#E97F33"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint42_linear_256_676" x1="6.11778" y1="8.2666" x2="6.11778" y2="8.99588" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint43_linear_256_676" x1="17.9455" y1="13.1656" x2="17.9455" y2="13.8949" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint44_linear_256_676" x1="8.14716" y1="3.36778" x2="8.14716" y2="4.09706" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#E97F33"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint45_linear_256_676" x1="8.14716" y1="3.36778" x2="8.14716" y2="4.09706" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE07D"/>
|
||||
<stop offset="0.688858" stop-color="#FFB749"/>
|
||||
<stop offset="0.985577" stop-color="#FB944B"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 24 KiB |
327
src/assets/img/captcha/top2.svg
Normal file
@ -0,0 +1,327 @@
|
||||
<svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25.084 1.77441L20.1682 5.51069L20.7939 8.63189C24.6015 5.94241 25.0839 4.43137 25.084 1.77441Z" fill="url(#paint0_linear_256_740)" stroke="url(#paint1_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 1.74219L19.5271 4.19773L20.126 7.28362C23.4547 6.06964 24.9557 2.90886 25.1108 1.74219Z" fill="url(#paint2_linear_256_740)" stroke="url(#paint3_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M25.0747 6.11915L19.1994 8.01789L18.7569 11.1703C23.24 9.89256 24.1953 8.62633 25.0747 6.11915Z" fill="url(#paint4_linear_256_740)" stroke="url(#paint5_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 6.09705L19.0291 6.56618L18.5729 9.67637C22.1158 9.63249 24.5783 7.14664 25.1108 6.09705Z" fill="url(#paint6_linear_256_740)" stroke="url(#paint7_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M25.072 9.44796L18.9882 10.5026L18.1072 13.5616C22.7254 12.9262 23.849 11.8067 25.072 9.44796Z" fill="url(#paint8_linear_256_740)" stroke="url(#paint9_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M25.1107 9.43114L19.0234 9.04135L18.1349 12.0566C21.6488 12.5108 24.4361 10.3955 25.1107 9.43114Z" fill="url(#paint10_linear_256_740)" stroke="url(#paint11_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M23.53 12.4864L17.3933 11.8043L15.695 14.4966C20.3072 15.1732 21.6983 14.4111 23.53 12.4864Z" fill="url(#paint12_linear_256_740)" stroke="url(#paint13_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M23.572 12.481L17.8343 10.4107L16.1409 13.059C19.3891 14.4742 22.6554 13.2193 23.572 12.481Z" fill="url(#paint14_linear_256_740)" stroke="url(#paint15_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.916275 1.77441L5.83203 5.51069L5.20633 8.63189C1.39875 5.94241 0.91639 4.43137 0.916275 1.77441Z" fill="url(#paint16_linear_256_740)" stroke="url(#paint17_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.889464 1.74219L6.47314 4.19773L5.87423 7.28362C2.54558 6.06964 1.04452 2.90886 0.889464 1.74219Z" fill="url(#paint18_linear_256_740)" stroke="url(#paint19_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.925496 6.11915L6.8008 8.01789L7.24337 11.1703C2.76025 9.89256 1.80497 8.62633 0.925496 6.11915Z" fill="url(#paint20_linear_256_740)" stroke="url(#paint21_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.889453 6.09705L6.97116 6.56618L7.42732 9.67637C3.88448 9.63249 1.4219 7.14664 0.889453 6.09705Z" fill="url(#paint22_linear_256_740)" stroke="url(#paint23_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.928288 9.44796L7.01205 10.5026L7.89304 13.5616C3.27489 12.9262 2.15122 11.8067 0.928288 9.44796Z" fill="url(#paint24_linear_256_740)" stroke="url(#paint25_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M0.889507 9.43114L6.97681 9.04135L7.86533 12.0566C4.35145 12.5108 1.56411 10.3955 0.889507 9.43114Z" fill="url(#paint26_linear_256_740)" stroke="url(#paint27_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M2.47021 12.4864L8.60691 11.8043L10.3053 14.4966C5.693 15.1732 4.30191 14.4111 2.47021 12.4864Z" fill="url(#paint28_linear_256_740)" stroke="url(#paint29_linear_256_740)" stroke-width="0.05"/>
|
||||
<path d="M2.42825 12.481L8.16592 10.4107L9.85936 13.059C6.61116 14.4742 3.34484 13.2193 2.42825 12.481Z" fill="url(#paint30_linear_256_740)" stroke="url(#paint31_linear_256_740)" stroke-width="0.05"/>
|
||||
<circle cx="13.0463" cy="8.63179" r="8.10445" fill="#A2B9CB"/>
|
||||
<circle cx="13.0463" cy="8.63171" r="7.74538" fill="url(#paint32_linear_256_740)" stroke="url(#paint33_linear_256_740)" stroke-width="0.05"/>
|
||||
<circle cx="13.0463" cy="8.63225" r="6.10764" fill="#C2D0DD" stroke="#DFECF6" stroke-width="0.1"/>
|
||||
<g filter="url(#filter0_d_256_740)">
|
||||
<circle cx="13.0463" cy="8.63174" r="5.34952" fill="#E3ECF8"/>
|
||||
<circle cx="13.0463" cy="8.63174" r="5.29952" stroke="#B9C9D9" stroke-width="0.1"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_256_740)">
|
||||
<circle cx="13.0466" cy="1.70335" r="0.44749" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="13.047" cy="1.70351" r="0.364642" fill="url(#paint34_linear_256_740)"/>
|
||||
<g filter="url(#filter2_d_256_740)">
|
||||
<circle cx="13.0466" cy="15.5598" r="0.44749" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="13.047" cy="15.56" r="0.364642" fill="url(#paint35_linear_256_740)"/>
|
||||
<g filter="url(#filter3_d_256_740)">
|
||||
<circle cx="17.9463" cy="3.73246" r="0.44749" transform="rotate(45 17.9463 3.73246)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="17.9465" cy="3.73248" r="0.364642" transform="rotate(45 17.9465 3.73248)" fill="url(#paint36_linear_256_740)"/>
|
||||
<g filter="url(#filter4_d_256_740)">
|
||||
<circle cx="8.14795" cy="13.5313" r="0.44749" transform="rotate(45 8.14795 13.5313)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="8.14819" cy="13.5313" r="0.364642" transform="rotate(45 8.14819 13.5313)" fill="url(#paint37_linear_256_740)"/>
|
||||
<g filter="url(#filter5_d_256_740)">
|
||||
<circle cx="19.9749" cy="8.63206" r="0.44749" transform="rotate(90 19.9749 8.63206)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="19.9747" cy="8.63222" r="0.364642" transform="rotate(90 19.9747 8.63222)" fill="url(#paint38_linear_256_740)"/>
|
||||
<g filter="url(#filter6_d_256_740)">
|
||||
<circle cx="6.11818" cy="8.63206" r="0.44749" transform="rotate(90 6.11818 8.63206)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="6.11802" cy="8.63222" r="0.364642" transform="rotate(90 6.11802 8.63222)" fill="url(#paint39_linear_256_740)"/>
|
||||
<g filter="url(#filter7_d_256_740)">
|
||||
<circle cx="17.9455" cy="13.5312" r="0.44749" transform="rotate(135 17.9455 13.5312)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="17.9453" cy="13.5312" r="0.364642" transform="rotate(135 17.9453 13.5312)" fill="url(#paint40_linear_256_740)"/>
|
||||
<g filter="url(#filter8_d_256_740)">
|
||||
<circle cx="8.14743" cy="3.7334" r="0.44749" transform="rotate(135 8.14743 3.7334)" fill="#F3F6F8"/>
|
||||
</g>
|
||||
<circle cx="8.14716" cy="3.7334" r="0.364642" transform="rotate(135 8.14716 3.7334)" fill="url(#paint41_linear_256_740)"/>
|
||||
<path d="M13.3781 5.14498C10.8453 4.9868 10.0373 6.70557 9.94983 7.58472L11.9541 7.73321C11.6425 6.52148 13.3781 6.23297 13.7775 6.68304C14.4699 7.50241 13.5327 7.58472 11.6643 8.61799C10.1696 9.44461 9.89851 10.7063 9.94983 11.2337H15.9286C15.8935 10.5128 16.0605 9.7317 16.1484 9.43129C15.7967 9.5368 13.3055 9.66576 12.1039 9.71705C12.1039 9.51922 14.8296 9.01365 15.6649 8.11243C16.5001 7.2112 16.5441 5.3427 13.3781 5.14498Z" fill="#91A7B8" stroke="#F5FAFF" stroke-width="0.1"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_256_740" x="7.49678" y="3.08223" width="11.099" height="11.0992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="0.1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.62323 0 0 0 0 0.666031 0 0 0 0 0.704327 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_256_740" x="12.5091" y="1.22586" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d_256_740" x="12.5091" y="15.0823" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d_256_740" x="17.4088" y="3.25516" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter4_d_256_740" x="7.61044" y="13.054" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter5_d_256_740" x="19.4373" y="8.15457" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter6_d_256_740" x="5.58065" y="8.15457" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter7_d_256_740" x="17.408" y="13.054" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter8_d_256_740" x="7.60995" y="3.25613" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.485484 0 0 0 0 0.56436 0 0 0 0 0.638597 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_740"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_740" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_256_740" x1="24.4895" y1="2.15758" x2="21.4798" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_256_740" x1="23.5584" y1="2.26682" x2="18.4079" y2="5.76594" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_256_740" x1="24.4141" y1="2.055" x2="22.3051" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_256_740" x1="23.3464" y1="2.13492" x2="16.9053" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_256_740" x1="24.387" y1="6.28398" x2="20.3221" y2="8.77982" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_256_740" x1="23.4722" y1="6.07887" x2="17.4539" y2="7.67616" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_256_740" x1="24.3499" y1="6.16166" x2="20.7919" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_256_740" x1="23.3158" y1="5.88369" x2="14.6362" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_256_740" x1="24.3679" y1="9.51454" x2="19.9927" y2="11.4147" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_256_740" x1="23.4909" y1="9.18297" x2="17.308" y2="9.91907" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_256_740" x1="24.3483" y1="9.38823" x2="20.2957" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_256_740" x1="23.3636" y1="8.96777" x2="14.0275" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_256_740" x1="22.8353" y1="12.3542" x2="18.104" y2="12.9601" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_256_740" x1="22.0854" y1="11.7914" x2="15.9422" y2="10.7757" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_256_740" x1="22.8517" y1="12.2274" x2="18.0583" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_256_740" x1="22.0231" y1="11.5492" x2="11.9384" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_256_740" x1="1.51073" y1="2.15758" x2="4.52046" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_256_740" x1="2.44188" y1="2.26682" x2="7.5923" y2="5.76594" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_256_740" x1="1.58611" y1="2.055" x2="3.69514" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_256_740" x1="2.65386" y1="2.13492" x2="9.09494" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint20_linear_256_740" x1="1.61327" y1="6.28398" x2="5.67813" y2="8.77982" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint21_linear_256_740" x1="2.52809" y1="6.07887" x2="8.54634" y2="7.67616" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint22_linear_256_740" x1="1.65036" y1="6.16166" x2="5.20838" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint23_linear_256_740" x1="2.6844" y1="5.88369" x2="11.364" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint24_linear_256_740" x1="1.63239" y1="9.51454" x2="6.00753" y2="11.4147" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint25_linear_256_740" x1="2.50933" y1="9.18297" x2="8.69228" y2="9.91907" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint26_linear_256_740" x1="1.65195" y1="9.38823" x2="5.70454" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint27_linear_256_740" x1="2.63669" y1="8.96777" x2="11.9727" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint28_linear_256_740" x1="3.16499" y1="12.3542" x2="7.89629" y2="12.9601" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A7BBCE"/>
|
||||
<stop offset="1" stop-color="#758695"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint29_linear_256_740" x1="3.91482" y1="11.7914" x2="10.058" y2="10.7757" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BFCEDB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint30_linear_256_740" x1="3.14855" y1="12.2274" x2="7.94198" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#E4EAF0"/>
|
||||
<stop offset="1" stop-color="#A7BACD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint31_linear_256_740" x1="3.97715" y1="11.5492" x2="14.0619" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#8699AA"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint32_linear_256_740" x1="5.27588" y1="0.861328" x2="15.9246" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.242116" stop-color="#EEF2F5"/>
|
||||
<stop offset="0.557692" stop-color="#C8D4DF"/>
|
||||
<stop offset="1" stop-color="#768797"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint33_linear_256_740" x1="13.0463" y1="0.861328" x2="13.0463" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint34_linear_256_740" x1="13.047" y1="1.33887" x2="13.047" y2="2.06815" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint35_linear_256_740" x1="13.047" y1="15.1953" x2="13.047" y2="15.9246" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint36_linear_256_740" x1="17.9465" y1="3.36784" x2="17.9465" y2="4.09712" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint37_linear_256_740" x1="8.14819" y1="13.1667" x2="8.14819" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint38_linear_256_740" x1="19.9747" y1="8.26758" x2="19.9747" y2="8.99686" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint39_linear_256_740" x1="6.11802" y1="8.26758" x2="6.11802" y2="8.99686" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint40_linear_256_740" x1="17.9453" y1="13.1666" x2="17.9453" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint41_linear_256_740" x1="8.14716" y1="3.36876" x2="8.14716" y2="4.09804" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#DDE4EC"/>
|
||||
<stop offset="0.688858" stop-color="#B6C7D6"/>
|
||||
<stop offset="0.985577" stop-color="#9BADBD"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
340
src/assets/img/captcha/top3.svg
Normal file
@ -0,0 +1,340 @@
|
||||
<svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25.084 1.77441L20.1682 5.51069L20.7939 8.63189C24.6015 5.94241 25.0839 4.43137 25.084 1.77441Z" fill="url(#paint0_linear_256_804)" stroke="url(#paint1_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 1.74219L19.5271 4.19773L20.126 7.28362C23.4547 6.06964 24.9557 2.90886 25.1108 1.74219Z" fill="url(#paint2_linear_256_804)" stroke="url(#paint3_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M25.0747 6.11915L19.1994 8.01789L18.7569 11.1703C23.24 9.89256 24.1953 8.62633 25.0747 6.11915Z" fill="url(#paint4_linear_256_804)" stroke="url(#paint5_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M25.1108 6.09705L19.0291 6.56618L18.5729 9.67637C22.1158 9.63249 24.5783 7.14664 25.1108 6.09705Z" fill="url(#paint6_linear_256_804)" stroke="url(#paint7_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M25.072 9.44796L18.9882 10.5026L18.1072 13.5616C22.7254 12.9262 23.849 11.8067 25.072 9.44796Z" fill="url(#paint8_linear_256_804)" stroke="url(#paint9_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M25.1107 9.43114L19.0234 9.04135L18.1349 12.0566C21.6488 12.5108 24.4361 10.3955 25.1107 9.43114Z" fill="url(#paint10_linear_256_804)" stroke="url(#paint11_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M23.53 12.4864L17.3933 11.8043L15.695 14.4966C20.3072 15.1732 21.6983 14.4111 23.53 12.4864Z" fill="url(#paint12_linear_256_804)" stroke="url(#paint13_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M23.572 12.481L17.8343 10.4107L16.1409 13.059C19.3891 14.4742 22.6554 13.2193 23.572 12.481Z" fill="url(#paint14_linear_256_804)" stroke="url(#paint15_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.916275 1.77441L5.83203 5.51069L5.20633 8.63189C1.39875 5.94241 0.91639 4.43137 0.916275 1.77441Z" fill="url(#paint16_linear_256_804)" stroke="url(#paint17_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.889464 1.74219L6.47314 4.19773L5.87423 7.28362C2.54558 6.06964 1.04452 2.90886 0.889464 1.74219Z" fill="url(#paint18_linear_256_804)" stroke="url(#paint19_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.925496 6.11915L6.8008 8.01789L7.24337 11.1703C2.76025 9.89256 1.80497 8.62633 0.925496 6.11915Z" fill="url(#paint20_linear_256_804)" stroke="url(#paint21_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.889453 6.09705L6.97116 6.56618L7.42732 9.67637C3.88448 9.63249 1.4219 7.14664 0.889453 6.09705Z" fill="url(#paint22_linear_256_804)" stroke="url(#paint23_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.928288 9.44796L7.01205 10.5026L7.89304 13.5616C3.27489 12.9262 2.15122 11.8067 0.928288 9.44796Z" fill="url(#paint24_linear_256_804)" stroke="url(#paint25_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M0.889507 9.43114L6.97681 9.04135L7.86533 12.0566C4.35145 12.5108 1.56411 10.3955 0.889507 9.43114Z" fill="url(#paint26_linear_256_804)" stroke="url(#paint27_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M2.47021 12.4864L8.60691 11.8043L10.3053 14.4966C5.693 15.1732 4.30191 14.4111 2.47021 12.4864Z" fill="url(#paint28_linear_256_804)" stroke="url(#paint29_linear_256_804)" stroke-width="0.05"/>
|
||||
<path d="M2.42825 12.481L8.16592 10.4107L9.85936 13.059C6.61116 14.4742 3.34484 13.2193 2.42825 12.481Z" fill="url(#paint30_linear_256_804)" stroke="url(#paint31_linear_256_804)" stroke-width="0.05"/>
|
||||
<circle cx="13.0002" cy="8.63179" r="8.10445" fill="#ED9152"/>
|
||||
<circle cx="13.0001" cy="8.63171" r="7.74538" fill="url(#paint32_linear_256_804)" stroke="url(#paint33_linear_256_804)" stroke-width="0.05"/>
|
||||
<circle cx="13.0002" cy="8.63225" r="6.10764" fill="#FFA76C" stroke="#FFC8A3" stroke-width="0.1"/>
|
||||
<g filter="url(#filter0_d_256_804)">
|
||||
<circle cx="13.0002" cy="8.63174" r="5.34952" fill="#FFD6BB"/>
|
||||
<circle cx="13.0002" cy="8.63174" r="5.29952" stroke="#FB9653" stroke-width="0.1"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_256_804)">
|
||||
<circle cx="12.9992" cy="1.70335" r="0.44749" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="12.9997" cy="1.70351" r="0.364642" fill="url(#paint34_linear_256_804)"/>
|
||||
<g filter="url(#filter2_d_256_804)">
|
||||
<circle cx="12.9992" cy="15.5598" r="0.44749" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="12.9997" cy="15.56" r="0.364642" fill="url(#paint35_linear_256_804)"/>
|
||||
<g filter="url(#filter3_d_256_804)">
|
||||
<circle cx="17.8989" cy="3.73246" r="0.44749" transform="rotate(45 17.8989 3.73246)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="17.8992" cy="3.73248" r="0.364642" transform="rotate(45 17.8992 3.73248)" fill="url(#paint36_linear_256_804)"/>
|
||||
<g filter="url(#filter4_d_256_804)">
|
||||
<circle cx="8.10059" cy="13.5313" r="0.44749" transform="rotate(45 8.10059 13.5313)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="8.10083" cy="13.5313" r="0.364642" transform="rotate(45 8.10083 13.5313)" fill="url(#paint37_linear_256_804)"/>
|
||||
<g filter="url(#filter5_d_256_804)">
|
||||
<circle cx="19.9278" cy="8.63206" r="0.44749" transform="rotate(90 19.9278 8.63206)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="19.9276" cy="8.63222" r="0.364642" transform="rotate(90 19.9276 8.63222)" fill="url(#paint38_linear_256_804)"/>
|
||||
<g filter="url(#filter6_d_256_804)">
|
||||
<circle cx="6.07106" cy="8.63206" r="0.44749" transform="rotate(90 6.07106 8.63206)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="6.07091" cy="8.63222" r="0.364642" transform="rotate(90 6.07091 8.63222)" fill="url(#paint39_linear_256_804)"/>
|
||||
<g filter="url(#filter7_d_256_804)">
|
||||
<circle cx="17.8984" cy="13.5312" r="0.44749" transform="rotate(135 17.8984 13.5312)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="17.8981" cy="13.5312" r="0.364642" transform="rotate(135 17.8981 13.5312)" fill="url(#paint40_linear_256_804)"/>
|
||||
<g filter="url(#filter8_d_256_804)">
|
||||
<circle cx="8.10031" cy="3.7334" r="0.44749" transform="rotate(135 8.10031 3.7334)" fill="#FFEFE4"/>
|
||||
</g>
|
||||
<circle cx="8.10004" cy="3.7334" r="0.364642" transform="rotate(135 8.10004 3.7334)" fill="url(#paint41_linear_256_804)"/>
|
||||
<g filter="url(#filter9_d_256_804)">
|
||||
<path d="M13.4399 5.42274C10.6997 5.36508 9.79097 6.67641 9.67915 7.33927C10.3804 7.41653 11.245 7.74484 11.5896 7.89933C11.8814 6.92168 13.5449 6.61525 14.0118 7.2427C14.3854 7.74466 12.932 7.76314 12.1587 7.70964V9.21259C12.5636 9.05887 13.6309 9.23609 14.114 9.30015C14.5809 9.66494 14.1577 10.0151 12.9904 10.0881C12.0565 10.1465 11.6674 9.6163 11.5896 9.34392C11.4962 9.46066 10.2276 9.77195 9.60498 9.913C9.67308 10.4918 10.4046 11.6845 12.786 11.8245C15.1674 11.9646 15.5374 11.2358 16.1567 10.5842C16.9855 8.73982 15.4417 8.43436 14.5662 8.51218C16.7842 8.24953 16.8652 5.49481 13.4399 5.42274Z" fill="#E18546"/>
|
||||
<path d="M13.4399 5.42274C10.6997 5.36508 9.79097 6.67641 9.67915 7.33927C10.3804 7.41653 11.245 7.74484 11.5896 7.89933C11.8814 6.92168 13.5449 6.61525 14.0118 7.2427C14.3854 7.74466 12.932 7.76314 12.1587 7.70964V9.21259C12.5636 9.05887 13.6309 9.23609 14.114 9.30015C14.5809 9.66494 14.1577 10.0151 12.9904 10.0881C12.0565 10.1465 11.6674 9.6163 11.5896 9.34392C11.4962 9.46066 10.2276 9.77195 9.60498 9.913C9.67308 10.4918 10.4046 11.6845 12.786 11.8245C15.1674 11.9646 15.5374 11.2358 16.1567 10.5842C16.9855 8.73982 15.4417 8.43436 14.5662 8.51218C16.7842 8.24953 16.8652 5.49481 13.4399 5.42274Z" stroke="#FFECDE" stroke-width="0.1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_256_804" x="7.45063" y="3.08223" width="11.099" height="11.0992" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="0.1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.909649 0 0 0 0 0.572 0 0 0 0 0.341785 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_256_804" x="12.4618" y="1.22586" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d_256_804" x="12.4618" y="15.0823" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d_256_804" x="17.3614" y="3.25516" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter4_d_256_804" x="7.56308" y="13.054" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter5_d_256_804" x="19.3902" y="8.15457" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter6_d_256_804" x="5.53354" y="8.15457" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter7_d_256_804" x="17.3609" y="13.054" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter8_d_256_804" x="7.56283" y="3.25613" width="1.07502" height="1.07453" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="0.06"/>
|
||||
<feGaussianBlur stdDeviation="0.045"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.947172 0 0 0 0 0.59246 0 0 0 0 0.346029 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter9_d_256_804" x="9.35005" y="5.17109" width="7.29355" height="6.92051" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="0.1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.939547 0 0 0 0 0.555727 0 0 0 0 0.294032 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_256_804"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_256_804" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_256_804" x1="24.4895" y1="2.15758" x2="21.4798" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_256_804" x1="23.5584" y1="2.26682" x2="18.4079" y2="5.76594" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_256_804" x1="24.4141" y1="2.055" x2="22.3051" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_256_804" x1="23.3464" y1="2.13492" x2="16.9053" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_256_804" x1="24.387" y1="6.28398" x2="20.3221" y2="8.77982" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_256_804" x1="23.4722" y1="6.07887" x2="17.4539" y2="7.67616" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_256_804" x1="24.3499" y1="6.16166" x2="20.7919" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_256_804" x1="23.3158" y1="5.88369" x2="14.6362" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_256_804" x1="24.3679" y1="9.51454" x2="19.9927" y2="11.4147" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_256_804" x1="23.4909" y1="9.18297" x2="17.308" y2="9.91907" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_256_804" x1="24.3483" y1="9.38823" x2="20.2957" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_256_804" x1="23.3636" y1="8.96777" x2="14.0275" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_256_804" x1="22.8353" y1="12.3542" x2="18.104" y2="12.9601" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_256_804" x1="22.0854" y1="11.7914" x2="15.9422" y2="10.7757" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_256_804" x1="22.8517" y1="12.2274" x2="18.0583" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_256_804" x1="22.0231" y1="11.5492" x2="11.9384" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_256_804" x1="1.51073" y1="2.15758" x2="4.52046" y2="5.8581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_256_804" x1="2.44188" y1="2.26682" x2="7.5923" y2="5.76594" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_256_804" x1="1.58611" y1="2.055" x2="3.69514" y2="6.79212" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_256_804" x1="2.65386" y1="2.13492" x2="9.09494" y2="9.9954" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint20_linear_256_804" x1="1.61327" y1="6.28398" x2="5.67813" y2="8.77982" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint21_linear_256_804" x1="2.52809" y1="6.07887" x2="8.54634" y2="7.67616" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint22_linear_256_804" x1="1.65036" y1="6.16166" x2="5.20838" y2="9.93379" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint23_linear_256_804" x1="2.6844" y1="5.88369" x2="11.364" y2="11.1694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint24_linear_256_804" x1="1.63239" y1="9.51454" x2="6.00753" y2="11.4147" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint25_linear_256_804" x1="2.50933" y1="9.18297" x2="8.69228" y2="9.91907" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint26_linear_256_804" x1="1.65195" y1="9.38823" x2="5.70454" y2="12.6232" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint27_linear_256_804" x1="2.63669" y1="8.96777" x2="11.9727" y2="12.9819" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint28_linear_256_804" x1="3.16499" y1="12.3542" x2="7.89629" y2="12.9601" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F9944F"/>
|
||||
<stop offset="1" stop-color="#BD642B"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint29_linear_256_804" x1="3.91482" y1="11.7914" x2="10.058" y2="10.7757" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#F7D6BE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint30_linear_256_804" x1="3.14855" y1="12.2274" x2="7.94198" y2="14.2051" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.442308" stop-color="#FFD9BF"/>
|
||||
<stop offset="1" stop-color="#ED9051"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint31_linear_256_804" x1="3.97715" y1="11.5492" x2="14.0619" y2="12.8032" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#FEEEE1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint32_linear_256_804" x1="5.22974" y1="0.861328" x2="15.8785" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.242116" stop-color="#FFEBDE"/>
|
||||
<stop offset="0.557692" stop-color="#FFC59E"/>
|
||||
<stop offset="1" stop-color="#CD7337"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint33_linear_256_804" x1="13.0001" y1="0.861328" x2="13.0001" y2="16.4021" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint34_linear_256_804" x1="12.9997" y1="1.33887" x2="12.9997" y2="2.06815" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint35_linear_256_804" x1="12.9997" y1="15.1953" x2="12.9997" y2="15.9246" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint36_linear_256_804" x1="17.8992" y1="3.36784" x2="17.8992" y2="4.09712" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint37_linear_256_804" x1="8.10083" y1="13.1667" x2="8.10083" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint38_linear_256_804" x1="19.9276" y1="8.26758" x2="19.9276" y2="8.99686" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint39_linear_256_804" x1="6.0709" y1="8.26758" x2="6.0709" y2="8.99686" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint40_linear_256_804" x1="17.8981" y1="13.1666" x2="17.8981" y2="13.8959" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint41_linear_256_804" x1="8.10004" y1="3.36876" x2="8.10004" y2="4.09804" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFD3B5"/>
|
||||
<stop offset="0.688858" stop-color="#FEA567"/>
|
||||
<stop offset="0.985577" stop-color="#E17C39"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/img/guide/applyed.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/img/guide/company.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src/assets/img/guide/guidebg.png
Normal file
|
After Width: | Height: | Size: 497 KiB |
BIN
src/assets/img/guide/passportbg.png
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
src/assets/img/guide/person.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
src/assets/img/guide/staff.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
src/assets/img/guide/star.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/img/hottranslation/good.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/img/hottranslation/normal.png
Normal file
|
After Width: | Height: | Size: 865 B |
BIN
src/assets/img/hottranslation/poor.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/img/hottranslation/star-fill1.png
Normal file
|
After Width: | Height: | Size: 577 B |
BIN
src/assets/img/hottranslation/star-fill2.png
Normal file
|
After Width: | Height: | Size: 541 B |
BIN
src/assets/img/hottranslation/star-fill3.png
Normal file
|
After Width: | Height: | Size: 614 B |
BIN
src/assets/img/hottranslation/star-fill4.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
src/assets/img/hottranslation/star-fill5.png
Normal file
|
After Width: | Height: | Size: 621 B |
BIN
src/assets/img/hottranslation/xhs.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
27324
src/assets/maps/china.json
Normal file
24
src/assets/play.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_261_2700)">
|
||||
<circle cx="21.0001" cy="19" r="17" fill="white"/>
|
||||
</g>
|
||||
<circle cx="21.0001" cy="19" r="14" fill="url(#paint0_linear_261_2700)"/>
|
||||
<path d="M17.5001 24.8565V13.1435C17.5001 12.7526 17.9284 12.5129 18.2616 12.7173L27.8056 18.5738C28.1236 18.769 28.1236 19.231 27.8056 19.4262L18.2616 25.2827C17.9284 25.4871 17.5001 25.2474 17.5001 24.8565Z" fill="white"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_261_2700" x="6.10352e-05" y="0" width="42" height="42" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.499541 0 0 0 0 0.38654 0 0 0 0 0.996056 0 0 0 0.2 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_261_2700"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_261_2700" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_261_2700" x1="7.00006" y1="19" x2="35.0001" y2="19" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E96B5D"/>
|
||||
<stop offset="0.5" stop-color="#7F63FE"/>
|
||||
<stop offset="1" stop-color="#459DDC"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
52
src/components/_base/breadcrumb/index.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<!--
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:14:16
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:17:52
|
||||
* @Description:
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const matched = computed(() => {
|
||||
if (route.matched.length === 1 && route.matched[0].path === '/') {
|
||||
return [];
|
||||
} else {
|
||||
return route.matched.reduce((t: RouteLocationNormalized[], o) => {
|
||||
const isExist = t.find((c) => c.name === o.name);
|
||||
return isExist ? t : [...t, router.resolve(o)];
|
||||
}, []);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view></view>
|
||||
<!-- <a-breadcrumb class="container-breadcrumb">
|
||||
<a-breadcrumb-item v-for="{ meta, name } in matched" :key="name">
|
||||
<router-link v-slot="{ href, navigate }" :to="{ name }" custom>
|
||||
<a-link v-if="meta.needNavigate" :href="href" @click="navigate">{{
|
||||
meta.locale ? meta.locale : '主页'
|
||||
}}</a-link>
|
||||
<a-link v-else disabled>{{ meta.locale ? meta.locale : '主页' }}</a-link>
|
||||
</router-link>
|
||||
</a-breadcrumb-item>
|
||||
</a-breadcrumb> -->
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container-breadcrumb {
|
||||
margin: 16px 0;
|
||||
:deep(.arco-breadcrumb-item) {
|
||||
> a {
|
||||
color: rgb(var(--gray-6));
|
||||
}
|
||||
&:last-child {
|
||||
color: rgb(var(--gray-8));
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
5
src/components/_base/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export { default as Navbar } from './navbar/index.vue';
|
||||
export { default as Menu } from './menu/index.vue';
|
||||
export { default as TabBar } from './tab-bar/index.vue';
|
||||
export { default as Breadcrumb } from './breadcrumb/index.vue';
|
||||
export { default as ModalSimple } from './modal/index.vue';
|
||||
140
src/components/_base/menu/index.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<script lang="tsx">
|
||||
import type { RouteMeta, RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { useAppStore } from '@/stores';
|
||||
import { listenerRouteChange } from '@/utils/route-listener';
|
||||
import { openWindow, regexUrl } from '@/utils';
|
||||
import useMenuTree from './use-menu-tree';
|
||||
|
||||
export default defineComponent({
|
||||
emit: ['collapse'],
|
||||
setup() {
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const { menuTree } = useMenuTree();
|
||||
const collapsed = computed({
|
||||
get() {
|
||||
if (appStore.device === 'desktop') return appStore.menuCollapse;
|
||||
return false;
|
||||
},
|
||||
set(value: boolean) {
|
||||
appStore.updateSettings({ menuCollapse: value });
|
||||
},
|
||||
});
|
||||
const topMenu = computed(() => appStore.topMenu);
|
||||
const openKeys = ref<string[]>([]);
|
||||
const selectedKey = ref<string[]>([]);
|
||||
const goto = (item: RouteRecordRaw) => {
|
||||
// Open external link
|
||||
if (regexUrl.test(item.path)) {
|
||||
openWindow(item.path);
|
||||
selectedKey.value = [item.name as string];
|
||||
return;
|
||||
}
|
||||
// Eliminate external link side effects
|
||||
const { hideInMenu, activeMenu } = item.meta as RouteMeta;
|
||||
if (route.name === item.name && !hideInMenu && !activeMenu) {
|
||||
selectedKey.value = [item.name as string];
|
||||
return;
|
||||
}
|
||||
// Trigger router change
|
||||
router.push({
|
||||
name: item.name,
|
||||
});
|
||||
};
|
||||
const findMenuOpenKeys = (target: string) => {
|
||||
const result: string[] = [];
|
||||
let isFind = false;
|
||||
const backtrack = (item: RouteRecordRaw, keys: string[]) => {
|
||||
if (item.name === target) {
|
||||
isFind = true;
|
||||
result.push(...keys);
|
||||
return;
|
||||
}
|
||||
if (item.children?.length) {
|
||||
item.children.forEach((el) => {
|
||||
backtrack(el, [...keys, el.name as string]);
|
||||
});
|
||||
}
|
||||
};
|
||||
menuTree.value.forEach((el: RouteRecordRaw) => {
|
||||
if (isFind) return; // Performance optimization
|
||||
backtrack(el, [el.name as string]);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
listenerRouteChange((newRoute) => {
|
||||
const { requiresAuth, activeMenu, hideInMenu } = newRoute.meta;
|
||||
if (requiresAuth && (!hideInMenu || activeMenu)) {
|
||||
const menuOpenKeys = findMenuOpenKeys((activeMenu || newRoute.name) as string);
|
||||
const keySet = new Set([...menuOpenKeys, ...openKeys.value]);
|
||||
openKeys.value = [...keySet];
|
||||
selectedKey.value = [activeMenu || menuOpenKeys[menuOpenKeys.length - 1]];
|
||||
}
|
||||
}, true);
|
||||
const setCollapse = (val: boolean) => {
|
||||
if (appStore.device === 'desktop') appStore.updateSettings({ menuCollapse: val });
|
||||
};
|
||||
const renderSubMenu = () => {
|
||||
function travel(_route: RouteRecordRaw[], nodes = []) {
|
||||
if (_route) {
|
||||
_route.forEach((element) => {
|
||||
// This is demo, modify nodes as needed
|
||||
const icon = element?.meta?.icon ? () => h(element?.meta?.icon as object) : null;
|
||||
const node =
|
||||
element?.children && element?.children.length !== 0 ? (
|
||||
<a-sub-menu
|
||||
key={element?.name}
|
||||
v-slots={{
|
||||
icon,
|
||||
title: () => element?.meta?.locale || '',
|
||||
}}
|
||||
>
|
||||
{travel(element?.children)}
|
||||
</a-sub-menu>
|
||||
) : (
|
||||
<a-menu-item key={element?.name} v-slots={{ icon }} onClick={() => goto(element)}>
|
||||
{element?.meta?.locale || ''}
|
||||
</a-menu-item>
|
||||
);
|
||||
nodes.push(node as never);
|
||||
});
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
return travel(menuTree.value);
|
||||
};
|
||||
return () => (
|
||||
<a-menu
|
||||
mode={topMenu.value ? 'horizontal' : 'vertical'}
|
||||
v-model:collapsed={collapsed.value}
|
||||
v-model:open-keys={openKeys.value}
|
||||
show-collapse-button={appStore.device !== 'mobile'}
|
||||
auto-open={false}
|
||||
selected-keys={selectedKey.value}
|
||||
auto-open-selected={true}
|
||||
level-indent={34}
|
||||
style="height: 100%;width:100%;"
|
||||
onCollapse={setCollapse}
|
||||
>
|
||||
{renderSubMenu()}
|
||||
</a-menu>
|
||||
);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.arco-menu-inner) {
|
||||
.arco-menu-inline-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.arco-icon {
|
||||
&:not(.arco-icon-down) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
60
src/components/_base/menu/use-menu-tree.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import type { RouteRecordRaw, RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
import { useAppStore } from '@/stores';
|
||||
import appClientMenus from '@/router/app-menus';
|
||||
|
||||
export default function useMenuTree() {
|
||||
const appStore = useAppStore();
|
||||
const appRoute = computed(() => {
|
||||
if (appStore.menuFromServer) {
|
||||
// return appClientMenus.concat(toRaw(appStore.appAsyncMenus));
|
||||
return toRaw(appStore.appAsyncMenus);
|
||||
}
|
||||
return appClientMenus;
|
||||
});
|
||||
const menuTree = computed(() => {
|
||||
const copyRouter = cloneDeep(appRoute.value) as RouteRecordNormalized[];
|
||||
copyRouter.sort((a: RouteRecordNormalized, b: RouteRecordNormalized) => {
|
||||
return (a.meta.order || 0) - (b.meta.order || 0);
|
||||
});
|
||||
function travel(_routes: RouteRecordRaw[], layer: number) {
|
||||
if (!_routes) return null;
|
||||
|
||||
const collector: any = _routes.map((element) => {
|
||||
// leaf node
|
||||
if (element.meta?.hideChildrenInMenu || !element.children) {
|
||||
element.children = [];
|
||||
return element;
|
||||
}
|
||||
|
||||
// route filter hideInMenu true
|
||||
element.children = element.children.filter((x) => x.meta?.hideInMenu !== true);
|
||||
|
||||
// Associated child node
|
||||
const subItem = travel(element.children, layer + 1);
|
||||
|
||||
if (subItem.length) {
|
||||
element.children = subItem;
|
||||
return element;
|
||||
}
|
||||
// the else logic
|
||||
if (layer > 1) {
|
||||
element.children = subItem;
|
||||
return element;
|
||||
}
|
||||
|
||||
if (element.meta?.hideInMenu === false) {
|
||||
return element;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
return collector.filter(Boolean);
|
||||
}
|
||||
return travel(copyRouter, 0);
|
||||
});
|
||||
|
||||
return {
|
||||
menuTree,
|
||||
};
|
||||
}
|
||||
32
src/components/_base/modal/index.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import type { Component, DefineComponent } from 'vue';
|
||||
|
||||
import IconHover from '@arco-design/web-vue/es/_components/icon-hover';
|
||||
|
||||
defineProps<{
|
||||
title?: string;
|
||||
content?: string | (() => DefineComponent | Component);
|
||||
}>();
|
||||
|
||||
defineEmits(['close']);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<slot name="header">
|
||||
<div class="flex justify-end mb7">
|
||||
<slot name="close">
|
||||
<icon-hover @click="$emit('close')">
|
||||
<icon-close />
|
||||
</icon-hover>
|
||||
</slot>
|
||||
</div>
|
||||
</slot>
|
||||
<slot>
|
||||
<div class="flex flex-col text-center">
|
||||
<div v-if="title" class="mb4 text-lg font-600">{{ title }}</div>
|
||||
<template v-else />
|
||||
<component :is="content" v-if="typeof content === 'function'" />
|
||||
<div v-else>{{ content }}</div>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
114
src/components/_base/navbar/index.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<script lang="ts" setup>
|
||||
import { useAppStore } from '@/stores';
|
||||
import { IconExport, IconFile, IconCaretDown } from '@arco-design/web-vue/es/icon';
|
||||
import { fetchMenusTree } from '@/api/all';
|
||||
const lists = ref([]);
|
||||
const getMenus = async () => {
|
||||
const res = await fetchMenusTree();
|
||||
lists.value = res;
|
||||
};
|
||||
onMounted(() => {
|
||||
getMenus();
|
||||
});
|
||||
const appStore = useAppStore();
|
||||
|
||||
const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
|
||||
const avatar = computed(
|
||||
() => '//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/dfdba5317c0c20ce20e64fac803d52bc.svg~tplv-49unhts6dw-image.image',
|
||||
);
|
||||
const topMenu = computed(() => appStore.topMenu && appStore.menu);
|
||||
const toggleDrawerMenu = inject('toggleDrawerMenu') as () => void;
|
||||
|
||||
function setServerMenu() {
|
||||
appStore.fetchServerMenuConfig();
|
||||
console.log(appStore.serverMenu);
|
||||
}
|
||||
const handleSelect = (index: any) => {
|
||||
console.log(index);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<div class="left-side">
|
||||
<a-space>
|
||||
<img src="@/assets/LOGO.svg" alt="" />
|
||||
</a-space>
|
||||
</div>
|
||||
<div class="center-side">
|
||||
<div class="menu-demo">
|
||||
<a-menu mode="horizontal" :default-selected-keys="['1']">
|
||||
<a-menu-item :key="'1'">
|
||||
<view>工作台</view>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-for="(item, index) in lists" :key="index + 2">
|
||||
<a-dropdown @select="handleSelect" :popup-max-height="false">
|
||||
<a-button>{{ item.name }}<icon-caret-down /></a-button>
|
||||
<template #content>
|
||||
<a-doption v-for="(child, index) in item.children" :key="index">{{ child.name }}</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="right-side">
|
||||
<li>
|
||||
<a-dropdown trigger="click">
|
||||
<a-avatar class="cursor-pointer" :size="32">
|
||||
<img alt="avatar" :src="avatar" />
|
||||
</a-avatar>
|
||||
</a-dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
background-color: var(--color-bg-2);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.left-side {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.center-side {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
margin-left: 40px;
|
||||
}
|
||||
.cneter-tip {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
.menu-demo {
|
||||
flex: 1;
|
||||
}
|
||||
.right-side {
|
||||
display: flex;
|
||||
padding-right: 20px;
|
||||
list-style: none;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: var(--color-text-1);
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-btn {
|
||||
border-color: rgb(var(--gray-2));
|
||||
color: rgb(var(--gray-8));
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
83
src/components/_base/tab-bar/index.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<script lang="ts" setup>
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
import { listenerRouteChange, removeRouteListener } from '@/utils/route-listener';
|
||||
import { useAppStore, useTabBarStore } from '@/stores';
|
||||
import TabItem from './tab-item.vue';
|
||||
const appStore = useAppStore();
|
||||
const tabBarStore = useTabBarStore();
|
||||
const affixRef = ref();
|
||||
const tagList = computed(() => {
|
||||
return tabBarStore.getTabList;
|
||||
});
|
||||
const offsetTop = computed(() => {
|
||||
return appStore.navbar ? 60 : 0;
|
||||
});
|
||||
watch(
|
||||
() => appStore.navbar,
|
||||
() => {
|
||||
affixRef.value.updatePosition();
|
||||
},
|
||||
);
|
||||
listenerRouteChange((route: RouteLocationNormalized) => {
|
||||
if (!route.meta.noAffix && !tagList.value.some((tag) => tag.fullPath === route.fullPath)) {
|
||||
tabBarStore.updateTabList(route);
|
||||
}
|
||||
}, true);
|
||||
onUnmounted(() => {
|
||||
removeRouteListener();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tab-bar-container">
|
||||
<a-affix ref="affixRef" :offset-top="offsetTop">
|
||||
<div class="tab-bar-box">
|
||||
<div class="tab-bar-scroll">
|
||||
<div class="tags-wrap">
|
||||
<tab-item v-for="(tag, index) in tagList" :key="tag.fullPath" :index="index" :item-data="tag" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tag-bar-operation"></div>
|
||||
</div>
|
||||
</a-affix>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.tab-bar-container {
|
||||
position: relative;
|
||||
background-color: var(--color-bg-2);
|
||||
.tab-bar-box {
|
||||
display: flex;
|
||||
padding: 0 0 0 20px;
|
||||
background-color: var(--color-bg-2);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
.tab-bar-scroll {
|
||||
height: 32px;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
.tags-wrap {
|
||||
padding: 4px 0;
|
||||
height: 48px;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
:deep(.arco-tag) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 6px;
|
||||
cursor: pointer;
|
||||
&:first-child {
|
||||
.arco-tag-close-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tag-bar-operation {
|
||||
width: 100px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
177
src/components/_base/tab-bar/tab-item.vue
Normal file
@ -0,0 +1,177 @@
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue';
|
||||
import type { TagProps } from '@/stores/modules/tab-bar/types';
|
||||
|
||||
import { useTabBarStore } from '@/stores';
|
||||
import { DEFAULT_ROUTE_NAME, REDIRECT_ROUTE_NAME } from '@/router/constants';
|
||||
|
||||
const props = defineProps({
|
||||
itemData: {
|
||||
type: Object as PropType<TagProps>,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
// eslint-disable-next-line no-shadow
|
||||
enum Eaction {
|
||||
reload = 'reload',
|
||||
current = 'current',
|
||||
left = 'left',
|
||||
right = 'right',
|
||||
others = 'others',
|
||||
all = 'all',
|
||||
}
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const tabBarStore = useTabBarStore();
|
||||
const goto = (tag: TagProps) => {
|
||||
router.push({ ...tag });
|
||||
};
|
||||
const tagList = computed(() => {
|
||||
return tabBarStore.getTabList;
|
||||
});
|
||||
const disabledReload = computed(() => {
|
||||
return props.itemData.fullPath !== route.fullPath;
|
||||
});
|
||||
const disabledCurrent = computed(() => {
|
||||
return props.index === 0;
|
||||
});
|
||||
const disabledLeft = computed(() => {
|
||||
return [0, 1].includes(props.index);
|
||||
});
|
||||
const disabledRight = computed(() => {
|
||||
return props.index === tagList.value.length - 1;
|
||||
});
|
||||
const tagClose = (tag: TagProps, idx: number) => {
|
||||
tabBarStore.deleteTag(idx, tag);
|
||||
if (props.itemData.fullPath === route.fullPath) {
|
||||
const latest = tagList.value[idx - 1]; // 获取队列的前一个tab
|
||||
router.push({ name: latest.name });
|
||||
}
|
||||
};
|
||||
const findCurrentRouteIndex = () => {
|
||||
return tagList.value.findIndex((el) => el.fullPath === route.fullPath);
|
||||
};
|
||||
const actionSelect = async (value: any) => {
|
||||
const { itemData, index } = props;
|
||||
const copyTagList = [...tagList.value];
|
||||
if (value === Eaction.current) {
|
||||
tagClose(itemData, index);
|
||||
} else if (value === Eaction.left) {
|
||||
const currentRouteIdx = findCurrentRouteIndex();
|
||||
copyTagList.splice(1, props.index - 1);
|
||||
tabBarStore.freshTabList(copyTagList);
|
||||
if (currentRouteIdx < index) {
|
||||
router.push({ name: itemData.name });
|
||||
}
|
||||
} else if (value === Eaction.right) {
|
||||
const currentRouteIdx = findCurrentRouteIndex();
|
||||
copyTagList.splice(props.index + 1);
|
||||
tabBarStore.freshTabList(copyTagList);
|
||||
if (currentRouteIdx > index) {
|
||||
router.push({ name: itemData.name });
|
||||
}
|
||||
} else if (value === Eaction.others) {
|
||||
const filterList = tagList.value.filter((el, idx) => {
|
||||
return idx === 0 || idx === props.index;
|
||||
});
|
||||
tabBarStore.freshTabList(filterList);
|
||||
router.push({ name: itemData.name });
|
||||
} else if (value === Eaction.reload) {
|
||||
tabBarStore.deleteCache(itemData);
|
||||
await router.push({
|
||||
name: REDIRECT_ROUTE_NAME,
|
||||
params: {
|
||||
path: route.fullPath,
|
||||
},
|
||||
});
|
||||
tabBarStore.addCache(itemData.name);
|
||||
} else {
|
||||
tabBarStore.resetTabList();
|
||||
router.push({ name: DEFAULT_ROUTE_NAME });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-dropdown trigger="contextMenu" :popup-max-height="false" @select="actionSelect">
|
||||
<span
|
||||
:class="[
|
||||
'arco-tag arco-tag-size-medium arco-tag-checked',
|
||||
{ 'link-activated': itemData.fullPath === $route.fullPath },
|
||||
]"
|
||||
@click="goto(itemData)"
|
||||
>
|
||||
<span class="tag-link">{{ itemData.title }}</span>
|
||||
<span
|
||||
class="arco-icon-hover arco-tag-icon-hover arco-icon-hover-size-medium arco-tag-close-btn"
|
||||
@click.stop="tagClose(itemData, index)"
|
||||
>
|
||||
<icon-close />
|
||||
</span>
|
||||
</span>
|
||||
<template #content>
|
||||
<a-doption :disabled="disabledReload" :value="Eaction.reload">
|
||||
<icon-refresh />
|
||||
<span>重新加载</span>
|
||||
</a-doption>
|
||||
<a-doption class="sperate-line" :disabled="disabledCurrent" :value="Eaction.current">
|
||||
<icon-close />
|
||||
<span>关闭当前标签页</span>
|
||||
</a-doption>
|
||||
<a-doption :disabled="disabledLeft" :value="Eaction.left">
|
||||
<icon-to-left />
|
||||
<span>关闭左侧标签页</span>
|
||||
</a-doption>
|
||||
<a-doption class="sperate-line" :disabled="disabledRight" :value="Eaction.right">
|
||||
<icon-to-right />
|
||||
<span>关闭右侧标签页</span>
|
||||
</a-doption>
|
||||
<a-doption :value="Eaction.others">
|
||||
<icon-swap />
|
||||
<span>关闭其它标签页</span>
|
||||
</a-doption>
|
||||
<a-doption :value="Eaction.all">
|
||||
<icon-folder-delete />
|
||||
<span>关闭全部标签页</span>
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.tag-link {
|
||||
color: var(--color-text-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
.link-activated {
|
||||
color: rgb(var(--link-6));
|
||||
.tag-link {
|
||||
color: rgb(var(--link-6));
|
||||
}
|
||||
& + .arco-tag-close-btn {
|
||||
color: rgb(var(--link-6));
|
||||
}
|
||||
}
|
||||
:deep(.arco-dropdown-option-content) {
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.arco-dropdown-open {
|
||||
.tag-link {
|
||||
color: rgb(var(--danger-6));
|
||||
}
|
||||
.arco-tag-close-btn {
|
||||
color: rgb(var(--danger-6));
|
||||
}
|
||||
}
|
||||
.sperate-line {
|
||||
border-bottom: 1px solid var(--color-neutral-3);
|
||||
}
|
||||
</style>
|
||||
70
src/components/confirm-button/index.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<!--
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-16 11:58:01
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-16 16:56:27
|
||||
* @Description: 二次确认框
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-popconfirm
|
||||
:content="content"
|
||||
:position="position"
|
||||
:ok-text="okText"
|
||||
:cancel-text="cancelText"
|
||||
:type="popupType"
|
||||
@ok="handleConfirm"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<slot></slot>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue-demi';
|
||||
|
||||
type Position = 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb';
|
||||
|
||||
type PopupType = 'info' | 'success' | 'warning' | 'error';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
default: '是否确认?',
|
||||
},
|
||||
position: {
|
||||
type: String as PropType<Position>,
|
||||
default: 'top',
|
||||
},
|
||||
okText: {
|
||||
type: String,
|
||||
default: '确定',
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: '取消',
|
||||
},
|
||||
popupType: {
|
||||
type: String as PropType<PopupType>,
|
||||
default: 'info',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['confirmEmit', 'cancelEmit']);
|
||||
|
||||
/**
|
||||
* 确定事件
|
||||
*/
|
||||
function handleConfirm() {
|
||||
emit('confirmEmit');
|
||||
}
|
||||
/**
|
||||
* 确定事件
|
||||
*/
|
||||
function handleCancel() {
|
||||
emit('cancelEmit');
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
5
src/components/wyg-form/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# 动态配置form表单
|
||||
示例见 views/components/form
|
||||
参数 fieldList:配置项,包括arco.design Form.Item和Input、Select以及自定义属性component等
|
||||
参数 model: 传默认值
|
||||
通过ref获取实例,调用子组件实例updateFieldsList方法更新配置项,调用setModel方法更新数据,调用setForm方法更新Form属性,自定义事件change处理逻辑
|
||||
40
src/components/wyg-form/constants.ts
Normal file
@ -0,0 +1,40 @@
|
||||
// form.item的属性名称集合
|
||||
export const formItemKeys = [
|
||||
'field',
|
||||
'label',
|
||||
'tooltip',
|
||||
'showColon',
|
||||
'noStyle',
|
||||
'disabled',
|
||||
'help',
|
||||
'extra',
|
||||
'required',
|
||||
'asteriskPosition',
|
||||
'rules',
|
||||
'validateStatus',
|
||||
'validateTrigger',
|
||||
'wrapperColProps',
|
||||
'hideLabel',
|
||||
'hideAsterisk',
|
||||
'labelColStyle',
|
||||
'wrapperColStyle',
|
||||
'rowProps',
|
||||
'rowClass',
|
||||
'contentClass',
|
||||
'contentFlex',
|
||||
'labelColFlex',
|
||||
'feedback',
|
||||
'labelComponent',
|
||||
'labelAttrs',
|
||||
];
|
||||
// 自定义属性名称集合
|
||||
export const customKeys = ['component', 'lists'];
|
||||
// 响应式栅格默认配置
|
||||
export const COL_PROPS = {
|
||||
xs: 12,
|
||||
sm: 12,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 6,
|
||||
xxl: 6,
|
||||
};
|
||||
271
src/components/wyg-form/index.vue
Normal file
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<slot name="header"></slot>
|
||||
<a-form v-bind="_options" ref="formRef" :model="model" @submit.prevent>
|
||||
<a-row v-bind="rowProps" :gutter="20">
|
||||
<template
|
||||
v-for="{ field, component, formItemProps, componentProps, lists, colProps } in newFieldList"
|
||||
:key="field"
|
||||
>
|
||||
<!-- 单选框 -->
|
||||
<a-col v-if="component === 'radio'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-radio-group v-bind="componentProps" v-model="model[field]">
|
||||
<a-radio v-for="val in lists" :key="val['value']" :label="val['value']" size="large">
|
||||
{{ val['label'] }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 复选框 -->
|
||||
<a-col v-if="component === 'checkbox'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-checkbox-group v-bind="componentProps" v-model="model[field]">
|
||||
<a-checkbox v-for="c in lists" :key="c['value']" :label="c['value']">{{ c['label'] }}</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 下拉框 -->
|
||||
<a-col v-if="component === 'select'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-select v-bind="componentProps" v-model="model[field]">
|
||||
<a-option v-for="s in lists" :key="s['value']" :label="s['label']" :value="s['value']" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 文本域 -->
|
||||
<a-col v-if="component === 'textarea'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-textarea v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 时间选择器 -->
|
||||
<a-col v-if="component === 'time'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-time-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 日期选择器 -->
|
||||
<a-col v-if="component === 'date'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-date-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 日期范围选择器 -->
|
||||
<a-col v-if="component === 'rangeDate'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-range-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 级联选择器 -->
|
||||
<a-col v-if="component === 'cascader'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-cascader v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 数字输入框 -->
|
||||
<a-col v-if="component === 'inputNumber'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-input-number v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 输入框 -->
|
||||
<a-col v-if="component === 'input'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-input v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 标题模块 -->
|
||||
<a-col v-if="component === 'title'" :span="24">
|
||||
<div class="title">
|
||||
<div class="bar"></div>
|
||||
<h4 class="text">{{ formItemProps.label }}</h4>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 自定义插槽slot -->
|
||||
<a-col v-if="component === 'slot'" :span="24">
|
||||
<slot :name="field"></slot>
|
||||
</a-col>
|
||||
</template>
|
||||
<a-col :span="24">
|
||||
<a-form-item>
|
||||
<slot name="buttons" :model="model" :formRef="formRef">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="onSubmit(formRef)">{{ _options.submitButtonText }}</a-button>
|
||||
<a-button v-if="_options.showResetButton" @click="resetForm(formRef)">
|
||||
{{ _options.resetButtonText }}
|
||||
</a-button>
|
||||
<a-button v-if="_options.showCancelButton" @click="emit('cancel')">
|
||||
{{ _options.cancelButtonText }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</slot>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<slot name="footer"></slot>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance, RowProps, ValidatedError } from '@arco-design/web-vue';
|
||||
import type { ComputedRef } from 'vue';
|
||||
import type { Form } from './interface';
|
||||
import { formItemKeys, customKeys, COL_PROPS } from './constants';
|
||||
import { changeFormList } from './utils';
|
||||
import type { FieldData } from '@arco-design/web-vue/es/form/interface';
|
||||
// 父组件传递的值
|
||||
interface Props {
|
||||
fieldList: Form.FieldItem[];
|
||||
model?: Record<string, any>;
|
||||
options?: Form.Options;
|
||||
rowProps?: RowProps;
|
||||
}
|
||||
interface EmitEvent {
|
||||
(e: 'submit' | 'change', params: any): void;
|
||||
(e: 'reset' | 'cancel'): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<EmitEvent>();
|
||||
// 表单的数据
|
||||
let model = ref<Record<string, any>>({});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
// 初始化处理Form组件属性options
|
||||
const _options = ref<Record<string, any>>({});
|
||||
const initOptions = () => {
|
||||
const option = {
|
||||
layout: 'vertical',
|
||||
disabled: false,
|
||||
submitButtonText: '提交',
|
||||
resetButtonText: '重置',
|
||||
cancelButtonText: '取消',
|
||||
showResetButton: true,
|
||||
};
|
||||
Object.assign(option, props?.options);
|
||||
_options.value = option;
|
||||
};
|
||||
initOptions();
|
||||
// 初始化处理model
|
||||
const initFormModel = () => {
|
||||
props.fieldList.forEach((item: Form.FieldItem) => {
|
||||
// 如果类型为checkbox,默认值需要设置一个空数组
|
||||
const value = item.component === 'checkbox' ? [] : '';
|
||||
const { field, component } = item;
|
||||
if (component !== 'slot' && component !== 'title') {
|
||||
model.value[item.field] = props?.model?.[field] || value;
|
||||
}
|
||||
});
|
||||
};
|
||||
initFormModel();
|
||||
// 初始化处理fieldList
|
||||
const newFieldList: any = ref(null);
|
||||
const initFieldList = () => {
|
||||
const list = props?.fieldList.map((item: Form.FieldItem) => {
|
||||
const customProps = pick(item, customKeys);
|
||||
const formItemProps = pick(item, formItemKeys);
|
||||
const componentProps = omit(item, [...formItemKeys, ...customKeys, 'field', 'colProps']);
|
||||
const { colProps = {}, field, placeholder, component = 'input', label } = item;
|
||||
componentProps.onChange = (val: any) => onChange(field, val);
|
||||
const newColProps = {
|
||||
...colProps,
|
||||
...COL_PROPS,
|
||||
};
|
||||
const obj = {
|
||||
field,
|
||||
colProps: newColProps,
|
||||
...customProps,
|
||||
formItemProps,
|
||||
componentProps,
|
||||
};
|
||||
if ((component === 'input' || component === 'textarea') && !placeholder) {
|
||||
componentProps.placeholder = `请输入${label}`;
|
||||
}
|
||||
if (component === 'select' && !placeholder) {
|
||||
componentProps.placeholder = `请选择${label}`;
|
||||
}
|
||||
if (component === 'rangeDate') {
|
||||
componentProps.value = [null, null];
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
newFieldList.value = list;
|
||||
return list;
|
||||
};
|
||||
initFieldList();
|
||||
// 提交
|
||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
let flag = false;
|
||||
await formEl.validate((errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (!errors) {
|
||||
emit('submit', model.value);
|
||||
flag = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return (flag && model.value) || null;
|
||||
};
|
||||
// 提交--父组件调用
|
||||
const submit = () => {
|
||||
return onSubmit(formRef.value);
|
||||
};
|
||||
// 重置
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
// 表单变化
|
||||
const onChange = (key: string, val: any) => {
|
||||
emit('change', { key, val });
|
||||
};
|
||||
// 设置
|
||||
const setModel = (data: Record<string, FieldData>) => {
|
||||
const newData = {
|
||||
...model.value,
|
||||
...data,
|
||||
};
|
||||
model.value = newData;
|
||||
};
|
||||
// 设置Form
|
||||
const setForm = (data: Form.Options) => {
|
||||
const options = {
|
||||
..._options.value,
|
||||
...data,
|
||||
};
|
||||
_options.value = options;
|
||||
};
|
||||
// 更新配置项
|
||||
const updateFieldsList = (updateList: any[]) => {
|
||||
const list = changeFormList(newFieldList.value, updateList);
|
||||
newFieldList.value = list;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
setModel,
|
||||
setForm,
|
||||
updateFieldsList,
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.arco-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.bar {
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
background-color: rgb(var(--primary-6));
|
||||
}
|
||||
.text {
|
||||
font-size: 16px;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
95
src/components/wyg-form/interface.d.ts
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
import type { FieldRule } from '@arco-design/web-vue/es/form/interface';
|
||||
import { Size, ColProps, CascaderOption, InputProps } from '@arco-design/web-vue';
|
||||
console.log(InputProps, 'InputProps=====');
|
||||
|
||||
export namespace Form {
|
||||
/** 表单项自身Props */
|
||||
interface FormItem<T = string> {
|
||||
field: string;
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
showColon?: boolean;
|
||||
noStyle?: boolean;
|
||||
disabled?: boolean;
|
||||
help?: string;
|
||||
extra?: string;
|
||||
required?: boolean;
|
||||
asteriskPosition?: 'start' | 'end';
|
||||
rules?: FieldRule | FieldRule[];
|
||||
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
|
||||
validateTrigger?: 'change' | 'input' | 'focus' | 'blur';
|
||||
labelColProps?: object;
|
||||
wrapperColProps?: object;
|
||||
hideLabel?: boolean;
|
||||
hideAsterisk?: boolean;
|
||||
labelColStyle?: object;
|
||||
wrapperColStyle?: object;
|
||||
rowProps?: object;
|
||||
rowClass?: string | Array<T> | object;
|
||||
contentClass?: string | Array<T> | object;
|
||||
contentFlex?: boolean;
|
||||
labelColFlex?: number | string;
|
||||
feedback?: boolean;
|
||||
labelComponent?: string;
|
||||
labelAttrs?: object;
|
||||
}
|
||||
// 当前 fieldItem 的类型 默认值'input'
|
||||
type ComponentType =
|
||||
| 'input'
|
||||
| 'textarea'
|
||||
| 'radio'
|
||||
| 'checkbox'
|
||||
| 'select'
|
||||
| 'time'
|
||||
| 'date'
|
||||
| 'rangeDate'
|
||||
| 'inputNumber'
|
||||
| 'cascader'
|
||||
| 'title'
|
||||
| 'slot';
|
||||
/** 自定义Props */
|
||||
interface CustomProps {
|
||||
component?: ComponentType;
|
||||
lists?: object; // 如果 type='checkbox' / 'radio' / 'select'时,需传入此配置项。格式参考FieldItemOptions配置项
|
||||
}
|
||||
/** Input、Select组件等的Props */
|
||||
interface ComponentProps {
|
||||
placeholder?: string; // 输入框占位文本
|
||||
readonly?: boolean; // 是否只读 false
|
||||
allowClear?: boolean; // 是否可清空 false
|
||||
onChange?: Function;
|
||||
options?: CascaderOption[];
|
||||
}
|
||||
/** 每一项配置项的属性 */
|
||||
interface FieldItem extends FormItem, CustomProps, ComponentProps {
|
||||
colProps?: ColProps;
|
||||
}
|
||||
/** 处理后的配置项属性 */
|
||||
interface NewFieldItem extends CustomProps {
|
||||
formItemProps: FormItem;
|
||||
componentProps: ComponentProps;
|
||||
field: string;
|
||||
colProps?: ColProps;
|
||||
}
|
||||
interface FieldItemOptions {
|
||||
label: string | number;
|
||||
value: string | number;
|
||||
}
|
||||
/** 表单Form自身Props */
|
||||
interface Options {
|
||||
layout?: 'horizontal' | 'vertical' | 'inline'; // 表单的布局方式,包括水平、垂直、多列
|
||||
size?: Size; // 用于控制该表单内组件的尺寸
|
||||
labelColProps?: object; // 标签元素布局选项。参数同 <col> 组件一致,默认值span: 5, offset: 0
|
||||
wrapperColProps?: object; // 表单控件布局选项。参数同 <col> 组件一致,默认值span: 19, offset: 0
|
||||
labelAlign?: 'left' | 'right'; // 标签的对齐方向,默认值'right'
|
||||
disabled?: boolean; // 是否禁用表单
|
||||
rules?: Record<string, FieldRule | FieldRule[]>; // 表单项校验规则
|
||||
autoLabelWidth?: boolean; // 是否开启自动标签宽度,仅在 layout="horizontal" 下生效。默认值false
|
||||
|
||||
showResetButton?: boolean; // 是否展示重置按钮
|
||||
showCancelButton?: boolean; // 是否展示取消按钮
|
||||
submitButtonText?: string;
|
||||
resetButtonText?: string;
|
||||
cancelButtonText?: string;
|
||||
}
|
||||
}
|
||||
25
src/components/wyg-form/utils.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { formItemKeys, customKeys, COL_PROPS } from './constants';
|
||||
import type { Form } from './interface';
|
||||
// fieldList更新
|
||||
export const changeFormList = (formList: Form.NewFieldItem[], updateList: Form.FieldItem[]): Form.NewFieldItem[] => {
|
||||
let list: any = formList;
|
||||
list.forEach((item: any, index: string | number) => {
|
||||
updateList.forEach((ele: any) => {
|
||||
if (item.field === ele.field) {
|
||||
list[index] = { ...item, ...ele };
|
||||
const keys: string[] = Object.keys(ele);
|
||||
keys.forEach((key: string) => {
|
||||
const val = ele[key];
|
||||
if (formItemKeys.includes(key)) {
|
||||
list[index].formItemProps[key] = val;
|
||||
} else if (customKeys.includes(key) || key === 'colProps') {
|
||||
list[index][key] = val;
|
||||
} else {
|
||||
list[index].componentProps[key] = val;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return list;
|
||||
};
|
||||
73
src/components/wyg-table/index.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<!--
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-16 14:40:38
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-16 16:37:52
|
||||
* @Description: table公用封装
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-table
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:data="tableData"
|
||||
:bordered="{ cell: borderCell }"
|
||||
:pagination="setPagination"
|
||||
page-position="br"
|
||||
v-bind="propsRes"
|
||||
v-on="propsEvent"
|
||||
>
|
||||
<template #columns>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationProps, TableData } from '@arco-design/web-vue';
|
||||
import type { PropType } from 'vue-demi';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
|
||||
type Size = 'mini' | 'small' | 'medium' | 'large';
|
||||
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: String as PropType<Size>,
|
||||
default: 'large',
|
||||
},
|
||||
tableData: {
|
||||
type: Array as PropType<TableData[]>,
|
||||
default: () => [],
|
||||
},
|
||||
borderCell: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
pagination: {
|
||||
type: Object as PropType<PaginationProps>,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const loading = ref(false);
|
||||
|
||||
const setPagination = computed(() => {
|
||||
const defaultPagination: PaginationProps = {
|
||||
showPageSize: true,
|
||||
showTotal: true,
|
||||
showMore: true,
|
||||
size: 'large',
|
||||
};
|
||||
return Object.assign(defaultPagination, props.pagination);
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.tableData.length === 0) {
|
||||
loading.value = true;
|
||||
} else {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
17
src/config/settings.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"theme": "light",
|
||||
"colorWeak": false,
|
||||
"navbar": true,
|
||||
"menu": true,
|
||||
"topMenu": false,
|
||||
"hideMenu": false,
|
||||
"menuCollapse": false,
|
||||
"footer": true,
|
||||
"themeColor": "#165DFF",
|
||||
"menuWidth": 220,
|
||||
"globalSettings": false,
|
||||
"device": "desktop",
|
||||
"tabBar": false,
|
||||
"menuFromServer": false,
|
||||
"serverMenu": []
|
||||
}
|
||||
0
src/core/dayjs.ts
Normal file
1
src/core/index.ts
Normal file
@ -0,0 +1 @@
|
||||
import './dayjs';
|
||||
0
src/directives/index.ts
Normal file
2
src/hooks/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './responsive';
|
||||
export * from './modal';
|
||||
55
src/hooks/modal.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-21 15:11:01
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-21 15:11:02
|
||||
* @Description:
|
||||
*/
|
||||
import type { AppContext, Component, DefineComponent } from 'vue';
|
||||
import type { ModalConfig } from '@arco-design/web-vue';
|
||||
|
||||
import { ModalSimple } from '@/components/_base';
|
||||
|
||||
type CompType = DefineComponent | Component;
|
||||
interface SlotsType {
|
||||
default?: CompType;
|
||||
header?: CompType;
|
||||
close?: CompType;
|
||||
}
|
||||
|
||||
export const useModal = () => {
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const Modal = AModal;
|
||||
|
||||
Modal._context = instance?.appContext as AppContext;
|
||||
|
||||
Modal.simple = (config: ModalConfig, slots: SlotsType) => {
|
||||
const { title, content, ..._config } = config || {};
|
||||
|
||||
const modal = Modal.open({
|
||||
..._config,
|
||||
simple: false,
|
||||
footer: false,
|
||||
closable: false,
|
||||
content: () =>
|
||||
h(
|
||||
ModalSimple,
|
||||
{
|
||||
title,
|
||||
content,
|
||||
onClose: modal.close,
|
||||
},
|
||||
{
|
||||
default: slots?.default,
|
||||
header: slots?.header,
|
||||
close: slots?.close,
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
return modal;
|
||||
};
|
||||
|
||||
return { Modal };
|
||||
};
|
||||
30
src/hooks/responsive.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { useAppStore } from '@/stores';
|
||||
import { addEventListen, removeEventListen } from '@/utils/event';
|
||||
|
||||
const WIDTH = 992;
|
||||
|
||||
function queryDevice() {
|
||||
const rect = document.body.getBoundingClientRect();
|
||||
return rect.width - 1 < WIDTH;
|
||||
}
|
||||
|
||||
export function useResponsive(immediate?: boolean) {
|
||||
const appStore = useAppStore();
|
||||
function resizeHandler() {
|
||||
if (!document.hidden) {
|
||||
const isMobile = queryDevice();
|
||||
appStore.toggleDevice(isMobile ? 'mobile' : 'desktop');
|
||||
appStore.toggleMenu(isMobile);
|
||||
}
|
||||
}
|
||||
const debounceFn = useDebounceFn(resizeHandler, 100);
|
||||
onMounted(() => {
|
||||
if (immediate) debounceFn();
|
||||
});
|
||||
onBeforeMount(() => {
|
||||
addEventListen(window, 'resize', debounceFn);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
removeEventListen(window, 'resize', debounceFn);
|
||||
});
|
||||
}
|
||||
172
src/hooks/table-hooks.ts
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-16 15:02:51
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-09 11:20:59
|
||||
* @Description: table-hooks
|
||||
*/
|
||||
import type { PaginationProps, TableBorder, TableColumnData, TableData, TableRowSelection } from '@arco-design/web-vue';
|
||||
type Size = 'mini' | 'small' | 'medium' | 'large';
|
||||
interface IDefaultProps {
|
||||
/** 是否显示边框 */
|
||||
bordered?: TableBorder;
|
||||
/** 是否显示选中效果 */
|
||||
hoverable?: boolean;
|
||||
/** 表格的大小 */
|
||||
size?: Size;
|
||||
/** 是否允许调整列宽 */
|
||||
'column-resizable'?: boolean;
|
||||
/** 是否为加载中状态 */
|
||||
loading?: boolean;
|
||||
/** 分页参数 */
|
||||
pagination?: PaginationProps;
|
||||
/** table数据类型 */
|
||||
data?: any[];
|
||||
/** 表头参数 */
|
||||
columns?: TableColumnData[];
|
||||
/** 表格行 key 的取值字段 */
|
||||
'row-key'?: string;
|
||||
/** 表格的行选择器配置 */
|
||||
'row-selection'?: TableRowSelection;
|
||||
'selected-keys'?: (string | number)[];
|
||||
[x: string]: any;
|
||||
}
|
||||
interface IPagination {
|
||||
/** 当前页数 */
|
||||
current?: number;
|
||||
/** 总页数默认是0条 */
|
||||
total?: number;
|
||||
}
|
||||
interface ITableResponse<T> {
|
||||
current?: number;
|
||||
records?: T[];
|
||||
size?: number;
|
||||
total?: number;
|
||||
[x: string]: any;
|
||||
}
|
||||
type GetListFunc<T> = (v: object) => Promise<ITableResponse<T>>;
|
||||
export default function useTableProps<T>(loadListFunc: GetListFunc<T>) {
|
||||
const defaultProps: IDefaultProps = {
|
||||
bordered: { cell: true },
|
||||
size: 'large',
|
||||
'column-resizable': true,
|
||||
loading: true,
|
||||
data: [] as any[],
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
showPageSize: true,
|
||||
showTotal: true,
|
||||
},
|
||||
hoverable: false,
|
||||
columns: [],
|
||||
};
|
||||
//* 属性组
|
||||
const propsRes = reactive<IDefaultProps>(defaultProps);
|
||||
//* 设置请求参数,如果出了分页参数还有搜索参数,在模板页面调用此方法,可以加入参数
|
||||
const loadListParams = reactive<object>({
|
||||
page: 1,
|
||||
size: 20,
|
||||
});
|
||||
/**
|
||||
* 单独设置默认属性
|
||||
* @param params
|
||||
*/
|
||||
const setProps = (params: IDefaultProps) => {
|
||||
if (Object.keys(params).length > 0) {
|
||||
Object.assign(defaultProps, params);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 设置表头数据
|
||||
* @param columns
|
||||
*/
|
||||
const setColumns = (columns: TableColumnData[]) => {
|
||||
propsRes.columns = columns;
|
||||
};
|
||||
/**
|
||||
* 设置loading
|
||||
* @param status
|
||||
*/
|
||||
const setLoading = (status: boolean) => {
|
||||
propsRes.loading = status;
|
||||
};
|
||||
/**
|
||||
* 设置分页
|
||||
* @param param0
|
||||
*/
|
||||
const setPagination = ({ current, total }: IPagination) => {
|
||||
propsRes.pagination!.current = current;
|
||||
total && (propsRes.pagination!.total = total);
|
||||
Object.assign(loadListParams, { page: current });
|
||||
};
|
||||
/**
|
||||
* 设置列表请求参数
|
||||
* @param params
|
||||
*/
|
||||
const setLoadListParams = <R>(params?: R) => {
|
||||
Object.assign(loadListParams, params);
|
||||
};
|
||||
/**
|
||||
* 加载列表
|
||||
* @returns
|
||||
*/
|
||||
const loadTableData = async (resetPageIndex = false) => {
|
||||
if (resetPageIndex) {
|
||||
setPagination({ current: 1 });
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
const resData = await loadListFunc({
|
||||
...loadListParams,
|
||||
});
|
||||
console.log(resData);
|
||||
const response = resData as ITableResponse<T>;
|
||||
propsRes.data = response.records;
|
||||
setPagination({
|
||||
current: response.current,
|
||||
total: response.total,
|
||||
});
|
||||
setLoading(false);
|
||||
return resData;
|
||||
} catch (error) {
|
||||
setLoading(false);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// 事件触发组
|
||||
const propsEvent = reactive({
|
||||
// 排序触发
|
||||
sorterChange: (dataIndex: string, direction: string) => {
|
||||
console.log(dataIndex, direction);
|
||||
},
|
||||
// 分页触发
|
||||
pageChange: (current: number) => {
|
||||
setPagination({ current });
|
||||
loadTableData();
|
||||
},
|
||||
// 修改每页显示条数
|
||||
pageSizeChange: (size: number) => {
|
||||
propsRes.pagination!.pageSize = size;
|
||||
Object.assign(loadListParams, { size });
|
||||
loadTableData();
|
||||
},
|
||||
selectionChange: (rowKeys: (string | number)[]) => {
|
||||
propsRes['selected-keys'] = rowKeys;
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
propsRes,
|
||||
propsEvent,
|
||||
loadListParams,
|
||||
setProps,
|
||||
setColumns,
|
||||
setLoading,
|
||||
setPagination,
|
||||
loadTableData,
|
||||
setLoadListParams,
|
||||
};
|
||||
}
|
||||
52
src/hooks/useEffect.ts
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2024-06-11 14:55:40
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2024-06-11 14:55:41
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @description 模拟的react的useEffect
|
||||
* @param fn
|
||||
* @param deps
|
||||
*/
|
||||
export function useEffect(fn: () => void | (() => any), deps: any[] = []) {
|
||||
const tract = new Error();
|
||||
const resFn = ref(() => { });
|
||||
if (deps.length === 0) {
|
||||
onMounted(() => {
|
||||
const res = fn();
|
||||
if (typeof res === 'function') {
|
||||
resFn.value = res;
|
||||
} else {
|
||||
resFn.value = () => { };
|
||||
}
|
||||
});
|
||||
} else {
|
||||
watch(
|
||||
() => deps,
|
||||
() => {
|
||||
resFn.value();
|
||||
const res = (() => {
|
||||
try {
|
||||
return fn();
|
||||
} catch (error) {
|
||||
console.error(tract);
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
if (typeof res === 'function') {
|
||||
resFn.value = res;
|
||||
} else {
|
||||
resFn.value = () => { };
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
}
|
||||
onUnmounted(() => {
|
||||
resFn.value();
|
||||
});
|
||||
}
|
||||
150
src/layouts/Basic.vue
Normal file
@ -0,0 +1,150 @@
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/stores';
|
||||
import { useResponsive } from '@/hooks';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
|
||||
useResponsive(true);
|
||||
const navbarHeight = `60px`;
|
||||
const navbar = computed(() => appStore.navbar);
|
||||
const renderMenu = computed(() => appStore.menu && !appStore.topMenu);
|
||||
const hideMenu = computed(() => appStore.hideMenu);
|
||||
|
||||
const menuWidth = computed(() => {
|
||||
return appStore.menuCollapse ? 48 : appStore.menuWidth;
|
||||
});
|
||||
const collapsed = computed(() => {
|
||||
return appStore.menuCollapse;
|
||||
});
|
||||
const paddingStyle = computed(() => {
|
||||
const paddingLeft = renderMenu.value && !hideMenu.value ? { paddingLeft: `${menuWidth.value}px` } : {};
|
||||
const paddingTop = navbar.value ? { paddingTop: navbarHeight } : {};
|
||||
return { ...paddingLeft, ...paddingTop };
|
||||
});
|
||||
const setCollapsed = (val: boolean) => {
|
||||
appStore.updateSettings({ menuCollapse: val });
|
||||
};
|
||||
|
||||
const drawerVisible = ref(false);
|
||||
const drawerCancel = () => {
|
||||
drawerVisible.value = false;
|
||||
};
|
||||
provide('toggleDrawerMenu', () => {
|
||||
drawerVisible.value = !drawerVisible.value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-layout :class="['layout', { mobile: appStore.hideMenu }]">
|
||||
<div v-if="navbar" class="layout-navbar">
|
||||
<base-navbar />
|
||||
</div>
|
||||
<a-layout>
|
||||
<a-layout>
|
||||
<a-layout-sider
|
||||
v-if="renderMenu"
|
||||
v-show="!hideMenu"
|
||||
class="layout-sider"
|
||||
breakpoint="xl"
|
||||
:collapsed="collapsed"
|
||||
:width="menuWidth"
|
||||
:style="{ paddingTop: navbar ? '60px' : '' }"
|
||||
collapsible
|
||||
hide-trigger
|
||||
@collapse="setCollapsed"
|
||||
>
|
||||
<div class="menu-wrapper">
|
||||
<base-menu />
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<a-drawer
|
||||
v-if="hideMenu"
|
||||
:visible="drawerVisible"
|
||||
placement="left"
|
||||
:footer="false"
|
||||
mask-closable
|
||||
:closable="false"
|
||||
@cancel="drawerCancel"
|
||||
>
|
||||
<base-menu />
|
||||
</a-drawer>
|
||||
<a-layout class="layout-content" :style="paddingStyle">
|
||||
<base-tab-bar v-if="appStore.tabBar" />
|
||||
<a-layout-content class="px-5">
|
||||
<base-breadcrumb />
|
||||
<layout-page />
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
@nav-size-height: 60px;
|
||||
@layout-max-width: 1100px;
|
||||
|
||||
.layout {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.layout-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
width: 100%;
|
||||
height: @nav-size-height;
|
||||
}
|
||||
.layout-sider {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
height: 100%;
|
||||
transition: all 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -1px;
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background-color: var(--color-border);
|
||||
content: '';
|
||||
}
|
||||
> :deep(.arco-layout-sider-children) {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
.menu-wrapper {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
:deep(.arco-menu) {
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
height: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border: 4px solid transparent;
|
||||
background-clip: padding-box;
|
||||
border-radius: 7px;
|
||||
background-color: var(--color-text-4);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--color-text-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
.layout-content {
|
||||
min-width: 1366px;
|
||||
min-height: 100vh;
|
||||
overflow-y: hidden;
|
||||
background-color: var(--color-fill-2);
|
||||
transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
|
||||
}
|
||||
</style>
|
||||
26
src/layouts/NotFound.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
const router = useRouter();
|
||||
const back = () => {
|
||||
router.replace('/');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content">
|
||||
<a-result class="result" status="404" subtitle="页面跑路了" />
|
||||
<div class="operation-row">
|
||||
<a-button key="back" type="primary" @click="back">返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -95px;
|
||||
margin-top: -121px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
40
src/layouts/Page.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { useTabBarStore } from '@/stores';
|
||||
import { useRoute } from 'vue-router';
|
||||
const tabBarStore = useTabBarStore();
|
||||
const cacheList = computed(() => tabBarStore.getCacheList);
|
||||
/** - <router-view> 上需要设置一个key,避免组件复用 */
|
||||
const route = useRoute();
|
||||
const routerKey = computed(() => {
|
||||
return route.path + Math.random();
|
||||
});
|
||||
/*** - end */
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-view v-slot="{ Component, route }" :key="routerKey">
|
||||
<transition name="fade" mode="out-in" appear>
|
||||
<component :is="Component" v-if="route.meta.ignoreCache" :key="route.fullPath" />
|
||||
<keep-alive v-else :include="cacheList">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
<view class="footer">
|
||||
<view>闽公网安备 352018502850842号 闽ICP备20250520582号 © 2025小题科技,All Rights Reserved.</view>
|
||||
<view>* 数据通过公开渠道获取,灵机进行统计分析</view>
|
||||
</view>
|
||||
</router-view>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.footer {
|
||||
margin: 20px;
|
||||
width: 98%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
color: rgb(var(--color-text-6));
|
||||
}
|
||||
</style>
|
||||
16
src/main.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './stores';
|
||||
import '@/api/index';
|
||||
|
||||
import './styles';
|
||||
import './core';
|
||||
import 'uno.css';
|
||||
import './mock';
|
||||
import '@/styles/vars.css'; // 优先加载
|
||||
import '@arco-design/web-vue/dist/arco.css'; // Arco 默认样式
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(store);
|
||||
app.use(router);
|
||||
app.mount('#app');
|
||||
15
src/mock/index.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:49:06
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 18:49:20
|
||||
* @Description: Mock数据
|
||||
*/
|
||||
|
||||
import Mock from 'mockjs';
|
||||
import './table';
|
||||
|
||||
|
||||
Mock.setup({
|
||||
timeout: '600-1000',
|
||||
});
|
||||
31
src/mock/setup-mock.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:59:18
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:02:04
|
||||
* @Description: mock设置
|
||||
*/
|
||||
|
||||
export default ({ mock, setup }: { mock?: boolean; setup: () => void }) => {
|
||||
if (mock !== false) setup();
|
||||
};
|
||||
|
||||
export const successResponseWrap = (data: unknown) => {
|
||||
return {
|
||||
success: true,
|
||||
msg: '请求成功',
|
||||
code: 200,
|
||||
data,
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
};
|
||||
|
||||
export const failResponseWrap = (data: unknown, msg: string, code = 50000) => {
|
||||
return {
|
||||
data,
|
||||
success: false,
|
||||
msg,
|
||||
code,
|
||||
timestamp: new Date().getTime(),
|
||||
};
|
||||
};
|
||||
28
src/mock/table.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import type { IExample } from '@/api/example';
|
||||
import Mock from 'mockjs';
|
||||
import setupMock, { successResponseWrap } from './setup-mock';
|
||||
|
||||
setupMock({
|
||||
setup() {
|
||||
Mock.mock(new RegExp('/api/example-table'), () => {
|
||||
let tableData: IExample.ITableResponse[] = [];
|
||||
|
||||
let count = 20;
|
||||
|
||||
tableData = new Array(count).fill('').map((item, index) => ({
|
||||
id: `${item + 1}`,
|
||||
column1: `第${item + 1}列的第${index + 1}条数据`,
|
||||
column2: `第${item + 2}列的第${index + 1}条数据`,
|
||||
column3: `第${item + 3}列的第${index + 1}条数据`,
|
||||
column4: `第${item + 4}列的第${index + 1}条数据`,
|
||||
column5: `第${item + 5}列的第${index + 1}条数据`,
|
||||
}));
|
||||
return successResponseWrap({
|
||||
records: tableData,
|
||||
total: tableData.length,
|
||||
current: 1,
|
||||
size: 20,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
16
src/router/app-menus/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { appRoutes, appExternalRoutes } from '../routes';
|
||||
|
||||
const mixinRoutes = [...appRoutes, ...appExternalRoutes];
|
||||
|
||||
const appClientMenus = mixinRoutes.map((el) => {
|
||||
const { name, path, meta, redirect, children } = el;
|
||||
return {
|
||||
name,
|
||||
path,
|
||||
meta,
|
||||
redirect,
|
||||
children,
|
||||
};
|
||||
});
|
||||
|
||||
export default mixinRoutes;
|
||||
25
src/router/constants.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:14:17
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 18:24:40
|
||||
* @Description:
|
||||
*/
|
||||
export const WHITE_LIST = [
|
||||
{ name: 'notFound', children: [] },
|
||||
{ name: 'login', children: [] },
|
||||
];
|
||||
|
||||
export const NOT_FOUND = {
|
||||
name: 'notFound',
|
||||
};
|
||||
|
||||
export const REDIRECT_ROUTE_NAME = 'Redirect';
|
||||
|
||||
export const DEFAULT_ROUTE_NAME = 'main';
|
||||
|
||||
export const DEFAULT_ROUTE = {
|
||||
title: '首页',
|
||||
name: DEFAULT_ROUTE_NAME,
|
||||
fullPath: '/',
|
||||
};
|
||||
24
src/router/guard/index.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:14:17
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:21:15
|
||||
* @Description:
|
||||
*/
|
||||
import type { Router } from 'vue-router';
|
||||
import { setRouteEmitter } from '@/utils/route-listener';
|
||||
import setupUserLoginInfoGuard from './userLoginInfo';
|
||||
import setupPermissionGuard from './permission';
|
||||
|
||||
function setupPageGuard(router: Router) {
|
||||
router.beforeEach(async (to) => {
|
||||
// emit route change
|
||||
setRouteEmitter(to);
|
||||
});
|
||||
}
|
||||
|
||||
export default function createRouteGuard(router: Router) {
|
||||
setupPageGuard(router);
|
||||
setupUserLoginInfoGuard(router);
|
||||
setupPermissionGuard(router);
|
||||
}
|
||||
29
src/router/guard/permission.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 14:46:43
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 15:55:36
|
||||
* @Description: 路由权限守卫
|
||||
*/
|
||||
import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
import { useAppStore } from '@/stores';
|
||||
|
||||
export default function setupPermissionGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
console.log('access permission router guard');
|
||||
const appStore = useAppStore();
|
||||
//* 菜单是否为服务端渲染
|
||||
if (appStore.menuFromServer) {
|
||||
//* 没有服务端渲染的菜单
|
||||
if(!appStore.appAsyncMenus) {
|
||||
// todo 请求服务端渲染菜单的接口,当前为mock数据
|
||||
await appStore.fetchServerMenuConfig();
|
||||
}
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
43
src/router/guard/userLoginInfo.ts
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 14:46:43
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 15:59:25
|
||||
* @Description: 路由登录状态守卫
|
||||
*/
|
||||
import type { Router, LocationQueryRaw } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
|
||||
import { isLogin, clearAllLocalStorage } from '@/utils/auth';
|
||||
import { useUserStore } from '@/stores/modules/user';
|
||||
|
||||
export default function setupUserLoginInfoGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
console.log('access login info router guard');
|
||||
NProgress.start();
|
||||
if (to.name === 'auth') {
|
||||
next();
|
||||
}
|
||||
const userStore = useUserStore();
|
||||
//* 判断用户是否登录,若登录则放过,进入下一步
|
||||
//* 若无,则清空所有缓存并弹回登录鉴权页
|
||||
if (isLogin()) {
|
||||
if (userStore.role) {
|
||||
next();
|
||||
} else {
|
||||
userStore.getUserInfo();
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
clearAllLocalStorage();
|
||||
// todo 跳转回登录鉴权页,当前为mock路由地址
|
||||
next({
|
||||
name: 'auth',
|
||||
query: {
|
||||
redirect: to.name,
|
||||
...to.query,
|
||||
} as LocationQueryRaw,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
50
src/router/index.ts
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-03-05 18:14:17
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-03-05 19:20:40
|
||||
* @Description:
|
||||
*/
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import { appRoutes } from './routes';
|
||||
import { REDIRECT_MAIN, NOT_FOUND_ROUTE } from './routes/base';
|
||||
import NProgress from 'nprogress';
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
import createRouteGuard from './guard';
|
||||
|
||||
NProgress.configure({ showSpinner: false }); // NProgress Configuration
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'workplace',
|
||||
component: () => import('@/views/components/workplace'),
|
||||
},
|
||||
{
|
||||
path: '/dataEngine',
|
||||
name: 'dataEngine',
|
||||
redirect: '@/views/components/dataEngine',
|
||||
children: [...appRoutes, REDIRECT_MAIN, NOT_FOUND_ROUTE],
|
||||
},
|
||||
{
|
||||
path: '/permission',
|
||||
name: 'permission',
|
||||
component: () => import('@/views/components/permission/choose-enterprise.vue'),
|
||||
},
|
||||
{
|
||||
path: '/auth',
|
||||
name: 'auth',
|
||||
component: () => import('@/views/components/permission/auth.vue'),
|
||||
},
|
||||
],
|
||||
scrollBehavior() {
|
||||
return { top: 0 };
|
||||
},
|
||||
});
|
||||
|
||||
createRouteGuard(router);
|
||||
|
||||
export default router;
|
||||
28
src/router/routes/base.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { REDIRECT_ROUTE_NAME } from '@/router/constants';
|
||||
|
||||
export const REDIRECT_MAIN: RouteRecordRaw = {
|
||||
path: '/redirect',
|
||||
name: 'redirect',
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hideInMenu: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path',
|
||||
name: REDIRECT_ROUTE_NAME,
|
||||
component: () => import('@/layouts/Basic.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
hideInMenu: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const NOT_FOUND_ROUTE: RouteRecordRaw = {
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'notFound',
|
||||
component: () => import('@/layouts/NotFound.vue'),
|
||||
};
|
||||
20
src/router/routes/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import type { RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
const modules = import.meta.glob('./modules/*.ts', { eager: true });
|
||||
const externalModules = import.meta.glob('./externalModules/*.ts', {
|
||||
eager: true,
|
||||
});
|
||||
|
||||
function formatModules(_modules: any, result: RouteRecordNormalized[]) {
|
||||
Object.keys(_modules).forEach((key) => {
|
||||
const defaultModule = _modules[key].default;
|
||||
if (!defaultModule) return;
|
||||
const moduleList = Array.isArray(defaultModule) ? [...defaultModule] : [defaultModule];
|
||||
result.push(...moduleList);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export const appRoutes: RouteRecordNormalized[] = formatModules(modules, []);
|
||||
|
||||
export const appExternalRoutes: RouteRecordNormalized[] = formatModules(externalModules, []);
|
||||