commit
8cd7118457
837 changed files with 72885 additions and 0 deletions
@ -0,0 +1,19 @@ |
|||||||
|
root = true |
||||||
|
|
||||||
|
[*] |
||||||
|
charset=utf-8 |
||||||
|
end_of_line=lf |
||||||
|
insert_final_newline=true |
||||||
|
indent_style=space |
||||||
|
indent_size=2 |
||||||
|
max_line_length = 100 |
||||||
|
|
||||||
|
[*.{yml,yaml,json}] |
||||||
|
indent_style = space |
||||||
|
indent_size = 2 |
||||||
|
|
||||||
|
[*.md] |
||||||
|
trim_trailing_whitespace = false |
||||||
|
|
||||||
|
[Makefile] |
||||||
|
indent_style = tab |
@ -0,0 +1,8 @@ |
|||||||
|
# 端口号 |
||||||
|
VITE_PORT = 3100 |
||||||
|
|
||||||
|
# 网站标题 |
||||||
|
VITE_GLOB_APP_TITLE = Vben Admin |
||||||
|
|
||||||
|
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符 |
||||||
|
VITE_GLOB_APP_SHORT_NAME = vue_vben_admin |
@ -0,0 +1,24 @@ |
|||||||
|
# 是否开启mock数据,关闭时需要自行对接后台接口 |
||||||
|
VITE_USE_MOCK = true |
||||||
|
|
||||||
|
# 资源公共路径,需要以 /开头和结尾 |
||||||
|
VITE_PUBLIC_PATH = / |
||||||
|
|
||||||
|
# 本地开发代理,可以解决跨域及多地址代理 |
||||||
|
# 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题 |
||||||
|
# 可以有多个,注意多个不能换行,否则代理将会失效 |
||||||
|
VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]] |
||||||
|
# VITE_PROXY=[["/api","https://vvbin.cn/test"]] |
||||||
|
|
||||||
|
# 是否删除Console.log |
||||||
|
VITE_DROP_CONSOLE = false |
||||||
|
|
||||||
|
# 接口地址 |
||||||
|
# 如果没有跨域问题,直接在这里配置即可 |
||||||
|
VITE_GLOB_API_URL = /basic-api |
||||||
|
|
||||||
|
# 文件上传接口 可选 |
||||||
|
VITE_GLOB_UPLOAD_URL = /upload |
||||||
|
|
||||||
|
# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换 |
||||||
|
VITE_GLOB_API_URL_PREFIX = |
@ -0,0 +1,31 @@ |
|||||||
|
# 是否开启mock |
||||||
|
VITE_USE_MOCK = true |
||||||
|
|
||||||
|
# 资源公共路径,需要以 / 开头和结尾 |
||||||
|
VITE_PUBLIC_PATH = / |
||||||
|
|
||||||
|
# 是否删除Console.log |
||||||
|
VITE_DROP_CONSOLE = true |
||||||
|
|
||||||
|
# 打包是否输出gz|br文件 |
||||||
|
# 可选: gzip | brotli | none |
||||||
|
# 也可以有多个, 例如 ‘gzip’|'brotli',这样会同时生成 .gz和.br文件 |
||||||
|
VITE_BUILD_COMPRESS = 'gzip' |
||||||
|
|
||||||
|
# 使用compress时是否删除源文件,默认false |
||||||
|
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false |
||||||
|
|
||||||
|
# 接口地址 可以由nginx做转发或者直接写实际地址 |
||||||
|
VITE_GLOB_API_URL = /basic-api |
||||||
|
|
||||||
|
# 文件上传地址 可以由nginx做转发或者直接写实际地址 |
||||||
|
VITE_GLOB_UPLOAD_URL = /upload |
||||||
|
|
||||||
|
# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换 |
||||||
|
VITE_GLOB_API_URL_PREFIX = |
||||||
|
|
||||||
|
# 打包是否开启pwa功能 |
||||||
|
VITE_USE_PWA = false |
||||||
|
|
||||||
|
# 是否兼容旧版浏览器。开启后打包时间会慢一倍左右。会多打出旧浏览器兼容包,且会根据浏览器兼容性自动使用相应的版本 |
||||||
|
VITE_LEGACY = false |
@ -0,0 +1,32 @@ |
|||||||
|
NODE_ENV=production |
||||||
|
# 是否开启mock |
||||||
|
VITE_USE_MOCK = true |
||||||
|
|
||||||
|
# 资源公共路径,需要以 / 开头和结尾 |
||||||
|
VITE_PUBLIC_PATH = / |
||||||
|
|
||||||
|
# 是否删除Console.log |
||||||
|
VITE_DROP_CONSOLE = true |
||||||
|
|
||||||
|
# 打包是否输出gz|br文件 |
||||||
|
# 可选: gzip | brotli | none |
||||||
|
# 也可以有多个, 例如 ‘gzip’|'brotli',这样会同时生成 .gz和.br文件 |
||||||
|
VITE_BUILD_COMPRESS = 'none' |
||||||
|
|
||||||
|
# 使用compress时是否删除源文件,默认false |
||||||
|
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false |
||||||
|
|
||||||
|
# 接口地址 可以由nginx做转发或者直接写实际地址 |
||||||
|
VITE_GLOB_API_URL = /basic-api |
||||||
|
|
||||||
|
# 文件上传地址 可以由nginx做转发或者直接写实际地址 |
||||||
|
VITE_GLOB_UPLOAD_URL = /upload |
||||||
|
|
||||||
|
# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换 |
||||||
|
VITE_GLOB_API_URL_PREFIX = |
||||||
|
|
||||||
|
# 打包是否开启pwa功能 |
||||||
|
VITE_USE_PWA = false |
||||||
|
|
||||||
|
# 是否兼容旧版浏览器。开启后打包时间会慢一倍左右。会多打出旧浏览器兼容包,且会根据浏览器兼容性自动使用相应的版本 |
||||||
|
VITE_LEGACY = false |
@ -0,0 +1,14 @@ |
|||||||
|
|
||||||
|
*.sh |
||||||
|
node_modules |
||||||
|
*.md |
||||||
|
*.woff |
||||||
|
*.ttf |
||||||
|
.vscode |
||||||
|
.idea |
||||||
|
dist |
||||||
|
/public |
||||||
|
/docs |
||||||
|
.local |
||||||
|
/bin |
||||||
|
Dockerfile |
@ -0,0 +1,74 @@ |
|||||||
|
module.exports = { |
||||||
|
root: true, |
||||||
|
env: { |
||||||
|
browser: true, |
||||||
|
node: true, |
||||||
|
es6: true |
||||||
|
}, |
||||||
|
parser: 'vue-eslint-parser', |
||||||
|
plugins: ['vue'], |
||||||
|
parserOptions: { |
||||||
|
parser: '@typescript-eslint/parser', |
||||||
|
ecmaVersion: 2020, |
||||||
|
sourceType: 'module', |
||||||
|
jsxPragma: 'React', |
||||||
|
ecmaFeatures: { |
||||||
|
jsx: true |
||||||
|
} |
||||||
|
}, |
||||||
|
extends: ['plugin:vue/vue3-recommended', 'prettier', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], |
||||||
|
rules: { |
||||||
|
'max-len': ['error', { code: 140, tabWidth: 2, ignoreComments: true }], |
||||||
|
'vue/script-setup-uses-vars': 'error', |
||||||
|
'@typescript-eslint/ban-ts-ignore': 'off', |
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off', |
||||||
|
'@typescript-eslint/no-explicit-any': 'off', |
||||||
|
'@typescript-eslint/no-var-requires': 'off', |
||||||
|
'@typescript-eslint/no-empty-function': 'off', |
||||||
|
'vue/custom-event-name-casing': 'off', |
||||||
|
'no-use-before-define': 'off', |
||||||
|
'@typescript-eslint/no-use-before-define': 'off', |
||||||
|
'@typescript-eslint/ban-ts-comment': 'off', |
||||||
|
'@typescript-eslint/ban-types': 'off', |
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off', |
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off', |
||||||
|
'@typescript-eslint/no-unused-vars': [ |
||||||
|
'error', |
||||||
|
{ |
||||||
|
argsIgnorePattern: '^_', |
||||||
|
varsIgnorePattern: '^_' |
||||||
|
} |
||||||
|
], |
||||||
|
'no-unused-vars': [ |
||||||
|
'error', |
||||||
|
{ |
||||||
|
argsIgnorePattern: '^_', |
||||||
|
varsIgnorePattern: '^_' |
||||||
|
} |
||||||
|
], |
||||||
|
'space-before-function-paren': 'off', |
||||||
|
|
||||||
|
'vue/attributes-order': 'off', |
||||||
|
'vue/one-component-per-file': 'off', |
||||||
|
'vue/html-closing-bracket-newline': 'off', |
||||||
|
'vue/max-attributes-per-line': 'off', |
||||||
|
'vue/multiline-html-element-content-newline': 'off', |
||||||
|
'vue/singleline-html-element-content-newline': 'off', |
||||||
|
'vue/attribute-hyphenation': 'off', |
||||||
|
'vue/require-default-prop': 'off', |
||||||
|
'vue/require-explicit-emits': 'off', |
||||||
|
'vue/html-self-closing': [ |
||||||
|
'error', |
||||||
|
{ |
||||||
|
html: { |
||||||
|
void: 'always', |
||||||
|
normal: 'never', |
||||||
|
component: 'always' |
||||||
|
}, |
||||||
|
svg: 'always', |
||||||
|
math: 'always' |
||||||
|
} |
||||||
|
], |
||||||
|
'vue/multi-word-component-names': 'off' |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings |
||||||
|
|
||||||
|
# Automatically normalize line endings (to LF) for all text-based files. |
||||||
|
* text=auto eol=lf |
||||||
|
|
||||||
|
# Declare files that will always have CRLF line endings on checkout. |
||||||
|
*.{cmd,[cC][mM][dD]} text eol=crlf |
||||||
|
*.{bat,[bB][aA][tT]} text eol=crlf |
||||||
|
|
||||||
|
# Denote all files that are truly binary and should not be modified. |
||||||
|
*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary |
@ -0,0 +1,33 @@ |
|||||||
|
node_modules |
||||||
|
.DS_Store |
||||||
|
dist |
||||||
|
.npmrc |
||||||
|
.cache |
||||||
|
|
||||||
|
tests/server/static |
||||||
|
tests/server/static/upload |
||||||
|
|
||||||
|
*.local |
||||||
|
# local env files |
||||||
|
.env.local |
||||||
|
.env.*.local |
||||||
|
.eslintcache |
||||||
|
|
||||||
|
# Log files |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
pnpm-debug.log* |
||||||
|
|
||||||
|
# Editor directories and files |
||||||
|
.idea |
||||||
|
# .vscode |
||||||
|
*.suo |
||||||
|
*.ntvs* |
||||||
|
*.njsproj |
||||||
|
*.sln |
||||||
|
*.sw? |
||||||
|
|
||||||
|
package-lock.json |
||||||
|
|
||||||
|
.history |
@ -0,0 +1,6 @@ |
|||||||
|
ports: |
||||||
|
- port: 3344 |
||||||
|
onOpen: open-preview |
||||||
|
tasks: |
||||||
|
- init: pnpm install |
||||||
|
command: pnpm run dev |
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"extends": [ |
||||||
|
"development" |
||||||
|
], |
||||||
|
"hints": { |
||||||
|
"compat-api/css": [ |
||||||
|
"default", |
||||||
|
{ |
||||||
|
"ignore": [ |
||||||
|
"-webkit-tap-highlight-color", |
||||||
|
"text-size-adjust" |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
# shellcheck source=./_/husky.sh |
||||||
|
. "$(dirname "$0")/_/husky.sh" |
||||||
|
|
||||||
|
PATH="/usr/local/bin:$PATH" |
||||||
|
|
||||||
|
npx --no-install commitlint --edit "$1" |
@ -0,0 +1,9 @@ |
|||||||
|
#!/bin/sh |
||||||
|
command_exists () { |
||||||
|
command -v "$1" >/dev/null 2>&1 |
||||||
|
} |
||||||
|
|
||||||
|
# Workaround for Windows 10, Git Bash and Yarn |
||||||
|
if command_exists winpty && test -t 1; then |
||||||
|
exec < /dev/tty |
||||||
|
fi |
@ -0,0 +1,10 @@ |
|||||||
|
#!/bin/sh |
||||||
|
. "$(dirname "$0")/_/husky.sh" |
||||||
|
. "$(dirname "$0")/common.sh" |
||||||
|
|
||||||
|
[ -n "$CI" ] && exit 0 |
||||||
|
|
||||||
|
PATH="/usr/local/bin:$PATH" |
||||||
|
|
||||||
|
# Format and submit code according to lintstagedrc.js configuration |
||||||
|
npm run lint:lint-staged |
@ -0,0 +1,8 @@ |
|||||||
|
// .lintstagedrc.js
|
||||||
|
module.exports = { |
||||||
|
'*.js': ['prettier --config prettier.config.js --write', 'eslint --fix --ext .js'], |
||||||
|
'*.ts': ['prettier --config prettier.config.js --write', 'eslint --fix --ext .ts'], |
||||||
|
'*.vue': ['prettier --config prettier.config.js --write', 'eslint --fix --ext .vue'], |
||||||
|
'*.tsx': ['prettier --config prettier.config.js --write', 'eslint --fix --ext .tsx'], |
||||||
|
'*.json': 'prettier --config prettier.config.js --write' |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
/dist/* |
||||||
|
.local |
||||||
|
.output.js |
||||||
|
/node_modules/** |
||||||
|
|
||||||
|
**/*.svg |
||||||
|
**/*.sh |
||||||
|
|
||||||
|
/public/* |
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"recommendations": [ |
||||||
|
"vue.volar", |
||||||
|
"dbaeumer.vscode-eslint", |
||||||
|
"stylelint.vscode-stylelint", |
||||||
|
"esbenp.prettier-vscode", |
||||||
|
"mrmlnc.vscode-less", |
||||||
|
"lokalise.i18n-ally", |
||||||
|
"antfu.iconify", |
||||||
|
"mikestead.dotenv", |
||||||
|
"heybourn.headwind" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
{ |
||||||
|
"version": "0.2.0", |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"type": "chrome", |
||||||
|
"request": "launch", |
||||||
|
"name": "Launch Chrome", |
||||||
|
"url": "http://localhost:3100", |
||||||
|
"webRoot": "${workspaceFolder}/src", |
||||||
|
"sourceMaps": true |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,167 @@ |
|||||||
|
{ |
||||||
|
"typescript.tsdk": "./node_modules/typescript/lib", |
||||||
|
"volar.tsPlugin": true, |
||||||
|
"volar.tsPluginStatus": false, |
||||||
|
"npm.packageManager": "pnpm", |
||||||
|
"editor.tabSize": 2, |
||||||
|
"prettier.printWidth": 140, // 超过最大值换行 |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode", |
||||||
|
"files.eol": "\n", |
||||||
|
"search.exclude": { |
||||||
|
"**/node_modules": true, |
||||||
|
"**/*.log": true, |
||||||
|
"**/*.log*": true, |
||||||
|
"**/bower_components": true, |
||||||
|
"**/dist": true, |
||||||
|
"**/elehukouben": true, |
||||||
|
"**/.git": true, |
||||||
|
"**/.gitignore": true, |
||||||
|
"**/.svn": true, |
||||||
|
"**/.DS_Store": true, |
||||||
|
"**/.idea": true, |
||||||
|
"**/.vscode": false, |
||||||
|
"**/yarn.lock": true, |
||||||
|
"**/tmp": true, |
||||||
|
"out": true, |
||||||
|
"dist": true, |
||||||
|
"node_modules": true, |
||||||
|
"CHANGELOG.md": true, |
||||||
|
"examples": true, |
||||||
|
"res": true, |
||||||
|
"screenshots": true, |
||||||
|
"yarn-error.log": true, |
||||||
|
"**/.yarn": true |
||||||
|
}, |
||||||
|
"files.exclude": { |
||||||
|
"**/.cache": true, |
||||||
|
"**/.editorconfig": true, |
||||||
|
"**/.eslintcache": true, |
||||||
|
"**/bower_components": true, |
||||||
|
"**/.idea": true, |
||||||
|
"**/tmp": true, |
||||||
|
"**/.git": true, |
||||||
|
"**/.svn": true, |
||||||
|
"**/.hg": true, |
||||||
|
"**/CVS": true, |
||||||
|
"**/.DS_Store": true |
||||||
|
}, |
||||||
|
"files.watcherExclude": { |
||||||
|
"**/.git/objects/**": true, |
||||||
|
"**/.git/subtree-cache/**": true, |
||||||
|
"**/.vscode/**": true, |
||||||
|
"**/node_modules/**": true, |
||||||
|
"**/tmp/**": true, |
||||||
|
"**/bower_components/**": true, |
||||||
|
"**/dist/**": true, |
||||||
|
"**/yarn.lock": true |
||||||
|
}, |
||||||
|
"stylelint.enable": true, |
||||||
|
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"], |
||||||
|
"path-intellisense.mappings": { |
||||||
|
"@/": "${workspaceRoot}/src" |
||||||
|
}, |
||||||
|
"[javascriptreact]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[typescript]": { |
||||||
|
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint" |
||||||
|
}, |
||||||
|
"[typescriptreact]": { |
||||||
|
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint" |
||||||
|
}, |
||||||
|
"[html]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[css]": { |
||||||
|
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint" |
||||||
|
}, |
||||||
|
"[less]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[scss]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[markdown]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"editor.codeActionsOnSave": { |
||||||
|
"source.fixAll.eslint": true |
||||||
|
}, |
||||||
|
"[vue]": { |
||||||
|
"editor.codeActionsOnSave": { |
||||||
|
"source.fixAll.eslint": true, |
||||||
|
"source.fixAll.stylelint": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"i18n-ally.localesPaths": ["src/locales/lang"], |
||||||
|
"i18n-ally.keystyle": "nested", |
||||||
|
"i18n-ally.sortKeys": true, |
||||||
|
"i18n-ally.namespace": true, |
||||||
|
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}", |
||||||
|
"i18n-ally.enabledParsers": ["ts"], |
||||||
|
"i18n-ally.sourceLanguage": "en", |
||||||
|
"i18n-ally.displayLanguage": "zh-CN", |
||||||
|
"i18n-ally.enabledFrameworks": ["vue", "react"], |
||||||
|
"cSpell.words": [ |
||||||
|
"vben", |
||||||
|
"windi", |
||||||
|
"browserslist", |
||||||
|
"tailwindcss", |
||||||
|
"esnext", |
||||||
|
"antv", |
||||||
|
"tinymce", |
||||||
|
"qrcode", |
||||||
|
"sider", |
||||||
|
"pinia", |
||||||
|
"sider", |
||||||
|
"nprogress", |
||||||
|
"INTLIFY", |
||||||
|
"stylelint", |
||||||
|
"esno", |
||||||
|
"vitejs", |
||||||
|
"sortablejs", |
||||||
|
"mockjs", |
||||||
|
"codemirror", |
||||||
|
"iconify", |
||||||
|
"commitlint", |
||||||
|
"vditor", |
||||||
|
"echarts", |
||||||
|
"cropperjs", |
||||||
|
"logicflow", |
||||||
|
"vueuse", |
||||||
|
"zxcvbn", |
||||||
|
"lintstagedrc", |
||||||
|
"brotli", |
||||||
|
"tailwindcss", |
||||||
|
"sider", |
||||||
|
"pnpm", |
||||||
|
"antd" |
||||||
|
], |
||||||
|
"vetur.format.scriptInitialIndent": true, |
||||||
|
"vetur.format.styleInitialIndent": true, |
||||||
|
"vetur.validation.script": false, |
||||||
|
"MicroPython.executeButton": [ |
||||||
|
{ |
||||||
|
"text": "▶", |
||||||
|
"tooltip": "运行", |
||||||
|
"alignment": "left", |
||||||
|
"command": "extension.executeFile", |
||||||
|
"priority": 3.5 |
||||||
|
} |
||||||
|
], |
||||||
|
"MicroPython.syncButton": [ |
||||||
|
{ |
||||||
|
"text": "$(sync)", |
||||||
|
"tooltip": "同步", |
||||||
|
"alignment": "left", |
||||||
|
"command": "extension.execute", |
||||||
|
"priority": 4 |
||||||
|
} |
||||||
|
], |
||||||
|
"[javascript]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
}, |
||||||
|
"[json]": { |
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2020-present, Vben |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,122 @@ |
|||||||
|
<div align="center"> <a href="https://github.com/xingyu4j/vue-vben-admin"> <img alt="VbenAdmin Logo" width="200" height="200" src="https://anncwb.github.io/anncwb/images/logo.png"> </a> <br> <br> |
||||||
|
|
||||||
|
[](LICENSE) |
||||||
|
|
||||||
|
<h1>v1.0.2</h1> |
||||||
|
|
||||||
|
## 精简版地址 |
||||||
|
|
||||||
|
[gitee](https://gitee.com/xingyu4j/vue-vben-admin/tree/thin/) [github](https://github.com/xingyu4j/vue-vben-admin/tree/thin) |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
## 简介 |
||||||
|
|
||||||
|
- Vue Vben Admin 是一个免费开源的中后台模版。 |
||||||
|
- 本项目基于 vben2.8 版本,升级依赖,重构部分组件,重构代码样式,重构 setup 语法糖。 |
||||||
|
- 使用了最新的`Vue3`,`Vite4`,`Antdv3`,`TypeScript5`,`Pinia`等主流技术开发,开箱即用的中后台前端解决方案。 |
||||||
|
|
||||||
|
## 框架 |
||||||
|
|
||||||
|
| 框架 | 说明 | 版本 | |
||||||
|
| --- | --- | --- | |
||||||
|
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.47 | |
||||||
|
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.2.0 | |
||||||
|
| [ant-design-vue](https://antdv.com/) | ant-design-vue | 3.2.15 | |
||||||
|
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.2 | |
||||||
|
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.33 | |
||||||
|
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.13.0 | |
||||||
|
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | |
||||||
|
| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.1.6 | |
||||||
|
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | |
||||||
|
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.0 | |
||||||
|
|
||||||
|
## 特性 |
||||||
|
|
||||||
|
- **最新技术栈**:使用 Vue3/vite4/antdv3 等前端前沿技术开发 |
||||||
|
- **TypeScript**: 应用程序级 JavaScript 的语言 |
||||||
|
- **主题**:可配置的主题 |
||||||
|
- **国际化**:内置完善的国际化方案 |
||||||
|
- **Mock 数据** 内置 Mock 数据方案 |
||||||
|
- **权限** 内置完善的动态路由权限生成方案 |
||||||
|
- **组件** 二次封装了多个常用的组件 |
||||||
|
|
||||||
|
<p align="center"> |
||||||
|
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png"> |
||||||
|
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png"> |
||||||
|
<img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png"> |
||||||
|
</p> |
||||||
|
|
||||||
|
## 预览地址 |
||||||
|
|
||||||
|
[预览地址](http://vben.x-surge.com) |
||||||
|
|
||||||
|
## 准备 |
||||||
|
|
||||||
|
- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境 |
||||||
|
- [Vite4](https://vitejs.dev/) - 熟悉 vite 特性 |
||||||
|
- [Vue3](https://v3.vuejs.org/) - 熟悉 Vue 基础语法 |
||||||
|
- [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法 |
||||||
|
- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法 |
||||||
|
- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用 |
||||||
|
- [Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/) - ui 基本使用 |
||||||
|
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法 |
||||||
|
|
||||||
|
## 安装使用 |
||||||
|
|
||||||
|
- 获取项目代码 |
||||||
|
|
||||||
|
```bash |
||||||
|
git clone https://github.com/xingyu4j/vue-vben-admin.git |
||||||
|
or |
||||||
|
git clone https://gitee.com/xingyu4j/vue-vben-admin |
||||||
|
``` |
||||||
|
|
||||||
|
- 安装依赖 |
||||||
|
|
||||||
|
```bash |
||||||
|
cd vue-vben-admin |
||||||
|
|
||||||
|
pnpm install |
||||||
|
|
||||||
|
``` |
||||||
|
|
||||||
|
- 运行 |
||||||
|
|
||||||
|
```bash |
||||||
|
pnpm serve |
||||||
|
``` |
||||||
|
|
||||||
|
- 打包 |
||||||
|
|
||||||
|
```bash |
||||||
|
pnpm build |
||||||
|
``` |
||||||
|
|
||||||
|
## Git 贡献提交规范 |
||||||
|
|
||||||
|
- 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular)) |
||||||
|
|
||||||
|
- `feat` 增加新功能 |
||||||
|
- `fix` 修复问题/BUG |
||||||
|
- `style` 代码风格相关无影响运行结果的 |
||||||
|
- `perf` 优化/性能提升 |
||||||
|
- `refactor` 重构 |
||||||
|
- `revert` 撤销修改 |
||||||
|
- `test` 测试相关 |
||||||
|
- `docs` 文档/注释 |
||||||
|
- `chore` 依赖更新/脚手架配置修改等 |
||||||
|
- `workflow` 工作流改进 |
||||||
|
- `ci` 持续集成 |
||||||
|
- `types` 类型定义文件更改 |
||||||
|
- `wip` 开发中 |
||||||
|
|
||||||
|
## 浏览器支持 |
||||||
|
|
||||||
|
本地开发推荐使用`Chrome 80+` 浏览器 |
||||||
|
|
||||||
|
支持现代浏览器, 不支持 IE |
||||||
|
|
||||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | |
||||||
|
| :-: | :-: | :-: | :-: | :-: | |
||||||
|
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions | |
@ -0,0 +1,69 @@ |
|||||||
|
import { generate } from '@ant-design/colors' |
||||||
|
|
||||||
|
export const primaryColor = '#0960bd' |
||||||
|
|
||||||
|
export const darkMode = 'light' |
||||||
|
|
||||||
|
type Fn = (...arg: any) => any |
||||||
|
|
||||||
|
type GenerateTheme = 'default' | 'dark' |
||||||
|
|
||||||
|
export interface GenerateColorsParams { |
||||||
|
mixLighten: Fn |
||||||
|
mixDarken: Fn |
||||||
|
tinycolor: any |
||||||
|
color?: string |
||||||
|
} |
||||||
|
|
||||||
|
export function generateAntColors(color: string, theme: GenerateTheme = 'default') { |
||||||
|
return generate(color, { |
||||||
|
theme |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
export function getThemeColors(color?: string) { |
||||||
|
const tc = color || primaryColor |
||||||
|
const lightColors = generateAntColors(tc) |
||||||
|
const primary = lightColors[5] |
||||||
|
const modeColors = generateAntColors(primary, 'dark') |
||||||
|
|
||||||
|
return [...lightColors, ...modeColors] |
||||||
|
} |
||||||
|
|
||||||
|
export function generateColors({ color = primaryColor, mixLighten, mixDarken, tinycolor }: GenerateColorsParams) { |
||||||
|
const arr = new Array(19).fill(0) |
||||||
|
const lightens = arr.map((_t, i) => { |
||||||
|
return mixLighten(color, i / 5) |
||||||
|
}) |
||||||
|
|
||||||
|
const darkens = arr.map((_t, i) => { |
||||||
|
return mixDarken(color, i / 5) |
||||||
|
}) |
||||||
|
|
||||||
|
const alphaColors = arr.map((_t, i) => { |
||||||
|
return tinycolor(color) |
||||||
|
.setAlpha(i / 20) |
||||||
|
.toRgbString() |
||||||
|
}) |
||||||
|
|
||||||
|
const shortAlphaColors = alphaColors.map((item) => item.replace(/\s/g, '').replace(/0\./g, '.')) |
||||||
|
|
||||||
|
const tinycolorLightens = arr |
||||||
|
.map((_t, i) => { |
||||||
|
return tinycolor(color) |
||||||
|
.lighten(i * 5) |
||||||
|
.toHexString() |
||||||
|
}) |
||||||
|
.filter((item) => item !== '#ffffff') |
||||||
|
|
||||||
|
const tinycolorDarkens = arr |
||||||
|
.map((_t, i) => { |
||||||
|
return tinycolor(color) |
||||||
|
.darken(i * 5) |
||||||
|
.toHexString() |
||||||
|
}) |
||||||
|
.filter((item) => item !== '#000000') |
||||||
|
return [...lightens, ...darkens, ...alphaColors, ...shortAlphaColors, ...tinycolorDarkens, ...tinycolorLightens].filter( |
||||||
|
(item) => !item.includes('-') |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
/** |
||||||
|
* The name of the configuration file entered in the production environment |
||||||
|
*/ |
||||||
|
export const GLOB_CONFIG_FILE_NAME = '_app.config.js' |
||||||
|
|
||||||
|
export const OUTPUT_DIR = 'dist' |
@ -0,0 +1,37 @@ |
|||||||
|
import { generateAntColors, primaryColor } from '../config/themeConfig' |
||||||
|
import { getThemeVariables } from 'ant-design-vue/dist/theme' |
||||||
|
import { resolve } from 'path' |
||||||
|
|
||||||
|
/** |
||||||
|
* less global variable |
||||||
|
*/ |
||||||
|
export function generateModifyVars(dark = false) { |
||||||
|
const palettes = generateAntColors(primaryColor) |
||||||
|
const primary = palettes[5] |
||||||
|
|
||||||
|
const primaryColorObj: Record<string, string> = {} |
||||||
|
|
||||||
|
for (let index = 0; index < 10; index++) { |
||||||
|
primaryColorObj[`primary-${index + 1}`] = palettes[index] |
||||||
|
} |
||||||
|
|
||||||
|
const modifyVars = getThemeVariables({ dark }) |
||||||
|
return { |
||||||
|
...modifyVars, |
||||||
|
// Used for global import to avoid the need to import each style file separately
|
||||||
|
// reference: Avoid repeated references
|
||||||
|
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, |
||||||
|
'primary-color': primary, |
||||||
|
...primaryColorObj, |
||||||
|
'info-color': primary, |
||||||
|
'processing-color': primary, |
||||||
|
'success-color': '#55D187', // Success color
|
||||||
|
'error-color': '#ED6F6F', // False color
|
||||||
|
'warning-color': '#EFBD47', // Warning color
|
||||||
|
//'border-color-base': '#EEEEEE',
|
||||||
|
'font-size-base': '14px', // Main font size
|
||||||
|
'border-radius-base': '2px', // Component/float fillet
|
||||||
|
'link-color': primary, // Link color
|
||||||
|
'app-content-background': '#fafafa' // Link color
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
import path from 'path' |
||||||
|
import fs from 'fs-extra' |
||||||
|
import inquirer from 'inquirer' |
||||||
|
import colors from 'picocolors' |
||||||
|
import pkg from '../../../package.json' |
||||||
|
|
||||||
|
async function generateIcon() { |
||||||
|
const dir = path.resolve(process.cwd(), 'node_modules/@iconify/json') |
||||||
|
|
||||||
|
const raw = await fs.readJSON(path.join(dir, 'collections.json')) |
||||||
|
|
||||||
|
const collections = Object.entries(raw).map(([id, v]) => ({ |
||||||
|
...(v as any), |
||||||
|
id |
||||||
|
})) |
||||||
|
|
||||||
|
const choices = collections.map((item) => ({ key: item.id, value: item.id, name: item.name })) |
||||||
|
|
||||||
|
inquirer |
||||||
|
.prompt([ |
||||||
|
{ |
||||||
|
type: 'list', |
||||||
|
name: 'useType', |
||||||
|
choices: [ |
||||||
|
{ key: 'local', value: 'local', name: 'Local' }, |
||||||
|
{ key: 'onLine', value: 'onLine', name: 'OnLine' } |
||||||
|
], |
||||||
|
message: 'How to use icons?' |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'list', |
||||||
|
name: 'iconSet', |
||||||
|
choices: choices, |
||||||
|
message: 'Select the icon set that needs to be generated?' |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: 'input', |
||||||
|
name: 'output', |
||||||
|
message: 'Select the icon set that needs to be generated?', |
||||||
|
default: 'src/components/Icon/data' |
||||||
|
} |
||||||
|
]) |
||||||
|
.then(async (answers) => { |
||||||
|
const { iconSet, output, useType } = answers |
||||||
|
const outputDir = path.resolve(process.cwd(), output) |
||||||
|
await fs.ensureDir(outputDir) |
||||||
|
const genCollections = collections.filter((item) => [iconSet].includes(item.id)) |
||||||
|
const prefixSet: string[] = [] |
||||||
|
for (const info of genCollections) { |
||||||
|
const data = await fs.readJSON(path.join(dir, 'json', `${info.id}.json`)) |
||||||
|
if (data) { |
||||||
|
const { prefix } = data |
||||||
|
const isLocal = useType === 'local' |
||||||
|
const icons = Object.keys(data.icons).map((item) => `${isLocal ? prefix + ':' : ''}${item}`) |
||||||
|
|
||||||
|
await fs.writeFileSync( |
||||||
|
path.join(output, `icons.data.ts`), |
||||||
|
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}` |
||||||
|
) |
||||||
|
prefixSet.push(prefix) |
||||||
|
} |
||||||
|
} |
||||||
|
await fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite')) |
||||||
|
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
generateIcon() |
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Get the configuration file variable name |
||||||
|
* @param env |
||||||
|
*/ |
||||||
|
export const getConfigFileName = (env: Record<string, any>) => { |
||||||
|
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '') |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
/** |
||||||
|
* Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging |
||||||
|
*/ |
||||||
|
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant' |
||||||
|
import fs, { writeFileSync } from 'fs-extra' |
||||||
|
import colors from 'picocolors' |
||||||
|
|
||||||
|
import { getEnvConfig, getRootPath } from '../utils' |
||||||
|
import { getConfigFileName } from '../getConfigFileName' |
||||||
|
|
||||||
|
import pkg from '../../package.json' |
||||||
|
|
||||||
|
interface CreateConfigParams { |
||||||
|
configName: string |
||||||
|
config: any |
||||||
|
configFileName?: string |
||||||
|
} |
||||||
|
|
||||||
|
function createConfig(params: CreateConfigParams) { |
||||||
|
const { configName, config, configFileName } = params |
||||||
|
try { |
||||||
|
const windowConf = `window.${configName}` |
||||||
|
// Ensure that the variable will not be modified
|
||||||
|
let configStr = `${windowConf}=${JSON.stringify(config)};` |
||||||
|
configStr += ` |
||||||
|
Object.freeze(${windowConf}); |
||||||
|
Object.defineProperty(window, "${configName}", { |
||||||
|
configurable: false, |
||||||
|
writable: false, |
||||||
|
}); |
||||||
|
`.replace(/\s/g, '')
|
||||||
|
|
||||||
|
fs.mkdirp(getRootPath(OUTPUT_DIR)) |
||||||
|
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr) |
||||||
|
|
||||||
|
console.log(colors.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`) |
||||||
|
console.log(colors.gray(OUTPUT_DIR + '/' + colors.green(configFileName)) + '\n') |
||||||
|
} catch (error) { |
||||||
|
console.log(colors.red('configuration file configuration file failed to package:\n' + error)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function runBuildConfig() { |
||||||
|
const config = getEnvConfig() |
||||||
|
const configFileName = getConfigFileName(config) |
||||||
|
createConfig({ config, configName: configFileName, configFileName: GLOB_CONFIG_FILE_NAME }) |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
// #!/usr/bin/env node
|
||||||
|
|
||||||
|
import { runBuildConfig } from './buildConf' |
||||||
|
import colors from 'picocolors' |
||||||
|
|
||||||
|
import pkg from '../../package.json' |
||||||
|
|
||||||
|
export const runBuild = async () => { |
||||||
|
try { |
||||||
|
const argvList = process.argv.splice(2) |
||||||
|
|
||||||
|
// Generate configuration file
|
||||||
|
if (!argvList.includes('disabled-config')) { |
||||||
|
runBuildConfig() |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!') |
||||||
|
} catch (error) { |
||||||
|
console.log(colors.red('vite build error:\n' + error)) |
||||||
|
process.exit(1) |
||||||
|
} |
||||||
|
} |
||||||
|
runBuild() |
@ -0,0 +1,92 @@ |
|||||||
|
import fs from 'fs' |
||||||
|
import path from 'path' |
||||||
|
import dotenv from 'dotenv' |
||||||
|
|
||||||
|
export function isDevFn(mode: string): boolean { |
||||||
|
return mode === 'development' |
||||||
|
} |
||||||
|
|
||||||
|
export function isProdFn(mode: string): boolean { |
||||||
|
return mode === 'production' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Whether to generate package preview |
||||||
|
*/ |
||||||
|
export function isReportMode(): boolean { |
||||||
|
return process.env.REPORT === 'true' |
||||||
|
} |
||||||
|
|
||||||
|
// Read all environment variable configuration files to process.env
|
||||||
|
export function wrapperEnv(envConf: Recordable): ViteEnv { |
||||||
|
const ret: any = {} |
||||||
|
|
||||||
|
for (const envName of Object.keys(envConf)) { |
||||||
|
let realName = envConf[envName].replace(/\\n/g, '\n') |
||||||
|
realName = realName === 'true' ? true : realName === 'false' ? false : realName |
||||||
|
|
||||||
|
if (envName === 'VITE_PORT') { |
||||||
|
realName = Number(realName) |
||||||
|
} |
||||||
|
if (envName === 'VITE_PROXY' && realName) { |
||||||
|
try { |
||||||
|
realName = JSON.parse(realName.replace(/'/g, '"')) |
||||||
|
} catch (error) { |
||||||
|
realName = '' |
||||||
|
} |
||||||
|
} |
||||||
|
ret[envName] = realName |
||||||
|
// if (typeof realName === 'string') {
|
||||||
|
// process.env[envName] = realName;
|
||||||
|
// } else if (typeof realName === 'object') {
|
||||||
|
// process.env[envName] = JSON.stringify(realName);
|
||||||
|
// }
|
||||||
|
} |
||||||
|
return ret |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前环境下生效的配置文件名 |
||||||
|
*/ |
||||||
|
function getConfFiles() { |
||||||
|
const script = process.env.npm_lifecycle_script |
||||||
|
const reg = new RegExp('--mode ([a-z_\\d]+)') |
||||||
|
const result = reg.exec(script as string) as any |
||||||
|
if (result) { |
||||||
|
const mode = result[1] as string |
||||||
|
return ['.env', `.env.${mode}`] |
||||||
|
} |
||||||
|
return ['.env', '.env.production'] |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the environment variables starting with the specified prefix |
||||||
|
* @param match prefix |
||||||
|
* @param confFiles ext |
||||||
|
*/ |
||||||
|
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { |
||||||
|
let envConfig = {} |
||||||
|
confFiles.forEach((item) => { |
||||||
|
try { |
||||||
|
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item))) |
||||||
|
envConfig = { ...envConfig, ...env } |
||||||
|
} catch (e) { |
||||||
|
console.error(`Error in parsing ${item}`, e) |
||||||
|
} |
||||||
|
}) |
||||||
|
const reg = new RegExp(`^(${match})`) |
||||||
|
Object.keys(envConfig).forEach((key) => { |
||||||
|
if (!reg.test(key)) { |
||||||
|
Reflect.deleteProperty(envConfig, key) |
||||||
|
} |
||||||
|
}) |
||||||
|
return envConfig |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get user root directory |
||||||
|
* @param dir file path |
||||||
|
*/ |
||||||
|
export function getRootPath(...dir: string[]) { |
||||||
|
return path.resolve(process.cwd(), ...dir) |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
const include = [ |
||||||
|
'qs', |
||||||
|
'vue', |
||||||
|
'less', |
||||||
|
'axios', |
||||||
|
'pinia', |
||||||
|
'dayjs', |
||||||
|
'qrcode', |
||||||
|
'echarts', |
||||||
|
'intro.js', |
||||||
|
'cropperjs', |
||||||
|
'crypto-js', |
||||||
|
'lodash-es', |
||||||
|
'nprogress', |
||||||
|
'vue-i18n', |
||||||
|
'vue-types', |
||||||
|
'vue-router', |
||||||
|
'sortablejs', |
||||||
|
'echarts/core', |
||||||
|
'echarts/charts', |
||||||
|
'echarts/components', |
||||||
|
'echarts/renderers', |
||||||
|
'@vueuse/core', |
||||||
|
'@zxcvbn-ts/core', |
||||||
|
'@iconify/iconify', |
||||||
|
'ant-design-vue', |
||||||
|
'ant-design-vue/es/style', |
||||||
|
'ant-design-vue/es/locale/zh_CN', |
||||||
|
'ant-design-vue/es/locale/en_US', |
||||||
|
'vite-plugin-windicss' |
||||||
|
] |
||||||
|
|
||||||
|
const exclude = ['@iconify/json'] |
||||||
|
|
||||||
|
export { include, exclude } |
@ -0,0 +1,32 @@ |
|||||||
|
/** |
||||||
|
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated |
||||||
|
* https://github.com/anncwb/vite-plugin-compression
|
||||||
|
*/ |
||||||
|
import type { PluginOption } from 'vite' |
||||||
|
import compressPlugin from 'vite-plugin-compression' |
||||||
|
|
||||||
|
export function configCompressPlugin(compress: 'gzip' | 'brotli' | 'none', deleteOriginFile = false): PluginOption | PluginOption[] { |
||||||
|
const compressList = compress.split(',') |
||||||
|
|
||||||
|
const plugins: PluginOption[] = [] |
||||||
|
|
||||||
|
if (compressList.includes('gzip')) { |
||||||
|
plugins.push( |
||||||
|
compressPlugin({ |
||||||
|
ext: '.gz', |
||||||
|
deleteOriginFile |
||||||
|
}) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
if (compressList.includes('brotli')) { |
||||||
|
plugins.push( |
||||||
|
compressPlugin({ |
||||||
|
ext: '.br', |
||||||
|
algorithm: 'brotliCompress', |
||||||
|
deleteOriginFile |
||||||
|
}) |
||||||
|
) |
||||||
|
} |
||||||
|
return plugins |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
/** |
||||||
|
* Plugin to minimize and use ejs template syntax in index.html. |
||||||
|
* https://github.com/anncwb/vite-plugin-html
|
||||||
|
*/ |
||||||
|
import type { PluginOption } from 'vite' |
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html' |
||||||
|
import pkg from '../../../package.json' |
||||||
|
import { GLOB_CONFIG_FILE_NAME } from '../../constant' |
||||||
|
|
||||||
|
export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) { |
||||||
|
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env |
||||||
|
|
||||||
|
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/` |
||||||
|
|
||||||
|
const getAppConfigSrc = () => { |
||||||
|
return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}` |
||||||
|
} |
||||||
|
|
||||||
|
const htmlPlugin: PluginOption[] = createHtmlPlugin({ |
||||||
|
minify: isBuild, |
||||||
|
inject: { |
||||||
|
// Inject data into ejs template
|
||||||
|
data: { |
||||||
|
title: VITE_GLOB_APP_TITLE |
||||||
|
}, |
||||||
|
// Embed the generated app.config.js file
|
||||||
|
tags: isBuild |
||||||
|
? [ |
||||||
|
{ |
||||||
|
tag: 'script', |
||||||
|
attrs: { |
||||||
|
src: getAppConfigSrc() |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
: [] |
||||||
|
} |
||||||
|
}) |
||||||
|
return htmlPlugin |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
import { PluginOption } from 'vite' |
||||||
|
import vue from '@vitejs/plugin-vue' |
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx' |
||||||
|
import legacy from '@vitejs/plugin-legacy' |
||||||
|
import progress from 'vite-plugin-progress' |
||||||
|
import windiCSS from 'vite-plugin-windicss' |
||||||
|
import purgeIcons from 'vite-plugin-purge-icons' |
||||||
|
import VitePluginCertificate from 'vite-plugin-mkcert' |
||||||
|
import vueSetupExtend from 'unplugin-vue-setup-extend-plus/vite' |
||||||
|
import { configHtmlPlugin } from './html' |
||||||
|
import { configPwaConfig } from './pwa' |
||||||
|
import { configMockPlugin } from './mock' |
||||||
|
import { configCompressPlugin } from './compress' |
||||||
|
import { configStyleImportPlugin } from './styleImport' |
||||||
|
import { configVisualizerConfig } from './visualizer' |
||||||
|
import { configThemePlugin } from './theme' |
||||||
|
import { configSvgIconsPlugin } from './svgSprite' |
||||||
|
import { isProdFn } from '../../utils' |
||||||
|
|
||||||
|
export function createVitePlugins(mode: string, viteEnv: ViteEnv, isBuild: boolean) { |
||||||
|
const { VITE_USE_MOCK, VITE_LEGACY, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv |
||||||
|
|
||||||
|
const vitePlugins: (PluginOption | PluginOption[])[] = [ |
||||||
|
// have to
|
||||||
|
vue(), |
||||||
|
// have to
|
||||||
|
vueJsx(), |
||||||
|
// 打包进度条
|
||||||
|
progress(), |
||||||
|
// support name
|
||||||
|
vueSetupExtend({}), |
||||||
|
VitePluginCertificate({ |
||||||
|
source: 'coding' |
||||||
|
}) |
||||||
|
] |
||||||
|
|
||||||
|
// vite-plugin-windicss
|
||||||
|
vitePlugins.push(windiCSS()) |
||||||
|
|
||||||
|
// @vitejs/plugin-legacy
|
||||||
|
VITE_LEGACY && isBuild && vitePlugins.push(legacy()) |
||||||
|
|
||||||
|
// vite-plugin-html
|
||||||
|
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild)) |
||||||
|
|
||||||
|
// vite-plugin-svg-icons
|
||||||
|
vitePlugins.push(configSvgIconsPlugin(isBuild)) |
||||||
|
|
||||||
|
// vite-plugin-mock
|
||||||
|
VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild)) |
||||||
|
|
||||||
|
// vite-plugin-purge-icons
|
||||||
|
vitePlugins.push(purgeIcons()) |
||||||
|
|
||||||
|
// vite-plugin-style-import
|
||||||
|
if (isProdFn(mode)) { |
||||||
|
vitePlugins.push(configStyleImportPlugin(isBuild)) |
||||||
|
} |
||||||
|
|
||||||
|
// rollup-plugin-visualizer
|
||||||
|
vitePlugins.push(configVisualizerConfig()) |
||||||
|
|
||||||
|
// vite-plugin-vben-theme
|
||||||
|
vitePlugins.push(configThemePlugin(isBuild)) |
||||||
|
|
||||||
|
// The following plugins only work in the production environment
|
||||||
|
if (isBuild) { |
||||||
|
// rollup-plugin-gzip
|
||||||
|
vitePlugins.push(configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)) |
||||||
|
|
||||||
|
// vite-plugin-pwa
|
||||||
|
vitePlugins.push(configPwaConfig(viteEnv)) |
||||||
|
} |
||||||
|
|
||||||
|
return vitePlugins |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
/** |
||||||
|
* Mock plugin for development and production. |
||||||
|
* https://github.com/anncwb/vite-plugin-mock
|
||||||
|
*/ |
||||||
|
import { viteMockServe } from 'vite-plugin-mock' |
||||||
|
|
||||||
|
export function configMockPlugin(isBuild: boolean) { |
||||||
|
return viteMockServe({ |
||||||
|
ignore: /^\_/, |
||||||
|
mockPath: 'mock', |
||||||
|
localEnabled: !isBuild, |
||||||
|
prodEnabled: isBuild, |
||||||
|
injectCode: ` |
||||||
|
import { setupProdMockServer } from '../mock/_createProductionServer'; |
||||||
|
|
||||||
|
setupProdMockServer(); |
||||||
|
` |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/** |
||||||
|
* Zero-config PWA for Vite |
||||||
|
* https://github.com/antfu/vite-plugin-pwa
|
||||||
|
*/ |
||||||
|
import { VitePWA } from 'vite-plugin-pwa' |
||||||
|
|
||||||
|
export function configPwaConfig(env: ViteEnv) { |
||||||
|
const { VITE_USE_PWA, VITE_GLOB_APP_TITLE, VITE_GLOB_APP_SHORT_NAME } = env |
||||||
|
|
||||||
|
if (VITE_USE_PWA) { |
||||||
|
// vite-plugin-pwa
|
||||||
|
const pwaPlugin = VitePWA({ |
||||||
|
manifest: { |
||||||
|
name: VITE_GLOB_APP_TITLE, |
||||||
|
short_name: VITE_GLOB_APP_SHORT_NAME, |
||||||
|
icons: [ |
||||||
|
{ |
||||||
|
src: './resource/img/pwa-192x192.png', |
||||||
|
sizes: '192x192', |
||||||
|
type: 'image/png' |
||||||
|
}, |
||||||
|
{ |
||||||
|
src: './resource/img/pwa-512x512.png', |
||||||
|
sizes: '512x512', |
||||||
|
type: 'image/png' |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
}) |
||||||
|
return pwaPlugin |
||||||
|
} |
||||||
|
return [] |
||||||
|
} |
@ -0,0 +1,82 @@ |
|||||||
|
/** |
||||||
|
* Introduces component library styles on demand. |
||||||
|
* https://github.com/anncwb/vite-plugin-style-import
|
||||||
|
*/ |
||||||
|
import { createStyleImportPlugin } from 'vite-plugin-style-import' |
||||||
|
|
||||||
|
export function configStyleImportPlugin(_isBuild: boolean) { |
||||||
|
if (!_isBuild) { |
||||||
|
return [] |
||||||
|
} |
||||||
|
const styleImportPlugin = createStyleImportPlugin({ |
||||||
|
libs: [ |
||||||
|
{ |
||||||
|
libraryName: 'ant-design-vue', |
||||||
|
esModule: true, |
||||||
|
resolveStyle: (name) => { |
||||||
|
// 这里是无需额外引入样式文件的“子组件”列表
|
||||||
|
const ignoreList = [ |
||||||
|
'anchor-link', |
||||||
|
'sub-menu', |
||||||
|
'menu-item', |
||||||
|
'menu-divider', |
||||||
|
'menu-item-group', |
||||||
|
'breadcrumb-item', |
||||||
|
'breadcrumb-separator', |
||||||
|
'form-item', |
||||||
|
'step', |
||||||
|
'select-option', |
||||||
|
'select-opt-group', |
||||||
|
'card-grid', |
||||||
|
'card-meta', |
||||||
|
'collapse-panel', |
||||||
|
'descriptions-item', |
||||||
|
'list-item', |
||||||
|
'list-item-meta', |
||||||
|
'table-column', |
||||||
|
'table-column-group', |
||||||
|
'tab-pane', |
||||||
|
'tab-content', |
||||||
|
'timeline-item', |
||||||
|
'tree-node', |
||||||
|
'skeleton-input', |
||||||
|
'skeleton-avatar', |
||||||
|
'skeleton-title', |
||||||
|
'skeleton-paragraph', |
||||||
|
'skeleton-image', |
||||||
|
'skeleton-button' |
||||||
|
] |
||||||
|
// 这里是需要额外引入样式的子组件列表
|
||||||
|
// 单独引入子组件时需引入组件样式,否则会在打包后导致子组件样式丢失
|
||||||
|
const replaceList = { |
||||||
|
textarea: 'input', |
||||||
|
'typography-text': 'typography', |
||||||
|
'typography-title': 'typography', |
||||||
|
'typography-paragraph': 'typography', |
||||||
|
'typography-link': 'typography', |
||||||
|
'dropdown-button': 'dropdown', |
||||||
|
'input-password': 'input', |
||||||
|
'input-search': 'input', |
||||||
|
'input-group': 'input', |
||||||
|
'radio-group': 'radio', |
||||||
|
'checkbox-group': 'checkbox', |
||||||
|
'layout-sider': 'layout', |
||||||
|
'layout-content': 'layout', |
||||||
|
'layout-footer': 'layout', |
||||||
|
'layout-header': 'layout', |
||||||
|
'month-picker': 'date-picker', |
||||||
|
'range-picker': 'date-picker', |
||||||
|
'image-preview-group': 'image' |
||||||
|
} |
||||||
|
|
||||||
|
return ignoreList.includes(name) |
||||||
|
? '' |
||||||
|
: replaceList.hasOwnProperty(name) |
||||||
|
? `ant-design-vue/es/${replaceList[name]}/style/index` |
||||||
|
: `ant-design-vue/es/${name}/style/index` |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}) |
||||||
|
return styleImportPlugin |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
/** |
||||||
|
* Vite Plugin for fast creating SVG sprites. |
||||||
|
* https://github.com/anncwb/vite-plugin-svg-icons
|
||||||
|
*/ |
||||||
|
|
||||||
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' |
||||||
|
import path from 'path' |
||||||
|
|
||||||
|
export function configSvgIconsPlugin(isBuild: boolean) { |
||||||
|
const svgIconsPlugin = createSvgIconsPlugin({ |
||||||
|
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], |
||||||
|
svgoOptions: isBuild, |
||||||
|
// default
|
||||||
|
symbolId: 'icon-[dir]-[name]' |
||||||
|
}) |
||||||
|
return svgIconsPlugin |
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
/** |
||||||
|
* Vite plugin for website theme color switching |
||||||
|
* https://github.com/anncwb/vite-plugin-theme
|
||||||
|
*/ |
||||||
|
import type { PluginOption } from 'vite' |
||||||
|
import path from 'path' |
||||||
|
import { viteThemePlugin, antdDarkThemePlugin, mixLighten, mixDarken, tinycolor } from '@kirklin/vite-plugin-vben-theme' |
||||||
|
import { getThemeColors, generateColors } from '../../config/themeConfig' |
||||||
|
import { generateModifyVars } from '../../generate/generateModifyVars' |
||||||
|
|
||||||
|
export function configThemePlugin(isBuild: boolean): PluginOption[] { |
||||||
|
const colors = generateColors({ |
||||||
|
mixDarken, |
||||||
|
mixLighten, |
||||||
|
tinycolor |
||||||
|
}) |
||||||
|
const plugin = [ |
||||||
|
viteThemePlugin({ |
||||||
|
resolveSelector: (s) => { |
||||||
|
s = s.trim() |
||||||
|
switch (s) { |
||||||
|
case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon': |
||||||
|
return '.ant-steps-item-icon > .ant-steps-icon' |
||||||
|
case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)': |
||||||
|
case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover': |
||||||
|
case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active': |
||||||
|
return s |
||||||
|
case '.ant-steps-item-icon > .ant-steps-icon': |
||||||
|
return s |
||||||
|
case '.ant-select-item-option-selected:not(.ant-select-item-option-disabled)': |
||||||
|
return s |
||||||
|
default: |
||||||
|
if (s.indexOf('.ant-btn') >= -1) { |
||||||
|
// 按钮被重新定制过,需要过滤掉class防止覆盖
|
||||||
|
return s |
||||||
|
} |
||||||
|
} |
||||||
|
return s.startsWith('[data-theme') ? s : `[data-theme] ${s}` |
||||||
|
}, |
||||||
|
colorVariables: [...getThemeColors(), ...colors] |
||||||
|
}), |
||||||
|
antdDarkThemePlugin({ |
||||||
|
preloadFiles: [ |
||||||
|
path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'), |
||||||
|
//path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
|
||||||
|
path.resolve(process.cwd(), 'src/design/index.less') |
||||||
|
], |
||||||
|
filter: (id) => (isBuild ? !id.endsWith('antd.less') : true), |
||||||
|
// extractCss: false,
|
||||||
|
darkModifyVars: { |
||||||
|
...generateModifyVars(true), |
||||||
|
'text-color': '#c9d1d9', |
||||||
|
'primary-1': 'rgb(255 255 255 / 8%)', |
||||||
|
'text-color-base': '#c9d1d9', |
||||||
|
'component-background': '#151515', |
||||||
|
'heading-color': 'rgb(255 255 255 / 65%)', |
||||||
|
// black: '#0e1117',
|
||||||
|
// #8b949e
|
||||||
|
'text-color-secondary': '#8b949e', |
||||||
|
'border-color-base': '#303030', |
||||||
|
// 'border-color-split': '#30363d',
|
||||||
|
'item-active-bg': '#111b26', |
||||||
|
'app-content-background': '#1e1e1e', |
||||||
|
'tree-node-selected-bg': '#11263c', |
||||||
|
|
||||||
|
'alert-success-border-color': '#274916', |
||||||
|
'alert-success-bg-color': '#162312', |
||||||
|
'alert-success-icon-color': '#49aa19', |
||||||
|
'alert-info-border-color': '#153450', |
||||||
|
'alert-info-bg-color': '#111b26', |
||||||
|
'alert-info-icon-color': '#177ddc', |
||||||
|
'alert-warning-border-color': '#594214', |
||||||
|
'alert-warning-bg-color': '#2b2111', |
||||||
|
'alert-warning-icon-color': '#d89614', |
||||||
|
'alert-error-border-color': '#58181c', |
||||||
|
'alert-error-bg-color': '#2a1215', |
||||||
|
'alert-error-icon-color': '#a61d24' |
||||||
|
} |
||||||
|
}) |
||||||
|
] |
||||||
|
|
||||||
|
return plugin as unknown as PluginOption[] |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
/** |
||||||
|
* Package file volume analysis |
||||||
|
*/ |
||||||
|
import visualizer from 'rollup-plugin-visualizer' |
||||||
|
import { isReportMode } from '../../utils' |
||||||
|
|
||||||
|
export function configVisualizerConfig() { |
||||||
|
if (isReportMode()) { |
||||||
|
return visualizer({ |
||||||
|
filename: './node_modules/.cache/visualizer/stats.html', |
||||||
|
open: true, |
||||||
|
gzipSize: true, |
||||||
|
brotliSize: true |
||||||
|
}) as Plugin |
||||||
|
} |
||||||
|
return [] |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
/** |
||||||
|
* Used to parse the .env.development proxy configuration |
||||||
|
*/ |
||||||
|
import type { ProxyOptions } from 'vite' |
||||||
|
|
||||||
|
type ProxyItem = [string, string] |
||||||
|
|
||||||
|
type ProxyList = ProxyItem[] |
||||||
|
|
||||||
|
type ProxyTargetList = Record<string, ProxyOptions> |
||||||
|
|
||||||
|
const httpsRE = /^https:\/\// |
||||||
|
|
||||||
|
/** |
||||||
|
* Generate proxy |
||||||
|
* @param list |
||||||
|
*/ |
||||||
|
export function createProxy(list: ProxyList = []) { |
||||||
|
const ret: ProxyTargetList = {} |
||||||
|
for (const [prefix, target] of list) { |
||||||
|
const isHttps = httpsRE.test(target) |
||||||
|
|
||||||
|
// https://github.com/http-party/node-http-proxy#options
|
||||||
|
ret[prefix] = { |
||||||
|
target: target, |
||||||
|
changeOrigin: true, |
||||||
|
ws: true, |
||||||
|
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), |
||||||
|
// https is require secure=false
|
||||||
|
...(isHttps ? { secure: false } : {}) |
||||||
|
} |
||||||
|
} |
||||||
|
return ret |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
const fs = require('fs') |
||||||
|
const path = require('path') |
||||||
|
const { execSync } = require('child_process') |
||||||
|
|
||||||
|
const scopes = fs |
||||||
|
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true }) |
||||||
|
.filter((dirent) => dirent.isDirectory()) |
||||||
|
.map((dirent) => dirent.name.replace(/s$/, '')) |
||||||
|
|
||||||
|
// precomputed scope
|
||||||
|
const scopeComplete = execSync('git status --porcelain || true') |
||||||
|
.toString() |
||||||
|
.trim() |
||||||
|
.split('\n') |
||||||
|
.find((r) => ~r.indexOf('M src')) |
||||||
|
?.replace(/(\/)/g, '%%') |
||||||
|
?.match(/src%%((\w|-)*)/)?.[1] |
||||||
|
?.replace(/s$/, '') |
||||||
|
|
||||||
|
/** @type {import('cz-git').UserConfig} */ |
||||||
|
module.exports = { |
||||||
|
ignores: [(commit) => commit.includes('init')], |
||||||
|
extends: ['@commitlint/config-conventional'], |
||||||
|
rules: { |
||||||
|
'body-leading-blank': [2, 'always'], |
||||||
|
'footer-leading-blank': [1, 'always'], |
||||||
|
'header-max-length': [2, 'always', 108], |
||||||
|
'subject-empty': [2, 'never'], |
||||||
|
'type-empty': [2, 'never'], |
||||||
|
'subject-case': [0], |
||||||
|
'type-enum': [ |
||||||
|
2, |
||||||
|
'always', |
||||||
|
['feat', 'fix', 'perf', 'style', 'docs', 'test', 'refactor', 'build', 'ci', 'chore', 'revert', 'wip', 'workflow', 'types', 'release'] |
||||||
|
] |
||||||
|
}, |
||||||
|
prompt: { |
||||||
|
/** @use `yarn commit :f` */ |
||||||
|
alias: { |
||||||
|
f: 'docs: fix typos', |
||||||
|
r: 'docs: update README', |
||||||
|
s: 'style: update code format', |
||||||
|
b: 'build: bump dependencies', |
||||||
|
c: 'chore: update config' |
||||||
|
}, |
||||||
|
customScopesAlign: !scopeComplete ? 'top' : 'bottom', |
||||||
|
defaultScope: scopeComplete, |
||||||
|
scopes: [...scopes, 'mock'], |
||||||
|
allowEmptyIssuePrefixs: false, |
||||||
|
allowCustomIssuePrefixs: false, |
||||||
|
|
||||||
|
// English
|
||||||
|
typesAppend: [ |
||||||
|
{ value: 'wip', name: 'wip: work in process' }, |
||||||
|
{ value: 'workflow', name: 'workflow: workflow improvements' }, |
||||||
|
{ value: 'types', name: 'types: type definition file changes' } |
||||||
|
], |
||||||
|
|
||||||
|
// 中英文对照版
|
||||||
|
messages: { |
||||||
|
type: '选择你要提交的类型 :', |
||||||
|
scope: '选择一个提交范围 (可选):', |
||||||
|
customScope: '请输入自定义的提交范围 :', |
||||||
|
subject: '填写简短精炼的变更描述 :\n', |
||||||
|
body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n', |
||||||
|
breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n', |
||||||
|
footerPrefixsSelect: '选择关联issue前缀 (可选):', |
||||||
|
customFooterPrefixs: '输入自定义issue前缀 :', |
||||||
|
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', |
||||||
|
confirmCommit: '是否提交或修改commit ?' |
||||||
|
}, |
||||||
|
types: [ |
||||||
|
{ value: 'feat', name: 'feat: 新增功能' }, |
||||||
|
{ value: 'fix', name: 'fix: 修复缺陷' }, |
||||||
|
{ value: 'docs', name: 'docs: 文档变更' }, |
||||||
|
{ value: 'style', name: 'style: 代码格式' }, |
||||||
|
{ value: 'refactor', name: 'refactor: 代码重构' }, |
||||||
|
{ value: 'perf', name: 'perf: 性能优化' }, |
||||||
|
{ value: 'test', name: 'test: 添加疏漏测试或已有测试改动' }, |
||||||
|
{ value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' }, |
||||||
|
{ value: 'ci', name: 'ci: 修改 CI 配置、脚本' }, |
||||||
|
{ value: 'revert', name: 'revert: 回滚 commit' }, |
||||||
|
{ value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' }, |
||||||
|
{ value: 'wip', name: 'wip: 正在开发中' }, |
||||||
|
{ value: 'workflow', name: 'workflow: 工作流程改进' }, |
||||||
|
{ value: 'types', name: 'types: 类型定义文件修改' } |
||||||
|
], |
||||||
|
emptyScopesAlias: 'empty: 不填写', |
||||||
|
customScopesAlias: 'custom: 自定义' |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,158 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en" id="htmlRoot"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8" /> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
||||||
|
<meta name="renderer" content="webkit" /> |
||||||
|
<meta |
||||||
|
name="viewport" |
||||||
|
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" |
||||||
|
/> |
||||||
|
<title><%= title %></title> |
||||||
|
<link rel="icon" href="/favicon.ico" /> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<script> |
||||||
|
(() => { |
||||||
|
var htmlRoot = document.getElementById('htmlRoot'); |
||||||
|
var theme = window.localStorage.getItem('__APP__DARK__MODE__'); |
||||||
|
if (htmlRoot && theme) { |
||||||
|
htmlRoot.setAttribute('data-theme', theme); |
||||||
|
theme = htmlRoot = null; |
||||||
|
} |
||||||
|
})(); |
||||||
|
</script> |
||||||
|
<div id="app"> |
||||||
|
<style> |
||||||
|
html[data-theme='dark'] .app-loading { |
||||||
|
background-color: #2c344a; |
||||||
|
} |
||||||
|
|
||||||
|
html[data-theme='dark'] .app-loading .app-loading-title { |
||||||
|
color: rgb(255 255 255 / 85%); |
||||||
|
} |
||||||
|
|
||||||
|
.app-loading { |
||||||
|
display: flex; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
background-color: #f4f7f9; |
||||||
|
} |
||||||
|
|
||||||
|
.app-loading .app-loading-wrap { |
||||||
|
position: absolute; |
||||||
|
top: 50%; |
||||||
|
left: 50%; |
||||||
|
display: flex; |
||||||
|
transform: translate3d(-50%, -50%, 0); |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
flex-direction: column; |
||||||
|
} |
||||||
|
|
||||||
|
.app-loading .dots { |
||||||
|
display: flex; |
||||||
|
padding: 98px; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.app-loading .app-loading-title { |
||||||
|
display: flex; |
||||||
|
margin-top: 30px; |
||||||
|
font-size: 30px; |
||||||
|
color: rgb(0 0 0 / 85%); |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.app-loading .app-loading-logo { |
||||||
|
display: block; |
||||||
|
width: 90px; |
||||||
|
margin: 0 auto 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.dot { |
||||||
|
position: relative; |
||||||
|
display: inline-block; |
||||||
|
width: 48px; |
||||||
|
height: 48px; |
||||||
|
margin-top: 30px; |
||||||
|
font-size: 32px; |
||||||
|
transform: rotate(45deg); |
||||||
|
box-sizing: border-box; |
||||||
|
animation: antRotate 1.2s infinite linear; |
||||||
|
} |
||||||
|
|
||||||
|
.dot i { |
||||||
|
position: absolute; |
||||||
|
display: block; |
||||||
|
width: 20px; |
||||||
|
height: 20px; |
||||||
|
background-color: #0065cc; |
||||||
|
border-radius: 100%; |
||||||
|
opacity: 30%; |
||||||
|
transform: scale(0.75); |
||||||
|
animation: antSpinMove 1s infinite linear alternate; |
||||||
|
transform-origin: 50% 50%; |
||||||
|
} |
||||||
|
|
||||||
|
.dot i:nth-child(1) { |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.dot i:nth-child(2) { |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
animation-delay: 0.4s; |
||||||
|
} |
||||||
|
|
||||||
|
.dot i:nth-child(3) { |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
animation-delay: 0.8s; |
||||||
|
} |
||||||
|
|
||||||
|
.dot i:nth-child(4) { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
animation-delay: 1.2s; |
||||||
|
} |
||||||
|
@keyframes antRotate { |
||||||
|
to { |
||||||
|
transform: rotate(405deg); |
||||||
|
} |
||||||
|
} |
||||||
|
@keyframes antRotate { |
||||||
|
to { |
||||||
|
transform: rotate(405deg); |
||||||
|
} |
||||||
|
} |
||||||
|
@keyframes antSpinMove { |
||||||
|
to { |
||||||
|
opacity: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
@keyframes antSpinMove { |
||||||
|
to { |
||||||
|
opacity: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
<div class="app-loading"> |
||||||
|
<div class="app-loading-wrap"> |
||||||
|
<img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" /> |
||||||
|
<div class="app-loading-dots"> |
||||||
|
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> |
||||||
|
</div> |
||||||
|
<div class="app-loading-title"><%= title %></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<script type="module" src="/src/main.ts"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,34 @@ |
|||||||
|
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer' |
||||||
|
|
||||||
|
// 问题描述
|
||||||
|
// 1. `import.meta.globEager` 已被弃用, 需要升级vite版本,有兼容问题
|
||||||
|
// 2. `vite-plugin-mock` 插件问题 https://github.com/vbenjs/vite-plugin-mock/issues/56
|
||||||
|
|
||||||
|
// const modules: Record<string, any> = import.meta.glob("./**/*.ts", {
|
||||||
|
// import: "default",
|
||||||
|
// eager: true,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const mockModules = Object.keys(modules).reduce((pre, key) => {
|
||||||
|
// if (!key.includes("/_")) {
|
||||||
|
// pre.push(...(modules as Recordable)[key]);
|
||||||
|
// }
|
||||||
|
// return pre;
|
||||||
|
// }, [] as any[]);
|
||||||
|
|
||||||
|
const modules = import.meta.globEager('./**/*.ts') |
||||||
|
|
||||||
|
const mockModules: any[] = [] |
||||||
|
Object.keys(modules).forEach((key) => { |
||||||
|
if (key.includes('/_')) { |
||||||
|
return |
||||||
|
} |
||||||
|
mockModules.push(...(modules as Recordable)[key].default) |
||||||
|
}) |
||||||
|
|
||||||
|
/** |
||||||
|
* Used in a production environment. Need to manually import all modules
|
||||||
|
*/ |
||||||
|
export function setupProdMockServer() { |
||||||
|
createProdMockServer(mockModules) |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
// Interface data format used to return a unified format
|
||||||
|
import { ResultEnum } from '@/enums/httpEnum' |
||||||
|
|
||||||
|
export function resultSuccess<T = Recordable>(result: T, { message = 'ok' } = {}) { |
||||||
|
return { |
||||||
|
code: ResultEnum.SUCCESS, |
||||||
|
result, |
||||||
|
message, |
||||||
|
type: 'success' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function resultPageSuccess<T = any>(page: number, pageSize: number, list: T[], { message = 'ok' } = {}) { |
||||||
|
const pageData = pagination(page, pageSize, list) |
||||||
|
|
||||||
|
return { |
||||||
|
...resultSuccess({ |
||||||
|
items: pageData, |
||||||
|
total: list.length |
||||||
|
}), |
||||||
|
message |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function resultError(message = 'Request failed', { code = ResultEnum.ERROR, result = null } = {}) { |
||||||
|
return { |
||||||
|
code, |
||||||
|
result, |
||||||
|
message, |
||||||
|
type: 'error' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function pagination<T = any>(pageNo: number, pageSize: number, array: T[]): T[] { |
||||||
|
const offset = (pageNo - 1) * Number(pageSize) |
||||||
|
return offset + Number(pageSize) >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + Number(pageSize)) |
||||||
|
} |
||||||
|
|
||||||
|
export interface requestParams { |
||||||
|
method: string |
||||||
|
body: any |
||||||
|
headers?: { authorization?: string } |
||||||
|
query: any |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description 本函数用于从request数据中获取token,请根据项目的实际情况修改 |
||||||
|
* |
||||||
|
*/ |
||||||
|
export function getRequestToken({ headers }: requestParams): string | undefined { |
||||||
|
return headers?.authorization |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultSuccess, resultError } from '../_util' |
||||||
|
import { ResultEnum } from '../../src/enums/httpEnum' |
||||||
|
|
||||||
|
const userInfo = { |
||||||
|
name: 'Vben', |
||||||
|
userid: '00000001', |
||||||
|
email: 'test@gmail.com', |
||||||
|
signature: '海纳百川,有容乃大', |
||||||
|
introduction: '微笑着,努力着,欣赏着', |
||||||
|
title: '交互专家', |
||||||
|
group: '某某某事业群-某某平台部-某某技术部-UED', |
||||||
|
tags: [ |
||||||
|
{ |
||||||
|
key: '0', |
||||||
|
label: '很有想法的' |
||||||
|
}, |
||||||
|
{ |
||||||
|
key: '1', |
||||||
|
label: '专注设计' |
||||||
|
}, |
||||||
|
{ |
||||||
|
key: '2', |
||||||
|
label: '辣~' |
||||||
|
}, |
||||||
|
{ |
||||||
|
key: '3', |
||||||
|
label: '大长腿' |
||||||
|
}, |
||||||
|
{ |
||||||
|
key: '4', |
||||||
|
label: '川妹子' |
||||||
|
}, |
||||||
|
{ |
||||||
|
key: '5', |
||||||
|
label: '海纳百川' |
||||||
|
} |
||||||
|
], |
||||||
|
notifyCount: 12, |
||||||
|
unreadCount: 11, |
||||||
|
country: 'China', |
||||||
|
address: 'Xiamen City 77', |
||||||
|
phone: '0592-268888888' |
||||||
|
} |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/account/getAccountInfo', |
||||||
|
timeout: 1000, |
||||||
|
method: 'get', |
||||||
|
response: () => { |
||||||
|
return resultSuccess(userInfo) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/user/sessionTimeout', |
||||||
|
method: 'post', |
||||||
|
statusCode: 401, |
||||||
|
response: () => { |
||||||
|
return resultError() |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/user/tokenExpired', |
||||||
|
method: 'post', |
||||||
|
statusCode: 200, |
||||||
|
response: () => { |
||||||
|
return resultError('Token Expired!', { code: ResultEnum.TIMEOUT as number }) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,325 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultSuccess } from '../_util' |
||||||
|
|
||||||
|
const areaList: any[] = [ |
||||||
|
{ |
||||||
|
id: '530825900854620160', |
||||||
|
code: '430000', |
||||||
|
parentCode: '100000', |
||||||
|
levelType: 1, |
||||||
|
name: '湖南省', |
||||||
|
province: '湖南省', |
||||||
|
city: null, |
||||||
|
district: null, |
||||||
|
town: null, |
||||||
|
village: null, |
||||||
|
parentPath: '430000', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 16:33:42', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530825900883980288', |
||||||
|
code: '430100', |
||||||
|
parentCode: '430000', |
||||||
|
levelType: 2, |
||||||
|
name: '长沙市', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: null, |
||||||
|
town: null, |
||||||
|
village: null, |
||||||
|
parentPath: '430000,430100', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 16:33:42', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530825900951089152', |
||||||
|
code: '430102', |
||||||
|
parentCode: '430100', |
||||||
|
levelType: 3, |
||||||
|
name: '芙蓉区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '芙蓉区', |
||||||
|
town: null, |
||||||
|
village: null, |
||||||
|
parentPath: '430000,430100,430102', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 16:33:42', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530825901014003712', |
||||||
|
code: '430104', |
||||||
|
parentCode: '430100', |
||||||
|
levelType: 3, |
||||||
|
name: '岳麓区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '岳麓区', |
||||||
|
town: null, |
||||||
|
village: null, |
||||||
|
parentPath: '430000,430100,430104', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 16:33:42', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530825900988837888', |
||||||
|
code: '430103', |
||||||
|
parentCode: '430100', |
||||||
|
levelType: 3, |
||||||
|
name: '天心区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: null, |
||||||
|
village: null, |
||||||
|
parentPath: '430000,430100,430103', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 16:33:42', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530826672489115648', |
||||||
|
code: '430103002', |
||||||
|
parentCode: '430103', |
||||||
|
levelType: 4, |
||||||
|
name: '坡子街街道', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: null, |
||||||
|
parentPath: '430000,430100,430103,430103002', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-12-14 15:26:43', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241171607552', |
||||||
|
code: '430103002001', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '八角亭社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '八角亭社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002001', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2021-01-20 14:07:23', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241200967680', |
||||||
|
code: '430103002002', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '西牌楼社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '西牌楼社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002002', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241230327808', |
||||||
|
code: '430103002003', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '太平街社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '太平街社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002003', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241259687936', |
||||||
|
code: '430103002005', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '坡子街社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '坡子街社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002005', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241284853760', |
||||||
|
code: '430103002006', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '青山祠社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '青山祠社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002006', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241310019584', |
||||||
|
code: '430103002007', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '沙河社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '沙河社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002007', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241381322752', |
||||||
|
code: '430103002008', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '碧湘社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '碧湘社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002008', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241410682880', |
||||||
|
code: '430103002009', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '创远社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '创远社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002009', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241431654400', |
||||||
|
code: '430103002010', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '楚湘社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '楚湘社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002010', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241465208832', |
||||||
|
code: '430103002011', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '西湖社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '西湖社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002011', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241502957568', |
||||||
|
code: '430103002012', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '登仁桥社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '登仁桥社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002012', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: '530840241553289216', |
||||||
|
code: '430103002013', |
||||||
|
parentCode: '430103002', |
||||||
|
levelType: 5, |
||||||
|
name: '文庙坪社区', |
||||||
|
province: '湖南省', |
||||||
|
city: '长沙市', |
||||||
|
district: '天心区', |
||||||
|
town: '坡子街街道', |
||||||
|
village: '文庙坪社区', |
||||||
|
parentPath: '430000,430100,430103,430103002,430103002013', |
||||||
|
createTime: '2020-11-30 15:47:31', |
||||||
|
updateTime: '2020-11-30 17:30:41', |
||||||
|
customized: false, |
||||||
|
usable: true |
||||||
|
} |
||||||
|
] |
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/cascader/getAreaRecord', |
||||||
|
timeout: 1000, |
||||||
|
method: 'post', |
||||||
|
response: ({ body }) => { |
||||||
|
const { parentCode } = body || {} |
||||||
|
if (!parentCode) { |
||||||
|
return resultSuccess(areaList.filter((it) => it.code === '430000')) |
||||||
|
} |
||||||
|
return resultSuccess(areaList.filter((it) => it.parentCode === parentCode)) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,28 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultSuccess } from '../_util' |
||||||
|
|
||||||
|
const demoList = (keyword, count = 20) => { |
||||||
|
const result = { |
||||||
|
list: [] as any[] |
||||||
|
} |
||||||
|
for (let index = 0; index < count; index++) { |
||||||
|
result.list.push({ |
||||||
|
name: `${keyword ?? ''}选项${index}`, |
||||||
|
id: `${index}` |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
} |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/select/getDemoOptions', |
||||||
|
timeout: 1000, |
||||||
|
method: 'get', |
||||||
|
response: ({ query }) => { |
||||||
|
const { keyword, count } = query |
||||||
|
console.log(keyword) |
||||||
|
return resultSuccess(demoList(keyword, count)) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,194 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultError, resultPageSuccess, resultSuccess } from '../_util' |
||||||
|
|
||||||
|
const accountList = (() => { |
||||||
|
const result: any[] = [] |
||||||
|
for (let index = 0; index < 20; index++) { |
||||||
|
result.push({ |
||||||
|
id: `${index}`, |
||||||
|
account: '@first', |
||||||
|
email: '@email', |
||||||
|
nickname: '@cname()', |
||||||
|
role: '@first', |
||||||
|
createTime: '@datetime', |
||||||
|
remark: '@cword(10,20)', |
||||||
|
'status|1': ['0', '1'] |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
})() |
||||||
|
|
||||||
|
const roleList = (() => { |
||||||
|
const result: any[] = [] |
||||||
|
for (let index = 0; index < 4; index++) { |
||||||
|
result.push({ |
||||||
|
id: index + 1, |
||||||
|
orderNo: `${index + 1}`, |
||||||
|
roleName: ['超级管理员', '管理员', '文章管理员', '普通用户'][index], |
||||||
|
roleValue: '@first', |
||||||
|
createTime: '@datetime', |
||||||
|
remark: '@cword(10,20)', |
||||||
|
menu: [['0', '1', '2'], ['0', '1'], ['0', '2'], ['2']][index], |
||||||
|
'status|1': ['0', '1'] |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
})() |
||||||
|
|
||||||
|
const deptList = (() => { |
||||||
|
const result: any[] = [] |
||||||
|
for (let index = 0; index < 3; index++) { |
||||||
|
result.push({ |
||||||
|
id: `${index}`, |
||||||
|
deptName: ['华东分部', '华南分部', '西北分部'][index], |
||||||
|
orderNo: index + 1, |
||||||
|
createTime: '@datetime', |
||||||
|
remark: '@cword(10,20)', |
||||||
|
'status|1': ['0', '0', '1'], |
||||||
|
children: (() => { |
||||||
|
const children: any[] = [] |
||||||
|
for (let j = 0; j < 4; j++) { |
||||||
|
children.push({ |
||||||
|
id: `${index}-${j}`, |
||||||
|
deptName: ['研发部', '市场部', '商务部', '财务部'][j], |
||||||
|
orderNo: j + 1, |
||||||
|
createTime: '@datetime', |
||||||
|
remark: '@cword(10,20)', |
||||||
|
'status|1': ['0', '1'], |
||||||
|
parentDept: `${index}`, |
||||||
|
children: undefined |
||||||
|
}) |
||||||
|
} |
||||||
|
return children |
||||||
|
})() |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
})() |
||||||
|
|
||||||
|
const menuList = (() => { |
||||||
|
const result: any[] = [] |
||||||
|
for (let index = 0; index < 3; index++) { |
||||||
|
result.push({ |
||||||
|
id: `${index}`, |
||||||
|
icon: ['ion:layers-outline', 'ion:git-compare-outline', 'ion:tv-outline'][index], |
||||||
|
component: 'LAYOUT', |
||||||
|
type: '0', |
||||||
|
menuName: ['Dashboard', '权限管理', '功能'][index], |
||||||
|
permission: '', |
||||||
|
orderNo: index + 1, |
||||||
|
createTime: '@datetime', |
||||||
|
'status|1': ['0', '0', '1'], |
||||||
|
children: (() => { |
||||||
|
const children: any[] = [] |
||||||
|
for (let j = 0; j < 4; j++) { |
||||||
|
children.push({ |
||||||
|
id: `${index}-${j}`, |
||||||
|
type: '1', |
||||||
|
menuName: ['菜单1', '菜单2', '菜单3', '菜单4'][j], |
||||||
|
icon: 'ion:document', |
||||||
|
permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index], |
||||||
|
component: ['/dashboard/welcome/index', '/dashboard/analysis/index', '/dashboard/workbench/index', '/dashboard/test/index'][j], |
||||||
|
orderNo: j + 1, |
||||||
|
createTime: '@datetime', |
||||||
|
'status|1': ['0', '1'], |
||||||
|
parentMenu: `${index}`, |
||||||
|
children: (() => { |
||||||
|
const children: any[] = [] |
||||||
|
for (let k = 0; k < 4; k++) { |
||||||
|
children.push({ |
||||||
|
id: `${index}-${j}-${k}`, |
||||||
|
type: '2', |
||||||
|
menuName: '按钮' + (j + 1) + '-' + (k + 1), |
||||||
|
icon: '', |
||||||
|
permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index] + ':btn' + (k + 1), |
||||||
|
component: [ |
||||||
|
'/dashboard/welcome/index', |
||||||
|
'/dashboard/analysis/index', |
||||||
|
'/dashboard/workbench/index', |
||||||
|
'/dashboard/test/index' |
||||||
|
][j], |
||||||
|
orderNo: j + 1, |
||||||
|
createTime: '@datetime', |
||||||
|
'status|1': ['0', '1'], |
||||||
|
parentMenu: `${index}-${j}`, |
||||||
|
children: undefined |
||||||
|
}) |
||||||
|
} |
||||||
|
return children |
||||||
|
})() |
||||||
|
}) |
||||||
|
} |
||||||
|
return children |
||||||
|
})() |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
})() |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/system/getAccountList', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: ({ query }) => { |
||||||
|
const { page = 1, pageSize = 20 } = query |
||||||
|
return resultPageSuccess(page, pageSize, accountList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/getRoleListByPage', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: ({ query }) => { |
||||||
|
const { page = 1, pageSize = 20 } = query |
||||||
|
return resultPageSuccess(page, pageSize, roleList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/setRoleStatus', |
||||||
|
timeout: 500, |
||||||
|
method: 'post', |
||||||
|
response: ({ query }) => { |
||||||
|
const { id, status } = query |
||||||
|
return resultSuccess({ id, status }) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/getAllRoleList', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: () => { |
||||||
|
return resultSuccess(roleList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/getDeptList', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: () => { |
||||||
|
return resultSuccess(deptList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/getMenuList', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: () => { |
||||||
|
return resultSuccess(menuList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/system/accountExist', |
||||||
|
timeout: 500, |
||||||
|
method: 'post', |
||||||
|
response: ({ body }) => { |
||||||
|
const { account } = body || {} |
||||||
|
if (account && account.indexOf('admin') !== -1) { |
||||||
|
return resultError('该字段不能包含admin') |
||||||
|
} else { |
||||||
|
return resultSuccess(`${account} can use`) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,55 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { Random } from 'mockjs' |
||||||
|
import { resultPageSuccess } from '../_util' |
||||||
|
|
||||||
|
function getRandomPics(count = 10): string[] { |
||||||
|
const arr: string[] = [] |
||||||
|
for (let i = 0; i < count; i++) { |
||||||
|
arr.push(Random.image('800x600', Random.color(), Random.color(), Random.title())) |
||||||
|
} |
||||||
|
return arr |
||||||
|
} |
||||||
|
|
||||||
|
const demoList = (() => { |
||||||
|
const result: any[] = [] |
||||||
|
for (let index = 0; index < 200; index++) { |
||||||
|
result.push({ |
||||||
|
id: `${index}`, |
||||||
|
beginTime: '@datetime', |
||||||
|
endTime: '@datetime', |
||||||
|
address: '@city()', |
||||||
|
name: '@cname()', |
||||||
|
name1: '@cname()', |
||||||
|
name2: '@cname()', |
||||||
|
name3: '@cname()', |
||||||
|
name4: '@cname()', |
||||||
|
name5: '@cname()', |
||||||
|
name6: '@cname()', |
||||||
|
name7: '@cname()', |
||||||
|
name8: '@cname()', |
||||||
|
radio1: `选项${index + 1}`, |
||||||
|
radio2: `选项${index + 1}`, |
||||||
|
radio3: `选项${index + 1}`, |
||||||
|
avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()), |
||||||
|
imgArr: getRandomPics(Math.ceil(Math.random() * 3) + 1), |
||||||
|
imgs: getRandomPics(Math.ceil(Math.random() * 3) + 1), |
||||||
|
date: `@date('yyyy-MM-dd')`, |
||||||
|
time: `@time('HH:mm')`, |
||||||
|
'no|100000-10000000': 100000, |
||||||
|
'status|1': ['normal', 'enable', 'disable'] |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
})() |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/table/getDemoList', |
||||||
|
timeout: 100, |
||||||
|
method: 'get', |
||||||
|
response: ({ query }) => { |
||||||
|
const { page = 1, pageSize = 20 } = query |
||||||
|
return resultPageSuccess(page, pageSize, demoList) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,38 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultSuccess } from '../_util' |
||||||
|
|
||||||
|
const demoTreeList = (keyword) => { |
||||||
|
const result = { |
||||||
|
list: [] as Recordable[] |
||||||
|
} |
||||||
|
for (let index = 0; index < 5; index++) { |
||||||
|
const children: Recordable[] = [] |
||||||
|
for (let j = 0; j < 3; j++) { |
||||||
|
children.push({ |
||||||
|
title: `${keyword ?? ''}选项${index}-${j}`, |
||||||
|
value: `${index}-${j}`, |
||||||
|
key: `${index}-${j}` |
||||||
|
}) |
||||||
|
} |
||||||
|
result.list.push({ |
||||||
|
title: `${keyword ?? ''}选项${index}`, |
||||||
|
value: `${index}`, |
||||||
|
key: `${index}`, |
||||||
|
children |
||||||
|
}) |
||||||
|
} |
||||||
|
return result |
||||||
|
} |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/tree/getDemoOptions', |
||||||
|
timeout: 1000, |
||||||
|
method: 'get', |
||||||
|
response: ({ query }) => { |
||||||
|
const { keyword } = query |
||||||
|
console.log(keyword) |
||||||
|
return resultSuccess(demoTreeList(keyword)) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,270 @@ |
|||||||
|
import { resultSuccess, resultError, getRequestToken, requestParams } from '../_util' |
||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { createFakeUserList } from './user' |
||||||
|
|
||||||
|
// single
|
||||||
|
const dashboardRoute = { |
||||||
|
path: '/dashboard', |
||||||
|
name: 'Dashboard', |
||||||
|
component: 'LAYOUT', |
||||||
|
redirect: '/dashboard/analysis', |
||||||
|
meta: { |
||||||
|
title: 'routes.dashboard.dashboard', |
||||||
|
hideChildrenInMenu: true, |
||||||
|
icon: 'bx:bx-home' |
||||||
|
}, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'analysis', |
||||||
|
name: 'Analysis', |
||||||
|
component: '/dashboard/analysis/index', |
||||||
|
meta: { |
||||||
|
hideMenu: true, |
||||||
|
hideBreadcrumb: true, |
||||||
|
title: 'routes.dashboard.analysis', |
||||||
|
currentActiveMenu: '/dashboard', |
||||||
|
icon: 'bx:bx-home' |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'workbench', |
||||||
|
name: 'Workbench', |
||||||
|
component: '/dashboard/workbench/index', |
||||||
|
meta: { |
||||||
|
hideMenu: true, |
||||||
|
hideBreadcrumb: true, |
||||||
|
title: 'routes.dashboard.workbench', |
||||||
|
currentActiveMenu: '/dashboard', |
||||||
|
icon: 'bx:bx-home' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const backRoute = { |
||||||
|
path: 'back', |
||||||
|
name: 'PermissionBackDemo', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.permission.back' |
||||||
|
}, |
||||||
|
|
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'page', |
||||||
|
name: 'BackAuthPage', |
||||||
|
component: '/demo/permission/back/index', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.permission.backPage' |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'btn', |
||||||
|
name: 'BackAuthBtn', |
||||||
|
component: '/demo/permission/back/Btn', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.permission.backBtn' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const authRoute = { |
||||||
|
path: '/permission', |
||||||
|
name: 'Permission', |
||||||
|
component: 'LAYOUT', |
||||||
|
redirect: '/permission/front/page', |
||||||
|
meta: { |
||||||
|
icon: 'carbon:user-role', |
||||||
|
title: 'routes.demo.permission.permission' |
||||||
|
}, |
||||||
|
children: [backRoute] |
||||||
|
} |
||||||
|
|
||||||
|
const levelRoute = { |
||||||
|
path: '/level', |
||||||
|
name: 'Level', |
||||||
|
component: 'LAYOUT', |
||||||
|
redirect: '/level/menu1/menu1-1', |
||||||
|
meta: { |
||||||
|
icon: 'carbon:user-role', |
||||||
|
title: 'routes.demo.level.level' |
||||||
|
}, |
||||||
|
|
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'menu1', |
||||||
|
name: 'Menu1Demo', |
||||||
|
meta: { |
||||||
|
title: 'Menu1' |
||||||
|
}, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'menu1-1', |
||||||
|
name: 'Menu11Demo', |
||||||
|
meta: { |
||||||
|
title: 'Menu1-1' |
||||||
|
}, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'menu1-1-1', |
||||||
|
name: 'Menu111Demo', |
||||||
|
component: '/demo/level/Menu111', |
||||||
|
meta: { |
||||||
|
title: 'Menu111' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'menu1-2', |
||||||
|
name: 'Menu12Demo', |
||||||
|
component: '/demo/level/Menu12', |
||||||
|
meta: { |
||||||
|
title: 'Menu1-2' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'menu2', |
||||||
|
name: 'Menu2Demo', |
||||||
|
component: '/demo/level/Menu2', |
||||||
|
meta: { |
||||||
|
title: 'Menu2' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const sysRoute = { |
||||||
|
path: '/system', |
||||||
|
name: 'System', |
||||||
|
component: 'LAYOUT', |
||||||
|
redirect: '/system/account', |
||||||
|
meta: { |
||||||
|
icon: 'ion:settings-outline', |
||||||
|
title: 'routes.demo.system.moduleName' |
||||||
|
}, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'account', |
||||||
|
name: 'AccountManagement', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.system.account', |
||||||
|
ignoreKeepAlive: true |
||||||
|
}, |
||||||
|
component: '/demo/system/account/index' |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'account_detail/:id', |
||||||
|
name: 'AccountDetail', |
||||||
|
meta: { |
||||||
|
hideMenu: true, |
||||||
|
title: 'routes.demo.system.account_detail', |
||||||
|
ignoreKeepAlive: true, |
||||||
|
showMenu: false, |
||||||
|
currentActiveMenu: '/system/account' |
||||||
|
}, |
||||||
|
component: '/demo/system/account/AccountDetail' |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'role', |
||||||
|
name: 'RoleManagement', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.system.role', |
||||||
|
ignoreKeepAlive: true |
||||||
|
}, |
||||||
|
component: '/demo/system/role/index' |
||||||
|
}, |
||||||
|
|
||||||
|
{ |
||||||
|
path: 'menu', |
||||||
|
name: 'MenuManagement', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.system.menu', |
||||||
|
ignoreKeepAlive: true |
||||||
|
}, |
||||||
|
component: '/demo/system/menu/index' |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'dept', |
||||||
|
name: 'DeptManagement', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.system.dept', |
||||||
|
ignoreKeepAlive: true |
||||||
|
}, |
||||||
|
component: '/demo/system/dept/index' |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'changePassword', |
||||||
|
name: 'ChangePassword', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.system.password', |
||||||
|
ignoreKeepAlive: true |
||||||
|
}, |
||||||
|
component: '/demo/system/password/index' |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const linkRoute = { |
||||||
|
path: '/link', |
||||||
|
name: 'Link', |
||||||
|
component: 'LAYOUT', |
||||||
|
meta: { |
||||||
|
icon: 'ion:tv-outline', |
||||||
|
title: 'routes.demo.iframe.frame' |
||||||
|
}, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: 'doc', |
||||||
|
name: 'Doc', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.iframe.doc', |
||||||
|
frameSrc: 'https://doc.vvbin.cn/' |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: 'https://doc.vvbin.cn/', |
||||||
|
name: 'DocExternal', |
||||||
|
component: 'LAYOUT', |
||||||
|
meta: { |
||||||
|
title: 'routes.demo.iframe.docExternal' |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
export default [ |
||||||
|
{ |
||||||
|
url: '/basic-api/getMenuList', |
||||||
|
timeout: 1000, |
||||||
|
method: 'get', |
||||||
|
response: (request: requestParams) => { |
||||||
|
const token = getRequestToken(request) |
||||||
|
if (!token) { |
||||||
|
return resultError('Invalid token!') |
||||||
|
} |
||||||
|
const checkUser = createFakeUserList().find((item) => item.token === token) |
||||||
|
if (!checkUser) { |
||||||
|
return resultError('Invalid user token!') |
||||||
|
} |
||||||
|
const id = checkUser.userId |
||||||
|
let menu: Object[] |
||||||
|
switch (id) { |
||||||
|
case '1': |
||||||
|
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[0].path |
||||||
|
menu = [dashboardRoute, authRoute, levelRoute, sysRoute, linkRoute] |
||||||
|
break |
||||||
|
case '2': |
||||||
|
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[1].path |
||||||
|
menu = [dashboardRoute, authRoute, levelRoute, linkRoute] |
||||||
|
break |
||||||
|
default: |
||||||
|
menu = [] |
||||||
|
} |
||||||
|
|
||||||
|
return resultSuccess(menu) |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,120 @@ |
|||||||
|
import { MockMethod } from 'vite-plugin-mock' |
||||||
|
import { resultError, resultSuccess, getRequestToken, requestParams } from '../_util' |
||||||
|
|
||||||
|
export function createFakeUserList() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
userId: '1', |
||||||
|
username: 'vben', |
||||||
|
realName: 'Vben Admin', |
||||||
|
avatar: '', |
||||||
|
desc: 'manager', |
||||||
|
password: '123456', |
||||||
|
token: 'fakeToken1', |
||||||
|
homePath: '/dashboard/analysis', |
||||||
|
roles: [ |
||||||
|
{ |
||||||
|
roleName: 'Super Admin', |
||||||
|
value: 'super' |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
userId: '2', |
||||||
|
username: 'test', |
||||||
|
password: '123456', |
||||||
|
realName: 'test user', |
||||||
|
avatar: '', |
||||||
|
desc: 'tester', |
||||||
|
token: 'fakeToken2', |
||||||
|
homePath: '/dashboard/workbench', |
||||||
|
roles: [ |
||||||
|
{ |
||||||
|
roleName: 'Tester', |
||||||
|
value: 'test' |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
const fakeCodeList: any = { |
||||||
|
'1': ['1000', '3000', '5000'], |
||||||
|
|
||||||
|
'2': ['2000', '4000', '6000'] |
||||||
|
} |
||||||
|
export default [ |
||||||
|
// mock user login
|
||||||
|
{ |
||||||
|
url: '/basic-api/login', |
||||||
|
timeout: 200, |
||||||
|
method: 'post', |
||||||
|
response: ({ body }) => { |
||||||
|
const { username, password } = body |
||||||
|
const checkUser = createFakeUserList().find((item) => item.username === username && password === item.password) |
||||||
|
if (!checkUser) { |
||||||
|
return resultError('Incorrect account or password!') |
||||||
|
} |
||||||
|
const { userId, username: _username, token, realName, desc, roles } = checkUser |
||||||
|
return resultSuccess({ |
||||||
|
roles, |
||||||
|
userId, |
||||||
|
username: _username, |
||||||
|
token, |
||||||
|
realName, |
||||||
|
desc |
||||||
|
}) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/getUserInfo', |
||||||
|
method: 'get', |
||||||
|
response: (request: requestParams) => { |
||||||
|
const token = getRequestToken(request) |
||||||
|
if (!token) return resultError('Invalid token') |
||||||
|
const checkUser = createFakeUserList().find((item) => item.token === token) |
||||||
|
if (!checkUser) { |
||||||
|
return resultError('The corresponding user information was not obtained!') |
||||||
|
} |
||||||
|
return resultSuccess(checkUser) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/getPermCode', |
||||||
|
timeout: 200, |
||||||
|
method: 'get', |
||||||
|
response: (request: requestParams) => { |
||||||
|
const token = getRequestToken(request) |
||||||
|
if (!token) return resultError('Invalid token') |
||||||
|
const checkUser = createFakeUserList().find((item) => item.token === token) |
||||||
|
if (!checkUser) { |
||||||
|
return resultError('Invalid token!') |
||||||
|
} |
||||||
|
const codeList = fakeCodeList[checkUser.userId] |
||||||
|
|
||||||
|
return resultSuccess(codeList) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/logout', |
||||||
|
timeout: 200, |
||||||
|
method: 'get', |
||||||
|
response: (request: requestParams) => { |
||||||
|
const token = getRequestToken(request) |
||||||
|
if (!token) return resultError('Invalid token') |
||||||
|
const checkUser = createFakeUserList().find((item) => item.token === token) |
||||||
|
if (!checkUser) { |
||||||
|
return resultError('Invalid token!') |
||||||
|
} |
||||||
|
return resultSuccess(undefined, { message: 'Token has been destroyed' }) |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
url: '/basic-api/testRetry', |
||||||
|
statusCode: 405, |
||||||
|
method: 'get', |
||||||
|
response: () => { |
||||||
|
return resultError('Error!') |
||||||
|
} |
||||||
|
} |
||||||
|
] as MockMethod[] |
@ -0,0 +1,189 @@ |
|||||||
|
{ |
||||||
|
"name": "vben-admin", |
||||||
|
"version": "1.0.2", |
||||||
|
"author": { |
||||||
|
"name": "xingyu4j", |
||||||
|
"email": "xingyu4j@vip.qq.com", |
||||||
|
"url": "https://gitee.com/xingyuv" |
||||||
|
}, |
||||||
|
"scripts": { |
||||||
|
"commit": "czg", |
||||||
|
"bootstrap": "pnpm install", |
||||||
|
"serve": "npm run dev", |
||||||
|
"dev": "vite", |
||||||
|
"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts", |
||||||
|
"build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts", |
||||||
|
"build:no-cache": "pnpm clean:cache && npm run build", |
||||||
|
"report": "cross-env REPORT=true npm run build", |
||||||
|
"type:check": "vue-tsc --noEmit --skipLibCheck", |
||||||
|
"preview": "npm run build && vite preview", |
||||||
|
"preview:dist": "vite preview", |
||||||
|
"log": "conventional-changelog -p angular -i CHANGELOG.md -s", |
||||||
|
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", |
||||||
|
"clean:lib": "rimraf node_modules", |
||||||
|
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", |
||||||
|
"lint:prettier": "prettier --write \"src/**/*.{js,json,ts,tsx,css,less,scss,vue,html,md}\"", |
||||||
|
"lint:style": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", |
||||||
|
"lint:lint-staged": "lint-staged", |
||||||
|
"test:unit": "jest", |
||||||
|
"test:gzip": "npx http-server dist --cors --gzip -c-1", |
||||||
|
"test:br": "npx http-server dist --cors --brotli -c-1", |
||||||
|
"npm:check": "npx npm-check-updates", |
||||||
|
"reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", |
||||||
|
"prepare": "husky install", |
||||||
|
"gen:icon": "esno ./build/generate/icon/index.ts" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"@ant-design/colors": "^7.0.0", |
||||||
|
"@ant-design/icons-vue": "^6.1.0", |
||||||
|
"@iconify/iconify": "^3.1.0", |
||||||
|
"@logicflow/core": "^1.2.1", |
||||||
|
"@logicflow/extension": "^1.2.1", |
||||||
|
"@vue/runtime-core": "^3.2.47", |
||||||
|
"@vueuse/core": "^9.13.0", |
||||||
|
"@zxcvbn-ts/core": "^2.2.1", |
||||||
|
"ant-design-vue": "^3.2.15", |
||||||
|
"axios": "^1.3.4", |
||||||
|
"codemirror": "^5.65.3", |
||||||
|
"cropperjs": "^1.5.13", |
||||||
|
"crypto-js": "^4.1.1", |
||||||
|
"dayjs": "^1.11.7", |
||||||
|
"echarts": "^5.4.1", |
||||||
|
"intro.js": "^6.0.0", |
||||||
|
"lodash-es": "^4.17.21", |
||||||
|
"mockjs": "^1.1.0", |
||||||
|
"nprogress": "^0.2.0", |
||||||
|
"path-to-regexp": "^6.2.1", |
||||||
|
"pinia": "^2.0.33", |
||||||
|
"print-js": "^1.6.0", |
||||||
|
"qrcode": "^1.5.1", |
||||||
|
"qs": "^6.11.1", |
||||||
|
"resize-observer-polyfill": "^1.5.1", |
||||||
|
"showdown": "^2.1.0", |
||||||
|
"sortablejs": "^1.15.0", |
||||||
|
"tinymce": "^5.10.7", |
||||||
|
"vditor": "^3.9.1", |
||||||
|
"vue": "^3.2.47", |
||||||
|
"vue-i18n": "^9.2.2", |
||||||
|
"vue-json-pretty": "^2.2.3", |
||||||
|
"vue-router": "^4.1.6", |
||||||
|
"vue-types": "^5.0.2", |
||||||
|
"xlsx": "^0.18.5" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@commitlint/cli": "^17.4.4", |
||||||
|
"@commitlint/config-conventional": "^17.4.4", |
||||||
|
"@iconify/json": "^2.2.36", |
||||||
|
"@kirklin/vite-plugin-vben-theme": "^0.1.1", |
||||||
|
"@purge-icons/generated": "^0.9.0", |
||||||
|
"@types/codemirror": "^5.60.5", |
||||||
|
"@types/crypto-js": "^4.1.1", |
||||||
|
"@types/fs-extra": "^11.0.1", |
||||||
|
"@types/inquirer": "^9.0.3", |
||||||
|
"@types/intro.js": "^5.1.1", |
||||||
|
"@types/lodash-es": "^4.17.7", |
||||||
|
"@types/mockjs": "^1.0.7", |
||||||
|
"@types/node": "^18.15.3", |
||||||
|
"@types/nprogress": "^0.2.0", |
||||||
|
"@types/qrcode": "^1.5.0", |
||||||
|
"@types/qs": "^6.9.7", |
||||||
|
"@types/showdown": "^2.0.0", |
||||||
|
"@types/sortablejs": "^1.15.1", |
||||||
|
"@typescript-eslint/eslint-plugin": "^5.55.0", |
||||||
|
"@typescript-eslint/parser": "^5.55.0", |
||||||
|
"@vitejs/plugin-legacy": "^4.0.2", |
||||||
|
"@vitejs/plugin-vue": "^4.1.0", |
||||||
|
"@vitejs/plugin-vue-jsx": "^3.0.1", |
||||||
|
"@vue/compiler-sfc": "^3.2.47", |
||||||
|
"@vue/test-utils": "^2.3.1", |
||||||
|
"autoprefixer": "^10.4.14", |
||||||
|
"conventional-changelog-cli": "^2.2.2", |
||||||
|
"cross-env": "^7.0.3", |
||||||
|
"cz-git": "^1.6.0", |
||||||
|
"czg": "^1.6.0", |
||||||
|
"dotenv": "^16.0.3", |
||||||
|
"eslint": "^8.36.0", |
||||||
|
"eslint-config-prettier": "^8.7.0", |
||||||
|
"eslint-plugin-prettier": "^4.2.1", |
||||||
|
"eslint-plugin-vue": "^9.9.0", |
||||||
|
"esno": "^0.16.3", |
||||||
|
"fs-extra": "^11.1.0", |
||||||
|
"husky": "^8.0.3", |
||||||
|
"inquirer": "^9.1.4", |
||||||
|
"less": "^4.1.3", |
||||||
|
"lint-staged": "^13.2.0", |
||||||
|
"npm-run-all": "^4.1.5", |
||||||
|
"picocolors": "^1.0.0", |
||||||
|
"postcss": "^8.4.21", |
||||||
|
"postcss-html": "^1.5.0", |
||||||
|
"postcss-less": "^6.0.0", |
||||||
|
"prettier": "^2.8.4", |
||||||
|
"rimraf": "^4.4.0", |
||||||
|
"rollup": "^3.19.1", |
||||||
|
"rollup-plugin-visualizer": "^5.9.0", |
||||||
|
"stylelint": "^14.16.1", |
||||||
|
"stylelint-config-prettier": "^9.0.5", |
||||||
|
"stylelint-config-recommended": "^9.0.0", |
||||||
|
"stylelint-config-recommended-vue": "^1.4.0", |
||||||
|
"stylelint-config-standard": "^29.0.0", |
||||||
|
"stylelint-order": "^6.0.2", |
||||||
|
"terser": "^5.16.6", |
||||||
|
"ts-node": "^10.9.1", |
||||||
|
"typescript": "^5.0.2", |
||||||
|
"unplugin-vue-setup-extend-plus": "^0.4.9", |
||||||
|
"vite": "^4.2.0", |
||||||
|
"vite-plugin-compression": "^0.5.1", |
||||||
|
"vite-plugin-html": "^3.2.0", |
||||||
|
"vite-plugin-mkcert": "^1.13.3", |
||||||
|
"vite-plugin-mock": "^2.9.6", |
||||||
|
"vite-plugin-progress": "^0.0.6", |
||||||
|
"vite-plugin-purge-icons": "^0.9.2", |
||||||
|
"vite-plugin-pwa": "^0.14.4", |
||||||
|
"vite-plugin-style-import": "^2.0.0", |
||||||
|
"vite-plugin-svg-icons": "^2.0.1", |
||||||
|
"vite-plugin-windicss": "^1.8.10", |
||||||
|
"vue-eslint-parser": "^9.1.0", |
||||||
|
"vue-tsc": "^1.2.0" |
||||||
|
}, |
||||||
|
"repository": { |
||||||
|
"type": "git", |
||||||
|
"url": "git+https://gitee.com/xingyuv/vue-vben-admin.git" |
||||||
|
}, |
||||||
|
"license": "MIT", |
||||||
|
"bugs": { |
||||||
|
"url": "https://gitee.com/xingyuv/issues" |
||||||
|
}, |
||||||
|
"homepage": "https://gitee.com/xingyuv", |
||||||
|
"engines": { |
||||||
|
"node": "> 16.18.0" |
||||||
|
}, |
||||||
|
"lint-staged": { |
||||||
|
"*.{js,jsx,ts,tsx}": [ |
||||||
|
"eslint --fix", |
||||||
|
"prettier --write" |
||||||
|
], |
||||||
|
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [ |
||||||
|
"prettier --write--parser json" |
||||||
|
], |
||||||
|
"package.json": [ |
||||||
|
"prettier --write" |
||||||
|
], |
||||||
|
"*.vue": [ |
||||||
|
"eslint --fix", |
||||||
|
"prettier --write", |
||||||
|
"stylelint --fix" |
||||||
|
], |
||||||
|
"*.{scss,less,styl,html}": [ |
||||||
|
"stylelint --fix", |
||||||
|
"prettier --write" |
||||||
|
], |
||||||
|
"*.md": [ |
||||||
|
"prettier --write" |
||||||
|
] |
||||||
|
}, |
||||||
|
"config": { |
||||||
|
"commitizen": { |
||||||
|
"path": "node_modules/cz-git" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
module.exports = { |
||||||
|
plugins: { |
||||||
|
autoprefixer: {} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
module.exports = { |
||||||
|
// 一行代码的最大字符数,默认是80
|
||||||
|
printWidth: 140, |
||||||
|
// tab宽度为2空格
|
||||||
|
tabWidth: 2, |
||||||
|
// 使用tab缩进,默认false
|
||||||
|
useTabs: false, |
||||||
|
// 结尾是否添加分号, 默认true
|
||||||
|
semi: false, |
||||||
|
// vue script和style标签中是否缩进,开启可能会破坏编辑器的代码折叠
|
||||||
|
vueIndentScriptAndStyle: false, |
||||||
|
// 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
|
||||||
|
singleQuote: true, |
||||||
|
// object对象中key值是否加引号 as-needed只有在需求要的情况下加引号,consistent是有一个需要引号就统一加,preserve是保留用户输入的引号
|
||||||
|
quoteProps: 'as-needed', |
||||||
|
// object对象里面的key和value值和括号间的空格
|
||||||
|
bracketSpacing: true, |
||||||
|
// 行尾逗号,默认none,可选 none|es5|all
|
||||||
|
// es5 包括es5中的数组、对象
|
||||||
|
// all 包括函数对象等所有可选
|
||||||
|
trailingComma: 'none', |
||||||
|
// 在jsx文件中的引号需要单独设置 默认false
|
||||||
|
jsxSingleQuote: false, |
||||||
|
// 箭头函数单个参数的情况是否省略括号,默认always是总是带括号
|
||||||
|
// avoid 能省略括号的时候就省略 例如x => x
|
||||||
|
// always 总是有括号
|
||||||
|
arrowParens: 'always', |
||||||
|
insertPragma: false, |
||||||
|
requirePragma: false, |
||||||
|
proseWrap: 'never', |
||||||
|
htmlWhitespaceSensitivity: 'strict', |
||||||
|
// endOfLine: "<lf|crlf|cr|auto>" 行尾换行符,默认是lf
|
||||||
|
endOfLine: 'auto', |
||||||
|
// range是format执行的范围,可以选执行一个文件的一部分,默认的设置是整个文件
|
||||||
|
rangeStart: 0, |
||||||
|
rangeEnd: Infinity |
||||||
|
} |
After Width: | Height: | Size: 894 B |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 51 KiB |
@ -0,0 +1,419 @@ |
|||||||
|
tinymce.addI18n('es', { |
||||||
|
Redo: 'Rehacer', |
||||||
|
Undo: 'Deshacer', |
||||||
|
Cut: 'Cortar', |
||||||
|
Copy: 'Copiar', |
||||||
|
Paste: 'Pegar', |
||||||
|
'Select all': 'Seleccionar todo', |
||||||
|
'New document': 'Nuevo documento', |
||||||
|
Ok: 'Ok', |
||||||
|
Cancel: 'Cancelar', |
||||||
|
'Visual aids': 'Ayudas visuales', |
||||||
|
Bold: 'Negrita', |
||||||
|
Italic: 'Cursiva', |
||||||
|
Underline: 'Subrayado', |
||||||
|
Strikethrough: 'Tachado', |
||||||
|
Superscript: 'Super\u00edndice', |
||||||
|
Subscript: 'Sub\u00edndice', |
||||||
|
'Clear formatting': 'Limpiar formato', |
||||||
|
'Align left': 'Alinear a la izquierda', |
||||||
|
'Align center': 'Alinear al centro', |
||||||
|
'Align right': 'Alinear a la derecha', |
||||||
|
Justify: 'Justificar', |
||||||
|
'Bullet list': 'Lista de vi\u00f1etas', |
||||||
|
'Numbered list': 'Lista numerada', |
||||||
|
'Decrease indent': 'Disminuir sangr\u00eda', |
||||||
|
'Increase indent': 'Incrementar sangr\u00eda', |
||||||
|
Close: 'Cerrar', |
||||||
|
Formats: 'Formatos', |
||||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": 'Su navegador no es compatible con el acceso directo al portapapeles. Use las teclas Crtl+X\/C\/V de su teclado.', |
||||||
|
Headers: 'Encabezados', |
||||||
|
'Header 1': 'Encabezado 1', |
||||||
|
'Header 2': 'Encabezado 2', |
||||||
|
'Header 3': 'Encabezado 3', |
||||||
|
'Header 4': 'Encabezado 4', |
||||||
|
'Header 5': 'Encabezado 5', |
||||||
|
'Header 6': 'Encabezado 6', |
||||||
|
Headings: 'Encabezados', |
||||||
|
'Heading 1': 'Encabezado 1', |
||||||
|
'Heading 2': 'Encabezado 2', |
||||||
|
'Heading 3': 'Encabezado 3', |
||||||
|
'Heading 4': 'Encabezado 4', |
||||||
|
'Heading 5': 'Encabezado 5', |
||||||
|
'Heading 6': 'Encabezado 6', |
||||||
|
Preformatted: 'Con formato previo', |
||||||
|
Div: 'Div', |
||||||
|
Pre: 'Pre', |
||||||
|
Code: 'C\u00f3digo', |
||||||
|
Paragraph: 'P\u00e1rrafo', |
||||||
|
Blockquote: 'Blockquote', |
||||||
|
Inline: 'Alineado', |
||||||
|
Blocks: 'Bloques', |
||||||
|
'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.': 'Pegar est\u00e1 ahora en modo de texto plano. El contenido se pegar\u00e1 como texto plano hasta que desactive esta opci\u00f3n.', |
||||||
|
Fonts: 'Fuentes', |
||||||
|
'Font Sizes': 'Tama\u00f1os de fuente', |
||||||
|
Class: 'Clase', |
||||||
|
'Browse for an image': 'Buscar una imagen', |
||||||
|
OR: 'OR', |
||||||
|
'Drop an image here': 'Arrastre una imagen aqu\u00ed', |
||||||
|
Upload: 'Cargar', |
||||||
|
Block: 'Bloque', |
||||||
|
Align: 'Alinear', |
||||||
|
Default: 'Por defecto', |
||||||
|
Circle: 'C\u00edrculo', |
||||||
|
Disc: 'Disco', |
||||||
|
Square: 'Cuadrado', |
||||||
|
'Lower Alpha': 'Inferior Alfa', |
||||||
|
'Lower Greek': 'Inferior Griega', |
||||||
|
'Lower Roman': 'Inferior Romana', |
||||||
|
'Upper Alpha': 'Superior Alfa', |
||||||
|
'Upper Roman': 'Superior Romana', |
||||||
|
'Anchor...': 'Anclaje...', |
||||||
|
Name: 'Nombre', |
||||||
|
Id: 'Id', |
||||||
|
'Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.': 'Deber\u00eda comenzar por una letra, seguida solo de letras, n\u00fameros, guiones, puntos, dos puntos o guiones bajos.', |
||||||
|
'You have unsaved changes are you sure you want to navigate away?': 'Tiene cambios sin guardar. \u00bfEst\u00e1 seguro de que quiere salir?', |
||||||
|
'Restore last draft': 'Restaurar el \u00faltimo borrador', |
||||||
|
'Special character...': 'Car\u00e1cter especial...', |
||||||
|
'Source code': 'C\u00f3digo fuente', |
||||||
|
'Insert\/Edit code sample': 'Insertar\/editar c\u00f3digo de prueba', |
||||||
|
Language: 'Idioma', |
||||||
|
'Code sample...': 'Ejemplo de c\u00f3digo...', |
||||||
|
'Color Picker': 'Selector de colores', |
||||||
|
R: 'R', |
||||||
|
G: 'V', |
||||||
|
B: 'A', |
||||||
|
'Left to right': 'De izquierda a derecha', |
||||||
|
'Right to left': 'De derecha a izquierda', |
||||||
|
'Emoticons...': 'Emoticones...', |
||||||
|
'Metadata and Document Properties': 'Metadatos y propiedades del documento', |
||||||
|
Title: 'T\u00edtulo', |
||||||
|
Keywords: 'Palabras clave', |
||||||
|
Description: 'Descripci\u00f3n', |
||||||
|
Robots: 'Robots', |
||||||
|
Author: 'Autor', |
||||||
|
Encoding: 'Codificaci\u00f3n', |
||||||
|
Fullscreen: 'Pantalla completa', |
||||||
|
Action: 'Acci\u00f3n', |
||||||
|
Shortcut: 'Atajo', |
||||||
|
Help: 'Ayuda', |
||||||
|
Address: 'Direcci\u00f3n', |
||||||
|
'Focus to menubar': 'Enfocar la barra del men\u00fa', |
||||||
|
'Focus to toolbar': 'Enfocar la barra de herramientas', |
||||||
|
'Focus to element path': 'Enfocar la ruta del elemento', |
||||||
|
'Focus to contextual toolbar': 'Enfocar la barra de herramientas contextual', |
||||||
|
'Insert link (if link plugin activated)': 'Insertar enlace (si el complemento de enlace est\u00e1 activado)', |
||||||
|
'Save (if save plugin activated)': 'Guardar (si el componente de salvar est\u00e1 activado)', |
||||||
|
'Find (if searchreplace plugin activated)': 'Buscar (si el complemento buscar-remplazar est\u00e1 activado)', |
||||||
|
'Plugins installed ({0}):': 'Plugins instalados ({0}):', |
||||||
|
'Premium plugins:': 'Complementos premium:', |
||||||
|
'Learn more...': 'Aprende m\u00e1s...', |
||||||
|
'You are using {0}': 'Estas usando {0}', |
||||||
|
Plugins: 'Complementos', |
||||||
|
'Handy Shortcuts': 'Accesos directos', |
||||||
|
'Horizontal line': 'L\u00ednea horizontal', |
||||||
|
'Insert\/edit image': 'Insertar\/editar imagen', |
||||||
|
'Image description': 'Descripci\u00f3n de la imagen', |
||||||
|
Source: 'Enlace', |
||||||
|
Dimensions: 'Dimensiones', |
||||||
|
'Constrain proportions': 'Restringir proporciones', |
||||||
|
General: 'General', |
||||||
|
Advanced: 'Avanzado', |
||||||
|
Style: 'Estilo', |
||||||
|
'Vertical space': 'Espacio vertical', |
||||||
|
'Horizontal space': 'Espacio horizontal', |
||||||
|
Border: 'Borde', |
||||||
|
'Insert image': 'Insertar imagen', |
||||||
|
'Image...': 'Imagen...', |
||||||
|
'Image list': 'Lista de im\u00e1genes', |
||||||
|
'Rotate counterclockwise': 'Girar a la izquierda', |
||||||
|
'Rotate clockwise': 'Girar a la derecha', |
||||||
|
'Flip vertically': 'Invertir verticalmente', |
||||||
|
'Flip horizontally': 'Invertir horizontalmente', |
||||||
|
'Edit image': 'Editar imagen', |
||||||
|
'Image options': 'Opciones de imagen', |
||||||
|
'Zoom in': 'Acercar', |
||||||
|
'Zoom out': 'Alejar', |
||||||
|
Crop: 'Recortar', |
||||||
|
Resize: 'Redimensionar', |
||||||
|
Orientation: 'Orientaci\u00f3n', |
||||||
|
Brightness: 'Brillo', |
||||||
|
Sharpen: 'Forma', |
||||||
|
Contrast: 'Contraste', |
||||||
|
'Color levels': 'Niveles de color', |
||||||
|
Gamma: 'Gamma', |
||||||
|
Invert: 'Invertir', |
||||||
|
Apply: 'Aplicar', |
||||||
|
Back: 'Atr\u00e1s', |
||||||
|
'Insert date\/time': 'Insertar fecha\/hora', |
||||||
|
'Date\/time': 'Fecha\/hora', |
||||||
|
'Insert\/Edit Link': 'Insertar\/editar enlace', |
||||||
|
'Insert\/edit link': 'Insertar\/editar enlace', |
||||||
|
'Text to display': 'Texto para mostrar', |
||||||
|
Url: 'URL', |
||||||
|
'Open link in...': 'Abrir enlace en...', |
||||||
|
'Current window': 'Ventana actual', |
||||||
|
None: 'Ninguno', |
||||||
|
'New window': 'Nueva ventana', |
||||||
|
'Remove link': 'Quitar enlace', |
||||||
|
Anchors: 'Anclas', |
||||||
|
'Link...': 'Enlace...', |
||||||
|
'Paste or type a link': 'Pega o introduce un enlace', |
||||||
|
'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?': 'El enlace que has introducido no parece ser una direcci\u00f3n de correo electr\u00f3nico. Quieres a\u00f1adir el prefijo necesario mailto: ?', |
||||||
|
'The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?': 'El enlace que has introducido no parece ser una enlace externo. Quieres a\u00f1adir el prefijo necesario http:\/\/ ?', |
||||||
|
'Link list': 'Lista de enlaces', |
||||||
|
'Insert video': 'Insertar video', |
||||||
|
'Insert\/edit video': 'Insertar\/editar video', |
||||||
|
'Insert\/edit media': 'Insertar\/editar medio', |
||||||
|
'Alternative source': 'Enlace alternativo', |
||||||
|
'Alternative source URL': 'Origen de URL alternativo', |
||||||
|
'Media poster (Image URL)': 'P\u00f3ster de medio (URL de imagen)', |
||||||
|
'Paste your embed code below:': 'Pega tu c\u00f3digo embebido debajo', |
||||||
|
Embed: 'Incrustado', |
||||||
|
'Media...': 'Medios...', |
||||||
|
'Nonbreaking space': 'Espacio fijo', |
||||||
|
'Page break': 'Salto de p\u00e1gina', |
||||||
|
'Paste as text': 'Pegar como texto', |
||||||
|
Preview: 'Previsualizar', |
||||||
|
'Print...': 'Imprimir...', |
||||||
|
Save: 'Guardar', |
||||||
|
Find: 'Buscar', |
||||||
|
'Replace with': 'Reemplazar con', |
||||||
|
Replace: 'Reemplazar', |
||||||
|
'Replace all': 'Reemplazar todo', |
||||||
|
Previous: 'Anterior', |
||||||
|
Next: 'Siguiente', |
||||||
|
'Find and replace...': 'Buscar y reemplazar...', |
||||||
|
'Could not find the specified string.': 'No se encuentra la cadena de texto especificada', |
||||||
|
'Match case': 'Coincidencia exacta', |
||||||
|
'Find whole words only': 'Solo palabras completas', |
||||||
|
'Spell check': 'Revisar ortograf\u00eda', |
||||||
|
Ignore: 'Ignorar', |
||||||
|
'Ignore all': 'Ignorar todos', |
||||||
|
Finish: 'Finalizar', |
||||||
|
'Add to Dictionary': 'A\u00f1adir al Diccionario', |
||||||
|
'Insert table': 'Insertar tabla', |
||||||
|
'Table properties': 'Propiedades de la tabla', |
||||||
|
'Delete table': 'Eliminar tabla', |
||||||
|
Cell: 'Celda', |
||||||
|
Row: 'Fila', |
||||||
|
Column: 'Columna', |
||||||
|
'Cell properties': 'Propiedades de la celda', |
||||||
|
'Merge cells': 'Combinar celdas', |
||||||
|
'Split cell': 'Dividir celdas', |
||||||
|
'Insert row before': 'Insertar fila antes', |
||||||
|
'Insert row after': 'Insertar fila despu\u00e9s ', |
||||||
|
'Delete row': 'Eliminar fila', |
||||||
|
'Row properties': 'Propiedades de la fila', |
||||||
|
'Cut row': 'Cortar fila', |
||||||
|
'Copy row': 'Copiar fila', |
||||||
|
'Paste row before': 'Pegar la fila antes', |
||||||
|
'Paste row after': 'Pegar la fila despu\u00e9s', |
||||||
|
'Insert column before': 'Insertar columna antes', |
||||||
|
'Insert column after': 'Insertar columna despu\u00e9s', |
||||||
|
'Delete column': 'Eliminar columna', |
||||||
|
Cols: 'Columnas', |
||||||
|
Rows: 'Filas', |
||||||
|
Width: 'Ancho', |
||||||
|
Height: 'Alto', |
||||||
|
'Cell spacing': 'Espacio entre celdas', |
||||||
|
'Cell padding': 'Relleno de celda', |
||||||
|
'Show caption': 'Mostrar t\u00edtulo', |
||||||
|
Left: 'Izquierda', |
||||||
|
Center: 'Centrado', |
||||||
|
Right: 'Derecha', |
||||||
|
'Cell type': 'Tipo de celda', |
||||||
|
Scope: '\u00c1mbito', |
||||||
|
Alignment: 'Alineaci\u00f3n', |
||||||
|
'H Align': 'Alineamiento Horizontal', |
||||||
|
'V Align': 'Alineamiento Vertical', |
||||||
|
Top: 'Arriba', |
||||||
|
Middle: 'Centro', |
||||||
|
Bottom: 'Abajo', |
||||||
|
'Header cell': 'Celda de la cebecera', |
||||||
|
'Row group': 'Grupo de filas', |
||||||
|
'Column group': 'Grupo de columnas', |
||||||
|
'Row type': 'Tipo de fila', |
||||||
|
Header: 'Cabecera', |
||||||
|
Body: 'Cuerpo', |
||||||
|
Footer: 'Pie de p\u00e1gina', |
||||||
|
'Border color': 'Color del borde', |
||||||
|
'Insert template...': 'Insertar plantilla...', |
||||||
|
Templates: 'Plantillas', |
||||||
|
Template: 'Plantilla', |
||||||
|
'Text color': 'Color del texto', |
||||||
|
'Background color': 'Color de fondo', |
||||||
|
'Custom...': 'Personalizar...', |
||||||
|
'Custom color': 'Color personalizado', |
||||||
|
'No color': 'Sin color', |
||||||
|
'Remove color': 'Quitar color', |
||||||
|
'Table of Contents': 'Tabla de contenidos', |
||||||
|
'Show blocks': 'Mostrar bloques', |
||||||
|
'Show invisible characters': 'Mostrar caracteres invisibles', |
||||||
|
'Word count': 'Contar palabras', |
||||||
|
Count: 'Recuento', |
||||||
|
Document: 'Documento', |
||||||
|
Selection: 'Selecci\u00f3n', |
||||||
|
Words: 'Palabras', |
||||||
|
'Words: {0}': 'Palabras: {0}', |
||||||
|
'{0} words': '{0} palabras', |
||||||
|
File: 'Archivo', |
||||||
|
Edit: 'Editar', |
||||||
|
Insert: 'Insertar', |
||||||
|
View: 'Ver', |
||||||
|
Format: 'Formato', |
||||||
|
Table: 'Tabla', |
||||||
|
Tools: 'Herramientas', |
||||||
|
'Powered by {0}': 'Desarrollado por {0}', |
||||||
|
'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help': '\u00c1rea de texto enriquecido. Pulse ALT-F9 para el menu. Pulse ALT-F10 para la barra de herramientas. Pulse ALT-0 para ayuda', |
||||||
|
'Image title': 'Titulo de imagen', |
||||||
|
'Border width': 'Ancho de borde', |
||||||
|
'Border style': 'Estilo de borde', |
||||||
|
Error: 'Error', |
||||||
|
Warn: 'Advertencia', |
||||||
|
Valid: 'V\u00e1lido', |
||||||
|
'To open the popup, press Shift+Enter': 'Para abrir el elemento emergente, pulse May\u00fas+Intro', |
||||||
|
'Rich Text Area. Press ALT-0 for help.': '\u00c1rea de texto enriquecido. Pulse ALT-0 para abrir la ayuda.', |
||||||
|
'System Font': 'Fuente de sistema', |
||||||
|
'Failed to upload image: {0}': 'Fallo al cargar imagen: {0}', |
||||||
|
'Failed to load plugin: {0} from url {1}': 'Fallo al cargar complemento: {0} desde URL {1}', |
||||||
|
'Failed to load plugin url: {0}': 'Fallo al cargar URL del complemento: {0}', |
||||||
|
'Failed to initialize plugin: {0}': 'Fallo al iniciar el complemento: {0}', |
||||||
|
example: 'ejemplo', |
||||||
|
Search: 'Buscar', |
||||||
|
All: 'Todo', |
||||||
|
Currency: 'Divisa', |
||||||
|
Text: 'Texto', |
||||||
|
Quotations: 'Comillas', |
||||||
|
Mathematical: 'S\u00edmbolo matem\u00e1tico', |
||||||
|
'Extended Latin': 'Latino extendido A', |
||||||
|
Symbols: 'S\u00edmbolos', |
||||||
|
Arrows: 'Flechas', |
||||||
|
'User Defined': 'Definido por el usuario', |
||||||
|
'dollar sign': 'signo de d\u00f3lar', |
||||||
|
'currency sign': 'signo de divisa', |
||||||
|
'euro-currency sign': 'signo de euro', |
||||||
|
'colon sign': 'signo de dos puntos', |
||||||
|
'cruzeiro sign': 'signo de cruceiro', |
||||||
|
'french franc sign': 'signo de franco franc\u00e9s', |
||||||
|
'lira sign': 'signo de lira', |
||||||
|
'mill sign': 'signo de mill', |
||||||
|
'naira sign': 'signo de naira', |
||||||
|
'peseta sign': 'signo de peseta', |
||||||
|
'rupee sign': 'signo de rupia', |
||||||
|
'won sign': 'signo de won', |
||||||
|
'new sheqel sign': 'signo de nuevo s\u00e9quel', |
||||||
|
'dong sign': 'signo de dong', |
||||||
|
'kip sign': 'signo de kip', |
||||||
|
'tugrik sign': 'signo de tugrik', |
||||||
|
'drachma sign': 'signo de dracma', |
||||||
|
'german penny symbol': 'signo de penique alem\u00e1n', |
||||||
|
'peso sign': 'signo de peso', |
||||||
|
'guarani sign': 'signo de guaran\u00ed', |
||||||
|
'austral sign': 'signo de austral', |
||||||
|
'hryvnia sign': 'signo de grivna', |
||||||
|
'cedi sign': 'signo de cedi', |
||||||
|
'livre tournois sign': 'signo de libra tornesa', |
||||||
|
'spesmilo sign': 'signo de spesmilo', |
||||||
|
'tenge sign': 'signo de tenge', |
||||||
|
'indian rupee sign': 'signo de rupia india', |
||||||
|
'turkish lira sign': 'signo de lira turca', |
||||||
|
'nordic mark sign': 'signo de marco n\u00f3rdico', |
||||||
|
'manat sign': 'signo de manat', |
||||||
|
'ruble sign': 'signo de rublo', |
||||||
|
'yen character': 'car\u00e1cter de yen', |
||||||
|
'yuan character': 'car\u00e1cter de yuan', |
||||||
|
'yuan character, in hong kong and taiwan': 'car\u00e1cter de yuan en Hong Kong y Taiw\u00e1n', |
||||||
|
'yen\/yuan character variant one': 'Variante uno de car\u00e1cter de yen\/yuan', |
||||||
|
'Loading emoticons...': 'Cargando emoticonos...', |
||||||
|
'Could not load emoticons': 'No se han podido cargar los emoticonos', |
||||||
|
People: 'Personas', |
||||||
|
'Animals and Nature': 'Animales y naturaleza', |
||||||
|
'Food and Drink': 'Comida y bebida', |
||||||
|
Activity: 'Actividad', |
||||||
|
'Travel and Places': 'Viajes y lugares', |
||||||
|
Objects: 'Objetos', |
||||||
|
Flags: 'Banderas', |
||||||
|
Characters: 'Caracteres', |
||||||
|
'Characters (no spaces)': 'Caracteres (sin espacios)', |
||||||
|
'{0} characters': '{0} caracteres', |
||||||
|
'Error: Form submit field collision.': 'Error: Colisi\u00f3n de campo al enviar formulario.', |
||||||
|
'Error: No form element found.': 'Error: No se encuentra ning\u00fan elemento de formulario.', |
||||||
|
Update: 'Actualizar', |
||||||
|
'Color swatch': 'Muestrario de colores', |
||||||
|
Turquoise: 'Turquesa', |
||||||
|
Green: 'Verde', |
||||||
|
Blue: 'Azul', |
||||||
|
Purple: 'P\u00farpura', |
||||||
|
'Navy Blue': 'Azul marino', |
||||||
|
'Dark Turquoise': 'Turquesa oscuro', |
||||||
|
'Dark Green': 'Verde oscuro', |
||||||
|
'Medium Blue': 'Azul medio', |
||||||
|
'Medium Purple': 'P\u00farpura medio', |
||||||
|
'Midnight Blue': 'Azul medio', |
||||||
|
Yellow: 'Amarillo', |
||||||
|
Orange: 'Naranja', |
||||||
|
Red: 'Rojo', |
||||||
|
'Light Gray': 'Gris claro', |
||||||
|
Gray: 'Gris', |
||||||
|
'Dark Yellow': 'Amarillo oscuro', |
||||||
|
'Dark Orange': 'Naranja oscuro', |
||||||
|
'Dark Red': 'Rojo oscuro', |
||||||
|
'Medium Gray': 'Gris medio', |
||||||
|
'Dark Gray': 'Gris oscuro', |
||||||
|
'Light Green': 'Verde claro', |
||||||
|
'Light Yellow': 'Amarillo claro', |
||||||
|
'Light Red': 'Rojo claro', |
||||||
|
'Light Purple': 'Morado claro', |
||||||
|
'Light Blue': 'Azul claro', |
||||||
|
'Dark Purple': 'Morado oscuro', |
||||||
|
'Dark Blue': 'Azul oscuro', |
||||||
|
Black: 'Negro', |
||||||
|
White: 'Blanco', |
||||||
|
'Switch to or from fullscreen mode': 'Activar o desactivar modo pantalla completa', |
||||||
|
'Open help dialog': 'Abrir di\u00e1logo de ayuda', |
||||||
|
history: 'historial', |
||||||
|
styles: 'estilos', |
||||||
|
formatting: 'formato', |
||||||
|
alignment: 'alineaci\u00f3n', |
||||||
|
indentation: 'sangr\u00eda', |
||||||
|
'permanent pen': 'bol\u00edgrafo permanente', |
||||||
|
comments: 'comentarios', |
||||||
|
'Format Painter': 'Copiar formato', |
||||||
|
'Insert\/edit iframe': 'Insertar\/editar iframe', |
||||||
|
Capitalization: 'Uso de may\u00fasculas', |
||||||
|
lowercase: 'min\u00fasculas', |
||||||
|
UPPERCASE: 'MAY\u00daSCULAS', |
||||||
|
'Title Case': 'Tipo T\u00edtulo', |
||||||
|
'Permanent Pen Properties': 'Propiedades del bol\u00edgrafo permanente', |
||||||
|
'Permanent pen properties...': 'Propiedades del bol\u00edgrafo permanente...', |
||||||
|
Font: 'Fuente', |
||||||
|
Size: 'Tama\u00f1o', |
||||||
|
'More...': 'M\u00e1s...', |
||||||
|
'Spellcheck Language': 'Corrector', |
||||||
|
'Select...': 'Seleccionar...', |
||||||
|
Preferences: 'Preferencias', |
||||||
|
Yes: 'S\u00ed', |
||||||
|
No: 'No', |
||||||
|
'Keyboard Navigation': 'Navegaci\u00f3n con el teclado', |
||||||
|
Version: 'Versi\u00f3n', |
||||||
|
Anchor: 'Ancla', |
||||||
|
'Special character': 'Car\u00e1cter especial', |
||||||
|
'Code sample': 'Ejemplo de c\u00f3digo', |
||||||
|
Color: 'Color', |
||||||
|
Emoticons: 'Emoticonos', |
||||||
|
'Document properties': 'Propiedades del documento', |
||||||
|
Image: 'Imagen', |
||||||
|
'Insert link': 'Insertar enlace', |
||||||
|
Target: 'Destino', |
||||||
|
Link: 'Enlace', |
||||||
|
Poster: 'Miniatura', |
||||||
|
Media: 'Media', |
||||||
|
Print: 'Imprimir', |
||||||
|
Prev: 'Anterior', |
||||||
|
'Find and replace': 'Buscar y reemplazar', |
||||||
|
'Whole words': 'Palabras completas', |
||||||
|
Spellcheck: 'Corrector ortogr\u00e1fico', |
||||||
|
Caption: 'Subt\u00edtulo', |
||||||
|
'Insert template': 'Insertar plantilla' |
||||||
|
}) |
@ -0,0 +1,389 @@ |
|||||||
|
tinymce.addI18n('zh_CN',{ |
||||||
|
"Redo": "\u91cd\u505a", |
||||||
|
"Undo": "\u64a4\u9500", |
||||||
|
"Cut": "\u526a\u5207", |
||||||
|
"Copy": "\u590d\u5236", |
||||||
|
"Paste": "\u7c98\u8d34", |
||||||
|
"Select all": "\u5168\u9009", |
||||||
|
"New document": "\u65b0\u6587\u4ef6", |
||||||
|
"Ok": "\u786e\u5b9a", |
||||||
|
"Cancel": "\u53d6\u6d88", |
||||||
|
"Visual aids": "\u7f51\u683c\u7ebf", |
||||||
|
"Bold": "\u7c97\u4f53", |
||||||
|
"Italic": "\u659c\u4f53", |
||||||
|
"Underline": "\u4e0b\u5212\u7ebf", |
||||||
|
"Strikethrough": "\u5220\u9664\u7ebf", |
||||||
|
"Superscript": "\u4e0a\u6807", |
||||||
|
"Subscript": "\u4e0b\u6807", |
||||||
|
"Clear formatting": "\u6e05\u9664\u683c\u5f0f", |
||||||
|
"Align left": "\u5de6\u8fb9\u5bf9\u9f50", |
||||||
|
"Align center": "\u4e2d\u95f4\u5bf9\u9f50", |
||||||
|
"Align right": "\u53f3\u8fb9\u5bf9\u9f50", |
||||||
|
"Justify": "\u4e24\u7aef\u5bf9\u9f50", |
||||||
|
"Bullet list": "\u9879\u76ee\u7b26\u53f7", |
||||||
|
"Numbered list": "\u7f16\u53f7\u5217\u8868", |
||||||
|
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb", |
||||||
|
"Increase indent": "\u589e\u52a0\u7f29\u8fdb", |
||||||
|
"Close": "\u5173\u95ed", |
||||||
|
"Formats": "\u683c\u5f0f", |
||||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002", |
||||||
|
"Headers": "\u6807\u9898", |
||||||
|
"Header 1": "\u6807\u98981", |
||||||
|
"Header 2": "\u6807\u98982", |
||||||
|
"Header 3": "\u6807\u98983", |
||||||
|
"Header 4": "\u6807\u98984", |
||||||
|
"Header 5": "\u6807\u98985", |
||||||
|
"Header 6": "\u6807\u98986", |
||||||
|
"Headings": "\u6807\u9898", |
||||||
|
"Heading 1": "\u6807\u98981", |
||||||
|
"Heading 2": "\u6807\u98982", |
||||||
|
"Heading 3": "\u6807\u98983", |
||||||
|
"Heading 4": "\u6807\u98984", |
||||||
|
"Heading 5": "\u6807\u98985", |
||||||
|
"Heading 6": "\u6807\u98986", |
||||||
|
"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684", |
||||||
|
"Div": "Div", |
||||||
|
"Pre": "Pre", |
||||||
|
"Code": "\u4ee3\u7801", |
||||||
|
"Paragraph": "\u6bb5\u843d", |
||||||
|
"Blockquote": "\u5f15\u6587\u533a\u5757", |
||||||
|
"Inline": "\u6587\u672c", |
||||||
|
"Blocks": "\u57fa\u5757", |
||||||
|
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002", |
||||||
|
"Fonts": "\u5b57\u4f53", |
||||||
|
"Font Sizes": "\u5b57\u53f7", |
||||||
|
"Class": "\u7c7b\u578b", |
||||||
|
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf", |
||||||
|
"OR": "\u6216", |
||||||
|
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64", |
||||||
|
"Upload": "\u4e0a\u4f20", |
||||||
|
"Block": "\u5757", |
||||||
|
"Align": "\u5bf9\u9f50", |
||||||
|
"Default": "\u9ed8\u8ba4", |
||||||
|
"Circle": "\u7a7a\u5fc3\u5706", |
||||||
|
"Disc": "\u5b9e\u5fc3\u5706", |
||||||
|
"Square": "\u65b9\u5757", |
||||||
|
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd", |
||||||
|
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd", |
||||||
|
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd", |
||||||
|
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd", |
||||||
|
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", |
||||||
|
"Anchor...": "\u951a\u70b9...", |
||||||
|
"Name": "\u540d\u79f0", |
||||||
|
"Id": "\u6807\u8bc6\u7b26", |
||||||
|
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002", |
||||||
|
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f", |
||||||
|
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f", |
||||||
|
"Special characters...": "\u7279\u6b8a\u5b57\u7b26...", |
||||||
|
"Source code": "\u6e90\u4ee3\u7801", |
||||||
|
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", |
||||||
|
"Language": "\u8bed\u8a00", |
||||||
|
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", |
||||||
|
"Color Picker": "\u9009\u8272\u5668", |
||||||
|
"R": "R", |
||||||
|
"G": "G", |
||||||
|
"B": "B", |
||||||
|
"Left to right": "\u4ece\u5de6\u5230\u53f3", |
||||||
|
"Right to left": "\u4ece\u53f3\u5230\u5de6", |
||||||
|
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", |
||||||
|
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027", |
||||||
|
"Title": "\u6807\u9898", |
||||||
|
"Keywords": "\u5173\u952e\u8bcd", |
||||||
|
"Description": "\u63cf\u8ff0", |
||||||
|
"Robots": "\u673a\u5668\u4eba", |
||||||
|
"Author": "\u4f5c\u8005", |
||||||
|
"Encoding": "\u7f16\u7801", |
||||||
|
"Fullscreen": "\u5168\u5c4f", |
||||||
|
"Action": "\u64cd\u4f5c", |
||||||
|
"Shortcut": "\u5feb\u6377\u952e", |
||||||
|
"Help": "\u5e2e\u52a9", |
||||||
|
"Address": "\u5730\u5740", |
||||||
|
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f", |
||||||
|
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f", |
||||||
|
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84", |
||||||
|
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355", |
||||||
|
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||||
|
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||||
|
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||||
|
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):", |
||||||
|
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a", |
||||||
|
"Learn more...": "\u4e86\u89e3\u66f4\u591a...", |
||||||
|
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}", |
||||||
|
"Plugins": "\u63d2\u4ef6", |
||||||
|
"Handy Shortcuts": "\u5feb\u6377\u952e", |
||||||
|
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf", |
||||||
|
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247", |
||||||
|
"Image description": "\u56fe\u7247\u63cf\u8ff0", |
||||||
|
"Source": "\u5730\u5740", |
||||||
|
"Dimensions": "\u5927\u5c0f", |
||||||
|
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", |
||||||
|
"General": "\u666e\u901a", |
||||||
|
"Advanced": "\u9ad8\u7ea7", |
||||||
|
"Style": "\u6837\u5f0f", |
||||||
|
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd", |
||||||
|
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd", |
||||||
|
"Border": "\u8fb9\u6846", |
||||||
|
"Insert image": "\u63d2\u5165\u56fe\u7247", |
||||||
|
"Image...": "\u56fe\u7247...", |
||||||
|
"Image list": "\u56fe\u7247\u5217\u8868", |
||||||
|
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c", |
||||||
|
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c", |
||||||
|
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c", |
||||||
|
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c", |
||||||
|
"Edit image": "\u7f16\u8f91\u56fe\u7247", |
||||||
|
"Image options": "\u56fe\u7247\u9009\u9879", |
||||||
|
"Zoom in": "\u653e\u5927", |
||||||
|
"Zoom out": "\u7f29\u5c0f", |
||||||
|
"Crop": "\u88c1\u526a", |
||||||
|
"Resize": "\u8c03\u6574\u5927\u5c0f", |
||||||
|
"Orientation": "\u65b9\u5411", |
||||||
|
"Brightness": "\u4eae\u5ea6", |
||||||
|
"Sharpen": "\u9510\u5316", |
||||||
|
"Contrast": "\u5bf9\u6bd4\u5ea6", |
||||||
|
"Color levels": "\u989c\u8272\u5c42\u6b21", |
||||||
|
"Gamma": "\u4f3d\u9a6c\u503c", |
||||||
|
"Invert": "\u53cd\u8f6c", |
||||||
|
"Apply": "\u5e94\u7528", |
||||||
|
"Back": "\u540e\u9000", |
||||||
|
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4", |
||||||
|
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4", |
||||||
|
"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
||||||
|
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
||||||
|
"Text to display": "\u663e\u793a\u6587\u5b57", |
||||||
|
"Url": "\u5730\u5740", |
||||||
|
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", |
||||||
|
"Current window": "\u5f53\u524d\u7a97\u53e3", |
||||||
|
"None": "\u65e0", |
||||||
|
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00", |
||||||
|
"Remove link": "\u5220\u9664\u94fe\u63a5", |
||||||
|
"Anchors": "\u951a\u70b9", |
||||||
|
"Link...": "\u94fe\u63a5...", |
||||||
|
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5", |
||||||
|
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f", |
||||||
|
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f", |
||||||
|
"Link list": "\u94fe\u63a5\u5217\u8868", |
||||||
|
"Insert video": "\u63d2\u5165\u89c6\u9891", |
||||||
|
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891", |
||||||
|
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53", |
||||||
|
"Alternative source": "\u955c\u50cf", |
||||||
|
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", |
||||||
|
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", |
||||||
|
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", |
||||||
|
"Embed": "\u5185\u5d4c", |
||||||
|
"Media...": "\u591a\u5a92\u4f53...", |
||||||
|
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c", |
||||||
|
"Page break": "\u5206\u9875\u7b26", |
||||||
|
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", |
||||||
|
"Preview": "\u9884\u89c8", |
||||||
|
"Print...": "\u6253\u5370...", |
||||||
|
"Save": "\u4fdd\u5b58", |
||||||
|
"Find": "\u67e5\u627e", |
||||||
|
"Replace with": "\u66ff\u6362\u4e3a", |
||||||
|
"Replace": "\u66ff\u6362", |
||||||
|
"Replace all": "\u5168\u90e8\u66ff\u6362", |
||||||
|
"Previous": "\u4e0a\u4e00\u4e2a", |
||||||
|
"Next": "\u4e0b\u4e00\u4e2a", |
||||||
|
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", |
||||||
|
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", |
||||||
|
"Match case": "\u533a\u5206\u5927\u5c0f\u5199", |
||||||
|
"Find whole words only": "\u5168\u5b57\u5339\u914d", |
||||||
|
"Spell check": "\u62fc\u5199\u68c0\u67e5", |
||||||
|
"Ignore": "\u5ffd\u7565", |
||||||
|
"Ignore all": "\u5168\u90e8\u5ffd\u7565", |
||||||
|
"Finish": "\u5b8c\u6210", |
||||||
|
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178", |
||||||
|
"Insert table": "\u63d2\u5165\u8868\u683c", |
||||||
|
"Table properties": "\u8868\u683c\u5c5e\u6027", |
||||||
|
"Delete table": "\u5220\u9664\u8868\u683c", |
||||||
|
"Cell": "\u5355\u5143\u683c", |
||||||
|
"Row": "\u884c", |
||||||
|
"Column": "\u5217", |
||||||
|
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027", |
||||||
|
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c", |
||||||
|
"Split cell": "\u62c6\u5206\u5355\u5143\u683c", |
||||||
|
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165", |
||||||
|
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165", |
||||||
|
"Delete row": "\u5220\u9664\u884c", |
||||||
|
"Row properties": "\u884c\u5c5e\u6027", |
||||||
|
"Cut row": "\u526a\u5207\u884c", |
||||||
|
"Copy row": "\u590d\u5236\u884c", |
||||||
|
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9", |
||||||
|
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9", |
||||||
|
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165", |
||||||
|
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165", |
||||||
|
"Delete column": "\u5220\u9664\u5217", |
||||||
|
"Cols": "\u5217", |
||||||
|
"Rows": "\u884c", |
||||||
|
"Width": "\u5bbd", |
||||||
|
"Height": "\u9ad8", |
||||||
|
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd", |
||||||
|
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd", |
||||||
|
"Show caption": "\u663e\u793a\u6807\u9898", |
||||||
|
"Left": "\u5de6\u5bf9\u9f50", |
||||||
|
"Center": "\u5c45\u4e2d", |
||||||
|
"Right": "\u53f3\u5bf9\u9f50", |
||||||
|
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b", |
||||||
|
"Scope": "\u8303\u56f4", |
||||||
|
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f", |
||||||
|
"H Align": "\u6c34\u5e73\u5bf9\u9f50", |
||||||
|
"V Align": "\u5782\u76f4\u5bf9\u9f50", |
||||||
|
"Top": "\u9876\u90e8\u5bf9\u9f50", |
||||||
|
"Middle": "\u5782\u76f4\u5c45\u4e2d", |
||||||
|
"Bottom": "\u5e95\u90e8\u5bf9\u9f50", |
||||||
|
"Header cell": "\u8868\u5934\u5355\u5143\u683c", |
||||||
|
"Row group": "\u884c\u7ec4", |
||||||
|
"Column group": "\u5217\u7ec4", |
||||||
|
"Row type": "\u884c\u7c7b\u578b", |
||||||
|
"Header": "\u8868\u5934", |
||||||
|
"Body": "\u8868\u4f53", |
||||||
|
"Footer": "\u8868\u5c3e", |
||||||
|
"Border color": "\u8fb9\u6846\u989c\u8272", |
||||||
|
"Insert template...": "\u63d2\u5165\u6a21\u677f...", |
||||||
|
"Templates": "\u6a21\u677f", |
||||||
|
"Template": "\u6a21\u677f", |
||||||
|
"Text color": "\u6587\u5b57\u989c\u8272", |
||||||
|
"Background color": "\u80cc\u666f\u8272", |
||||||
|
"Custom...": "\u81ea\u5b9a\u4e49...", |
||||||
|
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272", |
||||||
|
"No color": "\u65e0", |
||||||
|
"Remove color": "\u79fb\u9664\u989c\u8272", |
||||||
|
"Table of Contents": "\u5185\u5bb9\u5217\u8868", |
||||||
|
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846", |
||||||
|
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26", |
||||||
|
"Word count": "\u5b57\u6570", |
||||||
|
"Words: {0}": "\u5b57\u6570\uff1a{0}", |
||||||
|
"{0} words": "{0} \u5b57", |
||||||
|
"File": "\u6587\u4ef6", |
||||||
|
"Edit": "\u7f16\u8f91", |
||||||
|
"Insert": "\u63d2\u5165", |
||||||
|
"View": "\u89c6\u56fe", |
||||||
|
"Format": "\u683c\u5f0f", |
||||||
|
"Table": "\u8868\u683c", |
||||||
|
"Tools": "\u5de5\u5177", |
||||||
|
"Powered by {0}": "\u7531{0}\u9a71\u52a8", |
||||||
|
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9", |
||||||
|
"Image title": "\u56fe\u7247\u6807\u9898", |
||||||
|
"Border width": "\u8fb9\u6846\u5bbd\u5ea6", |
||||||
|
"Border style": "\u8fb9\u6846\u6837\u5f0f", |
||||||
|
"Error": "\u9519\u8bef", |
||||||
|
"Warn": "\u8b66\u544a", |
||||||
|
"Valid": "\u6709\u6548", |
||||||
|
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", |
||||||
|
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", |
||||||
|
"System Font": "\u7cfb\u7edf\u5b57\u4f53", |
||||||
|
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", |
||||||
|
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", |
||||||
|
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", |
||||||
|
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", |
||||||
|
"example": "\u793a\u4f8b", |
||||||
|
"Search": "\u641c\u7d22", |
||||||
|
"All": "\u5168\u90e8", |
||||||
|
"Currency": "\u8d27\u5e01", |
||||||
|
"Text": "\u6587\u5b57", |
||||||
|
"Quotations": "\u5f15\u7528", |
||||||
|
"Mathematical": "\u6570\u5b66", |
||||||
|
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", |
||||||
|
"Symbols": "\u7b26\u53f7", |
||||||
|
"Arrows": "\u7bad\u5934", |
||||||
|
"User Defined": "\u81ea\u5b9a\u4e49", |
||||||
|
"dollar sign": "\u7f8e\u5143\u7b26\u53f7", |
||||||
|
"currency sign": "\u8d27\u5e01\u7b26\u53f7", |
||||||
|
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", |
||||||
|
"colon sign": "\u5192\u53f7", |
||||||
|
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", |
||||||
|
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", |
||||||
|
"lira sign": "\u91cc\u62c9\u7b26\u53f7", |
||||||
|
"mill sign": "\u5bc6\u5c14\u7b26\u53f7", |
||||||
|
"naira sign": "\u5948\u62c9\u7b26\u53f7", |
||||||
|
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", |
||||||
|
"rupee sign": "\u5362\u6bd4\u7b26\u53f7", |
||||||
|
"won sign": "\u97e9\u5143\u7b26\u53f7", |
||||||
|
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", |
||||||
|
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", |
||||||
|
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", |
||||||
|
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", |
||||||
|
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", |
||||||
|
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", |
||||||
|
"peso sign": "\u6bd4\u7d22\u7b26\u53f7", |
||||||
|
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", |
||||||
|
"austral sign": "\u6fb3\u5143\u7b26\u53f7", |
||||||
|
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", |
||||||
|
"cedi sign": "\u585e\u5730\u7b26\u53f7", |
||||||
|
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", |
||||||
|
"spesmilo sign": "spesmilo\u7b26\u53f7", |
||||||
|
"tenge sign": "\u575a\u6208\u7b26\u53f7", |
||||||
|
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", |
||||||
|
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", |
||||||
|
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", |
||||||
|
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", |
||||||
|
"ruble sign": "\u5362\u5e03\u7b26\u53f7", |
||||||
|
"yen character": "\u65e5\u5143\u5b57\u6837", |
||||||
|
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", |
||||||
|
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", |
||||||
|
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", |
||||||
|
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", |
||||||
|
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", |
||||||
|
"People": "\u4eba\u7c7b", |
||||||
|
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", |
||||||
|
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", |
||||||
|
"Activity": "\u6d3b\u52a8", |
||||||
|
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", |
||||||
|
"Objects": "\u7269\u4ef6", |
||||||
|
"Flags": "\u65d7\u5e1c", |
||||||
|
"Characters": "\u5b57\u7b26", |
||||||
|
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", |
||||||
|
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", |
||||||
|
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", |
||||||
|
"Update": "\u66f4\u65b0", |
||||||
|
"Color swatch": "\u989c\u8272\u6837\u672c", |
||||||
|
"Turquoise": "\u9752\u7eff\u8272", |
||||||
|
"Green": "\u7eff\u8272", |
||||||
|
"Blue": "\u84dd\u8272", |
||||||
|
"Purple": "\u7d2b\u8272", |
||||||
|
"Navy Blue": "\u6d77\u519b\u84dd", |
||||||
|
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", |
||||||
|
"Dark Green": "\u6df1\u7eff\u8272", |
||||||
|
"Medium Blue": "\u4e2d\u84dd\u8272", |
||||||
|
"Medium Purple": "\u4e2d\u7d2b\u8272", |
||||||
|
"Midnight Blue": "\u6df1\u84dd\u8272", |
||||||
|
"Yellow": "\u9ec4\u8272", |
||||||
|
"Orange": "\u6a59\u8272", |
||||||
|
"Red": "\u7ea2\u8272", |
||||||
|
"Light Gray": "\u6d45\u7070\u8272", |
||||||
|
"Gray": "\u7070\u8272", |
||||||
|
"Dark Yellow": "\u6697\u9ec4\u8272", |
||||||
|
"Dark Orange": "\u6df1\u6a59\u8272", |
||||||
|
"Dark Red": "\u6df1\u7ea2\u8272", |
||||||
|
"Medium Gray": "\u4e2d\u7070\u8272", |
||||||
|
"Dark Gray": "\u6df1\u7070\u8272", |
||||||
|
"Black": "\u9ed1\u8272", |
||||||
|
"White": "\u767d\u8272", |
||||||
|
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", |
||||||
|
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", |
||||||
|
"history": "\u5386\u53f2", |
||||||
|
"styles": "\u6837\u5f0f", |
||||||
|
"formatting": "\u683c\u5f0f\u5316", |
||||||
|
"alignment": "\u5bf9\u9f50", |
||||||
|
"indentation": "\u7f29\u8fdb", |
||||||
|
"permanent pen": "\u8bb0\u53f7\u7b14", |
||||||
|
"comments": "\u5907\u6ce8", |
||||||
|
"Anchor": "\u951a\u70b9", |
||||||
|
"Special character": "\u7279\u6b8a\u7b26\u53f7", |
||||||
|
"Code sample": "\u4ee3\u7801\u793a\u4f8b", |
||||||
|
"Color": "\u989c\u8272", |
||||||
|
"Emoticons": "\u8868\u60c5", |
||||||
|
"Document properties": "\u6587\u6863\u5c5e\u6027", |
||||||
|
"Image": "\u56fe\u7247", |
||||||
|
"Insert link": "\u63d2\u5165\u94fe\u63a5", |
||||||
|
"Target": "\u6253\u5f00\u65b9\u5f0f", |
||||||
|
"Link": "\u94fe\u63a5", |
||||||
|
"Poster": "\u5c01\u9762", |
||||||
|
"Media": "\u5a92\u4f53", |
||||||
|
"Print": "\u6253\u5370", |
||||||
|
"Prev": "\u4e0a\u4e00\u4e2a", |
||||||
|
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", |
||||||
|
"Whole words": "\u5168\u5b57\u5339\u914d", |
||||||
|
"Spellcheck": "\u62fc\u5199\u68c0\u67e5", |
||||||
|
"Caption": "\u6807\u9898", |
||||||
|
"Insert template": "\u63d2\u5165\u6a21\u677f" |
||||||
|
}); |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) Tiny Technologies, Inc. All rights reserved. |
||||||
|
* Licensed under the LGPL or a commercial license. |
||||||
|
* For LGPL see License.txt in the project root for license information. |
||||||
|
* For commercial licenses see https://www.tiny.cloud/ |
||||||
|
*/ |
||||||
|
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) Tiny Technologies, Inc. All rights reserved. |
||||||
|
* Licensed under the LGPL or a commercial license. |
||||||
|
* For LGPL see License.txt in the project root for license information. |
||||||
|
* For commercial licenses see https://www.tiny.cloud/ |
||||||
|
*/ |
||||||
|
body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;-ms-scroll-chaining:none;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) Tiny Technologies, Inc. All rights reserved. |
||||||
|
* Licensed under the LGPL or a commercial license. |
||||||
|
* For LGPL see License.txt in the project root for license information. |
||||||
|
* For commercial licenses see https://www.tiny.cloud/ |
||||||
|
*/ |
||||||
|
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse} |
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@ |
|||||||
|
/** |
||||||
|
* Copyright (c) Tiny Technologies, Inc. All rights reserved. |
||||||
|
* Licensed under the LGPL or a commercial license. |
||||||
|
* For LGPL see License.txt in the project root for license information. |
||||||
|
* For commercial licenses see https://www.tiny.cloud/ |
||||||
|
*/ |
||||||
|
body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;-ms-scroll-chaining:none;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} |
@ -0,0 +1,27 @@ |
|||||||
|
<template> |
||||||
|
<ConfigProvider :locale="getAntdLocale" :component-size="componentSize"> |
||||||
|
<AppProvider> |
||||||
|
<RouterView /> |
||||||
|
</AppProvider> |
||||||
|
</ConfigProvider> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script lang="ts" setup> |
||||||
|
import { computed } from 'vue' |
||||||
|
import { ConfigProvider } from 'ant-design-vue' |
||||||
|
import { AppProvider } from '@/components/Application' |
||||||
|
import { useTitle } from '@/hooks/web/useTitle' |
||||||
|
import { useLocale } from '@/locales/useLocale' |
||||||
|
import { useAppStore } from '@/store/modules/app' |
||||||
|
|
||||||
|
import 'dayjs/locale/zh-cn' |
||||||
|
// support Multi-language |
||||||
|
const { getAntdLocale } = useLocale() |
||||||
|
|
||||||
|
const appStore = useAppStore() |
||||||
|
|
||||||
|
const componentSize = computed(() => appStore.getComponentSize) |
||||||
|
|
||||||
|
// Listening to page changes and dynamically changing site titles |
||||||
|
useTitle() |
||||||
|
</script> |
@ -0,0 +1,22 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { GetAccountInfoModel } from './model/accountModel' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
ACCOUNT_INFO = '/account/getAccountInfo', |
||||||
|
SESSION_TIMEOUT = '/user/sessionTimeout', |
||||||
|
TOKEN_EXPIRED = '/user/tokenExpired' |
||||||
|
} |
||||||
|
|
||||||
|
// Get personal center-basic settings
|
||||||
|
|
||||||
|
export const accountInfoApi = () => { |
||||||
|
return defHttp.get<GetAccountInfoModel>({ url: Api.ACCOUNT_INFO }) |
||||||
|
} |
||||||
|
|
||||||
|
export const sessionTimeoutApi = () => { |
||||||
|
return defHttp.post<void>({ url: Api.SESSION_TIMEOUT }) |
||||||
|
} |
||||||
|
|
||||||
|
export const tokenExpiredApi = () => { |
||||||
|
return defHttp.post<void>({ url: Api.TOKEN_EXPIRED }) |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { AreaModel, AreaParams } from '@/api/demo/model/areaModel' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
AREA_RECORD = '/cascader/getAreaRecord' |
||||||
|
} |
||||||
|
|
||||||
|
export const areaRecord = (data: AreaParams) => { |
||||||
|
return defHttp.post<AreaModel>({ url: Api.AREA_RECORD, data }) |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
// The address does not exist
|
||||||
|
Error = '/error' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Trigger ajax error |
||||||
|
*/ |
||||||
|
|
||||||
|
export const fireErrorApi = () => { |
||||||
|
return defHttp.get({ url: Api.Error }) |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
export interface GetAccountInfoModel { |
||||||
|
email: string |
||||||
|
name: string |
||||||
|
introduction: string |
||||||
|
phone: string |
||||||
|
address: string |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
export interface AreaModel { |
||||||
|
id: string |
||||||
|
code: string |
||||||
|
parentCode: string |
||||||
|
name: string |
||||||
|
levelType: number |
||||||
|
[key: string]: string | number |
||||||
|
} |
||||||
|
|
||||||
|
export interface AreaParams { |
||||||
|
parentCode: string |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
import { BasicFetchResult } from '@/api/model/baseModel' |
||||||
|
|
||||||
|
export interface DemoOptionsItem { |
||||||
|
label: string |
||||||
|
value: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface selectParams { |
||||||
|
id: number | string |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Request list return value |
||||||
|
*/ |
||||||
|
export type DemoOptionsGetResultModel = BasicFetchResult<DemoOptionsItem> |
@ -0,0 +1,74 @@ |
|||||||
|
import { BasicPageParams, BasicFetchResult } from '@/api/model/baseModel' |
||||||
|
|
||||||
|
export type AccountParams = BasicPageParams & { |
||||||
|
account?: string |
||||||
|
nickname?: string |
||||||
|
} |
||||||
|
|
||||||
|
export type RoleParams = { |
||||||
|
roleName?: string |
||||||
|
status?: string |
||||||
|
} |
||||||
|
|
||||||
|
export type RolePageParams = BasicPageParams & RoleParams |
||||||
|
|
||||||
|
export type DeptParams = { |
||||||
|
deptName?: string |
||||||
|
status?: string |
||||||
|
} |
||||||
|
|
||||||
|
export type MenuParams = { |
||||||
|
menuName?: string |
||||||
|
status?: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface AccountListItem { |
||||||
|
id: string |
||||||
|
account: string |
||||||
|
email: string |
||||||
|
nickname: string |
||||||
|
role: number |
||||||
|
createTime: string |
||||||
|
remark: string |
||||||
|
status: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface DeptListItem { |
||||||
|
id: string |
||||||
|
orderNo: string |
||||||
|
createTime: string |
||||||
|
remark: string |
||||||
|
status: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface MenuListItem { |
||||||
|
id: string |
||||||
|
orderNo: string |
||||||
|
createTime: string |
||||||
|
status: number |
||||||
|
icon: string |
||||||
|
component: string |
||||||
|
permission: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface RoleListItem { |
||||||
|
id: string |
||||||
|
roleName: string |
||||||
|
roleValue: string |
||||||
|
status: number |
||||||
|
orderNo: string |
||||||
|
createTime: string |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Request list return value |
||||||
|
*/ |
||||||
|
export type AccountListGetResultModel = BasicFetchResult<AccountListItem> |
||||||
|
|
||||||
|
export type DeptListGetResultModel = BasicFetchResult<DeptListItem> |
||||||
|
|
||||||
|
export type MenuListGetResultModel = BasicFetchResult<MenuListItem> |
||||||
|
|
||||||
|
export type RolePageListGetResultModel = BasicFetchResult<RoleListItem> |
||||||
|
|
||||||
|
export type RoleListGetResultModel = RoleListItem[] |
@ -0,0 +1,20 @@ |
|||||||
|
import { BasicPageParams, BasicFetchResult } from '@/api/model/baseModel' |
||||||
|
/** |
||||||
|
* @description: Request list interface parameters |
||||||
|
*/ |
||||||
|
export type DemoParams = BasicPageParams |
||||||
|
|
||||||
|
export interface DemoListItem { |
||||||
|
id: string |
||||||
|
beginTime: string |
||||||
|
endTime: string |
||||||
|
address: string |
||||||
|
name: string |
||||||
|
no: number |
||||||
|
status: number |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Request list return value |
||||||
|
*/ |
||||||
|
export type DemoListGetResultModel = BasicFetchResult<DemoListItem> |
@ -0,0 +1,12 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { DemoOptionsItem, selectParams } from './model/optionsModel' |
||||||
|
enum Api { |
||||||
|
OPTIONS_LIST = '/select/getDemoOptions' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get sample options value |
||||||
|
*/ |
||||||
|
export const optionsListApi = (params?: selectParams) => { |
||||||
|
return defHttp.get<DemoOptionsItem[]>({ url: Api.OPTIONS_LIST, params }) |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
import { |
||||||
|
AccountParams, |
||||||
|
DeptListItem, |
||||||
|
MenuParams, |
||||||
|
RoleParams, |
||||||
|
RolePageParams, |
||||||
|
MenuListGetResultModel, |
||||||
|
DeptListGetResultModel, |
||||||
|
AccountListGetResultModel, |
||||||
|
RolePageListGetResultModel, |
||||||
|
RoleListGetResultModel |
||||||
|
} from './model/systemModel' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
AccountList = '/system/getAccountList', |
||||||
|
IsAccountExist = '/system/accountExist', |
||||||
|
DeptList = '/system/getDeptList', |
||||||
|
setRoleStatus = '/system/setRoleStatus', |
||||||
|
MenuList = '/system/getMenuList', |
||||||
|
RolePageList = '/system/getRoleListByPage', |
||||||
|
GetAllRoleList = '/system/getAllRoleList' |
||||||
|
} |
||||||
|
|
||||||
|
export const getAccountList = (params: AccountParams) => { |
||||||
|
return defHttp.get<AccountListGetResultModel>({ url: Api.AccountList, params }) |
||||||
|
} |
||||||
|
|
||||||
|
export const getDeptList = (params?: DeptListItem) => { |
||||||
|
return defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params }) |
||||||
|
} |
||||||
|
|
||||||
|
export const getMenuList = (params?: MenuParams) => { |
||||||
|
return defHttp.get<MenuListGetResultModel>({ url: Api.MenuList, params }) |
||||||
|
} |
||||||
|
|
||||||
|
export const getRoleListByPage = (params?: RolePageParams) => { |
||||||
|
return defHttp.get<RolePageListGetResultModel>({ url: Api.RolePageList, params }) |
||||||
|
} |
||||||
|
|
||||||
|
export const getAllRoleList = (params?: RoleParams) => { |
||||||
|
return defHttp.get<RoleListGetResultModel>({ url: Api.GetAllRoleList, params }) |
||||||
|
} |
||||||
|
|
||||||
|
export const setRoleStatus = (id: number, status: string) => { |
||||||
|
return defHttp.post({ url: Api.setRoleStatus, params: { id, status } }) |
||||||
|
} |
||||||
|
|
||||||
|
export const isAccountExist = (account: string) => { |
||||||
|
return defHttp.post({ url: Api.IsAccountExist, params: { account } }, { errorMessageMode: 'none' }) |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { DemoParams, DemoListGetResultModel } from './model/tableModel' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
DEMO_LIST = '/table/getDemoList' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get sample list value |
||||||
|
*/ |
||||||
|
|
||||||
|
export const demoListApi = (params: DemoParams) => { |
||||||
|
return defHttp.get<DemoListGetResultModel>({ |
||||||
|
url: Api.DEMO_LIST, |
||||||
|
params, |
||||||
|
headers: { |
||||||
|
// @ts-ignore
|
||||||
|
ignoreCancelToken: true |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
TREE_OPTIONS_LIST = '/tree/getDemoOptions' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get sample options value |
||||||
|
*/ |
||||||
|
export const treeOptionsListApi = (params?: Recordable) => { |
||||||
|
return defHttp.get<Recordable[]>({ url: Api.TREE_OPTIONS_LIST, params }) |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
export interface BasicPageParams { |
||||||
|
page: number |
||||||
|
pageSize: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface BasicFetchResult<T> { |
||||||
|
items: T[] |
||||||
|
total: number |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { getMenuListResultModel } from './model/menuModel' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
GetMenuList = '/getMenuList' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get user menu based on id |
||||||
|
*/ |
||||||
|
|
||||||
|
export const getMenuList = () => { |
||||||
|
return defHttp.get<getMenuListResultModel>({ url: Api.GetMenuList }) |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
import type { RouteMeta } from 'vue-router' |
||||||
|
export interface RouteItem { |
||||||
|
path: string |
||||||
|
component: any |
||||||
|
meta: RouteMeta |
||||||
|
name?: string |
||||||
|
alias?: string | string[] |
||||||
|
redirect?: string |
||||||
|
caseSensitive?: boolean |
||||||
|
children?: RouteItem[] |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get menu return value |
||||||
|
*/ |
||||||
|
export type getMenuListResultModel = RouteItem[] |
@ -0,0 +1,5 @@ |
|||||||
|
export interface UploadApiResult { |
||||||
|
message: string |
||||||
|
code: number |
||||||
|
url: string |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/** |
||||||
|
* @description: Login interface parameters |
||||||
|
*/ |
||||||
|
export interface LoginParams { |
||||||
|
username: string |
||||||
|
password: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface RoleInfo { |
||||||
|
roleName: string |
||||||
|
value: string |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Login interface return value |
||||||
|
*/ |
||||||
|
export interface LoginResultModel { |
||||||
|
userId: string | number |
||||||
|
token: string |
||||||
|
role: RoleInfo |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Get user information return value |
||||||
|
*/ |
||||||
|
export interface GetUserInfoModel { |
||||||
|
roles: RoleInfo[] |
||||||
|
// 用户id
|
||||||
|
userId: string | number |
||||||
|
// 用户名
|
||||||
|
username: string |
||||||
|
// 真实名字
|
||||||
|
realName: string |
||||||
|
// 头像
|
||||||
|
avatar: string |
||||||
|
// 介绍
|
||||||
|
desc?: string |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
import { UploadApiResult } from './model/uploadModel' |
||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { UploadFileParams } from '@/types/axios' |
||||||
|
import { useGlobSetting } from '@/hooks/setting' |
||||||
|
|
||||||
|
const { uploadUrl = '' } = useGlobSetting() |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: Upload interface |
||||||
|
*/ |
||||||
|
export function uploadApi(params: UploadFileParams, onUploadProgress: (progressEvent: ProgressEvent) => void) { |
||||||
|
return defHttp.uploadFile<UploadApiResult>( |
||||||
|
{ |
||||||
|
url: uploadUrl, |
||||||
|
onUploadProgress |
||||||
|
}, |
||||||
|
params |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
import { defHttp } from '@/utils/http/axios' |
||||||
|
import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userModel' |
||||||
|
|
||||||
|
import { ErrorMessageMode } from '@/types/axios' |
||||||
|
|
||||||
|
enum Api { |
||||||
|
Login = '/login', |
||||||
|
Logout = '/logout', |
||||||
|
GetUserInfo = '/getUserInfo', |
||||||
|
GetPermCode = '/getPermCode', |
||||||
|
TestRetry = '/testRetry' |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: user login api |
||||||
|
*/ |
||||||
|
export const loginApi = (params: LoginParams, mode: ErrorMessageMode = 'modal') => { |
||||||
|
return defHttp.post<LoginResultModel>( |
||||||
|
{ |
||||||
|
url: Api.Login, |
||||||
|
params |
||||||
|
}, |
||||||
|
{ |
||||||
|
errorMessageMode: mode |
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @description: getUserInfo |
||||||
|
*/ |
||||||
|
export const getUserInfo = () => { |
||||||
|
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' }) |
||||||
|
} |
||||||
|
|
||||||
|
export const getPermCode = () => { |
||||||
|
return defHttp.get<string[]>({ url: Api.GetPermCode }) |
||||||
|
} |
||||||
|
|
||||||
|
export const doLogout = () => { |
||||||
|
return defHttp.get({ url: Api.Logout }) |
||||||
|
} |
||||||
|
|
||||||
|
export const testRetry = () => { |
||||||
|
return defHttp.get( |
||||||
|
{ url: Api.TestRetry }, |
||||||
|
{ |
||||||
|
retryRequest: { |
||||||
|
isOpenRetry: true, |
||||||
|
count: 5, |
||||||
|
waitTime: 1000 |
||||||
|
} |
||||||
|
} |
||||||
|
) |
||||||
|
} |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 19 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in new issue