初始项目,完成显示验证码
|
|
@ -0,0 +1,5 @@
|
||||||
|
Android 4.1
|
||||||
|
IOS 7.1
|
||||||
|
Chrome > 31
|
||||||
|
ff > 31
|
||||||
|
ie >= 11
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
# 环境
|
||||||
|
VITE_NODE_ENV=development
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_API_BASE_PATH=http://39.104.23.25:48080/admin-api/
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
VITE_APP_TITLE=ElementAdmin
|
||||||
|
|
||||||
|
# 是否全量引入element-plus样式
|
||||||
|
VITE_USE_ALL_ELEMENT_PLUS_STYLE=true
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# 是否使用在线图标
|
||||||
|
VITE_USE_ONLINE_ICON=true
|
||||||
|
|
||||||
|
# 是否隐藏全局设置按钮
|
||||||
|
VITE_HIDE_GLOBAL_SETTING=false
|
||||||
|
|
||||||
|
# 是否启用租户功能
|
||||||
|
VITE_APP_TENANT_ENABLE=true
|
||||||
|
|
||||||
|
# 默认租户名称
|
||||||
|
VITE_APP_DEFAULT_LOGIN_TENANT=芋道源码
|
||||||
|
|
||||||
|
#开启验证码
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# 环境
|
||||||
|
VITE_NODE_ENV=production
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_API_BASE_PATH=http://39.104.23.25:48080/admin-api/
|
||||||
|
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/dist-dev/
|
||||||
|
|
||||||
|
# 是否删除debugger
|
||||||
|
VITE_DROP_DEBUGGER=false
|
||||||
|
|
||||||
|
# 是否删除console.log
|
||||||
|
VITE_DROP_CONSOLE=false
|
||||||
|
|
||||||
|
# 是否sourcemap
|
||||||
|
VITE_SOURCEMAP=true
|
||||||
|
|
||||||
|
# 输出路径
|
||||||
|
VITE_OUT_DIR=dist-dev
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
VITE_APP_TITLE=ElementAdmin
|
||||||
|
|
||||||
|
# 是否包分析
|
||||||
|
VITE_USE_BUNDLE_ANALYZER=false
|
||||||
|
|
||||||
|
# 是否全量引入element-plus样式
|
||||||
|
VITE_USE_ALL_ELEMENT_PLUS_STYLE=false
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# 是否切割css
|
||||||
|
VITE_USE_CSS_SPLIT=true
|
||||||
|
|
||||||
|
# 是否使用在线图标
|
||||||
|
VITE_USE_ONLINE_ICON=true
|
||||||
|
|
||||||
|
# 是否隐藏全局设置按钮
|
||||||
|
VITE_HIDE_GLOBAL_SETTING=false
|
||||||
|
|
||||||
|
#开启验证码
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# 环境
|
||||||
|
VITE_NODE_ENV=production
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_API_BASE_PATH=http://39.104.23.25:48080/admin-api/
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/vue-element-plus-admin/
|
||||||
|
|
||||||
|
# 是否删除debugger
|
||||||
|
VITE_DROP_DEBUGGER=true
|
||||||
|
|
||||||
|
# 是否删除console.log
|
||||||
|
VITE_DROP_CONSOLE=true
|
||||||
|
|
||||||
|
# 是否sourcemap
|
||||||
|
VITE_SOURCEMAP=false
|
||||||
|
|
||||||
|
# 输出路径
|
||||||
|
VITE_OUT_DIR=dist-pro
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
VITE_APP_TITLE=ElementAdmin
|
||||||
|
|
||||||
|
# 是否包分析
|
||||||
|
VITE_USE_BUNDLE_ANALYZER=false
|
||||||
|
|
||||||
|
# 是否全量引入element-plus样式
|
||||||
|
VITE_USE_ALL_ELEMENT_PLUS_STYLE=false
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# 是否切割css
|
||||||
|
VITE_USE_CSS_SPLIT=true
|
||||||
|
|
||||||
|
# 是否使用在线图标
|
||||||
|
VITE_USE_ONLINE_ICON=true
|
||||||
|
|
||||||
|
# 是否隐藏全局设置按钮
|
||||||
|
VITE_HIDE_GLOBAL_SETTING=false
|
||||||
|
|
||||||
|
#开启验证码
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# 环境
|
||||||
|
VITE_NODE_ENV=production
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_API_BASE_PATH=http://39.104.23.25:48080/admin-api/
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/
|
||||||
|
|
||||||
|
# 是否删除debugger
|
||||||
|
VITE_DROP_DEBUGGER=true
|
||||||
|
|
||||||
|
# 是否删除console.log
|
||||||
|
VITE_DROP_CONSOLE=true
|
||||||
|
|
||||||
|
# 是否sourcemap
|
||||||
|
VITE_SOURCEMAP=false
|
||||||
|
|
||||||
|
# 输出路径
|
||||||
|
VITE_OUT_DIR=dist-pro
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
VITE_APP_TITLE=ElementAdmin
|
||||||
|
|
||||||
|
# 是否包分析
|
||||||
|
VITE_USE_BUNDLE_ANALYZER=true
|
||||||
|
|
||||||
|
# 是否全量引入element-plus样式
|
||||||
|
VITE_USE_ALL_ELEMENT_PLUS_STYLE=false
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# 是否切割css
|
||||||
|
VITE_USE_CSS_SPLIT=true
|
||||||
|
|
||||||
|
# 是否使用在线图标
|
||||||
|
VITE_USE_ONLINE_ICON=false
|
||||||
|
|
||||||
|
# 是否隐藏全局设置按钮
|
||||||
|
VITE_HIDE_GLOBAL_SETTING=false
|
||||||
|
|
||||||
|
#开启验证码
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# 环境
|
||||||
|
VITE_NODE_ENV=production
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_API_BASE_PATH=http://39.104.23.25:48080/admin-api/
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/dist-test/
|
||||||
|
|
||||||
|
# 是否删除debugger
|
||||||
|
VITE_DROP_DEBUGGER=false
|
||||||
|
|
||||||
|
# 是否删除console.log
|
||||||
|
VITE_DROP_CONSOLE=false
|
||||||
|
|
||||||
|
# 是否sourcemap
|
||||||
|
VITE_SOURCEMAP=true
|
||||||
|
|
||||||
|
# 输出路径
|
||||||
|
VITE_OUT_DIR=dist-test
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
VITE_APP_TITLE=ElementAdmin
|
||||||
|
|
||||||
|
# 是否包分析
|
||||||
|
VITE_USE_BUNDLE_ANALYZER=false
|
||||||
|
|
||||||
|
# 是否全量引入element-plus样式
|
||||||
|
VITE_USE_ALL_ELEMENT_PLUS_STYLE=false
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK=true
|
||||||
|
|
||||||
|
# 是否切割css
|
||||||
|
VITE_USE_CSS_SPLIT=false
|
||||||
|
|
||||||
|
# 是否使用在线图标
|
||||||
|
VITE_USE_ONLINE_ICON=true
|
||||||
|
|
||||||
|
# 是否隐藏全局设置按钮
|
||||||
|
VITE_HIDE_GLOBAL_SETTING=false
|
||||||
|
|
||||||
|
#开启验证码
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=true
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
name: Automerge
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- labeled
|
||||||
|
- unlabeled
|
||||||
|
- synchronize
|
||||||
|
- opened
|
||||||
|
- edited
|
||||||
|
- ready_for_review
|
||||||
|
- reopened
|
||||||
|
- unlocked
|
||||||
|
pull_request_review:
|
||||||
|
types:
|
||||||
|
- submitted
|
||||||
|
status: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# 合并发布版本的 pr 到 master
|
||||||
|
auto-merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Automerge
|
||||||
|
uses: 'pascalgn/automerge-action@v0.14.3'
|
||||||
|
env:
|
||||||
|
BASE_BRANCHES: 'release'
|
||||||
|
GITHUB_TOKEN: '${{ secrets.TOKEN }}'
|
||||||
|
MERGE_LABELS: ''
|
||||||
|
MERGE_FILTER_AUTHOR: 'kailong321200875'
|
||||||
|
|
||||||
|
push-to-gh-pages:
|
||||||
|
needs: [auto-merge]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup Pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
|
- name: use Node.js 18
|
||||||
|
uses: actions/setup-node@v2.1.2
|
||||||
|
with:
|
||||||
|
node-version: '18.x'
|
||||||
|
|
||||||
|
- name: Set SSH Environment
|
||||||
|
env:
|
||||||
|
DOCS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "$ACTIONS_DEPLOY_KEY" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan github.com > ~/.ssh/known_hosts
|
||||||
|
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
|
||||||
|
git config --local user.email "321200875@qq.com"
|
||||||
|
git config --local user.name "kailong321200875"
|
||||||
|
|
||||||
|
# 发布到 github
|
||||||
|
- name: Build Github
|
||||||
|
run: |
|
||||||
|
pnpm install --no-frozen-lockfile
|
||||||
|
pnpm run build:pro
|
||||||
|
|
||||||
|
- name: Deploy Github
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
deploy_key: ${{secrets.ACTIONS_DEPLOY_KEY}}
|
||||||
|
publish_branch: gh-pages
|
||||||
|
publish_dir: ./dist-pro
|
||||||
|
force_orphan: true
|
||||||
|
cname: element-plus-admin.cn
|
||||||
|
|
||||||
|
push-to-gh-pages-gitee:
|
||||||
|
needs: [auto-merge]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup Pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
|
- name: use Node.js 18
|
||||||
|
uses: actions/setup-node@v2.1.2
|
||||||
|
with:
|
||||||
|
node-version: '18.x'
|
||||||
|
|
||||||
|
- name: Set SSH Environment
|
||||||
|
env:
|
||||||
|
DOCS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "$ACTIONS_DEPLOY_KEY" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan github.com > ~/.ssh/known_hosts
|
||||||
|
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
|
||||||
|
git config --local user.email "321200875@qq.com"
|
||||||
|
git config --local user.name "kailong321200875"
|
||||||
|
|
||||||
|
- name: Build Gitee
|
||||||
|
run: |
|
||||||
|
pnpm install --no-frozen-lockfile
|
||||||
|
pnpm run build:gitee
|
||||||
|
|
||||||
|
# 发布到 gitee
|
||||||
|
- name: Deploy Gitee
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
deploy_key: ${{secrets.ACTIONS_DEPLOY_KEY}}
|
||||||
|
publish_branch: gh-pages-gitee
|
||||||
|
publish_dir: ./dist-pro
|
||||||
|
force_orphan: true
|
||||||
|
|
||||||
|
- name: Sync Github Repos To Gitee # 名字随便起
|
||||||
|
uses: Yikun/hub-mirror-action@v1.1 # 使用Yikun/hub-mirror-action
|
||||||
|
with:
|
||||||
|
src: github/kailong321200875 # 源端账户名(github)
|
||||||
|
dst: gitee/kailong110120130 # 目的端账户名(gitee)
|
||||||
|
dst_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} # SSH密钥对中的私钥
|
||||||
|
dst_token: ${{ secrets.GITEE_TOKEN }} # Gitee账户的私人令牌
|
||||||
|
account_type: user # 账户类型
|
||||||
|
clone_style: 'https' # 使用https方式进行clone,也可以使用ssh
|
||||||
|
debug: true # 启用后会显示所有执行命令
|
||||||
|
force_update: true # 启用后,强制同步,即强制覆盖目的端仓库
|
||||||
|
static_list: 'vue-element-plus-admin' # 静态同步列表,在此填写需要同步的仓库名称,可填写多个
|
||||||
|
timeout: '600s' # git超时设置,超时后会自动重试git操作
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- release
|
||||||
|
|
||||||
|
name: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-please:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: GoogleCloudPlatform/release-please-action@v3
|
||||||
|
id: release
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.TOKEN }}
|
||||||
|
default-branch: release
|
||||||
|
release-type: node
|
||||||
|
package-name: standard-version
|
||||||
|
changelog-types: '[{"type": "types", "section":"Types", "hidden": false},{"type": "revert", "section":"Reverts", "hidden": false},{"type": "feat", "section": "Features", "hidden": false},{"type": "fix", "section": "Bug Fixes", "hidden": false},{"type": "improvement", "section": "Feature Improvements", "hidden": false},{"type": "docs", "section":"Docs", "hidden": false},{"type": "style", "section":"Styling", "hidden": false},{"type": "refactor", "section":"Code Refactoring", "hidden": false},{"type": "perf", "section":"Performance Improvements", "hidden": false},{"type": "test", "section":"Tests", "hidden": false},{"type": "build", "section":"Build System", "hidden": false},{"type": "ci", "section":"CI", "hidden":false}]'
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
/dist*
|
||||||
|
*-lock.*
|
||||||
|
pnpm-debug
|
||||||
|
stats.html
|
||||||
|
.idea
|
||||||
|
.vtj/histories
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
npx --no -- commitlint --edit $1
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
module.exports = {
|
||||||
|
'*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
|
||||||
|
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --parser json --write'],
|
||||||
|
'package.json': ['prettier --write'],
|
||||||
|
'*.vue': ['prettier --write', 'stylelint --fix'],
|
||||||
|
'*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write'],
|
||||||
|
'*.md': ['prettier --write'],
|
||||||
|
'*.hbs': ['prettier --write']
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
npm run ts:check
|
||||||
|
npm run lint:lint-staged
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/node_modules/**
|
||||||
|
/dist/
|
||||||
|
/dist*
|
||||||
|
/public/*
|
||||||
|
/docs/*
|
||||||
|
/src/types/env.d.ts
|
||||||
|
/docs/**/*
|
||||||
|
/plop/**/*
|
||||||
|
CHANGELOG
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
/dist/*
|
||||||
|
/public/*
|
||||||
|
public/*
|
||||||
|
/dist*
|
||||||
|
/src/types/env.d.ts
|
||||||
|
/docs/**/*
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["vue.volar", "lokalise.i18n-ally"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
|
"prettier.enable": true,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": "explicit"
|
||||||
|
},
|
||||||
|
"[vue]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"i18n-ally.localesPaths": ["src/locales"],
|
||||||
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"i18n-ally.sortKeys": true,
|
||||||
|
"i18n-ally.namespace": false,
|
||||||
|
"i18n-ally.enabledParsers": ["ts"],
|
||||||
|
"i18n-ally.sourceLanguage": "en",
|
||||||
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
|
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||||
|
"god.tsconfig": "./tsconfig.json"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,313 @@
|
||||||
|
{
|
||||||
|
"name": "Users",
|
||||||
|
"locked": false,
|
||||||
|
"inject": [],
|
||||||
|
"state": {
|
||||||
|
"keyword": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "''"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lifeCycles": {},
|
||||||
|
"methods": {
|
||||||
|
"loader": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "(data) => {\n return this.getData(data)\n}"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n this.$refs.gridRef.search()\n}"
|
||||||
|
},
|
||||||
|
"rowAction": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "(row) => {\n this.$message.info('click row id: ' + row.id)\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"computed": {
|
||||||
|
"columns": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n return [\n {\n type: 'checkbox',\n width: 40\n },\n {\n type: 'seq',\n width: 60,\n title: '序号'\n },\n {\n field: 'name',\n title: '名称',\n minWidth: 100\n },\n {\n field: 'label',\n title: '描述',\n minWidth: 100\n },\n {\n field: 'isDefault',\n title: '默认角色',\n minWidth: 100,\n slots: {\n default: 'isDefault'\n }\n },\n {\n field: 'order',\n title: '排序',\n minWidth: 100,\n sortable: true\n },\n {\n field: 'desc',\n title: '备注',\n minWidth: 100\n },\n {\n field: 'createdAt',\n title: '创建时间',\n minWidth: 140\n },\n {\n field: 'actions',\n title: '操作',\n width: 160,\n slots: {\n default: 'actions'\n }\n }\n ]\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"watch": [],
|
||||||
|
"css": "",
|
||||||
|
"props": [],
|
||||||
|
"emits": [],
|
||||||
|
"slots": [],
|
||||||
|
"dataSources": {
|
||||||
|
"getData": {
|
||||||
|
"name": "getData",
|
||||||
|
"test": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => this.runApi({\n /* 在这里可输入接口参数 */\n})"
|
||||||
|
},
|
||||||
|
"type": "mock",
|
||||||
|
"label": "模拟数据",
|
||||||
|
"mockTemplate": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "(params) => {\n const { page = 1, pageSize = 50 } = params || {};\n const total = 1000;\n return {\n [`list|${pageSize}`]: [{\n id: '@guid',\n name: '@cname',\n label: '@ctitle',\n 'isDefault|1': '@boolean',\n 'order|+1': 1,\n desc: '@cparagraph',\n createdAt: '@date(yyyy-MM-dd hh:mm:ss)'\n }],\n total,\n page,\n limit: pageSize\n };\n}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"__VTJ_BLOCK__": true,
|
||||||
|
"__VERSION__": "1736401534792",
|
||||||
|
"id": "7pdk4mxyf",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "1kqd4haeckr",
|
||||||
|
"name": "XGrid",
|
||||||
|
"from": "@vtj/ui",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "1mp9b7mk9wj",
|
||||||
|
"name": "ElInput",
|
||||||
|
"from": "element-plus",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "toolbar__buttons",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "2ax97lz9cox",
|
||||||
|
"name": "ElButton",
|
||||||
|
"from": "element-plus",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "append",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": "查询",
|
||||||
|
"props": {
|
||||||
|
"type": "primary"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "this.search"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"width": "300px",
|
||||||
|
"margin-right": "10px"
|
||||||
|
},
|
||||||
|
"placeholder": "请输入查询关键字"
|
||||||
|
},
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"id": "l36jhkywal",
|
||||||
|
"name": "vModel",
|
||||||
|
"arg": "modelValue",
|
||||||
|
"value": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.state.keyword"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2ammdsu07o6",
|
||||||
|
"name": "ElButton",
|
||||||
|
"from": "element-plus",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "toolbar__buttons",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": "新增",
|
||||||
|
"props": {
|
||||||
|
"icon": "Plus",
|
||||||
|
"type": "primary"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n this.$message.info('click add button')\n}"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "257nvaelda4",
|
||||||
|
"name": "ElButton",
|
||||||
|
"from": "element-plus",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "toolbar__buttons",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": "批量删除",
|
||||||
|
"props": {
|
||||||
|
"icon": "Delete",
|
||||||
|
"type": "danger"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n const rows = this.$refs.gridRef.getSelected();\n if (rows.length) {\n this.$message.info('delete data rows: ' + rows.length);\n } else {\n this.$message.warning('请选择需要删除的数据项');\n }\n}"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "o52fisb3kt",
|
||||||
|
"name": "ElTag",
|
||||||
|
"from": "element-plus",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "isDefault",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.context.scope_1kqd4haeckr.row.isDefault ? '是' : '否'"
|
||||||
|
},
|
||||||
|
"props": {
|
||||||
|
"type": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.context.scope_1kqd4haeckr.row.isDefault ? 'success' : 'info'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1ft4np8i6i1",
|
||||||
|
"name": "XAction",
|
||||||
|
"from": "@vtj/ui",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "actions",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"props": {
|
||||||
|
"mode": "icon",
|
||||||
|
"size": "default",
|
||||||
|
"type": "primary",
|
||||||
|
"label": "编辑"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n this.rowAction(this.context.scope_1kqd4haeckr.row)\n}"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1e8ewprm6ts",
|
||||||
|
"name": "XAction",
|
||||||
|
"from": "@vtj/ui",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "actions",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"props": {
|
||||||
|
"mode": "icon",
|
||||||
|
"size": "default",
|
||||||
|
"type": "primary",
|
||||||
|
"label": "设置"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "() => {\n this.rowAction(this.context.scope_1kqd4haeckr.row)\n}"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2a1cq8bhwej",
|
||||||
|
"name": "XAction",
|
||||||
|
"from": "@vtj/ui",
|
||||||
|
"invisible": false,
|
||||||
|
"locked": false,
|
||||||
|
"slot": {
|
||||||
|
"name": "actions",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
"children": [],
|
||||||
|
"props": {
|
||||||
|
"mode": "icon",
|
||||||
|
"size": "default",
|
||||||
|
"type": "danger",
|
||||||
|
"label": "删除"
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {
|
||||||
|
"click": {
|
||||||
|
"name": "click",
|
||||||
|
"handler": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "async () => {\n const ret = await this.$confirm('确定删除?', '提示', { type: 'warning' }).catch(() => false);\n if (ret) {\n this.rowAction(this.context.scope_1kqd4haeckr.row)\n }\n}"
|
||||||
|
},
|
||||||
|
"modifiers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"props": {
|
||||||
|
"ref": "gridRef",
|
||||||
|
"pager": true,
|
||||||
|
"height": "auto",
|
||||||
|
"loader": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.loader"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.columns.value"
|
||||||
|
},
|
||||||
|
"resizable": true,
|
||||||
|
"customable": true,
|
||||||
|
"style": {
|
||||||
|
"background-color": "#FFFFFF",
|
||||||
|
"padding-top": "10px",
|
||||||
|
"padding-left": "10px",
|
||||||
|
"padding-right": "10px",
|
||||||
|
"padding-bottom": "10px",
|
||||||
|
"border-radius": "4px 4px 4px 4px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"directives": [],
|
||||||
|
"events": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
{
|
||||||
|
"__VTJ_PROJECT__": true,
|
||||||
|
"id": "vue-element-plus-admin",
|
||||||
|
"name": "ElementAdmin",
|
||||||
|
"homepage": "",
|
||||||
|
"description": "一套基于vue3、element-plus、typesScript、vite4的后台集成方案。",
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"package": "vue",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "Vue",
|
||||||
|
"urls": ["@vtj/materials/deps/vue/vue.global.prod.js"],
|
||||||
|
"assetsLibrary": "VueMaterial",
|
||||||
|
"required": true,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "vue-router",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VueRouter",
|
||||||
|
"urls": ["@vtj/materials/deps/vue-router/vue-router.global.prod.js"],
|
||||||
|
"assetsLibrary": "VueRouterMaterial",
|
||||||
|
"required": true,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "@vtj/utils",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VtjUtils",
|
||||||
|
"urls": ["@vtj/materials/deps/@vtj/utils/index.umd.js"],
|
||||||
|
"required": true,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "@vtj/icons",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VtjIcons",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/@vtj/icons/style.css",
|
||||||
|
"@vtj/materials/deps/@vtj/icons/index.umd.js"
|
||||||
|
],
|
||||||
|
"required": true,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "@vueuse/core",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VueUse",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/@vueuse/shared/index.iife.min.js",
|
||||||
|
"@vtj/materials/deps/@vueuse/core/index.iife.min.js"
|
||||||
|
],
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "element-plus",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "ElementPlus",
|
||||||
|
"localeLibrary": "ElementPlusLocaleZhCn",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/element-plus/dark/css-vars.css",
|
||||||
|
"@vtj/materials/deps/element-plus/index.css",
|
||||||
|
"@vtj/materials/deps/element-plus/zh-cn.js",
|
||||||
|
"@vtj/materials/deps/element-plus/index.full.min.js"
|
||||||
|
],
|
||||||
|
"assetsUrl": "@vtj/materials/assets/element/index.umd.js",
|
||||||
|
"assetsLibrary": "ElementPlusMaterial",
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "@vtj/ui",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VtjUI",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/vxe-table/style.min.css",
|
||||||
|
"@vtj/materials/deps/@vtj/ui/style.css",
|
||||||
|
"@vtj/materials/deps/xe-utils/xe-utils.umd.min.js",
|
||||||
|
"@vtj/materials/deps/vxe-table/index.umd.min.js",
|
||||||
|
"@vtj/materials/deps/@vtj/ui/index.umd.js"
|
||||||
|
],
|
||||||
|
"assetsUrl": "@vtj/materials/assets/ui/index.umd.js",
|
||||||
|
"assetsLibrary": "VtjUIMaterial",
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "@vtj/charts",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "VtjCharts",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/echarts/echarts.min.js",
|
||||||
|
"@vtj/materials/deps/@vtj/charts/index.umd.js"
|
||||||
|
],
|
||||||
|
"assetsUrl": "@vtj/materials/assets/charts/index.umd.js",
|
||||||
|
"assetsLibrary": "VtjChartsMaterial",
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "ant-design-vue",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "antd",
|
||||||
|
"urls": [
|
||||||
|
"@vtj/materials/deps/ant-design-vue/reset.css",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/dayjs.min.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/customParseFormat.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekday.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/localeData.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekOfYear.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekYear.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/advancedFormat.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/quarterOfYear.js",
|
||||||
|
"@vtj/materials/deps/ant-design-vue/antd.min.js"
|
||||||
|
],
|
||||||
|
"assetsUrl": "@vtj/materials/assets/antdv/index.umd.js",
|
||||||
|
"assetsLibrary": "AntdvMaterial",
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "vant",
|
||||||
|
"version": "latest",
|
||||||
|
"library": "vant",
|
||||||
|
"urls": ["@vtj/materials/deps/vant/index.css", "@vtj/materials/deps/vant/vant.min.js"],
|
||||||
|
"assetsUrl": "@vtj/materials/assets/vant/index.umd.js",
|
||||||
|
"assetsLibrary": "VantMaterial",
|
||||||
|
"required": false,
|
||||||
|
"official": true,
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"dir": true,
|
||||||
|
"name": "System",
|
||||||
|
"title": "系统管理",
|
||||||
|
"icon": "ChromeFilled",
|
||||||
|
"hidden": false,
|
||||||
|
"prue": false,
|
||||||
|
"id": "45rmet3ni",
|
||||||
|
"type": "page",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"dir": false,
|
||||||
|
"name": "Users",
|
||||||
|
"title": "用户管理",
|
||||||
|
"icon": "",
|
||||||
|
"mask": true,
|
||||||
|
"hidden": false,
|
||||||
|
"raw": false,
|
||||||
|
"prue": false,
|
||||||
|
"meta": "",
|
||||||
|
"cache": false,
|
||||||
|
"id": "7pdk4mxyf",
|
||||||
|
"type": "page",
|
||||||
|
"market": {
|
||||||
|
"id": "0290db4d-f64e-4119-b62d-1e0b56193d6f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"blocks": [],
|
||||||
|
"apis": [],
|
||||||
|
"meta": [],
|
||||||
|
"config": {},
|
||||||
|
"__BASE_PATH__": "/"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,222 @@
|
||||||
|
<template>
|
||||||
|
<XGrid
|
||||||
|
ref="gridRef"
|
||||||
|
:pager="true"
|
||||||
|
height="auto"
|
||||||
|
:loader="loader"
|
||||||
|
:columns="columns"
|
||||||
|
:resizable="true"
|
||||||
|
:customable="true"
|
||||||
|
class="XGrid_1kqd4haeckr"
|
||||||
|
>
|
||||||
|
<template #toolbar__buttons="scope_1kqd4haeckr">
|
||||||
|
<ElInput
|
||||||
|
v-model:modelValue="state.keyword"
|
||||||
|
placeholder="请输入查询关键字"
|
||||||
|
class="ElInput_1mp9b7mk9wj"
|
||||||
|
>
|
||||||
|
<template #append="scope_1mp9b7mk9wj">
|
||||||
|
<ElButton type="primary" @click="search"> 查询</ElButton>
|
||||||
|
</template></ElInput
|
||||||
|
>
|
||||||
|
<ElButton
|
||||||
|
icon="Plus"
|
||||||
|
type="primary"
|
||||||
|
@click="(...args: any[]) => click_2ammdsu07o6({ scope_1kqd4haeckr }, args)"
|
||||||
|
>
|
||||||
|
新增</ElButton
|
||||||
|
>
|
||||||
|
<ElButton
|
||||||
|
icon="Delete"
|
||||||
|
type="danger"
|
||||||
|
@click="(...args: any[]) => click_257nvaelda4({ scope_1kqd4haeckr }, args)"
|
||||||
|
>
|
||||||
|
批量删除</ElButton
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template #isDefault="scope_1kqd4haeckr">
|
||||||
|
<ElTag :type="scope_1kqd4haeckr.row.isDefault ? 'success' : 'info'">
|
||||||
|
{{ scope_1kqd4haeckr.row.isDefault ? '是' : '否' }}</ElTag
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template #actions="scope_1kqd4haeckr">
|
||||||
|
<XAction
|
||||||
|
mode="icon"
|
||||||
|
size="default"
|
||||||
|
type="primary"
|
||||||
|
label="编辑"
|
||||||
|
@click="(...args: any[]) => click_1ft4np8i6i1({ scope_1kqd4haeckr }, args)"
|
||||||
|
></XAction>
|
||||||
|
<XAction
|
||||||
|
mode="icon"
|
||||||
|
size="default"
|
||||||
|
type="primary"
|
||||||
|
label="设置"
|
||||||
|
@click="(...args: any[]) => click_1e8ewprm6ts({ scope_1kqd4haeckr }, args)"
|
||||||
|
></XAction>
|
||||||
|
<XAction
|
||||||
|
mode="icon"
|
||||||
|
size="default"
|
||||||
|
type="danger"
|
||||||
|
label="删除"
|
||||||
|
@click="(...args: any[]) => click_2a1cq8bhwej({ scope_1kqd4haeckr }, args)"
|
||||||
|
></XAction> </template
|
||||||
|
></XGrid>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
// @ts-nocheck
|
||||||
|
import { defineComponent, reactive } from 'vue'
|
||||||
|
import { XGrid, XAction } from '@vtj/ui'
|
||||||
|
import { ElInput, ElButton, ElTag } from 'element-plus'
|
||||||
|
import { useProvider } from '@vtj/renderer'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Users',
|
||||||
|
components: { XGrid, ElInput, ElButton, ElTag, XAction },
|
||||||
|
setup(props) {
|
||||||
|
const provider = useProvider({ id: '7pdk4mxyf', version: '1736401534792' })
|
||||||
|
const state = reactive<Record<string, any>>({ keyword: '' })
|
||||||
|
return { state, props, provider }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columns() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
width: 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'seq',
|
||||||
|
width: 60,
|
||||||
|
title: '序号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
title: '名称',
|
||||||
|
minWidth: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'label',
|
||||||
|
title: '描述',
|
||||||
|
minWidth: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isDefault',
|
||||||
|
title: '默认角色',
|
||||||
|
minWidth: 100,
|
||||||
|
slots: {
|
||||||
|
default: 'isDefault'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order',
|
||||||
|
title: '排序',
|
||||||
|
minWidth: 100,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'desc',
|
||||||
|
title: '备注',
|
||||||
|
minWidth: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'createdAt',
|
||||||
|
title: '创建时间',
|
||||||
|
minWidth: 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'actions',
|
||||||
|
title: '操作',
|
||||||
|
width: 160,
|
||||||
|
slots: {
|
||||||
|
default: 'actions'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getData(...args: any[]) {
|
||||||
|
const mock = this.provider.createMock((params) => {
|
||||||
|
const { page = 1, pageSize = 50 } = params || {}
|
||||||
|
const total = 1000
|
||||||
|
return {
|
||||||
|
[`list|${pageSize}`]: [
|
||||||
|
{
|
||||||
|
id: '@guid',
|
||||||
|
name: '@cname',
|
||||||
|
label: '@ctitle',
|
||||||
|
'isDefault|1': '@boolean',
|
||||||
|
'order|+1': 1,
|
||||||
|
desc: '@cparagraph',
|
||||||
|
createdAt: '@date(yyyy-MM-dd hh:mm:ss)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
total,
|
||||||
|
page,
|
||||||
|
limit: pageSize
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return await mock.apply(this, args)
|
||||||
|
},
|
||||||
|
click_2ammdsu07o6({ scope_1kqd4haeckr }, args) {
|
||||||
|
return (() => {
|
||||||
|
this.$message.info('click add button')
|
||||||
|
}).apply(this, args)
|
||||||
|
},
|
||||||
|
click_257nvaelda4({ scope_1kqd4haeckr }, args) {
|
||||||
|
return (() => {
|
||||||
|
const rows = this.$refs.gridRef.getSelected()
|
||||||
|
if (rows.length) {
|
||||||
|
this.$message.info('delete data rows: ' + rows.length)
|
||||||
|
} else {
|
||||||
|
this.$message.warning('请选择需要删除的数据项')
|
||||||
|
}
|
||||||
|
}).apply(this, args)
|
||||||
|
},
|
||||||
|
click_1ft4np8i6i1({ scope_1kqd4haeckr }, args) {
|
||||||
|
return (() => {
|
||||||
|
this.rowAction(scope_1kqd4haeckr.row)
|
||||||
|
}).apply(this, args)
|
||||||
|
},
|
||||||
|
click_1e8ewprm6ts({ scope_1kqd4haeckr }, args) {
|
||||||
|
return (() => {
|
||||||
|
this.rowAction(scope_1kqd4haeckr.row)
|
||||||
|
}).apply(this, args)
|
||||||
|
},
|
||||||
|
click_2a1cq8bhwej({ scope_1kqd4haeckr }, args) {
|
||||||
|
return (async () => {
|
||||||
|
const ret = await this.$confirm('确定删除?', '提示', {
|
||||||
|
type: 'warning'
|
||||||
|
}).catch(() => false)
|
||||||
|
if (ret) {
|
||||||
|
this.rowAction(scope_1kqd4haeckr.row)
|
||||||
|
}
|
||||||
|
}).apply(this, args)
|
||||||
|
},
|
||||||
|
loader(data) {
|
||||||
|
return this.getData(data)
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.$refs.gridRef.search()
|
||||||
|
},
|
||||||
|
rowAction(row) {
|
||||||
|
this.$message.info('click row id: ' + row.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.XGrid_1kqd4haeckr {
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-radius: 4px 4px 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ElInput_1mp9b7mk9wj {
|
||||||
|
width: 300px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
FROM node:18.0.0
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install -g pnpm@8.1.0
|
||||||
|
|
||||||
|
COPY package.json .
|
||||||
|
|
||||||
|
RUN pnpm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
CMD [ "pnpm", "run", "dev" ]
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021-present Archer
|
||||||
|
|
||||||
|
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,22 @@
|
||||||
|
获取代码
|
||||||
|
git clone
|
||||||
|
安装依赖
|
||||||
|
cd vue-element-plus-admin
|
||||||
|
pnpm config set registry https://registry.npmmirror.com/
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
运行
|
||||||
|
pnpm run dev
|
||||||
|
打包
|
||||||
|
pnpm run build:pro
|
||||||
|
|
||||||
|
问题
|
||||||
|
1.集成到本地项目 本地启动运行可以看到设计器入口
|
||||||
|
设计器是在开发环境提供辅助开发服务的,不是在线的
|
||||||
|
在线参考 https://gitee.com/newgateway/vtj/tree/master/lcdp
|
||||||
|
|
||||||
|
npm install -g lerna@latest pnpm@latest --registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
|
2.关于下载依赖报错:error (ERR_INVALID_THIS)
|
||||||
|
pnpm升级到 8.3.1 :
|
||||||
|
npm install -g pnpm@8.3.1
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
<div align="center"> <a href="https://github.com/kailong321200875/vue-element-plus-admin"> <img width="100" src="./public/logo.png"> </a> <br> <br>
|
||||||
|
|
||||||
|
[](LICENSE) [](repo-size) [](last-commit) [](stars) [](forks) [](release) [](watchers)
|
||||||
|
|
||||||
|
<h1>vue-element-plus-admin</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
[English](./README.md) | **中文**
|
||||||
|
|
||||||
|
## 介绍
|
||||||
|
|
||||||
|
vue-element-plus-admin 是一个基于 `element-plus` 免费开源的中后台模版。使用了最新的`vue3`,`vite`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,可以用来作为项目的启动模版,也可用于学习参考。并且时刻关注着最新技术动向,尽可能的第一时间更新。
|
||||||
|
|
||||||
|
vue-element-plus-admin 的定位是后台集成方案,不太适合当基础模板来进行二次开发。因为集成了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。
|
||||||
|
|
||||||
|
如需要基础模版,请切换到 `mini` 分支,`mini` 只简单集成了一些如:布局、动态菜单等常用布局功能,更适合开发者进行二次开发。
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
- **最新技术栈**:使用 Vue3/vite4 等前端前沿技术开发
|
||||||
|
- **TypeScript**: 应用程序级 JavaScript 的语言
|
||||||
|
- **主题**: 可配置的主题
|
||||||
|
- **国际化**:内置完善的国际化方案
|
||||||
|
- **自定义数据** 内置 Mock 数据方案
|
||||||
|
- **权限** 内置完善的动态路由权限生成方案
|
||||||
|
- **组件** 二次封装了多个常用的组件
|
||||||
|
- **示例** 内置丰富的示例
|
||||||
|
|
||||||
|
## 预览
|
||||||
|
|
||||||
|
- [vue-element-plus-admin](https://element-plus-admin.cn/) - 完整版 github 站点
|
||||||
|
- [vue-element-plus-admin](https://kailong110120130.gitee.io/vue-element-plus-admin) - 完整版 gitee 站点
|
||||||
|
|
||||||
|
帐号:**admin/admin**
|
||||||
|
|
||||||
|
在线例子默认不适用菜单过滤,而是直接使用静态路由表
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
[文档地址 Github](https://element-plus-admin-doc.cn/)
|
||||||
|
|
||||||
|
[文档地址 Gitee](https://kailong110120130.gitee.io/vue-element-plus-admin-doc)
|
||||||
|
|
||||||
|
## 前序准备
|
||||||
|
|
||||||
|
- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) - 项目开发环境
|
||||||
|
- [Vite](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 基本使用
|
||||||
|
- [Element-Plus](https://element-plus.org/) - element-plus 基本使用
|
||||||
|
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法
|
||||||
|
|
||||||
|
## 安装和使用
|
||||||
|
|
||||||
|
- 获取代码
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/kailong321200875/vue-element-plus-admin.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd vue-element-plus-admin
|
||||||
|
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
- 运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
- 打包
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run build:pro
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
[更新日志](./CHANGELOG.md)
|
||||||
|
|
||||||
|
## 如何贡献
|
||||||
|
|
||||||
|
<a href="https://github.com/kailong321200875/vue-element-plus-admin/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=kailong321200875/vue-element-plus-admin" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
你可以[提一个 issue](https://github.com/kailong321200875/vue-element-plus-admin/issues/new) 或者提交一个 Pull Request。
|
||||||
|
|
||||||
|
**Pull Request:**
|
||||||
|
|
||||||
|
1. Fork 代码
|
||||||
|
2. 创建自己的分支: `git checkout -b feat/xxxx`
|
||||||
|
3. 提交你的修改: `git commit -am 'feat(function): add xxxxx'`
|
||||||
|
4. 推送您的分支: `git push origin feat/xxxx`
|
||||||
|
5. 提交 `pull request`
|
||||||
|
|
||||||
|
## Git 贡献提交规范
|
||||||
|
|
||||||
|
- `feat` 新功能
|
||||||
|
- `fix` 修补 bug
|
||||||
|
- `docs` 文档
|
||||||
|
- `style` 格式、样式(不影响代码运行的变动)
|
||||||
|
- `refactor` 重构(即不是新增功能,也不是修改 BUG 的代码)
|
||||||
|
- `perf` 优化相关,比如提升性能、体验
|
||||||
|
- `test` 添加测试
|
||||||
|
- `build` 编译相关的修改,对项目构建或者依赖的改动
|
||||||
|
- `ci` 持续集成修改
|
||||||
|
- `chore` 构建过程或辅助工具的变动
|
||||||
|
- `revert` 回滚到上一个版本
|
||||||
|
- `workflow` 工作流改进
|
||||||
|
- `mod` 不确定分类的修改
|
||||||
|
- `wip` 开发中
|
||||||
|
- `types` 类型
|
||||||
|
|
||||||
|
## 浏览器支持
|
||||||
|
|
||||||
|
本地开发推荐使用 `Chrome 80+` 浏览器
|
||||||
|
|
||||||
|
支持现代浏览器, 不支持 IE
|
||||||
|
|
||||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_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 |
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
如果你觉得这个项目有帮助,欢迎赞助以示支持~
|
||||||
|
|
||||||
|
[Paypal Me](https://www.paypal.com/paypalme/ckl94)
|
||||||
|
|
||||||
|
<img src="https://gitee.com/kailong110120130/my-image/raw/master/pay.jpg" />
|
||||||
|
|
||||||
|
### 我的二维码
|
||||||
|
|
||||||
|
如有项目合作或项目外包,扫码加我好友,请备注来意。
|
||||||
|
|
||||||
|
<img src="https://gitee.com/kailong110120130/my-image/raw/master/me.jpg" />
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
[MIT](./LICENSE)
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
rules: {
|
||||||
|
'type-enum': [
|
||||||
|
2,
|
||||||
|
'always',
|
||||||
|
[
|
||||||
|
'feat', // 新功能(feature)
|
||||||
|
'fix', // 修补bug
|
||||||
|
'docs', // 文档(documentation)
|
||||||
|
'style', // 格式、样式(不影响代码运行的变动)
|
||||||
|
'refactor', // 重构(即不是新增功能,也不是修改BUG的代码)
|
||||||
|
'perf', // 优化相关,比如提升性能、体验
|
||||||
|
'test', // 添加测试
|
||||||
|
'ci', // 持续集成修改
|
||||||
|
'chore', // 构建过程或辅助工具的变动
|
||||||
|
'revert', // 回滚到上一个版本
|
||||||
|
'workflow', // 工作流改进
|
||||||
|
'mod', // 不确定分类的修改
|
||||||
|
'wip', // 开发中
|
||||||
|
'types', // 类型修改
|
||||||
|
'release' // 版本发布
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'subject-full-stop': [0, 'never'],
|
||||||
|
'subject-case': [0, 'never']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
services:
|
||||||
|
vue-element-plus-admin:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
ports:
|
||||||
|
- "4000:4000"
|
||||||
|
volumes:
|
||||||
|
- /app/node_modules
|
||||||
|
- .:/app
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// 引入vue模版的eslint
|
||||||
|
import pluginVue from 'eslint-plugin-vue'
|
||||||
|
import eslint from '@eslint/js'
|
||||||
|
// ts-eslint解析器,使 eslint 可以解析 ts 语法
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
// vue文件解析器
|
||||||
|
import vueParser from 'vue-eslint-parser'
|
||||||
|
import prettier from 'eslint-plugin-prettier'
|
||||||
|
|
||||||
|
export default tseslint.config({
|
||||||
|
// ignores: ['node_modules', 'prettier.config.cjs', 'dist*'],
|
||||||
|
files: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
|
||||||
|
// tseslint.config添加了extends扁平函数,直接用。否则是eslint9.0版本是没有extends的
|
||||||
|
extends: [
|
||||||
|
eslint.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
...pluginVue.configs['flat/essential']
|
||||||
|
],
|
||||||
|
plugins: {
|
||||||
|
prettier
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parser: vueParser, // 使用vue解析器,这个可以识别vue文件
|
||||||
|
parserOptions: {
|
||||||
|
parser: tseslint.parser, // 在vue文件上使用ts解析器
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': 'error',
|
||||||
|
'no-useless-escape': 0,
|
||||||
|
'no-undef': 0,
|
||||||
|
'vue/no-setup-props-destructure': 0,
|
||||||
|
'vue/script-setup-uses-vars': 1,
|
||||||
|
'vue/no-reserved-component-names': 0,
|
||||||
|
'@typescript-eslint/ban-ts-ignore': 0,
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 0,
|
||||||
|
'@typescript-eslint/no-explicit-any': 0,
|
||||||
|
'@typescript-eslint/no-var-requires': 0,
|
||||||
|
'@typescript-eslint/no-empty-function': 0,
|
||||||
|
'vue/custom-event-name-casing': 0,
|
||||||
|
'no-use-before-define': 0,
|
||||||
|
'@typescript-eslint/no-use-before-define': 0,
|
||||||
|
'@typescript-eslint/ban-ts-comment': 0,
|
||||||
|
'@typescript-eslint/ban-types': 0,
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 0,
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||||
|
'@typescript-eslint/no-unused-vars': 0,
|
||||||
|
'no-unused-vars': 0,
|
||||||
|
'space-before-function-paren': 0,
|
||||||
|
|
||||||
|
'vue/attributes-order': 0,
|
||||||
|
'vue/one-component-per-file': 0,
|
||||||
|
'vue/html-closing-bracket-newline': 0,
|
||||||
|
'vue/max-attributes-per-line': 0,
|
||||||
|
'vue/multiline-html-element-content-newline': 0,
|
||||||
|
'vue/singleline-html-element-content-newline': 0,
|
||||||
|
'vue/attribute-hyphenation': 0,
|
||||||
|
'vue/require-default-prop': 0,
|
||||||
|
'vue/require-explicit-emits': 0,
|
||||||
|
'vue/html-self-closing': [
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
html: {
|
||||||
|
void: 'always',
|
||||||
|
normal: 'never',
|
||||||
|
component: 'always'
|
||||||
|
},
|
||||||
|
svg: 'always',
|
||||||
|
math: 'always'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'vue/multi-word-component-names': 0,
|
||||||
|
'vue/no-v-html': 0,
|
||||||
|
'vue/require-toggle-inside-transition': 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title><%= title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<style>
|
||||||
|
.app-loading {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #f0f2f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
display: flex;
|
||||||
|
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||||
|
transform: translate3d(-50%, -50%, 0);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-title {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-logo {
|
||||||
|
width: 100px;
|
||||||
|
margin: 0 auto 15px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-item {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-outter {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 4px solid #2d8cf0;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: loader-outter 1s cubic-bezier(0.42, 0.61, 0.58, 0.41) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-inner {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 20px);
|
||||||
|
left: calc(50% - 20px);
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 4px solid #87bdff;
|
||||||
|
border-right: 0;
|
||||||
|
border-top-color: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: loader-inner 1s cubic-bezier(0.42, 0.61, 0.58, 0.41) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes loader-outter {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes loader-outter {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes loader-inner {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(-360deg);
|
||||||
|
transform: rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes loader-inner {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(-360deg);
|
||||||
|
transform: rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="app-loading">
|
||||||
|
<div class="app-loading-wrap">
|
||||||
|
<div class="app-loading-title">
|
||||||
|
<img src="/logo.png" class="app-loading-logo" alt="Logo" />
|
||||||
|
<div class="app-loading-title"><%= title %></div>
|
||||||
|
</div>
|
||||||
|
<div class="app-loading-item">
|
||||||
|
<div class="app-loading-outter"></div>
|
||||||
|
<div class="app-loading-inner"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
|
||||||
|
|
||||||
|
const modules = import.meta.glob('./**/*.mock.ts', {
|
||||||
|
import: 'default',
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockModules: any[] = []
|
||||||
|
Object.keys(modules).forEach(async (key) => {
|
||||||
|
if (key.includes('_')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mockModules.push(...(modules[key] as any))
|
||||||
|
})
|
||||||
|
|
||||||
|
export function setupProdMockServer() {
|
||||||
|
createProdMockServer(mockModules)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
import { MockMethod } from 'vite-plugin-mock'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 分析页统计接口
|
||||||
|
{
|
||||||
|
url: '/mock/analysis/total',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
users: 102400,
|
||||||
|
messages: 81212,
|
||||||
|
moneys: 9280,
|
||||||
|
shoppings: 13600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 用户来源
|
||||||
|
{
|
||||||
|
url: '/mock/analysis/userAccessSource',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{ value: 1000, name: 'analysis.directAccess' },
|
||||||
|
{ value: 310, name: 'analysis.mailMarketing' },
|
||||||
|
{ value: 234, name: 'analysis.allianceAdvertising' },
|
||||||
|
{ value: 135, name: 'analysis.videoAdvertising' },
|
||||||
|
{ value: 1548, name: 'analysis.searchEngines' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 每周用户活跃量
|
||||||
|
{
|
||||||
|
url: '/mock/analysis/weeklyUserActivity',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{ value: 13253, name: 'analysis.monday' },
|
||||||
|
{ value: 34235, name: 'analysis.tuesday' },
|
||||||
|
{ value: 26321, name: 'analysis.wednesday' },
|
||||||
|
{ value: 12340, name: 'analysis.thursday' },
|
||||||
|
{ value: 24643, name: 'analysis.friday' },
|
||||||
|
{ value: 1322, name: 'analysis.saturday' },
|
||||||
|
{ value: 1324, name: 'analysis.sunday' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 每月销售额
|
||||||
|
{
|
||||||
|
url: '/mock/analysis/monthlySales',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{ estimate: 100, actual: 120, name: 'analysis.january' },
|
||||||
|
{ estimate: 120, actual: 82, name: 'analysis.february' },
|
||||||
|
{ estimate: 161, actual: 91, name: 'analysis.march' },
|
||||||
|
{ estimate: 134, actual: 154, name: 'analysis.april' },
|
||||||
|
{ estimate: 105, actual: 162, name: 'analysis.may' },
|
||||||
|
{ estimate: 160, actual: 140, name: 'analysis.june' },
|
||||||
|
{ estimate: 165, actual: 145, name: 'analysis.july' },
|
||||||
|
{ estimate: 114, actual: 250, name: 'analysis.august' },
|
||||||
|
{ estimate: 163, actual: 134, name: 'analysis.september' },
|
||||||
|
{ estimate: 185, actual: 56, name: 'analysis.october' },
|
||||||
|
{ estimate: 118, actual: 99, name: 'analysis.november' },
|
||||||
|
{ estimate: 123, actual: 123, name: 'analysis.december' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
] as MockMethod[]
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
import { toAnyString } from '@/utils'
|
||||||
|
import Mock from 'mockjs'
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const departmentList: any = []
|
||||||
|
|
||||||
|
const citys = ['厦门总公司', '北京分公司', '上海分公司', '福州分公司', '深圳分公司', '杭州分公司']
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
departmentList.push({
|
||||||
|
// 部门名称
|
||||||
|
departmentName: citys[i],
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '研发部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '产品部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '运营部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '市场部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '销售部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 部门名称
|
||||||
|
departmentName: '客服部',
|
||||||
|
id: toAnyString(),
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 状态
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
// 备注
|
||||||
|
remark: '@cword(10, 15)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 列表接口
|
||||||
|
{
|
||||||
|
url: '/mock/department/list',
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
list: departmentList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/department/table/list',
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
list: departmentList,
|
||||||
|
total: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/department/users',
|
||||||
|
method: 'get',
|
||||||
|
timeout: 1000,
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { pageSize } = query
|
||||||
|
// 根据pageSize来创建数据
|
||||||
|
const mockList: any = []
|
||||||
|
for (let i = 0; i < pageSize; i++) {
|
||||||
|
mockList.push(
|
||||||
|
Mock.mock({
|
||||||
|
// 用户名
|
||||||
|
username: '@cname',
|
||||||
|
// 账号
|
||||||
|
account: '@first',
|
||||||
|
// 邮箱
|
||||||
|
email: '@EMAIL',
|
||||||
|
// 创建时间
|
||||||
|
createTime: '@datetime',
|
||||||
|
// 用户id
|
||||||
|
id: toAnyString()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: 100,
|
||||||
|
list: mockList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 保存接口
|
||||||
|
{
|
||||||
|
url: '/mock/department/user/save',
|
||||||
|
method: 'post',
|
||||||
|
timeout: 1000,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除接口
|
||||||
|
{
|
||||||
|
url: '/mock/department/user/delete',
|
||||||
|
method: 'post',
|
||||||
|
response: ({ body }) => {
|
||||||
|
const ids = body.ids
|
||||||
|
if (!ids) {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
message: '请选择需要删除的数据'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 保存接口
|
||||||
|
{
|
||||||
|
url: '/mock/department/save',
|
||||||
|
method: 'post',
|
||||||
|
timeout: 1000,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除接口
|
||||||
|
{
|
||||||
|
url: '/mock/department/delete',
|
||||||
|
method: 'post',
|
||||||
|
response: ({ body }) => {
|
||||||
|
const ids = body.ids
|
||||||
|
if (!ids) {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
message: '请选择需要删除的数据'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
|
||||||
|
const dictObj: Recordable = {
|
||||||
|
importance: [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: 'tableDemo.commonly'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: 'tableDemo.good'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: 'tableDemo.important'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 字典接口
|
||||||
|
{
|
||||||
|
url: '/mock/dict/list',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: dictObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取某个字典
|
||||||
|
{
|
||||||
|
url: '/mock/dict/one',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
label: 'test1',
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'test2',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'test3',
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,357 @@
|
||||||
|
import Mock from 'mockjs'
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 列表接口
|
||||||
|
{
|
||||||
|
url: '/mock/menu/list',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
path: '/dashboard',
|
||||||
|
component: '#',
|
||||||
|
redirect: '/dashboard/analysis',
|
||||||
|
name: 'Dashboard',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 1,
|
||||||
|
type: 0,
|
||||||
|
parentId: undefined,
|
||||||
|
title: '首页',
|
||||||
|
meta: {
|
||||||
|
title: '首页',
|
||||||
|
icon: 'vi-ant-design:dashboard-filled',
|
||||||
|
alwaysShow: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'analysis',
|
||||||
|
component: 'views/Dashboard/Analysis',
|
||||||
|
name: 'Analysis',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 2,
|
||||||
|
type: 1,
|
||||||
|
parentId: 1,
|
||||||
|
title: '分析页',
|
||||||
|
permissionList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '新增',
|
||||||
|
value: 'add'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '编辑',
|
||||||
|
value: 'edit'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
title: '分析页',
|
||||||
|
noCache: true,
|
||||||
|
permission: ['add', 'edit']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'workplace',
|
||||||
|
component: 'views/Dashboard/Workplace',
|
||||||
|
name: 'Workplace',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 3,
|
||||||
|
type: 1,
|
||||||
|
parentId: 1,
|
||||||
|
title: '工作台',
|
||||||
|
permissionList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '新增',
|
||||||
|
value: 'add'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '编辑',
|
||||||
|
value: 'edit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: '删除',
|
||||||
|
value: 'delete'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
title: '工作台',
|
||||||
|
noCache: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/external-link',
|
||||||
|
component: '#',
|
||||||
|
meta: {
|
||||||
|
title: '文档',
|
||||||
|
icon: 'vi-clarity:document-solid'
|
||||||
|
},
|
||||||
|
name: 'ExternalLink',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 4,
|
||||||
|
type: 0,
|
||||||
|
parentId: undefined,
|
||||||
|
title: '文档',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'https://element-plus-admin-doc.cn/',
|
||||||
|
name: 'DocumentLink',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 5,
|
||||||
|
type: 1,
|
||||||
|
parentId: 4,
|
||||||
|
title: '文档',
|
||||||
|
meta: {
|
||||||
|
title: '文档'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/level',
|
||||||
|
component: '#',
|
||||||
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
|
name: 'Level',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 6,
|
||||||
|
type: 0,
|
||||||
|
parentId: undefined,
|
||||||
|
title: '菜单',
|
||||||
|
meta: {
|
||||||
|
title: '菜单',
|
||||||
|
icon: 'vi-carbon:skill-level-advanced'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1',
|
||||||
|
name: 'Menu1',
|
||||||
|
component: '##',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 7,
|
||||||
|
type: 0,
|
||||||
|
parentId: 6,
|
||||||
|
title: '菜单1',
|
||||||
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
|
meta: {
|
||||||
|
title: '菜单1'
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1-1',
|
||||||
|
name: 'Menu11',
|
||||||
|
component: '##',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 8,
|
||||||
|
type: 0,
|
||||||
|
parentId: 7,
|
||||||
|
title: '菜单1-1',
|
||||||
|
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||||
|
meta: {
|
||||||
|
title: '菜单1-1',
|
||||||
|
alwaysShow: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1-1-1',
|
||||||
|
name: 'Menu111',
|
||||||
|
component: 'views/Level/Menu111',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 9,
|
||||||
|
type: 1,
|
||||||
|
parentId: 8,
|
||||||
|
title: '菜单1-1-1',
|
||||||
|
meta: {
|
||||||
|
title: '菜单1-1-1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'menu1-2',
|
||||||
|
name: 'Menu12',
|
||||||
|
component: 'views/Level/Menu12',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 10,
|
||||||
|
type: 1,
|
||||||
|
parentId: 7,
|
||||||
|
title: '菜单1-2',
|
||||||
|
meta: {
|
||||||
|
title: '菜单1-2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'menu2',
|
||||||
|
name: 'Menu2Demo',
|
||||||
|
component: 'views/Level/Menu2',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 11,
|
||||||
|
type: 1,
|
||||||
|
parentId: 6,
|
||||||
|
title: '菜单2',
|
||||||
|
meta: {
|
||||||
|
title: '菜单2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/example',
|
||||||
|
component: '#',
|
||||||
|
redirect: '/example/example-dialog',
|
||||||
|
name: 'Example',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 12,
|
||||||
|
type: 0,
|
||||||
|
parentId: undefined,
|
||||||
|
title: '综合示例',
|
||||||
|
meta: {
|
||||||
|
title: '综合示例',
|
||||||
|
icon: 'vi-ep:management',
|
||||||
|
alwaysShow: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'example-dialog',
|
||||||
|
component: 'views/Example/Dialog/ExampleDialog',
|
||||||
|
name: 'ExampleDialog',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 13,
|
||||||
|
type: 1,
|
||||||
|
parentId: 12,
|
||||||
|
title: '综合示例-弹窗',
|
||||||
|
permissionList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '新增',
|
||||||
|
value: 'add'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '编辑',
|
||||||
|
value: 'edit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: '删除',
|
||||||
|
value: 'delete'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: '查看',
|
||||||
|
value: 'view'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
title: '综合示例-弹窗'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'example-page',
|
||||||
|
component: 'views/Example/Page/ExamplePage',
|
||||||
|
name: 'ExamplePage',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 14,
|
||||||
|
type: 1,
|
||||||
|
parentId: 12,
|
||||||
|
title: '综合示例-页面',
|
||||||
|
permissionList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '新增',
|
||||||
|
value: 'add'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '编辑',
|
||||||
|
value: 'edit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: '删除',
|
||||||
|
value: 'delete'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: '查看',
|
||||||
|
value: 'view'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
title: '综合示例-页面'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'example-add',
|
||||||
|
component: 'views/Example/Page/ExampleAdd',
|
||||||
|
name: 'ExampleAdd',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 15,
|
||||||
|
type: 1,
|
||||||
|
parentId: 12,
|
||||||
|
title: '综合示例-新增',
|
||||||
|
meta: {
|
||||||
|
title: '综合示例-新增',
|
||||||
|
noTagsView: true,
|
||||||
|
noCache: true,
|
||||||
|
hidden: true,
|
||||||
|
showMainRoute: true,
|
||||||
|
activeMenu: '/example/example-page'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'example-edit',
|
||||||
|
component: 'views/Example/Page/ExampleEdit',
|
||||||
|
name: 'ExampleEdit',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 16,
|
||||||
|
type: 1,
|
||||||
|
parentId: 12,
|
||||||
|
title: '综合示例-编辑',
|
||||||
|
meta: {
|
||||||
|
title: '综合示例-编辑',
|
||||||
|
noTagsView: true,
|
||||||
|
noCache: true,
|
||||||
|
hidden: true,
|
||||||
|
showMainRoute: true,
|
||||||
|
activeMenu: '/example/example-page'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'example-detail',
|
||||||
|
component: 'views/Example/Page/ExampleDetail',
|
||||||
|
name: 'ExampleDetail',
|
||||||
|
status: Mock.Random.integer(0, 1),
|
||||||
|
id: 17,
|
||||||
|
type: 1,
|
||||||
|
parentId: 12,
|
||||||
|
title: '综合示例-详情',
|
||||||
|
meta: {
|
||||||
|
title: '综合示例-详情',
|
||||||
|
noTagsView: true,
|
||||||
|
noCache: true,
|
||||||
|
hidden: true,
|
||||||
|
showMainRoute: true,
|
||||||
|
activeMenu: '/example/example-page'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const timeout = 600000
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: '/mock/request/1',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'request-1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/request/2',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'request-2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/request/3',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'request-3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/request/4',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'request-4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/request/5',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'request-5'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/request/expired',
|
||||||
|
method: 'get',
|
||||||
|
timeout: 0,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: 401,
|
||||||
|
message: 'token expired'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
import Mock from 'mockjs'
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
import { toAnyString } from '@/utils'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
const count = 100
|
||||||
|
|
||||||
|
const baseContent =
|
||||||
|
'<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
|
||||||
|
|
||||||
|
interface ListProps {
|
||||||
|
id: string
|
||||||
|
author: string
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
importance: number
|
||||||
|
display_time: any
|
||||||
|
pageviews: number
|
||||||
|
image_uri: string
|
||||||
|
video_uri?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TreeListProps {
|
||||||
|
id: string
|
||||||
|
author: string
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
importance: number
|
||||||
|
display_time: any
|
||||||
|
image_uri: string
|
||||||
|
pageviews: number
|
||||||
|
video_uri?: string
|
||||||
|
children?: TreeListProps[]
|
||||||
|
}
|
||||||
|
|
||||||
|
let List: ListProps[] = []
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
List.push(
|
||||||
|
Mock.mock({
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(100, 500)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)'),
|
||||||
|
video_uri:
|
||||||
|
'//sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const treeList: TreeListProps[] = []
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
treeList.push(
|
||||||
|
Mock.mock({
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: toAnyString(),
|
||||||
|
// timestamp: +Mock.Random.date('T'),
|
||||||
|
author: '@first',
|
||||||
|
title: '@title(5, 10)',
|
||||||
|
content: baseContent,
|
||||||
|
importance: '@integer(1, 3)',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)',
|
||||||
|
image_uri: Mock.Random.image('@integer(100, 500)x@integer(100, 500)')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// image_uri
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardList = [
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
|
||||||
|
name: 'Alipay',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png',
|
||||||
|
name: 'Angular',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png',
|
||||||
|
name: 'Bootstrap',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png',
|
||||||
|
name: 'React',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png',
|
||||||
|
name: 'Vue',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png',
|
||||||
|
name: 'Webpack',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 树形列表接口
|
||||||
|
{
|
||||||
|
url: '/mock/example/treeList',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { title, pageIndex, pageSize } = query
|
||||||
|
const mockList = treeList.filter((item) => {
|
||||||
|
if (title && item.title.indexOf(title) < 0) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const pageList = mockList.filter(
|
||||||
|
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: mockList.length,
|
||||||
|
list: pageList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 列表接口
|
||||||
|
{
|
||||||
|
url: '/mock/example/list',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { title, pageIndex, pageSize } = query
|
||||||
|
const mockList = List.filter((item) => {
|
||||||
|
if (title && item.title.indexOf(title) < 0) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const pageList = mockList.filter(
|
||||||
|
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: mockList.length,
|
||||||
|
list: pageList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 保存接口
|
||||||
|
{
|
||||||
|
url: '/mock/example/save',
|
||||||
|
method: 'post',
|
||||||
|
timeout,
|
||||||
|
response: ({ body }) => {
|
||||||
|
if (!body.id) {
|
||||||
|
List = [
|
||||||
|
Object.assign(body, {
|
||||||
|
id: toAnyString()
|
||||||
|
})
|
||||||
|
].concat(List)
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List.map((item) => {
|
||||||
|
if (item.id === body.id) {
|
||||||
|
for (const key in item) {
|
||||||
|
item[key] = body[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 详情接口
|
||||||
|
{
|
||||||
|
url: '/mock/example/detail',
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { id } = query
|
||||||
|
for (const example of List) {
|
||||||
|
if (example.id === id) {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: example
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 删除接口
|
||||||
|
{
|
||||||
|
url: '/mock/example/delete',
|
||||||
|
method: 'post',
|
||||||
|
response: ({ body }) => {
|
||||||
|
const ids = body.ids
|
||||||
|
if (!ids) {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
message: '请选择需要删除的数据'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let i = List.length
|
||||||
|
while (i--) {
|
||||||
|
if (ids.indexOf(List[i].id) !== -1) {
|
||||||
|
List.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/card/list',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { name, pageIndex, pageSize } = query
|
||||||
|
const mockList = cardList.filter((item) => {
|
||||||
|
if (name && item.name.indexOf(name) < 0) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const pageList = mockList.filter(
|
||||||
|
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: mockList.length,
|
||||||
|
list: pageList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
|
||||||
|
const List: {
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
role: string
|
||||||
|
roleId: string
|
||||||
|
permissions: string | string[]
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
username: 'admin',
|
||||||
|
password: 'admin',
|
||||||
|
role: 'admin',
|
||||||
|
roleId: '1',
|
||||||
|
permissions: ['*.*.*']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
username: 'test',
|
||||||
|
password: 'test',
|
||||||
|
role: 'test',
|
||||||
|
roleId: '2',
|
||||||
|
permissions: ['example:dialog:create', 'example:dialog:delete']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 列表接口
|
||||||
|
{
|
||||||
|
url: '/mock/user/list',
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { username, pageIndex, pageSize } = query
|
||||||
|
|
||||||
|
const mockList = List.filter((item) => {
|
||||||
|
if (username && item.username.indexOf(username) < 0) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const pageList = mockList.filter(
|
||||||
|
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: mockList.length,
|
||||||
|
list: pageList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 登录接口
|
||||||
|
{
|
||||||
|
url: '/mock/user/login',
|
||||||
|
method: 'post',
|
||||||
|
timeout,
|
||||||
|
response: ({ body }) => {
|
||||||
|
const data = body
|
||||||
|
let hasUser = false
|
||||||
|
for (const user of List) {
|
||||||
|
if (user.username === data.username && user.password === data.password) {
|
||||||
|
hasUser = true
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasUser) {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
message: '账号或密码错误'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 退出接口
|
||||||
|
{
|
||||||
|
url: '/mock/user/loginOut',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
import { SUCCESS_CODE } from '@/constants'
|
||||||
|
|
||||||
|
const timeout = 1000
|
||||||
|
|
||||||
|
export default [
|
||||||
|
// 获取统计
|
||||||
|
{
|
||||||
|
url: '/mock/workplace/total',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
project: 40,
|
||||||
|
access: 2340,
|
||||||
|
todo: 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取项目
|
||||||
|
{
|
||||||
|
url: '/mock/workplace/project',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'Github',
|
||||||
|
icon: 'akar-icons:github-fill',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Vue',
|
||||||
|
icon: 'logos:vue',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Angular',
|
||||||
|
icon: 'logos:angular-icon',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'React',
|
||||||
|
icon: 'logos:react',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Webpack',
|
||||||
|
icon: 'logos:webpack',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Vite',
|
||||||
|
icon: 'vscode-icons:file-type-vite',
|
||||||
|
message: 'workplace.introduction',
|
||||||
|
personal: 'Archer',
|
||||||
|
time: new Date()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取动态
|
||||||
|
{
|
||||||
|
url: '/mock/workplace/dynamic',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['workplace.push', 'Github'],
|
||||||
|
time: new Date()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取团队信息
|
||||||
|
{
|
||||||
|
url: '/mock/workplace/team',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'Github',
|
||||||
|
icon: 'akar-icons:github-fill'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Vue',
|
||||||
|
icon: 'logos:vue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Angular',
|
||||||
|
icon: 'logos:angular-icon'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'React',
|
||||||
|
icon: 'logos:react'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Webpack',
|
||||||
|
icon: 'logos:webpack'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Vite',
|
||||||
|
icon: 'vscode-icons:file-type-vite'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取指数
|
||||||
|
{
|
||||||
|
url: '/mock/workplace/radar',
|
||||||
|
method: 'get',
|
||||||
|
timeout,
|
||||||
|
response: () => {
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: [
|
||||||
|
{ name: 'workplace.quote', max: 65, personal: 42, team: 50 },
|
||||||
|
{ name: 'workplace.contribution', max: 160, personal: 30, team: 140 },
|
||||||
|
{ name: 'workplace.hot', max: 300, personal: 20, team: 28 },
|
||||||
|
{ name: 'workplace.yield', max: 130, personal: 35, team: 35 },
|
||||||
|
{ name: 'workplace.follow', max: 100, personal: 80, team: 90 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
{
|
||||||
|
"name": "vue-element-plus-admin",
|
||||||
|
"version": "2.8.1",
|
||||||
|
"description": "一套基于vue3、element-plus、typesScript、vite4的后台集成方案。",
|
||||||
|
"author": "Archer <502431556@qq.com>",
|
||||||
|
"private": false,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"i": "pnpm install",
|
||||||
|
"dev": "pnpm vite --mode base",
|
||||||
|
"ts:check": "pnpm vue-tsc --noEmit --skipLibCheck",
|
||||||
|
"build:pro": "pnpm vite build --mode pro",
|
||||||
|
"build:gitee": "pnpm vite build --mode gitee",
|
||||||
|
"build:dev": "pnpm vite build --mode dev",
|
||||||
|
"build:test": "pnpm vite build --mode test",
|
||||||
|
"serve:pro": "pnpm vite preview --mode pro",
|
||||||
|
"serve:dev": "pnpm vite preview --mode dev",
|
||||||
|
"serve:test": "pnpm vite preview --mode test",
|
||||||
|
"npm:check": "pnpx npm-check-updates -u",
|
||||||
|
"clean": "pnpx rimraf node_modules",
|
||||||
|
"clean:cache": "pnpx rimraf node_modules/.cache",
|
||||||
|
"lint:eslint": "eslint . --fix \"src/**/*.{js,ts,tsx,vue,html}\"",
|
||||||
|
"lint:format": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,vue,html,md}\"",
|
||||||
|
"lint:style": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||||
|
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.cjs",
|
||||||
|
"prepare": "husky install",
|
||||||
|
"p": "plop",
|
||||||
|
"icon": "esno ./scripts/icon.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/iconify": "^3.1.1",
|
||||||
|
"@iconify/vue": "^4.1.2",
|
||||||
|
"@vtj/icons": "^0.11.6",
|
||||||
|
"@vtj/web": "latest",
|
||||||
|
"@vueuse/core": "^10.11.0",
|
||||||
|
"@wangeditor/editor": "^5.1.23",
|
||||||
|
"@wangeditor/editor-for-vue": "^5.1.10",
|
||||||
|
"@zxcvbn-ts/core": "^3.0.4",
|
||||||
|
"animate.css": "^4.1.1",
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"cropperjs": "^1.6.2",
|
||||||
|
"dayjs": "^1.11.11",
|
||||||
|
"driver.js": "^1.3.1",
|
||||||
|
"echarts": "^5.5.1",
|
||||||
|
"echarts-wordcloud": "^2.1.0",
|
||||||
|
"element-plus": "2.7.7",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
|
"monaco-editor": "^0.50.0",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
|
"qrcode": "^1.5.3",
|
||||||
|
"qs": "^6.12.3",
|
||||||
|
"url": "^0.11.3",
|
||||||
|
"vue": "3.4.32",
|
||||||
|
"vue-draggable-plus": "^0.5.2",
|
||||||
|
"vue-i18n": "9.13.1",
|
||||||
|
"vue-json-pretty": "^2.4.0",
|
||||||
|
"vue-router": "^4.4.0",
|
||||||
|
"vue-types": "^5.1.3",
|
||||||
|
"xgplayer": "^3.0.18"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@commitlint/cli": "^19.3.0",
|
||||||
|
"@commitlint/config-conventional": "^19.2.2",
|
||||||
|
"@iconify/json": "^2.2.229",
|
||||||
|
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||||
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
"@types/inquirer": "^9.0.7",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
"@types/mockjs": "^1.0.10",
|
||||||
|
"@types/node": "^20.14.11",
|
||||||
|
"@types/nprogress": "^0.2.3",
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
|
"@types/qs": "^6.9.15",
|
||||||
|
"@types/sortablejs": "^1.15.8",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.16.1",
|
||||||
|
"@typescript-eslint/parser": "^7.16.1",
|
||||||
|
"@unocss/transformer-variant-group": "^0.61.5",
|
||||||
|
"@vitejs/plugin-legacy": "^5.4.1",
|
||||||
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||||
|
"@vtj/cli": "latest",
|
||||||
|
"@vtj/pro": "latest",
|
||||||
|
"autoprefixer": "^10.4.19",
|
||||||
|
"chalk": "^5.3.0",
|
||||||
|
"consola": "^3.2.3",
|
||||||
|
"eslint": "^9.7.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-define-config": "^2.1.0",
|
||||||
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
|
"eslint-plugin-vue": "^9.27.0",
|
||||||
|
"esno": "^4.7.0",
|
||||||
|
"fs-extra": "^11.2.0",
|
||||||
|
"husky": "^9.1.0",
|
||||||
|
"inquirer": "^10.0.3",
|
||||||
|
"less": "^4.2.0",
|
||||||
|
"lint-staged": "^15.2.7",
|
||||||
|
"mockjs": "^1.1.0",
|
||||||
|
"plop": "^4.0.1",
|
||||||
|
"postcss": "^8.4.39",
|
||||||
|
"postcss-html": "^1.7.0",
|
||||||
|
"postcss-less": "^6.0.0",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"rimraf": "^6.0.1",
|
||||||
|
"rollup": "^4.18.1",
|
||||||
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
|
"stylelint": "^16.7.0",
|
||||||
|
"stylelint-config-html": "^1.1.0",
|
||||||
|
"stylelint-config-recommended": "^14.0.1",
|
||||||
|
"stylelint-config-standard": "^36.0.1",
|
||||||
|
"stylelint-order": "^6.0.4",
|
||||||
|
"terser": "^5.31.3",
|
||||||
|
"typescript": "5.5.3",
|
||||||
|
"typescript-eslint": "^7.16.1",
|
||||||
|
"unocss": "^0.61.5",
|
||||||
|
"vite": "5.3.4",
|
||||||
|
"vite-plugin-ejs": "^1.7.0",
|
||||||
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
|
"vite-plugin-mock": "2.9.6",
|
||||||
|
"vite-plugin-progress": "^0.0.7",
|
||||||
|
"vite-plugin-purge-icons": "^0.10.0",
|
||||||
|
"vite-plugin-style-import": "2.0.0",
|
||||||
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
|
"vite-plugin-url-copy": "^1.1.4",
|
||||||
|
"vue-tsc": "^2.0.26"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@8.1.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0",
|
||||||
|
"pnpm": ">=8.1.0"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/kailong321200875/vue-element-plus-admin.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/kailong321200875/vue-element-plus-admin/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/kailong321200875/vue-element-plus-admin",
|
||||||
|
"vtj": {
|
||||||
|
"id": "vue-element-plus-admin",
|
||||||
|
"name": "ElementAdmin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('{{ name }}')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="`${prefixCls}-{{ name }}`">{{ upperFirstName }}</div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import {{ upperFirstName }} from './src/{{ upperFirstName }}.vue'
|
||||||
|
|
||||||
|
export { {{ upperFirstName }} }
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
const toUpperCase = (str) => str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
description: 'Create vue component',
|
||||||
|
prompts: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'name',
|
||||||
|
message: '请输入组件名称(Please enter the component name)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions: (data) => {
|
||||||
|
const { name } = data
|
||||||
|
const upperFirstName = toUpperCase(name)
|
||||||
|
|
||||||
|
const actions = []
|
||||||
|
if (name) {
|
||||||
|
actions.push({
|
||||||
|
type: 'add',
|
||||||
|
path: `./src/components/${upperFirstName}/src/${upperFirstName}.vue`,
|
||||||
|
templateFile: './plop/component/component.hbs',
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
upperFirstName
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
type: 'add',
|
||||||
|
path: `./src/components/${upperFirstName}/index.ts`,
|
||||||
|
templateFile: './plop/component/index.hbs',
|
||||||
|
data: {
|
||||||
|
upperFirstName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
const toUpperCase = (str) => str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
description: 'Create vue view',
|
||||||
|
prompts: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'path',
|
||||||
|
message: '请输入路径(Please enter a path)',
|
||||||
|
default: 'views'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'name',
|
||||||
|
message: '请输入模块名称(Please enter module name)'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions: (data) => {
|
||||||
|
const { name, path } = data
|
||||||
|
const upperFirstName = toUpperCase(name)
|
||||||
|
|
||||||
|
const actions = []
|
||||||
|
if (name) {
|
||||||
|
actions.push({
|
||||||
|
type: 'add',
|
||||||
|
path: `./src/${path}/${upperFirstName}.vue`,
|
||||||
|
templateFile: './plop/view/view.hbs',
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
upperFirstName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap title="{{ upperFirstName }}"> {{ name }} </ContentWrap>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
const viewGenerator = require('./plop/view/prompt.cjs')
|
||||||
|
const componentGenerator = require('./plop/component/prompt.cjs')
|
||||||
|
|
||||||
|
module.exports = function (plop) {
|
||||||
|
plop.setGenerator('view', viewGenerator)
|
||||||
|
plop.setGenerator('component', componentGenerator)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
autoprefixer: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 100,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: false,
|
||||||
|
vueIndentScriptAndStyle: false,
|
||||||
|
singleQuote: true,
|
||||||
|
quoteProps: 'as-needed',
|
||||||
|
bracketSpacing: true,
|
||||||
|
trailingComma: 'none',
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
arrowParens: 'always',
|
||||||
|
insertPragma: false,
|
||||||
|
requirePragma: false,
|
||||||
|
proseWrap: 'never',
|
||||||
|
htmlWhitespaceSensitivity: 'strict',
|
||||||
|
endOfLine: 'auto',
|
||||||
|
rangeStart: 0
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
|
@ -0,0 +1,73 @@
|
||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs-extra'
|
||||||
|
import inquirer from 'inquirer'
|
||||||
|
import chalk from 'chalk'
|
||||||
|
import pkg from '../package.json'
|
||||||
|
import { ICON_PREFIX } from '../src/constants'
|
||||||
|
|
||||||
|
interface Icon {
|
||||||
|
name: string
|
||||||
|
prefix: string
|
||||||
|
icons: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
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?'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
// ↓命令行问答的答案
|
||||||
|
.then(async (answers) => {
|
||||||
|
const { iconSet } = answers
|
||||||
|
// const isOnLine = useType === 'onLine'
|
||||||
|
const outputDir = path.resolve(process.cwd(), 'src/components/IconPicker/src/data')
|
||||||
|
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 prefixName = `${ICON_PREFIX}${prefix}`
|
||||||
|
const icons = Object.keys(data.icons).map((item) => `${prefixName}:${item}`)
|
||||||
|
|
||||||
|
await fs.writeFileSync(
|
||||||
|
path.join('src/components/IconPicker/src/data', `icons.${prefix}.ts`),
|
||||||
|
`export default ${JSON.stringify({ name: info.name, prefix: prefixName, icons })}`
|
||||||
|
)
|
||||||
|
// ↓分类处理完成,push类型名称
|
||||||
|
prefixSet.push(prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
generateIcon()
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import { ConfigGlobal } from '@/components/ConfigGlobal'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { ElNotification } from 'element-plus'
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('app')
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const currentSize = computed(() => appStore.getCurrentSize)
|
||||||
|
|
||||||
|
const greyMode = computed(() => appStore.getGreyMode)
|
||||||
|
|
||||||
|
appStore.initTheme()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ConfigGlobal :size="currentSize">
|
||||||
|
<RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" />
|
||||||
|
</ConfigGlobal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@prefix-cls: ~'@{adminNamespace}-app';
|
||||||
|
|
||||||
|
.size {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
.size;
|
||||||
|
|
||||||
|
#app {
|
||||||
|
.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{prefix-cls}-grey-mode {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
|
||||||
|
// 获取所有字典
|
||||||
|
export const getDictApi = () => {
|
||||||
|
return request.get({ url: '/mock/dict/list' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟获取某个字典
|
||||||
|
export const getDictOneApi = async () => {
|
||||||
|
return request.get({ url: '/mock/dict/one' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import type {
|
||||||
|
AnalysisTotalTypes,
|
||||||
|
UserAccessSource,
|
||||||
|
WeeklyUserActivity,
|
||||||
|
MonthlySales
|
||||||
|
} from './types'
|
||||||
|
|
||||||
|
export const getCountApi = (): Promise<IResponse<AnalysisTotalTypes[]>> => {
|
||||||
|
return request.get({ url: '/mock/analysis/total' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserAccessSourceApi = (): Promise<IResponse<UserAccessSource[]>> => {
|
||||||
|
return request.get({ url: '/mock/analysis/userAccessSource' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getWeeklyUserActivityApi = (): Promise<IResponse<WeeklyUserActivity[]>> => {
|
||||||
|
return request.get({ url: '/mock/analysis/weeklyUserActivity' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getMonthlySalesApi = (): Promise<IResponse<MonthlySales[]>> => {
|
||||||
|
return request.get({ url: '/mock/analysis/monthlySales' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
export type AnalysisTotalTypes = {
|
||||||
|
users: number
|
||||||
|
messages: number
|
||||||
|
moneys: number
|
||||||
|
shoppings: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserAccessSource = {
|
||||||
|
value: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WeeklyUserActivity = {
|
||||||
|
value: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MonthlySales = {
|
||||||
|
name: string
|
||||||
|
estimate: number
|
||||||
|
actual: number
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import type { WorkplaceTotal, Project, Dynamic, Team, RadarData } from './types'
|
||||||
|
|
||||||
|
export const getCountApi = (): Promise<IResponse<WorkplaceTotal>> => {
|
||||||
|
return request.get({ url: '/mock/workplace/total' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getProjectApi = (): Promise<IResponse<Project>> => {
|
||||||
|
return request.get({ url: '/mock/workplace/project' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getDynamicApi = (): Promise<IResponse<Dynamic[]>> => {
|
||||||
|
return request.get({ url: '/mock/workplace/dynamic' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTeamApi = (): Promise<IResponse<Team[]>> => {
|
||||||
|
return request.get({ url: '/mock/workplace/team' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getRadarApi = (): Promise<IResponse<RadarData[]>> => {
|
||||||
|
return request.get({ url: '/mock/workplace/radar' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
export type WorkplaceTotal = {
|
||||||
|
project: number
|
||||||
|
access: number
|
||||||
|
todo: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Project = {
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
|
message: string
|
||||||
|
personal: string
|
||||||
|
time: Date | number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Dynamic = {
|
||||||
|
keys: string[]
|
||||||
|
time: Date | number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Team = {
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RadarData = {
|
||||||
|
personal: number
|
||||||
|
team: number
|
||||||
|
max: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import { DepartmentListResponse, DepartmentUserParams, DepartmentUserResponse } from './types'
|
||||||
|
|
||||||
|
export const getDepartmentApi = () => {
|
||||||
|
return request.get<DepartmentListResponse>({ url: '/mock/department/list' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserByIdApi = (params: DepartmentUserParams) => {
|
||||||
|
return request.get<DepartmentUserResponse>({ url: '/mock/department/users', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteUserByIdApi = (ids: string[] | number[]) => {
|
||||||
|
return request.post({ url: '/mock/department/user/delete', data: { ids } })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveUserApi = (data: any) => {
|
||||||
|
return request.post({ url: '/mock/department/user/save', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveDepartmentApi = (data: any) => {
|
||||||
|
return request.post({ url: '/mock/department/save', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteDepartmentApi = (ids: string[] | number[]) => {
|
||||||
|
return request.post({ url: '/mock/department/delete', data: { ids } })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getDepartmentTableApi = (params: any) => {
|
||||||
|
return request.get({ url: '/mock/department/table/list', params })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
export interface DepartmentItem {
|
||||||
|
id: string
|
||||||
|
departmentName: string
|
||||||
|
children?: DepartmentItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DepartmentListResponse {
|
||||||
|
list: DepartmentItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DepartmentUserParams {
|
||||||
|
pageSize: number
|
||||||
|
pageIndex: number
|
||||||
|
id: string
|
||||||
|
username?: string
|
||||||
|
account?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DepartmentUserItem {
|
||||||
|
id: string
|
||||||
|
username: string
|
||||||
|
account: string
|
||||||
|
email: string
|
||||||
|
createTime: string
|
||||||
|
role: string
|
||||||
|
department: DepartmentItem
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DepartmentUserResponse {
|
||||||
|
list: DepartmentUserItem[]
|
||||||
|
total: number
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import { getRefreshToken } from '@/utils/auth'
|
||||||
|
import type { UserVO, UserLoginVO, RegisterVO } from './types'
|
||||||
|
|
||||||
|
export interface SmsCodeVO {
|
||||||
|
mobile: string
|
||||||
|
scene: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SmsLoginVO {
|
||||||
|
mobile: string
|
||||||
|
code: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
export const login = (data: UserLoginVO) => {
|
||||||
|
return request.post({ url: '/system/auth/login', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册
|
||||||
|
export const register = (data: RegisterVO) => {
|
||||||
|
return request.post({ url: '/system/auth/register', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用租户名,获得租户编号
|
||||||
|
export const getTenantIdByName = (name: string) => {
|
||||||
|
return request.get({ url: '/system/tenant/get-id-by-name?name=' + name })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用租户域名,获得租户信息
|
||||||
|
export const getTenantByWebsite = (website: string) => {
|
||||||
|
return request.get({ url: '/system/tenant/get-by-website?website=' + website })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登出
|
||||||
|
export const loginOutApi = () => {
|
||||||
|
return request.post({ url: '/system/auth/logout' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户权限信息
|
||||||
|
export const getInfo = () => {
|
||||||
|
return request.get({ url: '/system/auth/get-permission-info' })
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取登录验证码
|
||||||
|
export const sendSmsCode = (data: SmsCodeVO) => {
|
||||||
|
return request.post({ url: '/system/auth/send-sms-code', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 短信验证码登录
|
||||||
|
export const smsLogin = (data: SmsLoginVO) => {
|
||||||
|
return request.post({ url: '/system/auth/sms-login', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 社交快捷登录,使用 code 授权码
|
||||||
|
export function socialLogin(type: string, code: string, state: string) {
|
||||||
|
return request.post({
|
||||||
|
url: '/system/auth/social-login',
|
||||||
|
data: {
|
||||||
|
type,
|
||||||
|
code,
|
||||||
|
state
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 社交授权的跳转
|
||||||
|
export const socialAuthRedirect = (type: number, redirectUri: string) => {
|
||||||
|
return request.get({
|
||||||
|
url: '/system/auth/social-auth-redirect?type=' + type + '&redirectUri=' + redirectUri
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取验证图片以及 token
|
||||||
|
export const getCode = (data: any) => {
|
||||||
|
return request.post({ url: '/system/captcha/get', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 滑动或者点选验证
|
||||||
|
export const reqCheck = (data: any) => {
|
||||||
|
return request.post({ url: '/system/captcha/check', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过短信重置密码
|
||||||
|
export const smsResetPassword = (data: any) => {
|
||||||
|
return request.post({ url: '/system/auth/reset-password', data })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
export type UserLoginVO = {
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
captchaVerification: string
|
||||||
|
rememberMe?: boolean
|
||||||
|
socialType?: string
|
||||||
|
socialCode?: string
|
||||||
|
socialState?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TokenType = {
|
||||||
|
id: number // 编号
|
||||||
|
accessToken: string // 访问令牌
|
||||||
|
refreshToken: string // 刷新令牌
|
||||||
|
userId: number // 用户编号
|
||||||
|
userType: number //用户类型
|
||||||
|
clientId: string //客户端编号
|
||||||
|
expiresTime: number //过期时间
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserVO = {
|
||||||
|
id: number
|
||||||
|
username: string
|
||||||
|
nickname: string
|
||||||
|
deptId: number
|
||||||
|
email: string
|
||||||
|
mobile: string
|
||||||
|
sex: number
|
||||||
|
avatar: string
|
||||||
|
loginIp: string
|
||||||
|
loginDate: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RegisterVO = {
|
||||||
|
tenantName: string
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
captchaVerification: string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
|
||||||
|
export const getMenuListApi = () => {
|
||||||
|
return request.get({ url: '/mock/menu/list' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import { RequestResponse } from './types'
|
||||||
|
|
||||||
|
export const request1 = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/1'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const request2 = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/2'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const request3 = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/3'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const request4 = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/4'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const request5 = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/5'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const expired = () => {
|
||||||
|
return request.get<IResponse<RequestResponse>>({
|
||||||
|
url: '/mock/request/expired'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface RequestResponse {
|
||||||
|
data: string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
|
||||||
|
export const getRoleListApi = () => {
|
||||||
|
return request.get({ url: '/mock/role/table' })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import request from '@/axios'
|
||||||
|
import type { TableData } from './types'
|
||||||
|
|
||||||
|
export const getTableListApi = (params: any) => {
|
||||||
|
return request.get({ url: '/mock/example/list', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCardTableListApi = (params: any) => {
|
||||||
|
return request.get({ url: '/mock/card/list', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTreeTableListApi = (params: any) => {
|
||||||
|
return request.get({ url: '/mock/example/treeList', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveTableApi = (data: Partial<TableData>): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/mock/example/save', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTableDetApi = (id: string): Promise<IResponse<TableData>> => {
|
||||||
|
return request.get({ url: '/mock/example/detail', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delTableListApi = (ids: string[] | number[]): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/mock/example/delete', data: { ids } })
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
export type TableData = {
|
||||||
|
id: string
|
||||||
|
author: string
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
importance: number
|
||||||
|
display_time: string
|
||||||
|
pageviews: number
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 014.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 012.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="5760" height="3040"><image width="5760" height="3040" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFoAAAAvgAQMAAAC1QKagAAAABGdBTUEAALGPC/xhBQAAACBjSFJN AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEUsNEr///91v/yPAAAA AWJLR0QB/wIt3gAAAAd0SU1FB+YBBQYyN1c3BnEAAAhjSURBVHja7cExAQAAAMKg9U9tDB+gAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAACAtwFzzwABY3VrRQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMi0wMS0wNVQwNjo1 MDo1MyswMDowMCfNlVoAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjItMDEtMDVUMDY6NTA6NTQrMDA6 MDCTNxNoAAAAAElFTkSuQmCC"/></svg>
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg>
|
||||||
|
After Width: | Height: | Size: 669 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg>
|
||||||
|
After Width: | Height: | Size: 335 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg>
|
||||||
|
After Width: | Height: | Size: 731 B |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 013.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 01-3.889 2.843 10.582 10.582 0 01-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 01-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 01-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 013.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 013.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 01-3.89 2.843 11 11 0 01-4.732 1.066 10.58 10.58 0 01-4.667-1.066 12.478 12.478 0 01-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 01-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 013.824-2.772 11.212 11.212 0 014.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 01.778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 01-2.788 8.743 1236.373 1236.373 0 00-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 01-1.88-4.478 44.128 44.128 0 01-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 01-2.14-2.558 10.416 10.416 0 01-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 011.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { AxiosResponse, InternalAxiosRequestConfig } from './types'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import qs from 'qs'
|
||||||
|
import { SUCCESS_CODE, TRANSFORM_REQUEST_DATA } from '@/constants'
|
||||||
|
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||||
|
import { objToFormData } from '@/utils'
|
||||||
|
import { getTenantId } from '@/utils/auth'
|
||||||
|
|
||||||
|
const defaultRequestInterceptors = (config: InternalAxiosRequestConfig) => {
|
||||||
|
// 添加租户ID请求头
|
||||||
|
const tenantId = getTenantId()
|
||||||
|
if (tenantId) {
|
||||||
|
config.headers['Tenant-Id'] = tenantId
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
config.method === 'post' &&
|
||||||
|
config.headers['Content-Type'] === 'application/x-www-form-urlencoded'
|
||||||
|
) {
|
||||||
|
config.data = qs.stringify(config.data)
|
||||||
|
} else if (
|
||||||
|
TRANSFORM_REQUEST_DATA &&
|
||||||
|
config.method === 'post' &&
|
||||||
|
config.headers['Content-Type'] === 'multipart/form-data' &&
|
||||||
|
!(config.data instanceof FormData)
|
||||||
|
) {
|
||||||
|
config.data = objToFormData(config.data)
|
||||||
|
}
|
||||||
|
if (config.method === 'get' && config.params) {
|
||||||
|
let url = config.url as string
|
||||||
|
url += '?'
|
||||||
|
const keys = Object.keys(config.params)
|
||||||
|
for (const key of keys) {
|
||||||
|
if (config.params[key] !== void 0 && config.params[key] !== null) {
|
||||||
|
url += `${key}=${encodeURIComponent(config.params[key])}&`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url = url.substring(0, url.length - 1)
|
||||||
|
config.params = {}
|
||||||
|
config.url = url
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultResponseInterceptors = (response: AxiosResponse) => {
|
||||||
|
// 添加调试日志
|
||||||
|
console.log('响应URL:', response.config.url);
|
||||||
|
console.log('响应状态:', response.status);
|
||||||
|
console.log('响应数据类型:', typeof response.data);
|
||||||
|
|
||||||
|
// 验证码接口特殊处理
|
||||||
|
if (response.config.url?.includes('/system/captcha')) {
|
||||||
|
console.log('验证码接口响应:', response.data);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response?.config?.responseType === 'blob') {
|
||||||
|
// 如果是文件流,直接过
|
||||||
|
return response
|
||||||
|
} else if (response.data.code === SUCCESS_CODE) {
|
||||||
|
return response.data
|
||||||
|
} else {
|
||||||
|
// 添加更详细的错误日志
|
||||||
|
console.error('响应错误:', response.data);
|
||||||
|
console.error('错误代码:', response.data.code);
|
||||||
|
console.error('错误消息:', response.data.message);
|
||||||
|
|
||||||
|
ElMessage.error(response?.data?.message || '请求失败')
|
||||||
|
if (response?.data?.code === 401) {
|
||||||
|
const userStore = useUserStoreWithOut()
|
||||||
|
userStore.logout()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回响应数据,让调用方处理错误
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { defaultResponseInterceptors, defaultRequestInterceptors }
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import service from './service'
|
||||||
|
import { CONTENT_TYPE } from '@/constants'
|
||||||
|
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||||
|
|
||||||
|
const request = (option: AxiosConfig) => {
|
||||||
|
const { url, method, params, data, headers, responseType } = option
|
||||||
|
|
||||||
|
const userStore = useUserStoreWithOut()
|
||||||
|
return service.request({
|
||||||
|
url: url,
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
data: data,
|
||||||
|
responseType: responseType,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': CONTENT_TYPE,
|
||||||
|
[userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? '',
|
||||||
|
...headers
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
get: <T = any>(option: AxiosConfig) => {
|
||||||
|
return request({ method: 'get', ...option }) as Promise<IResponse<T>>
|
||||||
|
},
|
||||||
|
post: <T = any>(option: AxiosConfig) => {
|
||||||
|
return request({ method: 'post', ...option }) as Promise<IResponse<T>>
|
||||||
|
},
|
||||||
|
delete: <T = any>(option: AxiosConfig) => {
|
||||||
|
return request({ method: 'delete', ...option }) as Promise<IResponse<T>>
|
||||||
|
},
|
||||||
|
put: <T = any>(option: AxiosConfig) => {
|
||||||
|
return request({ method: 'put', ...option }) as Promise<IResponse<T>>
|
||||||
|
},
|
||||||
|
cancelRequest: (url: string | string[]) => {
|
||||||
|
return service.cancelRequest(url)
|
||||||
|
},
|
||||||
|
cancelAllRequest: () => {
|
||||||
|
return service.cancelAllRequest()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
import axios, { AxiosError } from 'axios'
|
||||||
|
import { defaultRequestInterceptors, defaultResponseInterceptors } from './config'
|
||||||
|
|
||||||
|
import { AxiosInstance, InternalAxiosRequestConfig, RequestConfig, AxiosResponse } from './types'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { REQUEST_TIMEOUT } from '@/constants'
|
||||||
|
|
||||||
|
export const PATH_URL = import.meta.env.VITE_API_BASE_PATH
|
||||||
|
|
||||||
|
const abortControllerMap: Map<string, AbortController> = new Map()
|
||||||
|
|
||||||
|
const axiosInstance: AxiosInstance = axios.create({
|
||||||
|
timeout: REQUEST_TIMEOUT,
|
||||||
|
baseURL: PATH_URL
|
||||||
|
})
|
||||||
|
|
||||||
|
axiosInstance.interceptors.request.use((res: InternalAxiosRequestConfig) => {
|
||||||
|
const controller = new AbortController()
|
||||||
|
const url = res.url || ''
|
||||||
|
res.signal = controller.signal
|
||||||
|
abortControllerMap.set(
|
||||||
|
import.meta.env.VITE_USE_MOCK === 'true' ? url.replace('/mock', '') : url,
|
||||||
|
controller
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
|
||||||
|
axiosInstance.interceptors.response.use(
|
||||||
|
(res: AxiosResponse) => {
|
||||||
|
const url = res.config.url || ''
|
||||||
|
abortControllerMap.delete(url)
|
||||||
|
// 这里不能做任何处理,否则后面的 interceptors 拿不到完整的上下文了
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
(error: AxiosError) => {
|
||||||
|
console.log('err: ' + error) // for debug
|
||||||
|
ElMessage.error(error.message)
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
axiosInstance.interceptors.request.use(defaultRequestInterceptors)
|
||||||
|
axiosInstance.interceptors.response.use(defaultResponseInterceptors)
|
||||||
|
|
||||||
|
const service = {
|
||||||
|
request: (config: RequestConfig) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (config.interceptors?.requestInterceptors) {
|
||||||
|
config = config.interceptors.requestInterceptors(config as any)
|
||||||
|
}
|
||||||
|
|
||||||
|
axiosInstance
|
||||||
|
.request(config)
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancelRequest: (url: string | string[]) => {
|
||||||
|
const urlList = Array.isArray(url) ? url : [url]
|
||||||
|
for (const _url of urlList) {
|
||||||
|
abortControllerMap.get(_url)?.abort()
|
||||||
|
abortControllerMap.delete(_url)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancelAllRequest() {
|
||||||
|
for (const [_, controller] of abortControllerMap) {
|
||||||
|
controller.abort()
|
||||||
|
}
|
||||||
|
abortControllerMap.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default service
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import type {
|
||||||
|
InternalAxiosRequestConfig,
|
||||||
|
AxiosResponse,
|
||||||
|
AxiosRequestConfig,
|
||||||
|
AxiosInstance,
|
||||||
|
AxiosRequestHeaders,
|
||||||
|
AxiosError
|
||||||
|
} from 'axios'
|
||||||
|
|
||||||
|
interface RequestInterceptors<T> {
|
||||||
|
// 请求拦截
|
||||||
|
requestInterceptors?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig
|
||||||
|
requestInterceptorsCatch?: (err: any) => any
|
||||||
|
// 响应拦截
|
||||||
|
responseInterceptors?: (config: T) => T
|
||||||
|
responseInterceptorsCatch?: (err: any) => any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
|
||||||
|
interceptors?: RequestInterceptors<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
AxiosResponse,
|
||||||
|
RequestInterceptors,
|
||||||
|
RequestConfig,
|
||||||
|
AxiosInstance,
|
||||||
|
InternalAxiosRequestConfig,
|
||||||
|
AxiosRequestHeaders,
|
||||||
|
AxiosError
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Avatars from './src/Avatars.vue'
|
||||||
|
|
||||||
|
export type { AvatarItem } from './src/types'
|
||||||
|
export { Avatars }
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ComponentSize, ElAvatar, ElTooltip } from 'element-plus'
|
||||||
|
import { PropType, computed } from 'vue'
|
||||||
|
import { AvatarItem } from './types'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('avatars')
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
size: {
|
||||||
|
type: [String, Number] as PropType<ComponentSize | number>,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array as PropType<AvatarItem[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
showTooltip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const filterData = computed(() => props.data.slice(0, props.max))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="prefixCls" class="flex items-center">
|
||||||
|
<template v-for="item in filterData" :key="item.url">
|
||||||
|
<template v-if="showTooltip && item.name">
|
||||||
|
<ElTooltip :content="item.name" placement="top">
|
||||||
|
<ElAvatar
|
||||||
|
:size="size"
|
||||||
|
:src="item.url"
|
||||||
|
class="relative"
|
||||||
|
:style="{
|
||||||
|
zIndex: filterData.indexOf(item)
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</ElTooltip>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<ElAvatar
|
||||||
|
:size="size"
|
||||||
|
:src="item.url"
|
||||||
|
class="relative"
|
||||||
|
:style="{
|
||||||
|
zIndex: filterData.indexOf(item)
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<ElAvatar
|
||||||
|
v-if="data.length > max"
|
||||||
|
:style="{
|
||||||
|
zIndex: data.length
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span>+{{ data.length - max }}</span>
|
||||||
|
</ElAvatar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
@prefix-cls: ~'@{adminNamespace}-avatars';
|
||||||
|
|
||||||
|
.@{prefix-cls} {
|
||||||
|
.@{elNamespace}-avatar + .@{elNamespace}-avatar {
|
||||||
|
margin-left: -15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface AvatarItem {
|
||||||
|
url: string
|
||||||
|
name?: string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Backtop from './src/Backtop.vue'
|
||||||
|
|
||||||
|
export { Backtop }
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElBacktop } from 'element-plus'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
const { getPrefixCls, variables } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('backtop')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElBacktop
|
||||||
|
:class="prefixCls"
|
||||||
|
:target="`.${variables.namespace}-layout-content-scrollbar .${variables.elNamespace}-scrollbar__wrap`"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Breadcrumb from './src/Breadcrumb.vue'
|
||||||
|
|
||||||
|
export { Breadcrumb }
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
<script lang="tsx">
|
||||||
|
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
||||||
|
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { usePermissionStore } from '@/store/modules/permission'
|
||||||
|
import { filterBreadcrumb } from './helper'
|
||||||
|
import { filter, treeToList } from '@/utils/tree'
|
||||||
|
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { Icon } from '@/components/Icon'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('breadcrumb')
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
// 面包屑图标
|
||||||
|
const breadcrumbIcon = computed(() => appStore.getBreadcrumbIcon)
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Breadcrumb',
|
||||||
|
setup() {
|
||||||
|
const { currentRoute } = useRouter()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const levelList = ref<AppRouteRecordRaw[]>([])
|
||||||
|
|
||||||
|
const permissionStore = usePermissionStore()
|
||||||
|
|
||||||
|
const menuRouters = computed(() => {
|
||||||
|
const routers = permissionStore.getRouters
|
||||||
|
return filterBreadcrumb(routers)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getBreadcrumb = () => {
|
||||||
|
const currentPath = currentRoute.value.matched.slice(-1)[0].path
|
||||||
|
levelList.value = filter<AppRouteRecordRaw>(unref(menuRouters), (node: AppRouteRecordRaw) => {
|
||||||
|
return node.path === currentPath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderBreadcrumb = () => {
|
||||||
|
const breadcrumbList = treeToList<AppRouteRecordRaw[]>(unref(levelList))
|
||||||
|
return breadcrumbList.map((v) => {
|
||||||
|
const disabled = !v.redirect || v.redirect === 'noredirect'
|
||||||
|
const meta = v.meta
|
||||||
|
return (
|
||||||
|
<ElBreadcrumbItem to={{ path: disabled ? '' : v.path }} key={v.name}>
|
||||||
|
{meta?.icon && breadcrumbIcon.value ? (
|
||||||
|
<>
|
||||||
|
<Icon icon={meta.icon} class="mr-[5px]"></Icon> {t(v?.meta?.title || '')}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
t(v?.meta?.title || '')
|
||||||
|
)}
|
||||||
|
</ElBreadcrumbItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => currentRoute.value,
|
||||||
|
(route: RouteLocationNormalizedLoaded) => {
|
||||||
|
if (route.path.startsWith('/redirect/')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getBreadcrumb()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<ElBreadcrumb separator="/" class={`${prefixCls} flex items-center h-full ml-[10px]`}>
|
||||||
|
<TransitionGroup appear enter-active-class="animate__animated animate__fadeInRight">
|
||||||
|
{renderBreadcrumb()}
|
||||||
|
</TransitionGroup>
|
||||||
|
</ElBreadcrumb>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@prefix-cls: ~'@{elNamespace}-breadcrumb';
|
||||||
|
|
||||||
|
.@{prefix-cls} {
|
||||||
|
:deep(&__item) {
|
||||||
|
display: flex;
|
||||||
|
.@{prefix-cls}__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--top-header-text-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(&__item):not(:last-child) {
|
||||||
|
.@{prefix-cls}__inner {
|
||||||
|
color: var(--top-header-text-color);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(&__item):last-child {
|
||||||
|
.@{prefix-cls}__inner {
|
||||||
|
color: var(--el-text-color-placeholder);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-text-color-placeholder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { pathResolve } from '@/utils/routerHelper'
|
||||||
|
|
||||||
|
export const filterBreadcrumb = (
|
||||||
|
routes: AppRouteRecordRaw[],
|
||||||
|
parentPath = ''
|
||||||
|
): AppRouteRecordRaw[] => {
|
||||||
|
const res: AppRouteRecordRaw[] = []
|
||||||
|
|
||||||
|
for (const route of routes) {
|
||||||
|
const meta = route?.meta
|
||||||
|
if (meta.hidden && !meta.canTo) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: AppRouteRecordRaw =
|
||||||
|
!meta.alwaysShow && route.children?.length === 1
|
||||||
|
? { ...route.children[0], path: pathResolve(route.path, route.children[0].path) }
|
||||||
|
: { ...route }
|
||||||
|
|
||||||
|
data.path = pathResolve(parentPath, data.path)
|
||||||
|
|
||||||
|
if (data.children) {
|
||||||
|
data.children = filterBreadcrumb(data.children, data.path)
|
||||||
|
}
|
||||||
|
if (data) {
|
||||||
|
res.push(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import BaseButton from './src/Button.vue'
|
||||||
|
|
||||||
|
export { BaseButton }
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { ElButton, ComponentSize, ButtonType } from 'element-plus'
|
||||||
|
import { PropType, Component, computed, unref } from 'vue'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const getTheme = computed(() => appStore.getTheme)
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('button')
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
size: {
|
||||||
|
type: String as PropType<ComponentSize>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String as PropType<ButtonType>,
|
||||||
|
default: 'default'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
plain: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
bg: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
round: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
circle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
loadingIcon: {
|
||||||
|
type: [String, Object] as PropType<String | Component>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: [String, Object] as PropType<String | Component>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
autofocus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
nativeType: {
|
||||||
|
type: String as PropType<'button' | 'submit' | 'reset'>,
|
||||||
|
default: 'button'
|
||||||
|
},
|
||||||
|
autoInsertSpace: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
darker: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
type: [String, Object] as PropType<String | Component>,
|
||||||
|
default: 'button'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['click'])
|
||||||
|
|
||||||
|
const color = computed(() => {
|
||||||
|
const { type, link } = props
|
||||||
|
if (type === 'primary' && !link) {
|
||||||
|
return unref(getTheme).elColorPrimary
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const style = computed(() => {
|
||||||
|
const { type, link } = props
|
||||||
|
if (type === 'primary' && !link) {
|
||||||
|
return '--el-button-text-color: #fff; --el-button-hover-text-color: #fff'
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElButton
|
||||||
|
:class="`${prefixCls} color-#fff`"
|
||||||
|
v-bind="{ ...props }"
|
||||||
|
:color="color"
|
||||||
|
:style="style"
|
||||||
|
@click="() => emits('click')"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
<slot name="icon"></slot>
|
||||||
|
<slot name="loading"></slot>
|
||||||
|
</ElButton>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import CodeEditor from './src/CodeEditor.vue'
|
||||||
|
|
||||||
|
export { CodeEditor }
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
<script setup lang="tsx">
|
||||||
|
import { useMonacoEditor } from '@/hooks/web/useMonacoEditor'
|
||||||
|
import { onMounted, computed, watch, ref } from 'vue'
|
||||||
|
import { ElSelect, ElOption, ElFormItem, ElForm } from 'element-plus'
|
||||||
|
import { languageOptions, themeOptions } from './config/config'
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
width?: string | number
|
||||||
|
height?: string | number
|
||||||
|
languageSelector?: boolean
|
||||||
|
language?: string
|
||||||
|
themeSelector?: boolean
|
||||||
|
theme?: string
|
||||||
|
editorOption?: Object
|
||||||
|
modelValue: string
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
languageSelector: true,
|
||||||
|
language: 'javascript',
|
||||||
|
themeSelector: true,
|
||||||
|
theme: 'vs-dark',
|
||||||
|
editorOption: () => ({}),
|
||||||
|
modelValue: ''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'blur'): void
|
||||||
|
(e: 'update:modelValue', val: string): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const monacoEditorStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
width: typeof props.width === 'string' ? props.width : props.width + 'px',
|
||||||
|
height: typeof props.height === 'string' ? props.height : props.height + 'px'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const {
|
||||||
|
monacoEditorRef,
|
||||||
|
createEditor,
|
||||||
|
updateVal,
|
||||||
|
updateOptions,
|
||||||
|
getEditor,
|
||||||
|
changeLanguage,
|
||||||
|
changeTheme
|
||||||
|
} = useMonacoEditor(props.language)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const monacoEditor = createEditor(props.editorOption)
|
||||||
|
updateMonacoVal(props.modelValue)
|
||||||
|
monacoEditor?.onDidChangeModelContent(() => {
|
||||||
|
emits('update:modelValue', monacoEditor!.getValue())
|
||||||
|
})
|
||||||
|
monacoEditor?.onDidBlurEditorText(() => {
|
||||||
|
emits('blur')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
() => {
|
||||||
|
updateMonacoVal(props.modelValue)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const localLanguage = ref(props.language)
|
||||||
|
|
||||||
|
watch(localLanguage, (newLanguage) => {
|
||||||
|
changeLanguage(newLanguage)
|
||||||
|
})
|
||||||
|
|
||||||
|
const localTheme = ref(props.theme)
|
||||||
|
watch(localTheme, (newTheme) => {
|
||||||
|
changeTheme(newTheme)
|
||||||
|
})
|
||||||
|
|
||||||
|
function updateMonacoVal(val: string) {
|
||||||
|
if (val !== getEditor()?.getValue()) {
|
||||||
|
updateVal(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ updateOptions })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElForm :inline="true">
|
||||||
|
<ElFormItem v-if="languageSelector" label="language" class="w-30% mb-5px!">
|
||||||
|
<ElSelect
|
||||||
|
v-model="localLanguage"
|
||||||
|
placeholder="Please select language"
|
||||||
|
size="small"
|
||||||
|
filterable
|
||||||
|
>
|
||||||
|
<ElOption
|
||||||
|
v-for="item in languageOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem v-if="themeSelector" label="theme" class="w-30% mb-5px!">
|
||||||
|
<ElSelect v-model="localTheme" placeholder="Please select language" size="small" filterable>
|
||||||
|
<ElOption
|
||||||
|
v-for="item in themeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElForm>
|
||||||
|
<div ref="monacoEditorRef" :style="monacoEditorStyle"></div>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
export const languageOptions = [
|
||||||
|
{ label: 'plaintext', value: 'plaintext' },
|
||||||
|
{ label: 'abap', value: 'abap' },
|
||||||
|
{ label: 'apex', value: 'apex' },
|
||||||
|
{ label: 'azcli', value: 'azcli' },
|
||||||
|
{ label: 'bat', value: 'bat' },
|
||||||
|
{ label: 'bicep', value: 'bicep' },
|
||||||
|
{ label: 'cameligo', value: 'cameligo' },
|
||||||
|
{ label: 'clojure', value: 'clojure' },
|
||||||
|
{ label: 'coffeescript', value: 'coffeescript' },
|
||||||
|
{ label: 'c', value: 'c' },
|
||||||
|
{ label: 'cpp', value: 'cpp' },
|
||||||
|
{ label: 'csharp', value: 'csharp' },
|
||||||
|
{ label: 'csp', value: 'csp' },
|
||||||
|
{ label: 'css', value: 'css' },
|
||||||
|
{ label: 'cypher', value: 'cypher' },
|
||||||
|
{ label: 'dart', value: 'dart' },
|
||||||
|
{ label: 'dockerfile', value: 'dockerfile' },
|
||||||
|
{ label: 'ecl', value: 'ecl' },
|
||||||
|
{ label: 'elixir', value: 'elixir' },
|
||||||
|
{ label: 'flow9', value: 'flow9' },
|
||||||
|
{ label: 'fsharp', value: 'fsharp' },
|
||||||
|
{ label: 'freemarker2', value: 'freemarker2' },
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-angle.interpolation-dollar',
|
||||||
|
value: 'freemarker2.tag-angle.interpolation-dollar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-bracket.interpolation-dollar',
|
||||||
|
value: 'freemarker2.tag-bracket.interpolation-dollar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-angle.interpolation-bracket',
|
||||||
|
value: 'freemarker2.tag-angle.interpolation-bracket'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-bracket.interpolation-bracket',
|
||||||
|
value: 'freemarker2.tag-bracket.interpolation-bracket'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-auto.interpolation-dollar',
|
||||||
|
value: 'freemarker2.tag-auto.interpolation-dollar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'freemarker2.tag-auto.interpolation-bracket',
|
||||||
|
value: 'freemarker2.tag-auto.interpolation-bracket'
|
||||||
|
},
|
||||||
|
{ label: 'go', value: 'go' },
|
||||||
|
{ label: 'graphql', value: 'graphql' },
|
||||||
|
{ label: 'handlebars', value: 'handlebars' },
|
||||||
|
{ label: 'hcl', value: 'hcl' },
|
||||||
|
{ label: 'html', value: 'html' },
|
||||||
|
{ label: 'ini', value: 'ini' },
|
||||||
|
{ label: 'java', value: 'java' },
|
||||||
|
{ label: 'javascript', value: 'javascript' },
|
||||||
|
{ label: 'julia', value: 'julia' },
|
||||||
|
{ label: 'kotlin', value: 'kotlin' },
|
||||||
|
{ label: 'less', value: 'less' },
|
||||||
|
{ label: 'lexon', value: 'lexon' },
|
||||||
|
{ label: 'lua', value: 'lua' },
|
||||||
|
{ label: 'liquid', value: 'liquid' },
|
||||||
|
{ label: 'm3', value: 'm3' },
|
||||||
|
{ label: 'markdown', value: 'markdown' },
|
||||||
|
{ label: 'mdx', value: 'mdx' },
|
||||||
|
{ label: 'mips', value: 'mips' },
|
||||||
|
{ label: 'msdax', value: 'msdax' },
|
||||||
|
{ label: 'mysql', value: 'mysql' },
|
||||||
|
{ label: 'objective-c', value: 'objective-c' },
|
||||||
|
{ label: 'pascal', value: 'pascal' },
|
||||||
|
{ label: 'pascaligo', value: 'pascaligo' },
|
||||||
|
{ label: 'perl', value: 'perl' },
|
||||||
|
{ label: 'pgsql', value: 'pgsql' },
|
||||||
|
{ label: 'php', value: 'php' },
|
||||||
|
{ label: 'pla', value: 'pla' },
|
||||||
|
{ label: 'postiats', value: 'postiats' },
|
||||||
|
{ label: 'powerquery', value: 'powerquery' },
|
||||||
|
{ label: 'powershell', value: 'powershell' },
|
||||||
|
{ label: 'proto', value: 'proto' },
|
||||||
|
{ label: 'pug', value: 'pug' },
|
||||||
|
{ label: 'python', value: 'python' },
|
||||||
|
{ label: 'qsharp', value: 'qsharp' },
|
||||||
|
{ label: 'r', value: 'r' },
|
||||||
|
{ label: 'razor', value: 'razor' },
|
||||||
|
{ label: 'redis', value: 'redis' },
|
||||||
|
{ label: 'redshift', value: 'redshift' },
|
||||||
|
{ label: 'restructuredtext', value: 'restructuredtext' },
|
||||||
|
{ label: 'ruby', value: 'ruby' },
|
||||||
|
{ label: 'rust', value: 'rust' },
|
||||||
|
{ label: 'sb', value: 'sb' },
|
||||||
|
{ label: 'scala', value: 'scala' },
|
||||||
|
{ label: 'scheme', value: 'scheme' },
|
||||||
|
{ label: 'scss', value: 'scss' },
|
||||||
|
{ label: 'shell', value: 'shell' },
|
||||||
|
{ label: 'sol', value: 'sol' },
|
||||||
|
{ label: 'aes', value: 'aes' },
|
||||||
|
{ label: 'sparql', value: 'sparql' },
|
||||||
|
{ label: 'sql', value: 'sql' },
|
||||||
|
{ label: 'st', value: 'st' },
|
||||||
|
{ label: 'swift', value: 'swift' },
|
||||||
|
{ label: 'systemverilog', value: 'systemverilog' },
|
||||||
|
{ label: 'verilog', value: 'verilog' },
|
||||||
|
{ label: 'tcl', value: 'tcl' },
|
||||||
|
{ label: 'twig', value: 'twig' },
|
||||||
|
{ label: 'typescript', value: 'typescript' },
|
||||||
|
{ label: 'vb', value: 'vb' },
|
||||||
|
{ label: 'wgsl', value: 'wgsl' },
|
||||||
|
{ label: 'xml', value: 'xml' },
|
||||||
|
{ label: 'yaml', value: 'yaml' },
|
||||||
|
{ label: 'json', value: 'json' }
|
||||||
|
]
|
||||||
|
|
||||||
|
export const themeOptions = [
|
||||||
|
{
|
||||||
|
label: 'vs',
|
||||||
|
value: 'vs'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'vs-dark',
|
||||||
|
value: 'vs-dark'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'hc-black',
|
||||||
|
value: 'hc-black'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'hc-light',
|
||||||
|
value: 'hc-light'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Collapse from './src/Collapse.vue'
|
||||||
|
|
||||||
|
export { Collapse }
|
||||||