├── .env.development ├── .env.example ├── .env.production ├── .github └── workflows │ ├── deploy.yml │ └── release.yml ├── .gitignore ├── .gitlab-ci.yml ├── .vscode └── settings.json ├── Dockerfile ├── LICENSE ├── README.md ├── index.html ├── jsconfig.json ├── package.json ├── postcss.config.cjs ├── public ├── auth-bg.svg ├── avatar.jpg ├── favicon.ico ├── logo.svg ├── not-image.png ├── skins-thumb │ ├── businessGray │ │ └── thumb.jpg │ ├── city │ │ └── thumb.jpg │ └── mine │ │ └── thumb.jpg └── tinymce │ ├── i18n │ └── zh_CN.js │ └── skins │ ├── content │ ├── dark │ │ ├── content.css │ │ └── content.min.css │ ├── default │ │ ├── content.css │ │ └── content.min.css │ ├── document │ │ ├── content.css │ │ └── content.min.css │ ├── tinymce-5-dark │ │ ├── content.css │ │ └── content.min.css │ ├── tinymce-5 │ │ ├── content.css │ │ └── content.min.css │ └── writer │ │ ├── content.css │ │ └── content.min.css │ └── ui │ ├── oxide-dark │ ├── content.css │ ├── content.inline.css │ ├── content.inline.min.css │ ├── content.min.css │ ├── skin.css │ ├── skin.min.css │ ├── skin.shadowdom.css │ └── skin.shadowdom.min.css │ ├── oxide │ ├── content.css │ ├── content.inline.css │ ├── content.inline.min.css │ ├── content.min.css │ ├── skin.css │ ├── skin.min.css │ ├── skin.shadowdom.css │ └── skin.shadowdom.min.css │ ├── tinymce-5-dark │ ├── content.css │ ├── content.inline.css │ ├── content.inline.min.css │ ├── content.min.css │ ├── skin.css │ ├── skin.min.css │ ├── skin.shadowdom.css │ └── skin.shadowdom.min.css │ └── tinymce-5 │ ├── content.css │ ├── content.inline.css │ ├── content.inline.min.css │ ├── content.min.css │ ├── skin.css │ ├── skin.min.css │ ├── skin.shadowdom.css │ └── skin.shadowdom.min.css ├── scripts └── postinstall.js ├── src ├── App.vue ├── api │ ├── common.js │ ├── doc.js │ ├── login.js │ ├── setting │ │ ├── config.js │ │ ├── crontab.js │ │ ├── datasource.js │ │ ├── generate.js │ │ └── module.js │ ├── store.js │ └── system │ │ ├── api.js │ │ ├── apiColumn.js │ │ ├── apiGroup.js │ │ ├── apiLog.js │ │ ├── app.js │ │ ├── appGroup.js │ │ ├── attachment.js │ │ ├── dataMaintain.js │ │ ├── dept.js │ │ ├── dict.js │ │ ├── loginLog.js │ │ ├── menu.js │ │ ├── monitor.js │ │ ├── notice.js │ │ ├── operLog.js │ │ ├── post.js │ │ ├── queueLog.js │ │ ├── queueMessage.js │ │ ├── role.js │ │ └── user.js ├── assets │ ├── 404.svg │ ├── BingWallpaper.jpg │ ├── login_picture.svg │ ├── ma-icons │ │ ├── Attach.vue │ │ ├── Code.vue │ │ ├── Db.vue │ │ ├── Dept.vue │ │ ├── Dict.vue │ │ ├── Group.vue │ │ ├── Menu.vue │ │ ├── Mineadmin.vue │ │ ├── Online.vue │ │ ├── Permission.vue │ │ ├── Post.vue │ │ ├── Rely.vue │ │ ├── Role.vue │ │ ├── Tool.vue │ │ ├── User.vue │ │ └── Workflow.vue │ └── userBanner.jpg ├── components │ ├── index.js │ ├── ma-charts │ │ └── index.vue │ ├── ma-cityLinkage │ │ ├── index.vue │ │ └── lib │ │ │ └── city.json │ ├── ma-codeEditor │ │ └── index.vue │ ├── ma-colorPicker │ │ └── index.vue │ ├── ma-crud │ │ ├── components │ │ │ ├── column.vue │ │ │ ├── contextMenu.vue │ │ │ ├── form.vue │ │ │ ├── import.vue │ │ │ ├── search.vue │ │ │ ├── searchFormItem │ │ │ │ ├── form-cascader.vue │ │ │ │ ├── form-input.vue │ │ │ │ ├── form-picker.vue │ │ │ │ ├── form-select.vue │ │ │ │ └── form-tree-select.vue │ │ │ └── setting.vue │ │ ├── index.vue │ │ ├── js │ │ │ ├── custom-render.js │ │ │ └── defaultOptions.js │ │ └── types │ │ │ ├── columns.ts │ │ │ ├── crud.ts │ │ │ └── index.ts │ ├── ma-editor │ │ └── index.vue │ ├── ma-form-modal │ │ └── index.vue │ ├── ma-form │ │ ├── containerItem │ │ │ ├── card.vue │ │ │ ├── children-form.vue │ │ │ ├── grid-col.vue │ │ │ ├── grid-tailwind-col.vue │ │ │ ├── grid-tailwind.vue │ │ │ ├── grid.vue │ │ │ ├── table-cell.vue │ │ │ ├── table.vue │ │ │ └── tabs.vue │ │ ├── formItem │ │ │ ├── form-auto-complete.vue │ │ │ ├── form-button.vue │ │ │ ├── form-cascader.vue │ │ │ ├── form-checkbox.vue │ │ │ ├── form-city-linkage.vue │ │ │ ├── form-code-editor.vue │ │ │ ├── form-color-picker.vue │ │ │ ├── form-component.vue │ │ │ ├── form-dialog.vue │ │ │ ├── form-divider.vue │ │ │ ├── form-editor.vue │ │ │ ├── form-icon-picker.vue │ │ │ ├── form-input-number.vue │ │ │ ├── form-input-tag.vue │ │ │ ├── form-input.vue │ │ │ ├── form-item.vue │ │ │ ├── form-key-value.vue │ │ │ ├── form-link.vue │ │ │ ├── form-mention.vue │ │ │ ├── form-picker.vue │ │ │ ├── form-radio.vue │ │ │ ├── form-rate.vue │ │ │ ├── form-resource.vue │ │ │ ├── form-select.vue │ │ │ ├── form-sku.vue │ │ │ ├── form-slider.vue │ │ │ ├── form-static-text.vue │ │ │ ├── form-switch.vue │ │ │ ├── form-textarea.vue │ │ │ ├── form-transfer.vue │ │ │ ├── form-tree-select.vue │ │ │ ├── form-upload.vue │ │ │ ├── form-user-select.vue │ │ │ ├── form-userinfo.vue │ │ │ ├── form-verify-code.vue │ │ │ └── form-wang-editor.vue │ │ ├── index.vue │ │ └── js │ │ │ ├── columnService.js │ │ │ ├── defaultArrayComponent.js │ │ │ ├── defaultOptions.js │ │ │ ├── event.js │ │ │ ├── networkRequest.js │ │ │ └── utils.js │ ├── ma-icon │ │ └── index.vue │ ├── ma-info-modal │ │ └── index.vue │ ├── ma-info │ │ └── index.vue │ ├── ma-resource │ │ ├── button.vue │ │ └── index.vue │ ├── ma-treeSlider │ │ └── index.vue │ ├── ma-upload │ │ ├── components │ │ │ ├── chunk-upload.vue │ │ │ ├── file-upload.vue │ │ │ └── image-upload.vue │ │ ├── index.vue │ │ └── js │ │ │ └── utils.js │ ├── ma-user │ │ └── index.vue │ ├── ma-userInfo │ │ └── index.vue │ ├── ma-verifyCode │ │ └── index.vue │ └── ma-wangEditor │ │ └── index.vue ├── config │ ├── column.js │ ├── crud.js │ ├── map.js │ ├── skins.js │ └── upload.js ├── directives │ ├── auth │ │ ├── auth.js │ │ └── index.js │ ├── copy │ │ └── index.js │ ├── index.js │ └── role │ │ ├── index.js │ │ └── role.js ├── i18n │ ├── en │ │ ├── crud.js │ │ ├── maResource.js │ │ ├── menus.js │ │ ├── skin.js │ │ ├── sys.js │ │ ├── upload.js │ │ └── user.js │ ├── index.js │ └── zh_CN │ │ ├── crud.js │ │ ├── maResource.js │ │ ├── menus.js │ │ ├── skin.js │ │ ├── sys.js │ │ ├── upload.js │ │ └── user.js ├── layout │ ├── 404.vue │ ├── components │ │ ├── banner │ │ │ └── index.vue │ │ ├── classic │ │ │ ├── index.vue │ │ │ ├── ma-classic-header.vue │ │ │ └── ma-classic-slider.vue │ │ ├── columns │ │ │ ├── index.vue │ │ │ ├── ma-columns-header.vue │ │ │ └── ma-columns-menu.vue │ │ ├── components │ │ │ ├── children-banner.vue │ │ │ ├── children-menu.vue │ │ │ ├── iframe-view.vue │ │ │ ├── message-notification.vue │ │ │ ├── search.vue │ │ │ ├── skin.vue │ │ │ └── sub-menu.vue │ │ ├── ma-breadcrumb.vue │ │ ├── ma-buttonMenu.vue │ │ ├── ma-menu.vue │ │ ├── ma-operation.vue │ │ ├── ma-tags.vue │ │ ├── ma-workerArea.vue │ │ └── mixed │ │ │ ├── index.vue │ │ │ └── top-menu.vue │ ├── empty.vue │ ├── form.vue │ ├── index.vue │ ├── search.vue │ └── setting.vue ├── main.js ├── plugin │ └── index.js ├── router │ ├── homePageRoutes.js │ ├── index.js │ └── webRouter.js ├── store │ ├── index.js │ └── modules │ │ ├── app.js │ │ ├── config.js │ │ ├── doc.js │ │ ├── form.js │ │ ├── iframe.js │ │ ├── keepAlive.js │ │ ├── message.js │ │ ├── tag.js │ │ └── user.js ├── style │ ├── animation.less │ ├── dark.less │ ├── global.less │ ├── index.css │ ├── skin.less │ └── skins │ │ ├── businessGray │ │ └── index.less │ │ ├── city │ │ ├── background.jpg │ │ └── index.less │ │ └── mine │ │ └── index.less ├── utils │ ├── Wsocket.js │ ├── common.js │ ├── print.js │ ├── request.js │ └── tool.js ├── views │ ├── appStore │ │ ├── components │ │ │ ├── app.vue │ │ │ ├── appDetail.vue │ │ │ ├── appList.vue │ │ │ ├── noDev.vue │ │ │ ├── notice.vue │ │ │ └── style │ │ │ │ └── preview.css │ │ └── index.vue │ ├── dashboard │ │ ├── components │ │ │ ├── components │ │ │ │ ├── st-announced.vue │ │ │ │ ├── st-count.vue │ │ │ │ ├── st-loginChart.vue │ │ │ │ ├── st-mineadmin.vue │ │ │ │ └── st-welcome.vue │ │ │ ├── statistics.vue │ │ │ └── work-panel.vue │ │ └── index.vue │ ├── login.vue │ ├── mineDoc │ │ ├── components │ │ │ ├── auth.vue │ │ │ └── docMain.vue │ │ ├── index.vue │ │ └── page │ │ │ ├── components │ │ │ ├── globalParams.vue │ │ │ ├── simRequest.vue │ │ │ └── sliderDrawer.vue │ │ │ ├── interfaceCode.vue │ │ │ ├── interfaceList.vue │ │ │ └── signature.vue │ ├── setting │ │ ├── autoform │ │ │ └── index.vue │ │ ├── code │ │ │ ├── components │ │ │ │ ├── editInfo.vue │ │ │ │ ├── loadTable.vue │ │ │ │ ├── preview.vue │ │ │ │ └── settingComponent.vue │ │ │ ├── index.vue │ │ │ └── js │ │ │ │ └── vars.js │ │ ├── config │ │ │ ├── components │ │ │ │ ├── addConfig.vue │ │ │ │ ├── addGroup.vue │ │ │ │ ├── js │ │ │ │ │ └── configDefine.js │ │ │ │ └── manageConfig.vue │ │ │ └── index.vue │ │ ├── crontab │ │ │ ├── index.vue │ │ │ └── logList.vue │ │ ├── datasource │ │ │ └── index.vue │ │ ├── module │ │ │ └── index.vue │ │ └── systemInterface │ │ │ └── index.vue │ ├── system │ │ ├── api │ │ │ ├── index.vue │ │ │ └── paramsList.vue │ │ ├── apiGroup │ │ │ └── index.vue │ │ ├── app │ │ │ ├── bind.vue │ │ │ └── index.vue │ │ ├── appGroup │ │ │ └── index.vue │ │ ├── attachment │ │ │ └── index.vue │ │ ├── dataMaintain │ │ │ └── index.vue │ │ ├── dept │ │ │ ├── index.vue │ │ │ └── leader.vue │ │ ├── dict │ │ │ ├── dataList.vue │ │ │ └── index.vue │ │ ├── logs │ │ │ ├── apiLog.vue │ │ │ ├── loginLog.vue │ │ │ ├── operLog.vue │ │ │ └── queueLog.vue │ │ ├── menu │ │ │ └── index.vue │ │ ├── monitor │ │ │ ├── cache │ │ │ │ └── index.vue │ │ │ ├── onlineUser │ │ │ │ └── index.vue │ │ │ └── server │ │ │ │ └── index.vue │ │ ├── notice │ │ │ └── index.vue │ │ ├── post │ │ │ └── index.vue │ │ ├── role │ │ │ ├── components │ │ │ │ ├── dataPermission.vue │ │ │ │ └── menuPermission.vue │ │ │ └── index.vue │ │ └── user │ │ │ └── index.vue │ └── userCenter │ │ ├── components │ │ ├── modifyPassword.vue │ │ └── userInfomation.vue │ │ ├── index.vue │ │ └── message.vue └── ws-serve │ └── message.js ├── tailwind.config.cjs ├── tsconfig.json ├── vite.config.js └── yarn.lock /.env.development: -------------------------------------------------------------------------------- 1 | # .env.development 2 | VITE_APP_ENV = development 3 | 4 | VITE_APP_BASE_URL = http://127.0.0.1:9501 5 | VITE_APP_WS_URL = ws://127.0.0.1:9502/message.io 6 | VITE_APP_PROXY_PREFIX = /dev -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | VITE_APP_TITLE = MineAdmin 2 | VITE_APP_PORT = 2888 3 | VITE_APP_OPEN_PROXY = true 4 | VITE_APP_BASE = / 5 | VITE_APP_TOKEN_PREFIX = token -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | # .env.production 2 | VITE_APP_ENV = production 3 | 4 | VITE_APP_BASE_URL = http://127.0.0.1:9501 5 | VITE_APP_WS_URL = ws://127.0.0.1:9502/message.io 6 | VITE_APP_PROXY_PREFIX = /prod -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Gitee 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | 17 | - run: | 18 | git config user.email "root@imoi.cn" 19 | git config user.name "xmo" 20 | git remote rm origin 21 | git remote add origin https://xmo:${{ secrets.GITEE_TOKEN }}@gitee.com/mineadmin/mineadmin-vue.git 22 | git push -f origin main 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | # Sequence of patterns matched against refs/tags 4 | tags: 5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 6 | 7 | name: Release 8 | 9 | jobs: 10 | release: 11 | name: Release 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v2 16 | - name: Create Release 17 | id: create_release 18 | uses: actions/create-release@v1 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | with: 22 | tag_name: ${{ github.ref }} 23 | release_name: Release ${{ github.ref }} 24 | draft: false 25 | prerelease: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | .DS_Store 4 | dist 5 | dist-ssr 6 | *.local 7 | .idea 8 | .env -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # usermod -aG docker gitlab-runner 2 | 3 | stages: 4 | - build 5 | - deploy 6 | 7 | variables: 8 | PROJECT_NAME: mineadmin-vue 9 | REGISTRY_URL: registry-docker.org 10 | 11 | build_dev_docker: 12 | stage: build 13 | before_script: 14 | - docker login -u "$username" -p "$password" registry-docker.org 15 | script: 16 | - docker build . -t $PROJECT_NAME --build-arg NODE_ENV=development 17 | - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:dev 18 | - docker push $REGISTRY_URL/$PROJECT_NAME:dev 19 | # 打包镜像后推送钩子,触发自动部署 20 | # after_script: 21 | # - 'curl -H ''X-Gitlab-Token: token'' -d ''{"ref": "_/tags/自动发布"}'' http://127.0.0.1:80/api/apis/deploy/2/tag/' 22 | only: 23 | - dev 24 | tags: 25 | - builder 26 | 27 | deploy_docker: 28 | stage: deploy 29 | script: 30 | - echo SUCCESS 31 | only: 32 | - tags 33 | tags: 34 | - builder 35 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "githubPullRequests.ignoredPullRequestBranches": [ 3 | "main" 4 | ] 5 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | #FROM node:18.16.0-alpine3.16 AS build 2 | FROM node:lts-alpine AS build 3 | 4 | WORKDIR /opt/www 5 | COPY . /opt/www/ 6 | 7 | ARG MINE_NODE_ENV=production 8 | 9 | ENV MINE_NODE_ENV $MINE_NODE_ENV 10 | 11 | RUN echo "MINE_NODE_ENV=$MINE_NODE_ENV" 12 | 13 | #RUN yarn install --network-timeout 100000 14 | 15 | # RUN yarn config set registry http://mirrors.cloud.tencent.com/npm/ 16 | 17 | # RUN npm config set registry http://mirrors.cloud.tencent.com/npm/ 18 | 19 | 20 | RUN yarn config list 21 | 22 | 23 | RUN yarn install && \ 24 | if [ "$MINE_NODE_ENV" = "development" ]; then yarn build --mode development; fi && \ 25 | if [ "$MINE_NODE_ENV" = "production" ]; then yarn build --mode production; fi && \ 26 | yarn cache clean 27 | 28 | RUN yarn generate:version 29 | 30 | FROM nginx:alpine 31 | 32 | COPY --from=build /opt/www/dist /usr/share/nginx/html 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 青衣煮茶 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"], 6 | "@cps/*": ["src/components/*"], 7 | "vue-i18n": ["vue-i18n/dist/vue-i18n.cjs.js"] 8 | }, 9 | "jsx": "preserve" 10 | }, 11 | "exclude": ["node_modules", "dist", "build"] 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mineadmin-vue", 3 | "admin_name": "mineadmin-vue", 4 | "version": "2.0LTS", 5 | "type": "module", 6 | "license": "MIT", 7 | "scripts": { 8 | "dev": "vite serve --mode development", 9 | "build": "vite build", 10 | "preview": "vite preview", 11 | "tailwind": "tailwind-config-viewer -o -c tailwind.config.cjs", 12 | "generate:version": "generate-version-file dist public", 13 | "postinstall": "node ./scripts/postinstall.js" 14 | }, 15 | "dependencies": { 16 | "@arco-design/color": "^0.4.0", 17 | "@arco-design/web-vue": "^2.55.3", 18 | "@arco-themes/vue-mine-admin-v2": "^0.0.3", 19 | "@tinymce/tinymce-vue": "^5.0.0", 20 | "@wangeditor/editor": "^5.1.23", 21 | "@wangeditor/editor-for-vue": "^5.1.12", 22 | "autoprefixer": "^10.4.17", 23 | "axios": "^0.27.2", 24 | "crypto-js": "^4.2.0", 25 | "dayjs": "^1.11.11", 26 | "echarts": "^5.4.2", 27 | "file2md5": "^1.3.0", 28 | "lodash": "^4.17.21", 29 | "md-editor-v3": "^4.13.5", 30 | "monaco-editor": "^0.33.0", 31 | "nprogress": "^0.2.0", 32 | "pinia": "^2.1.7", 33 | "postcss-import": "^14.1.0", 34 | "qs": "^6.10.3", 35 | "resize-observer-polyfill": "^1.5.1", 36 | "sortablejs": "^1.15.0", 37 | "tailwindcss": "^3.4.1", 38 | "tinymce": "^6.1.0", 39 | "version-rocket": "^1.6.2", 40 | "vue": "^3.4.19", 41 | "vue-clipboard3": "^2.0.0", 42 | "vue-color-kit": "^1.0.5", 43 | "vue-echarts": "^6.0.2", 44 | "vue-i18n": "^9.1.10", 45 | "vue-router": "^4.2.5", 46 | "vuedraggable": "^4.1.0" 47 | }, 48 | "devDependencies": { 49 | "@vitejs/plugin-vue": "^5.0.4", 50 | "@vitejs/plugin-vue-jsx": "^3.1.0", 51 | "less": "^4.1.3", 52 | "less-loader": "^11.1.4", 53 | "tailwind-config-viewer": "^1.7.3", 54 | "typescript": "^4.7.4", 55 | "vite": "^5.1.4" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/avatar.jpg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/favicon.ico -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /public/not-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/not-image.png -------------------------------------------------------------------------------- /public/skins-thumb/businessGray/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/skins-thumb/businessGray/thumb.jpg -------------------------------------------------------------------------------- /public/skins-thumb/city/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/skins-thumb/city/thumb.jpg -------------------------------------------------------------------------------- /public/skins-thumb/mine/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/public/skins-thumb/mine/thumb.jpg -------------------------------------------------------------------------------- /public/tinymce/skins/content/dark/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #222f3e; 3 | color: #fff; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 5 | line-height: 1.4; 6 | margin: 1rem; 7 | } 8 | a { 9 | color: #4099ff; 10 | } 11 | table { 12 | border-collapse: collapse; 13 | } 14 | /* Apply a default padding if legacy cellpadding attribute is missing */ 15 | table:not([cellpadding]) th, 16 | table:not([cellpadding]) td { 17 | padding: 0.4rem; 18 | } 19 | /* Set default table styles if a table has a positive border attribute 20 | and no inline css */ 21 | table[border]:not([border="0"]):not([style*="border-width"]) th, 22 | table[border]:not([border="0"]):not([style*="border-width"]) td { 23 | border-width: 1px; 24 | } 25 | /* Set default table styles if a table has a positive border attribute 26 | and no inline css */ 27 | table[border]:not([border="0"]):not([style*="border-style"]) th, 28 | table[border]:not([border="0"]):not([style*="border-style"]) td { 29 | border-style: solid; 30 | } 31 | /* Set default table styles if a table has a positive border attribute 32 | and no inline css */ 33 | table[border]:not([border="0"]):not([style*="border-color"]) th, 34 | table[border]:not([border="0"]):not([style*="border-color"]) td { 35 | border-color: #6d737b; 36 | } 37 | figure { 38 | display: table; 39 | margin: 1rem auto; 40 | } 41 | figure figcaption { 42 | color: #8a8f97; 43 | display: block; 44 | margin-top: 0.25rem; 45 | text-align: center; 46 | } 47 | hr { 48 | border-color: #6d737b; 49 | border-style: solid; 50 | border-width: 1px 0 0 0; 51 | } 52 | code { 53 | background-color: #6d737b; 54 | border-radius: 3px; 55 | padding: 0.1rem 0.2rem; 56 | } 57 | .mce-content-body:not([dir=rtl]) blockquote { 58 | border-left: 2px solid #6d737b; 59 | margin-left: 1.5rem; 60 | padding-left: 1rem; 61 | } 62 | .mce-content-body[dir=rtl] blockquote { 63 | border-right: 2px solid #6d737b; 64 | margin-right: 1.5rem; 65 | padding-right: 1rem; 66 | } 67 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/dark/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/default/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem; 5 | } 6 | table { 7 | border-collapse: collapse; 8 | } 9 | /* Apply a default padding if legacy cellpadding attribute is missing */ 10 | table:not([cellpadding]) th, 11 | table:not([cellpadding]) td { 12 | padding: 0.4rem; 13 | } 14 | /* Set default table styles if a table has a positive border attribute 15 | and no inline css */ 16 | table[border]:not([border="0"]):not([style*="border-width"]) th, 17 | table[border]:not([border="0"]):not([style*="border-width"]) td { 18 | border-width: 1px; 19 | } 20 | /* Set default table styles if a table has a positive border attribute 21 | and no inline css */ 22 | table[border]:not([border="0"]):not([style*="border-style"]) th, 23 | table[border]:not([border="0"]):not([style*="border-style"]) td { 24 | border-style: solid; 25 | } 26 | /* Set default table styles if a table has a positive border attribute 27 | and no inline css */ 28 | table[border]:not([border="0"]):not([style*="border-color"]) th, 29 | table[border]:not([border="0"]):not([style*="border-color"]) td { 30 | border-color: #ccc; 31 | } 32 | figure { 33 | display: table; 34 | margin: 1rem auto; 35 | } 36 | figure figcaption { 37 | color: #999; 38 | display: block; 39 | margin-top: 0.25rem; 40 | text-align: center; 41 | } 42 | hr { 43 | border-color: #ccc; 44 | border-style: solid; 45 | border-width: 1px 0 0 0; 46 | } 47 | code { 48 | background-color: #e8e8e8; 49 | border-radius: 3px; 50 | padding: 0.1rem 0.2rem; 51 | } 52 | .mce-content-body:not([dir=rtl]) blockquote { 53 | border-left: 2px solid #ccc; 54 | margin-left: 1.5rem; 55 | padding-left: 1rem; 56 | } 57 | .mce-content-body[dir=rtl] blockquote { 58 | border-right: 2px solid #ccc; 59 | margin-right: 1.5rem; 60 | padding-right: 1rem; 61 | } 62 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/default/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/document/content.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | html { 3 | background: #f4f4f4; 4 | min-height: 100%; 5 | } 6 | } 7 | body { 8 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | @media screen { 11 | body { 12 | background-color: #fff; 13 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.15); 14 | box-sizing: border-box; 15 | margin: 1rem auto 0; 16 | max-width: 820px; 17 | min-height: calc(100vh - 1rem); 18 | padding: 4rem 6rem 6rem 6rem; 19 | } 20 | } 21 | table { 22 | border-collapse: collapse; 23 | } 24 | /* Apply a default padding if legacy cellpadding attribute is missing */ 25 | table:not([cellpadding]) th, 26 | table:not([cellpadding]) td { 27 | padding: 0.4rem; 28 | } 29 | /* Set default table styles if a table has a positive border attribute 30 | and no inline css */ 31 | table[border]:not([border="0"]):not([style*="border-width"]) th, 32 | table[border]:not([border="0"]):not([style*="border-width"]) td { 33 | border-width: 1px; 34 | } 35 | /* Set default table styles if a table has a positive border attribute 36 | and no inline css */ 37 | table[border]:not([border="0"]):not([style*="border-style"]) th, 38 | table[border]:not([border="0"]):not([style*="border-style"]) td { 39 | border-style: solid; 40 | } 41 | /* Set default table styles if a table has a positive border attribute 42 | and no inline css */ 43 | table[border]:not([border="0"]):not([style*="border-color"]) th, 44 | table[border]:not([border="0"]):not([style*="border-color"]) td { 45 | border-color: #ccc; 46 | } 47 | figure figcaption { 48 | color: #999; 49 | margin-top: 0.25rem; 50 | text-align: center; 51 | } 52 | hr { 53 | border-color: #ccc; 54 | border-style: solid; 55 | border-width: 1px 0 0 0; 56 | } 57 | .mce-content-body:not([dir=rtl]) blockquote { 58 | border-left: 2px solid #ccc; 59 | margin-left: 1.5rem; 60 | padding-left: 1rem; 61 | } 62 | .mce-content-body[dir=rtl] blockquote { 63 | border-right: 2px solid #ccc; 64 | margin-right: 1.5rem; 65 | padding-right: 1rem; 66 | } 67 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/document/content.min.css: -------------------------------------------------------------------------------- 1 | @media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/tinymce-5-dark/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #2f3742; 3 | color: #dfe0e4; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 5 | line-height: 1.4; 6 | margin: 1rem; 7 | } 8 | a { 9 | color: #4099ff; 10 | } 11 | table { 12 | border-collapse: collapse; 13 | } 14 | /* Apply a default padding if legacy cellpadding attribute is missing */ 15 | table:not([cellpadding]) th, 16 | table:not([cellpadding]) td { 17 | padding: 0.4rem; 18 | } 19 | /* Set default table styles if a table has a positive border attribute 20 | and no inline css */ 21 | table[border]:not([border="0"]):not([style*="border-width"]) th, 22 | table[border]:not([border="0"]):not([style*="border-width"]) td { 23 | border-width: 1px; 24 | } 25 | /* Set default table styles if a table has a positive border attribute 26 | and no inline css */ 27 | table[border]:not([border="0"]):not([style*="border-style"]) th, 28 | table[border]:not([border="0"]):not([style*="border-style"]) td { 29 | border-style: solid; 30 | } 31 | /* Set default table styles if a table has a positive border attribute 32 | and no inline css */ 33 | table[border]:not([border="0"]):not([style*="border-color"]) th, 34 | table[border]:not([border="0"]):not([style*="border-color"]) td { 35 | border-color: #6d737b; 36 | } 37 | figure { 38 | display: table; 39 | margin: 1rem auto; 40 | } 41 | figure figcaption { 42 | color: #8a8f97; 43 | display: block; 44 | margin-top: 0.25rem; 45 | text-align: center; 46 | } 47 | hr { 48 | border-color: #6d737b; 49 | border-style: solid; 50 | border-width: 1px 0 0 0; 51 | } 52 | code { 53 | background-color: #6d737b; 54 | border-radius: 3px; 55 | padding: 0.1rem 0.2rem; 56 | } 57 | .mce-content-body:not([dir=rtl]) blockquote { 58 | border-left: 2px solid #6d737b; 59 | margin-left: 1.5rem; 60 | padding-left: 1rem; 61 | } 62 | .mce-content-body[dir=rtl] blockquote { 63 | border-right: 2px solid #6d737b; 64 | margin-right: 1.5rem; 65 | padding-right: 1rem; 66 | } 67 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/tinymce-5-dark/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#2f3742;color:#dfe0e4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/tinymce-5/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem; 5 | } 6 | table { 7 | border-collapse: collapse; 8 | } 9 | /* Apply a default padding if legacy cellpadding attribute is missing */ 10 | table:not([cellpadding]) th, 11 | table:not([cellpadding]) td { 12 | padding: 0.4rem; 13 | } 14 | /* Set default table styles if a table has a positive border attribute 15 | and no inline css */ 16 | table[border]:not([border="0"]):not([style*="border-width"]) th, 17 | table[border]:not([border="0"]):not([style*="border-width"]) td { 18 | border-width: 1px; 19 | } 20 | /* Set default table styles if a table has a positive border attribute 21 | and no inline css */ 22 | table[border]:not([border="0"]):not([style*="border-style"]) th, 23 | table[border]:not([border="0"]):not([style*="border-style"]) td { 24 | border-style: solid; 25 | } 26 | /* Set default table styles if a table has a positive border attribute 27 | and no inline css */ 28 | table[border]:not([border="0"]):not([style*="border-color"]) th, 29 | table[border]:not([border="0"]):not([style*="border-color"]) td { 30 | border-color: #ccc; 31 | } 32 | figure { 33 | display: table; 34 | margin: 1rem auto; 35 | } 36 | figure figcaption { 37 | color: #999; 38 | display: block; 39 | margin-top: 0.25rem; 40 | text-align: center; 41 | } 42 | hr { 43 | border-color: #ccc; 44 | border-style: solid; 45 | border-width: 1px 0 0 0; 46 | } 47 | code { 48 | background-color: #e8e8e8; 49 | border-radius: 3px; 50 | padding: 0.1rem 0.2rem; 51 | } 52 | .mce-content-body:not([dir=rtl]) blockquote { 53 | border-left: 2px solid #ccc; 54 | margin-left: 1.5rem; 55 | padding-left: 1rem; 56 | } 57 | .mce-content-body[dir=rtl] blockquote { 58 | border-right: 2px solid #ccc; 59 | margin-right: 1.5rem; 60 | padding-right: 1rem; 61 | } 62 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/tinymce-5/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/writer/content.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 3 | line-height: 1.4; 4 | margin: 1rem auto; 5 | max-width: 900px; 6 | } 7 | table { 8 | border-collapse: collapse; 9 | } 10 | /* Apply a default padding if legacy cellpadding attribute is missing */ 11 | table:not([cellpadding]) th, 12 | table:not([cellpadding]) td { 13 | padding: 0.4rem; 14 | } 15 | /* Set default table styles if a table has a positive border attribute 16 | and no inline css */ 17 | table[border]:not([border="0"]):not([style*="border-width"]) th, 18 | table[border]:not([border="0"]):not([style*="border-width"]) td { 19 | border-width: 1px; 20 | } 21 | /* Set default table styles if a table has a positive border attribute 22 | and no inline css */ 23 | table[border]:not([border="0"]):not([style*="border-style"]) th, 24 | table[border]:not([border="0"]):not([style*="border-style"]) td { 25 | border-style: solid; 26 | } 27 | /* Set default table styles if a table has a positive border attribute 28 | and no inline css */ 29 | table[border]:not([border="0"]):not([style*="border-color"]) th, 30 | table[border]:not([border="0"]):not([style*="border-color"]) td { 31 | border-color: #ccc; 32 | } 33 | figure { 34 | display: table; 35 | margin: 1rem auto; 36 | } 37 | figure figcaption { 38 | color: #999; 39 | display: block; 40 | margin-top: 0.25rem; 41 | text-align: center; 42 | } 43 | hr { 44 | border-color: #ccc; 45 | border-style: solid; 46 | border-width: 1px 0 0 0; 47 | } 48 | code { 49 | background-color: #e8e8e8; 50 | border-radius: 3px; 51 | padding: 0.1rem 0.2rem; 52 | } 53 | .mce-content-body:not([dir=rtl]) blockquote { 54 | border-left: 2px solid #ccc; 55 | margin-left: 1.5rem; 56 | padding-left: 1rem; 57 | } 58 | .mce-content-body[dir=rtl] blockquote { 59 | border-right: 2px solid #ccc; 60 | margin-right: 1.5rem; 61 | padding-right: 1rem; 62 | } 63 | -------------------------------------------------------------------------------- /public/tinymce/skins/content/writer/content.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/oxide-dark/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/oxide/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/oxide/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/tinymce-5/skin.shadowdom.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll { 2 | overflow: hidden; 3 | } 4 | .tox-fullscreen { 5 | border: 0; 6 | height: 100%; 7 | margin: 0; 8 | overflow: hidden; 9 | overscroll-behavior: none; 10 | padding: 0; 11 | touch-action: pinch-zoom; 12 | width: 100%; 13 | } 14 | .tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle { 15 | display: none; 16 | } 17 | .tox.tox-tinymce.tox-fullscreen, 18 | .tox-shadowhost.tox-fullscreen { 19 | left: 0; 20 | position: fixed; 21 | top: 0; 22 | z-index: 1200; 23 | } 24 | .tox.tox-tinymce.tox-fullscreen { 25 | background-color: transparent; 26 | } 27 | .tox-fullscreen .tox.tox-tinymce-aux, 28 | .tox-fullscreen ~ .tox.tox-tinymce-aux { 29 | z-index: 1201; 30 | } 31 | -------------------------------------------------------------------------------- /public/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css: -------------------------------------------------------------------------------- 1 | body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201} 2 | -------------------------------------------------------------------------------- /scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | import {access, constants, copyFile} from 'fs'; 2 | 3 | access('.env', constants.F_OK, (err) => { 4 | if (err) { 5 | copyFile('.env.example', '.env', (err) => { 6 | if (err) throw err; 7 | console.log('.env.example was copied to .env'); 8 | }); 9 | } 10 | }); -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/api/doc.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 接口文档 5 | */ 6 | export default { 7 | /** 8 | * 登录接口文档 9 | * @returns 10 | */ 11 | login (data = {}) { 12 | return request({ 13 | url: 'apiDoc/login', 14 | method: 'post', 15 | data 16 | }) 17 | }, 18 | 19 | /** 20 | * 获取app信息和接口列表 21 | * @returns 22 | */ 23 | getAppAndInterfaceList (appId = null) { 24 | return request({ 25 | url: 'apiDoc/getAppAndInterfaceList/' + appId, 26 | method: 'get' 27 | }) 28 | }, 29 | 30 | /** 31 | * 获取字段列表 32 | * @returns 33 | */ 34 | getColumnList (apiId = null) { 35 | return request({ 36 | url: 'apiDoc/getColumnList/' + apiId, 37 | method: 'get' 38 | }) 39 | } 40 | } -------------------------------------------------------------------------------- /src/api/login.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取验证码 7 | * @returns 8 | */ 9 | getCaptch() { 10 | return request({ 11 | url: 'system/captcha', 12 | method: 'get' 13 | }) 14 | }, 15 | 16 | /** 17 | * 用户登录 18 | * @param {object} params 19 | * @returns 20 | */ 21 | login(params = {}) { 22 | return request({ 23 | url: 'system/login', 24 | method: 'post', 25 | data: params 26 | }) 27 | }, 28 | 29 | /** 30 | * 用户退出 31 | * @param {object} params 32 | * @returns 33 | */ 34 | logout(params = {}) { 35 | return request({ 36 | url: 'system/logout', 37 | method: 'post', 38 | data: params 39 | }) 40 | }, 41 | 42 | /** 43 | * 获取登录用户信息 44 | * @param {object} params 45 | * @returns 46 | */ 47 | getInfo(params = {}) { 48 | return request({ 49 | url: 'system/getInfo', 50 | method: 'get', 51 | data: params 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/api/setting/crontab.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | /** 5 | * 获取分页列表 6 | * @returns 7 | */ 8 | getPageList (params = {}) { 9 | return request({ 10 | url: 'setting/crontab/index', 11 | method: 'get', 12 | params 13 | }) 14 | }, 15 | 16 | /** 17 | * 获取任务日志列表 18 | * @returns 19 | */ 20 | getLogPageList (params = {}) { 21 | return request({ 22 | url: 'setting/crontab/logPageList', 23 | method: 'get', 24 | params 25 | }) 26 | }, 27 | 28 | /** 29 | * 删除定时任务日志 30 | * @returns 31 | */ 32 | deleteLog (data) { 33 | return request({ 34 | url: 'setting/crontab/deleteCrontabLog', 35 | method: 'delete', 36 | data 37 | }) 38 | }, 39 | 40 | /** 41 | * 立刻执行一次定时任务 42 | * @returns 43 | */ 44 | run (data = {}) { 45 | return request({ 46 | url: 'setting/crontab/run', 47 | method: 'post', 48 | data 49 | }) 50 | }, 51 | 52 | /** 53 | * 添加 54 | * @returns 55 | */ 56 | save (data = {}) { 57 | return request({ 58 | url: 'setting/crontab/save', 59 | method: 'post', 60 | data 61 | }) 62 | }, 63 | 64 | /** 65 | * 删除 66 | * @returns 67 | */ 68 | deletes (data) { 69 | return request({ 70 | url: 'setting/crontab/delete', 71 | method: 'delete', 72 | data 73 | }) 74 | }, 75 | 76 | /** 77 | * 更新数据 78 | * @returns 79 | */ 80 | update (id, params = {}) { 81 | return request({ 82 | url: 'setting/crontab/update/' + id, 83 | method: 'put', 84 | data: params 85 | }) 86 | }, 87 | 88 | /** 89 | * 更改状态 90 | * @returns 91 | */ 92 | changeStatus(data = {}) { 93 | return request({ 94 | url: 'setting/crontab/changeStatus', 95 | method: 'put', 96 | data 97 | }) 98 | }, 99 | 100 | } -------------------------------------------------------------------------------- /src/api/setting/module.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | /** 5 | * 获取本地模块分页列表 6 | * @returns 7 | */ 8 | getPageList (params = {}) { 9 | return request({ 10 | url: 'setting/module/index', 11 | method: 'get', 12 | params 13 | }) 14 | }, 15 | 16 | /** 17 | * 创建新模块 18 | * @returns 19 | */ 20 | save (data = {}) { 21 | return request({ 22 | url: 'setting/module/save', 23 | method: 'put', 24 | data 25 | }) 26 | }, 27 | 28 | /** 29 | * 删除模块 30 | * @returns 31 | */ 32 | deletes (data) { 33 | return request({ 34 | url: 'setting/module/delete', 35 | method: 'delete', 36 | data 37 | }) 38 | }, 39 | 40 | /** 41 | * 安装模块 42 | * @returns 43 | */ 44 | install (data) { 45 | return request({ 46 | url: 'setting/module/install', 47 | method: 'put', 48 | data 49 | }) 50 | }, 51 | 52 | /** 53 | * 启停用模块 54 | * @returns 55 | */ 56 | modifyStatus (data = {}) { 57 | return request({ 58 | url: 'setting/module/modifyStatus', 59 | method: 'post', 60 | data 61 | }) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/api/store.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 检查是.env 是否设置了 access_token 5 | */ 6 | export const hasAccessToken = () => { 7 | return request({ 8 | url: 'plugin/store/hasAccessToken', 9 | method: 'get', 10 | }) 11 | } 12 | 13 | /** 14 | * 请求应用列表 15 | */ 16 | export const getAppList = (params) => { 17 | return request({ 18 | url: 'plugin/store/index', 19 | method: 'get', 20 | params 21 | }) 22 | } 23 | 24 | /** 25 | * 已购买应用 26 | */ 27 | export const getPayApp = () => { 28 | return request({ 29 | url: 'plugin/store/getPayApp', 30 | method: 'get' 31 | }) 32 | } 33 | 34 | /** 35 | * 本地应用安装状态 36 | */ 37 | export const getLocalAppInstallList = () => { 38 | return request({ 39 | url: 'plugin/store/getLocalAppInstallList', 40 | method: 'get' 41 | }) 42 | } 43 | 44 | /** 45 | * 详情 46 | */ 47 | export const getDetail = (params) => { 48 | return request({ 49 | url: 'plugin/store/detail', 50 | method: 'get', 51 | params 52 | }) 53 | } 54 | 55 | /** 56 | * 下载应用 57 | */ 58 | export const download = (data) => { 59 | return request({ 60 | url: 'plugin/store/download', 61 | method: 'post', 62 | timeout: 500000, 63 | data, 64 | }) 65 | } 66 | 67 | /** 68 | * 安装应用 69 | */ 70 | export const install = (data) => { 71 | return request({ 72 | url: 'plugin/store/install', 73 | method: 'post', 74 | data, 75 | }) 76 | } 77 | 78 | /** 79 | * 安装应用 80 | */ 81 | export const unInstall = (data) => { 82 | return request({ 83 | url: 'plugin/store/unInstall', 84 | method: 'post', 85 | data, 86 | }) 87 | } -------------------------------------------------------------------------------- /src/api/system/api.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 接口管理 API JS 5 | */ 6 | 7 | export default { 8 | 9 | /** 10 | * 获取接口管理分页列表 11 | * @returns 12 | */ 13 | getList(params = {}) { 14 | return request({ 15 | url: 'system/api/index', 16 | method: 'get', 17 | params 18 | }) 19 | }, 20 | 21 | /** 22 | * 获取模块列表 23 | * @returns 24 | */ 25 | getModuleList() { 26 | return request({ 27 | url: 'system/api/getModuleList', 28 | method: 'get' 29 | }) 30 | }, 31 | 32 | /** 33 | * 从回收站获取接口管理数据列表 34 | * @returns 35 | */ 36 | getRecycleList(params = {}) { 37 | return request({ 38 | url: 'system/api/recycle', 39 | method: 'get', 40 | params 41 | }) 42 | }, 43 | 44 | /** 45 | * 添加接口管理 46 | * @returns 47 | */ 48 | save(data = {}) { 49 | return request({ 50 | url: 'system/api/save', 51 | method: 'post', 52 | data 53 | }) 54 | }, 55 | 56 | /** 57 | * 读取接口管理 58 | * @returns 59 | */ 60 | read(id) { 61 | return request({ 62 | url: 'system/api/read/' + id, 63 | method: 'post', 64 | }) 65 | }, 66 | 67 | /** 68 | * 将接口管理移到回收站 69 | * @returns 70 | */ 71 | deletes(data) { 72 | return request({ 73 | url: 'system/api/delete', 74 | method: 'delete', 75 | data 76 | }) 77 | }, 78 | 79 | /** 80 | * 恢复接口管理数据 81 | * @returns 82 | */ 83 | recoverys(data) { 84 | return request({ 85 | url: 'system/api/recovery', 86 | method: 'put', 87 | data 88 | }) 89 | }, 90 | 91 | /** 92 | * 真实删除接口管理 93 | * @returns 94 | */ 95 | realDeletes(data) { 96 | return request({ 97 | url: 'system/api/realDelete', 98 | method: 'delete', 99 | data 100 | }) 101 | }, 102 | 103 | /** 104 | * 更新接口管理数据 105 | * @returns 106 | */ 107 | update(id, data = {}) { 108 | return request({ 109 | url: 'system/api/update/' + id, 110 | method: 'put', 111 | data 112 | }) 113 | }, 114 | 115 | /** 116 | * 更改部门状态 117 | * @returns 118 | */ 119 | changeStatus(data = {}) { 120 | return request({ 121 | url: 'system/api/changeStatus', 122 | method: 'put', 123 | data 124 | }) 125 | }, 126 | 127 | } -------------------------------------------------------------------------------- /src/api/system/apiColumn.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 接口字段管理 API JS 5 | */ 6 | 7 | export default { 8 | 9 | /** 10 | * 获取接口字段管理分页列表 11 | * @returns 12 | */ 13 | getList(params = {}) { 14 | return request({ 15 | url: 'system/apiColumn/index', 16 | method: 'get', 17 | params 18 | }) 19 | }, 20 | 21 | /** 22 | * 从回收站获取接口字段管理数据列表 23 | * @returns 24 | */ 25 | getRecycleList(params = {}) { 26 | return request({ 27 | url: 'system/apiColumn/recycle', 28 | method: 'get', 29 | params 30 | }) 31 | }, 32 | 33 | /** 34 | * 添加接口字段管理 35 | * @returns 36 | */ 37 | save(data = {}) { 38 | return request({ 39 | url: 'system/apiColumn/save', 40 | method: 'post', 41 | data 42 | }) 43 | }, 44 | 45 | /** 46 | * 读取接口字段管理 47 | * @returns 48 | */ 49 | read(id) { 50 | return request({ 51 | url: 'system/apiColumn/read/' + id, 52 | method: 'post', 53 | }) 54 | }, 55 | 56 | /** 57 | * 将接口字段管理移到回收站 58 | * @returns 59 | */ 60 | deletes(data) { 61 | return request({ 62 | url: 'system/apiColumn/delete', 63 | method: 'delete', 64 | data 65 | }) 66 | }, 67 | 68 | /** 69 | * 恢复接口字段管理数据 70 | * @returns 71 | */ 72 | recoverys(data) { 73 | return request({ 74 | url: 'system/apiColumn/recovery', 75 | method: 'put', 76 | data 77 | }) 78 | }, 79 | 80 | /** 81 | * 真实删除接口字段管理 82 | * @returns 83 | */ 84 | realDeletes(data) { 85 | return request({ 86 | url: 'system/apiColumn/realDelete', 87 | method: 'delete', 88 | data 89 | }) 90 | }, 91 | 92 | /** 93 | * 更新接口字段管理数据 94 | * @returns 95 | */ 96 | update(id, data = {}) { 97 | return request({ 98 | url: 'system/apiColumn/update/' + id, 99 | method: 'put', 100 | data 101 | }) 102 | }, 103 | 104 | /** 105 | * 更改部门状态 106 | * @returns 107 | */ 108 | changeStatus(data = {}) { 109 | return request({ 110 | url: 'system/apiColumn/changeStatus', 111 | method: 'put', 112 | data 113 | }) 114 | }, 115 | } 116 | -------------------------------------------------------------------------------- /src/api/system/apiGroup.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 接口分组 API JS 5 | */ 6 | 7 | export default { 8 | 9 | /** 10 | * 获取接口分组分页列表 11 | * @returns 12 | */ 13 | getList (params = {}) { 14 | return request({ 15 | url: 'system/apiGroup/index', 16 | method: 'get', 17 | params 18 | }) 19 | }, 20 | 21 | /** 22 | * 获取接口分组分页列表,无分页,下拉用 23 | * @returns 24 | */ 25 | getSelectList (params = {}) { 26 | return request({ 27 | url: 'system/apiGroup/list', 28 | method: 'get', 29 | params 30 | }) 31 | }, 32 | 33 | /** 34 | * 从回收站获取接口分组数据列表 35 | * @returns 36 | */ 37 | getRecycleList (params = {}) { 38 | return request({ 39 | url: 'system/apiGroup/recycle', 40 | method: 'get', 41 | params 42 | }) 43 | }, 44 | 45 | /** 46 | * 添加接口分组 47 | * @returns 48 | */ 49 | save (data = {}) { 50 | return request({ 51 | url: 'system/apiGroup/save', 52 | method: 'post', 53 | data 54 | }) 55 | }, 56 | 57 | /** 58 | * 读取接口分组 59 | * @returns 60 | */ 61 | read (data = {}) { 62 | return request({ 63 | url: 'system/apiGroup/read', 64 | method: 'post', 65 | data 66 | }) 67 | }, 68 | 69 | /** 70 | * 将接口分组移到回收站 71 | * @returns 72 | */ 73 | deletes (data) { 74 | return request({ 75 | url: 'system/apiGroup/delete', 76 | method: 'delete', 77 | data 78 | }) 79 | }, 80 | 81 | /** 82 | * 恢复接口分组数据 83 | * @returns 84 | */ 85 | recoverys (data) { 86 | return request({ 87 | url: 'system/apiGroup/recovery', 88 | method: 'put', 89 | data 90 | }) 91 | }, 92 | 93 | /** 94 | * 真实删除接口分组 95 | * @returns 96 | */ 97 | realDeletes (data) { 98 | return request({ 99 | url: 'system/apiGroup/realDelete', 100 | method: 'delete', 101 | data 102 | }) 103 | }, 104 | 105 | /** 106 | * 更新接口分组数据 107 | * @returns 108 | */ 109 | update (id, data = {}) { 110 | return request({ 111 | url: 'system/apiGroup/update/' + id, 112 | method: 'put', 113 | data 114 | }) 115 | } 116 | } -------------------------------------------------------------------------------- /src/api/system/apiLog.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取接口日志分页列表 7 | * @returns 8 | */ 9 | getPageList(params = {}) { 10 | return request({ 11 | url: 'system/logs/getApiLogPageList', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 删除 19 | * @returns 20 | */ 21 | deletes(data) { 22 | return request({ 23 | url: 'system/logs/deleteApiLog', 24 | method: 'delete', 25 | data 26 | }) 27 | } 28 | } -------------------------------------------------------------------------------- /src/api/system/attachment.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取文件分页列表 7 | * @returns 8 | */ 9 | getPageList (params = {}) { 10 | return request({ 11 | url: 'system/attachment/index', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 从回收站获取文件 19 | * @returns 20 | */ 21 | getRecyclePageList (params = {}) { 22 | return request({ 23 | url: 'system/attachment/recycle', 24 | method: 'get', 25 | params 26 | }) 27 | }, 28 | 29 | /** 30 | * 移到回收站 31 | * @returns 32 | */ 33 | deletes (data) { 34 | return request({ 35 | url: 'system/attachment/delete', 36 | method: 'delete', 37 | data 38 | }) 39 | }, 40 | 41 | /** 42 | * 恢复数据 43 | * @returns 44 | */ 45 | recoverys (data) { 46 | return request({ 47 | url: 'system/attachment/recovery', 48 | method: 'put', 49 | data 50 | }) 51 | }, 52 | 53 | /** 54 | * 真实删除 55 | * @returns 56 | */ 57 | realDeletes (data) { 58 | return request({ 59 | url: 'system/attachment/realDelete', 60 | method: 'delete', 61 | data 62 | }) 63 | } 64 | } -------------------------------------------------------------------------------- /src/api/system/dataMaintain.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | /** 5 | * 获取数据表分页列表 6 | * @returns 7 | */ 8 | getPageList (params = {}) { 9 | return request({ 10 | url: 'system/dataMaintain/index', 11 | method: 'get', 12 | params 13 | }) 14 | }, 15 | 16 | /** 17 | * 获取表字段列表 18 | * @returns 19 | */ 20 | getDetailed (params = {}) { 21 | return request({ 22 | url: 'system/dataMaintain/detailed', 23 | method: 'get', 24 | params 25 | }) 26 | }, 27 | 28 | /** 29 | * 优化表 30 | * @returns 31 | */ 32 | optimize (data = {}) { 33 | return request({ 34 | url: 'system/dataMaintain/optimize', 35 | method: 'post', 36 | data 37 | }) 38 | }, 39 | 40 | /** 41 | * 清理表碎片 42 | * @returns 43 | */ 44 | fragment (data = {}) { 45 | return request({ 46 | url: 'system/dataMaintain/fragment', 47 | method: 'post', 48 | data 49 | }) 50 | } 51 | } -------------------------------------------------------------------------------- /src/api/system/loginLog.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取登录日志分页列表 7 | * @returns 8 | */ 9 | getPageList(params = {}) { 10 | return request({ 11 | url: 'system/logs/getLoginLogPageList', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 删除 19 | * @returns 20 | */ 21 | deletes(data) { 22 | return request({ 23 | url: 'system/logs/deleteLoginLog', 24 | method: 'delete', 25 | data 26 | }) 27 | } 28 | } -------------------------------------------------------------------------------- /src/api/system/menu.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | /** 5 | * 获取菜单树 6 | * @returns 7 | */ 8 | getList(params = {}) { 9 | return request({ 10 | url: 'system/menu/index', 11 | method: 'get', 12 | params 13 | }) 14 | }, 15 | 16 | /** 17 | * 从回收站获取菜单树 18 | * @returns 19 | */ 20 | getRecycleList(params = {}) { 21 | return request({ 22 | url: 'system/menu/recycle', 23 | method: 'get', 24 | params 25 | }) 26 | }, 27 | 28 | /** 29 | * 获取菜单选择树 30 | * @returns 31 | */ 32 | tree(params = {}) { 33 | return request({ 34 | url: 'system/menu/tree', 35 | method: 'get', 36 | params 37 | }) 38 | }, 39 | 40 | /** 41 | * 添加菜单 42 | * @returns 43 | */ 44 | save(params = {}) { 45 | return request({ 46 | url: 'system/menu/save', 47 | method: 'post', 48 | data: params 49 | }) 50 | }, 51 | 52 | /** 53 | * 移到回收站 54 | * @returns 55 | */ 56 | deletes(data) { 57 | return request({ 58 | url: 'system/menu/delete', 59 | method: 'delete', 60 | data 61 | }) 62 | }, 63 | 64 | /** 65 | * 恢复数据 66 | * @returns 67 | */ 68 | recoverys(data) { 69 | return request({ 70 | url: 'system/menu/recovery', 71 | method: 'put', 72 | data 73 | }) 74 | }, 75 | 76 | /** 77 | * 真实删除 78 | * @returns 79 | */ 80 | realDeletes(data) { 81 | return request({ 82 | url: 'system/menu/realDelete', 83 | method: 'delete', 84 | data 85 | }) 86 | }, 87 | 88 | /** 89 | * 更新数据 90 | * @returns 91 | */ 92 | update(id, data = {}) { 93 | return request({ 94 | url: 'system/menu/update/' + id, 95 | method: 'put', 96 | data 97 | }) 98 | }, 99 | 100 | /** 101 | * 数字运算操作 102 | * @returns 103 | */ 104 | numberOperation(data = {}) { 105 | return request({ 106 | url: 'system/menu/numberOperation', 107 | method: 'put', 108 | data 109 | }) 110 | }, 111 | 112 | /** 113 | * 更改菜单状态 114 | * @returns 115 | */ 116 | changeStatus(data = {}) { 117 | return request({ 118 | url: 'system/menu/changeStatus', 119 | method: 'put', 120 | data 121 | }) 122 | }, 123 | } 124 | -------------------------------------------------------------------------------- /src/api/system/monitor.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取服务器信息 7 | * @returns 8 | */ 9 | getServerInfo () { 10 | return request({ 11 | url: 'system/server/monitor', 12 | method: 'get' 13 | }) 14 | }, 15 | 16 | /** 17 | * 获取在线用户列表 18 | * @param {*} params 19 | * @returns 20 | */ 21 | getOnlineUserPageList (params = {}) { 22 | return request({ 23 | url: 'system/onlineUser/index', 24 | method: 'get', 25 | params 26 | }) 27 | }, 28 | 29 | /** 30 | * 强退用户 (踢下线) 31 | * @param {*} params 32 | * @returns 33 | */ 34 | kickUser (data = {}) { 35 | return request({ 36 | url: 'system/onlineUser/kick', 37 | method: 'post', 38 | data 39 | }) 40 | }, 41 | 42 | /** 43 | * 获取缓存信息 44 | * @returns 45 | */ 46 | getCacheInfo () { 47 | return request({ 48 | url: 'system/cache/monitor', 49 | method: 'get' 50 | }) 51 | }, 52 | 53 | /** 54 | * 查看key内容 55 | * @returns 56 | */ 57 | view (data) { 58 | return request({ 59 | url: 'system/cache/view', 60 | method: 'post', 61 | data 62 | }) 63 | }, 64 | 65 | 66 | /** 67 | * 删除一个缓存 68 | * @returns 69 | */ 70 | deleteKey (data) { 71 | return request({ 72 | url: 'system/cache/delete', 73 | method: 'delete', 74 | data 75 | }) 76 | }, 77 | 78 | /** 79 | * 清空缓存 80 | * @returns 81 | */ 82 | clear () { 83 | return request({ 84 | url: 'system/cache/clear', 85 | method: 'delete' 86 | }) 87 | }, 88 | } -------------------------------------------------------------------------------- /src/api/system/notice.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | /** 4 | * 系统公告 API JS 5 | */ 6 | 7 | export default { 8 | 9 | /** 10 | * 获取系统公告分页列表 11 | * @returns 12 | */ 13 | getPageList (params = {}) { 14 | return request({ 15 | url: 'system/notice/index', 16 | method: 'get', 17 | params 18 | }) 19 | }, 20 | 21 | /** 22 | * 从回收站获取系统公告数据列表 23 | * @returns 24 | */ 25 | getRecyclePageList (params = {}) { 26 | return request({ 27 | url: 'system/notice/recycle', 28 | method: 'get', 29 | params 30 | }) 31 | }, 32 | 33 | /** 34 | * 添加系统公告 35 | * @returns 36 | */ 37 | save (params = {}) { 38 | return request({ 39 | url: 'system/notice/save', 40 | method: 'post', 41 | data: params 42 | }) 43 | }, 44 | 45 | /** 46 | * 读取系统公告 47 | * @returns 48 | */ 49 | read (params = {}) { 50 | return request({ 51 | url: 'system/notice/read', 52 | method: 'post', 53 | data: params 54 | }) 55 | }, 56 | 57 | /** 58 | * 将系统公告移到回收站 59 | * @returns 60 | */ 61 | deletes (data) { 62 | return request({ 63 | url: 'system/notice/delete', 64 | method: 'delete', 65 | data 66 | }) 67 | }, 68 | 69 | /** 70 | * 恢复系统公告数据 71 | * @returns 72 | */ 73 | recoverys (data) { 74 | return request({ 75 | url: 'system/notice/recovery', 76 | method: 'put', 77 | data 78 | }) 79 | }, 80 | 81 | /** 82 | * 真实删除系统公告 83 | * @returns 84 | */ 85 | realDeletes (data) { 86 | return request({ 87 | url: 'system/notice/realDelete', 88 | method: 'delete', 89 | data 90 | }) 91 | }, 92 | 93 | /** 94 | * 更新系统公告数据 95 | * @returns 96 | */ 97 | update (id, data = {}) { 98 | return request({ 99 | url: 'system/notice/update/' + id, 100 | method: 'put', 101 | data 102 | }) 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /src/api/system/operLog.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取操作日志分页列表 7 | * @returns 8 | */ 9 | getPageList(params = {}) { 10 | return request({ 11 | url: 'system/logs/getOperLogPageList', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 删除 19 | * @returns 20 | */ 21 | deletes(data) { 22 | return request({ 23 | url: 'system/logs/deleteOperLog', 24 | method: 'delete', 25 | data 26 | }) 27 | } 28 | } -------------------------------------------------------------------------------- /src/api/system/post.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | /** 5 | * 获取岗位分页列表 6 | * @returns 7 | */ 8 | getPageList(params = {}) { 9 | return request({ 10 | url: 'system/post/index', 11 | method: 'get', 12 | params 13 | }) 14 | }, 15 | 16 | /** 17 | * 获取岗位列表 18 | * @returns 19 | */ 20 | getList(params = {}) { 21 | return request({ 22 | url: 'system/post/list', 23 | method: 'get', 24 | params 25 | }) 26 | }, 27 | 28 | /** 29 | * 从回收站获取岗位 30 | * @returns 31 | */ 32 | getRecyclePageList(params = {}) { 33 | return request({ 34 | url: 'system/post/recycle', 35 | method: 'get', 36 | params 37 | }) 38 | }, 39 | 40 | /** 41 | * 添加岗位 42 | * @returns 43 | */ 44 | save(params = {}) { 45 | return request({ 46 | url: 'system/post/save', 47 | method: 'post', 48 | data: params 49 | }) 50 | }, 51 | 52 | /** 53 | * 移到回收站 54 | * @returns 55 | */ 56 | deletes(data) { 57 | return request({ 58 | url: 'system/post/delete', 59 | method: 'delete', 60 | data 61 | }) 62 | }, 63 | 64 | /** 65 | * 恢复数据 66 | * @returns 67 | */ 68 | recoverys(data) { 69 | return request({ 70 | url: 'system/post/recovery', 71 | method: 'put', 72 | data 73 | }) 74 | }, 75 | 76 | /** 77 | * 真实删除 78 | * @returns 79 | */ 80 | realDeletes(data) { 81 | return request({ 82 | url: 'system/post/realDelete', 83 | method: 'delete', 84 | data 85 | }) 86 | }, 87 | 88 | /** 89 | * 更新数据 90 | * @returns 91 | */ 92 | update(id, data = {}) { 93 | return request({ 94 | url: 'system/post/update/' + id, 95 | method: 'put', 96 | data 97 | }) 98 | }, 99 | 100 | /** 101 | * 数字运算操作 102 | * @returns 103 | */ 104 | numberOperation(data = {}) { 105 | return request({ 106 | url: 'system/post/numberOperation', 107 | method: 'put', 108 | data 109 | }) 110 | }, 111 | 112 | /** 113 | * 更改岗位状态 114 | * @returns 115 | */ 116 | changeStatus(data = {}) { 117 | return request({ 118 | url: 'system/post/changeStatus', 119 | method: 'put', 120 | data 121 | }) 122 | }, 123 | 124 | } -------------------------------------------------------------------------------- /src/api/system/queueLog.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取队列日志分页列表 7 | * @returns 8 | */ 9 | getPageList(params = {}) { 10 | return request({ 11 | url: 'system/logs/getQueueLogPageList', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 删除队列日志 19 | * @returns 20 | */ 21 | deletes(data) { 22 | return request({ 23 | url: 'system/logs/deleteQueueLog', 24 | method: 'delete', 25 | data 26 | }) 27 | } 28 | } -------------------------------------------------------------------------------- /src/api/system/queueMessage.js: -------------------------------------------------------------------------------- 1 | import { request } from '@/utils/request.js' 2 | 3 | export default { 4 | 5 | /** 6 | * 获取接收消息列表 7 | * @returns 8 | */ 9 | getReceiveList(params = {}) { 10 | return request({ 11 | url: 'system/queueMessage/receiveList', 12 | method: 'get', 13 | params 14 | }) 15 | }, 16 | 17 | /** 18 | * 获取发送消息列表 19 | * @returns 20 | */ 21 | getSendList(params = {}) { 22 | return request({ 23 | url: 'system/queueMessage/sendList', 24 | method: 'get', 25 | params 26 | }) 27 | }, 28 | 29 | /** 30 | * 获取接收人列表 31 | * @returns 32 | */ 33 | getReceiveUser(params = {}) { 34 | return request({ 35 | url: 'system/queueMessage/getReceiveUser', 36 | method: 'get', 37 | params 38 | }) 39 | }, 40 | 41 | /** 42 | * 删除消息 43 | * @returns 44 | */ 45 | deletes(data = {}) { 46 | return request({ 47 | url: 'system/queueMessage/deletes', 48 | method: 'delete', 49 | data 50 | }) 51 | }, 52 | 53 | /** 54 | * 更新读取状态 55 | * @returns 56 | */ 57 | updateReadStatus(data = {}) { 58 | return request({ 59 | url: 'system/queueMessage/updateReadStatus', 60 | method: 'put', 61 | data 62 | }) 63 | }, 64 | 65 | /** 66 | * 发私信 67 | * @returns 68 | */ 69 | sendPrivateMessage(data = {}) { 70 | return request({ 71 | url: 'system/queueMessage/sendPrivateMessage', 72 | method: 'post', 73 | data 74 | }) 75 | }, 76 | } -------------------------------------------------------------------------------- /src/assets/BingWallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/src/assets/BingWallpaper.jpg -------------------------------------------------------------------------------- /src/assets/ma-icons/Code.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Db.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Dept.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Dict.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Mineadmin.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Online.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Permission.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Post.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Rely.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Role.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/User.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/ma-icons/Workflow.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/userBanner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/src/assets/userBanner.jpg -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import { use } from 'echarts/core' 2 | import { CanvasRenderer } from 'echarts/renderers' 3 | import { BarChart, LineChart, PieChart, RadarChart, GaugeChart } from 'echarts/charts' 4 | import { 5 | GridComponent, 6 | TooltipComponent, 7 | LegendComponent, 8 | DataZoomComponent, 9 | GraphicComponent, 10 | } from 'echarts/components' 11 | 12 | import MaCrud from './ma-crud/index.vue' 13 | import MaForm from './ma-form/index.vue' 14 | import MaChart from './ma-charts/index.vue' 15 | import MaUpload from './ma-upload/index.vue' 16 | import MaTreeSlider from './ma-treeSlider/index.vue' 17 | import MaResource from './ma-resource/index.vue' 18 | import MaResourceButton from './ma-resource/button.vue' 19 | import MaUser from './ma-user/index.vue' 20 | import MaEditor from './ma-editor/index.vue' 21 | import MaWangEditor from './ma-wangEditor/index.vue' 22 | import MaIcon from './ma-icon/index.vue' 23 | import MaCodeEditor from './ma-codeEditor/index.vue' 24 | import MaUserInfo from './ma-userInfo/index.vue' 25 | import MaCityLinkage from './ma-cityLinkage/index.vue' 26 | 27 | use([ 28 | CanvasRenderer, 29 | BarChart, 30 | LineChart, 31 | PieChart, 32 | RadarChart, 33 | GaugeChart, 34 | GridComponent, 35 | TooltipComponent, 36 | LegendComponent, 37 | DataZoomComponent, 38 | GraphicComponent, 39 | ]); 40 | 41 | export default { 42 | install(Vue) { 43 | Vue.component('MaChart', MaChart) 44 | Vue.component('MaCrud', MaCrud) 45 | Vue.component('MaForm', MaForm) 46 | Vue.component('MaUpload', MaUpload) 47 | Vue.component('MaTreeSlider', MaTreeSlider) 48 | Vue.component('MaResource', MaResource) 49 | Vue.component('MaResourceButton', MaResourceButton) 50 | Vue.component('MaUser', MaUser) 51 | Vue.component('MaEditor', MaEditor) 52 | Vue.component('MaWangEditor', MaWangEditor) 53 | Vue.component('MaIcon', MaIcon) 54 | Vue.component('MaCodeEditor', MaCodeEditor) 55 | Vue.component('MaUserInfo', MaUserInfo) 56 | Vue.component('MaCityLinkage', MaCityLinkage) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/ma-charts/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 19 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/components/ma-colorPicker/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 选择颜色 5 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/components/ma-crud/components/searchFormItem/form-cascader.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/ma-crud/components/searchFormItem/form-picker.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/ma-crud/components/searchFormItem/form-tree-select.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/components/ma-crud/js/custom-render.js: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | export default defineComponent({ 3 | name: 'CustomRender', 4 | props: { 5 | record: Object, 6 | render: Function, 7 | rowIndex: Number, 8 | column: { 9 | type: Object, 10 | default: null, 11 | }, 12 | }, 13 | render() { 14 | return this.render({ record: this.record, column: this.column, rowIndex: this.rowIndex }) 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /src/components/ma-crud/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./columns" 2 | export * from "./crud" 3 | -------------------------------------------------------------------------------- /src/components/ma-form/containerItem/grid-col.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/components/ma-form/containerItem/grid-tailwind-col.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/ma-form/containerItem/grid.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/components/ma-form/containerItem/table-cell.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/components/ma-form/containerItem/table.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 49 | 50 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-button.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 25 | 26 | 27 | 28 | {{ props.component.title ?? 'button' }} 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-city-linkage.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-code-editor.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-color-picker.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-component.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-divider.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 22 | {{ props.component?.title ?? '' }} 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-editor.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-icon-picker.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-item.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-link.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | {{ props.component.title ?? 'link' }} 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-rate.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-static-text.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | {{ props.component.title ?? '' }} 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-user-select.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-userinfo.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/components/ma-form/formItem/form-wang-editor.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 25 | 26 | 27 | 28 | 29 | 30 | 57 | -------------------------------------------------------------------------------- /src/components/ma-form/js/defaultArrayComponent.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'checkbox', 3 | 'user-select', 4 | 'children-form', 5 | 'resource' 6 | ] -------------------------------------------------------------------------------- /src/components/ma-form/js/defaultOptions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 是否自动初始化表单并加载字典及联动远程数据 3 | init: true, 4 | // 表单加载数据中提示文案 5 | loadingText: '加载中...', 6 | // 表单样式class 7 | customClass: [], 8 | // 表单控件尺寸(全局) 'mini' | 'small' | 'medium' | 'large' 9 | size: 'medium', 10 | // 标签的对齐方向 11 | labelAlign: 'right', 12 | // horizontal 水平排列 vertical 垂直排列 inline 行内排列 13 | layout: 'horizontal', 14 | // 表单是否禁用 15 | disabled: false, 16 | // 表单项验证规则整体配置,例子:{ title: [{ required: true, message: '请输入标题'}] } 17 | rules: [], 18 | // 是否显示按钮 19 | showButtons: true, 20 | 21 | // 提交按钮图标 22 | submitIcon: 'icon-send', 23 | // 提交按钮类型 24 | submitType: 'primary', 25 | // 提交按钮状态 26 | submitStatus: 'normal', 27 | // 提交按钮文案 28 | submitText: '提交', 29 | // 是否显示提交按钮 30 | submitShowBtn: true, 31 | 32 | // 重置按钮图标 33 | resetIcon: 'icon-refresh', 34 | // 重置按钮类型 35 | resetType: 'secondary', 36 | // 重置按钮状态 37 | resetStatus: 'normal', 38 | // 重置按钮文案 39 | resetText: '重置', 40 | // 是否显示重置按钮 41 | resetShowBtn: true, 42 | 43 | // 表单标题文案 44 | formTitle: '未命名表单', 45 | // 是否显示表单标题 46 | showFormTitle: false, 47 | // 自定义标题样式css 48 | formTitleStyle: '', 49 | // 自定义标题样式class 50 | formTitleClass: [], 51 | 52 | // 数据源列表,配合表单设计器使用,单独无法使用 53 | sourceList: [], 54 | 55 | // 全局CSS class 56 | globalCss: '', 57 | // 全局function 58 | globalFunction: '', 59 | } -------------------------------------------------------------------------------- /src/components/ma-form/js/event.js: -------------------------------------------------------------------------------- 1 | import { isString, isFunction } from 'lodash' 2 | 3 | export const haveArgsEvent = async (component, value, evName, maformObj) => { 4 | if (component[evName]) { 5 | if ( isFunction(component[evName]) ) { 6 | return await component[evName](value, maformObj) 7 | } 8 | if ( isString(component[evName]) ) { 9 | const customFn = new Function('value', 'maFormObject', component[evName]) 10 | return await customFn.call(component, value, maformObj) 11 | } 12 | } 13 | } 14 | 15 | export const notHaveArgsEvent = async (component, evName, maformObj) => { 16 | if (component[evName]) { 17 | if ( isFunction(component[evName]) ) { 18 | return await component[evName](maformObj) 19 | } 20 | if ( isString(component[evName]) ) { 21 | const customFn = new Function('maFormObject', component[evName]) 22 | return await customFn.call(component[evName], maformObj) 23 | } 24 | } 25 | } 26 | 27 | export const tabAddEvent = (component, maformObj) => { 28 | haveArgsEvent(component, component?.tabs, 'onTabAdd', maformObj) 29 | } 30 | 31 | export const tabDeleteEvent = (component, value, maformObj) => { 32 | haveArgsEvent(component, { tabs: component?.tabs, value }, 'onTabDelete', maformObj) 33 | } 34 | 35 | export const runEvent = async (component, evName, maformObj, value = undefined) => { 36 | return value 37 | ? await haveArgsEvent(component, value, evName, maformObj) 38 | : await notHaveArgsEvent(component, evName, maformObj) 39 | } 40 | -------------------------------------------------------------------------------- /src/components/ma-upload/js/utils.js: -------------------------------------------------------------------------------- 1 | import commonApi from '@/api/common' 2 | import tool from '@/utils/tool' 3 | import file2md5 from 'file2md5' 4 | 5 | export const getFileUrl = async (returnType, value, storageMode) => { 6 | if (returnType === 'url') { 7 | return value 8 | } else if (returnType === 'id') { 9 | const { data } = await commonApi.getFileInfoById(value) 10 | if (data) { 11 | data.url = tool.attachUrl(data.url, storageMode[data.storage_mode]) 12 | return data 13 | } 14 | return '' 15 | } else if (returnType === 'hash') { 16 | const { data } = await commonApi.getFileInfoByHash(value) 17 | if (data) { 18 | data.url = tool.attachUrl(data.url, storageMode[data.storage_mode]) 19 | return data 20 | } 21 | return '' 22 | } 23 | } 24 | 25 | export const uploadRequest = async (file, type, method, requestData = {}) => { 26 | const hash = await file2md5(file) 27 | const dataForm = new FormData() 28 | dataForm.append(type, file) 29 | dataForm.append('isChunk', false) 30 | dataForm.append('hash', hash) 31 | for (let name in requestData) { 32 | dataForm.append(name, requestData[name]) 33 | } 34 | const response = await commonApi[method](dataForm) 35 | return response.data 36 | } 37 | -------------------------------------------------------------------------------- /src/components/ma-userInfo/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 37 | 38 | 43 | -------------------------------------------------------------------------------- /src/config/column.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } -------------------------------------------------------------------------------- /src/config/crud.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | // 响应返回解析 4 | parseResponseData: (res) => { 5 | 6 | return res?.data?.items 7 | ? 8 | // 分页响应字段结构定义 9 | { 10 | rows: res?.data?.items ?? [], // 分析行数据字段结构 11 | pageInfo: res?.data?.pageInfo, // 分析总数字段结构 12 | message: res?.message, // 分析描述字段结构 13 | code: res?.code // 分析状态字段结构 14 | } 15 | : 16 | // 无分页响应字段结构定义 17 | { 18 | rows: res?.data ?? [], // 分析行数据字段结构 19 | message: res?.message, // 分析描述字段结构 20 | code: res?.code // 分析状态字段结构 21 | } 22 | 23 | }, 24 | 25 | // 请求字段结构定义 26 | request: { 27 | page: 'page', //规定当前分页字段 28 | pageSize: 'pageSize', //规定一页条数字段 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/config/map.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baidu: { appid: '' }, 3 | } -------------------------------------------------------------------------------- /src/config/skins.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | name: 'mine', 4 | thumb: 'skins-thumb/mine/thumb.jpg', 5 | }, 6 | { 7 | name: 'businessGray', 8 | thumb: 'skins-thumb/businessGray/thumb.jpg', 9 | }, 10 | { 11 | name: 'city', 12 | thumb: 'skins-thumb/city/thumb.jpg', 13 | } 14 | ] -------------------------------------------------------------------------------- /src/config/upload.js: -------------------------------------------------------------------------------- 1 | export default { 2 | storage: { 3 | LOCAL: 'http://127.0.0.1:9501', 4 | OSS: '', 5 | QINIU: '', 6 | COS: '', 7 | FTP: '', 8 | MEMORY: '', 9 | S3: '', 10 | MINIO: '' 11 | }, 12 | 13 | storageMode: { 14 | '1': 'LOCAL', 15 | '2': 'OSS', 16 | '3': 'QINIU', 17 | '4': 'COS', 18 | '5': 'FTP', 19 | '6': 'MEMORY', 20 | '7': 'S3', 21 | '8': 'MINIO' 22 | } 23 | } -------------------------------------------------------------------------------- /src/directives/auth/auth.js: -------------------------------------------------------------------------------- 1 | import { useUserStore } from '@/store' 2 | 3 | const auth = name => { 4 | const userStore = useUserStore() 5 | return (userStore.codes && userStore.codes.includes(name)) || (userStore.codes && userStore.codes.includes('*')) 6 | } 7 | 8 | export default auth -------------------------------------------------------------------------------- /src/directives/auth/index.js: -------------------------------------------------------------------------------- 1 | import auth from './auth' 2 | 3 | const checkAuth = (el, binding) => { 4 | const { value } = binding 5 | 6 | if (Array.isArray(value)) { 7 | if (value.length > 0) { 8 | let isHas = false 9 | value.map(item => { 10 | isHas = auth(item) 11 | }) 12 | 13 | if (!isHas && el.parentNode) { 14 | el.parentNode.removeChild(el) 15 | } 16 | } 17 | } else { 18 | throw new Error(`need permission! Like v-auth="['admin','user']"`) 19 | } 20 | } 21 | 22 | export default { 23 | mounted(el, binding) { 24 | checkAuth(el, binding) 25 | }, 26 | updated(el, binding) { 27 | checkAuth(el, binding) 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /src/directives/copy/index.js: -------------------------------------------------------------------------------- 1 | import useClipboard from 'vue-clipboard3' 2 | import { Message } from '@arco-design/web-vue' 3 | 4 | const copy = (el, binding) => { 5 | const { value } = binding 6 | el.addEventListener('click', async () => { 7 | if (value && value !== '') { 8 | try { 9 | await useClipboard().toClipboard(value) 10 | Message.success('已成功复制到剪切板') 11 | } catch(e) { 12 | Message.error('复制失败') 13 | } 14 | } else { 15 | throw new Error(`need for copy content! Like v-copy="Hello World"`) 16 | } 17 | }) 18 | } 19 | 20 | export default { 21 | mounted(el, binding) { 22 | copy(el, binding) 23 | }, 24 | updated(el, binding) { 25 | copy(el, binding) 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /src/directives/index.js: -------------------------------------------------------------------------------- 1 | import auth from './auth/index' 2 | import role from './role/index' 3 | import copy from './copy/index' 4 | 5 | 6 | export default { 7 | install (Vue) { 8 | Vue.directive('auth', auth) 9 | Vue.directive('role', role) 10 | Vue.directive('copy', copy) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/directives/role/index.js: -------------------------------------------------------------------------------- 1 | import role from './role' 2 | 3 | const checkRole = (el, binding) => { 4 | const { value } = binding 5 | 6 | if (Array.isArray(value)) { 7 | if (value.length > 0) { 8 | let isHas = false 9 | value.map(item => { 10 | if(!isHas) { 11 | isHas = role(item) 12 | } 13 | }) 14 | 15 | if (!isHas && el.parentNode) { 16 | el.parentNode.remove() 17 | } 18 | } 19 | } else { 20 | throw new Error(`need role! Like v-role="['seo', 'cfo']"`) 21 | } 22 | } 23 | 24 | export default { 25 | mounted(el, binding) { 26 | checkRole(el, binding) 27 | }, 28 | updated(el, binding) { 29 | checkRole(el, binding) 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /src/directives/role/role.js: -------------------------------------------------------------------------------- 1 | import { useUserStore } from '@/store' 2 | 3 | const role = name => { 4 | const userStore = useUserStore() 5 | return (userStore.roles && userStore.roles.includes(name)) || (userStore.roles && userStore.roles.includes('superAdmin')) 6 | } 7 | 8 | export default role -------------------------------------------------------------------------------- /src/i18n/en/crud.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } -------------------------------------------------------------------------------- /src/i18n/en/maResource.js: -------------------------------------------------------------------------------- 1 | export default { 2 | loadingText: 'Loading...', 3 | searchFileNotice: 'Search file by name', 4 | searchResource: 'Search resource type', 5 | saveNetworkImage: 'Save network image', 6 | networkImageNotice: 'Please paste the web picture address', 7 | ok: 'OK', 8 | } -------------------------------------------------------------------------------- /src/i18n/en/menus.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 特殊页 3 | 'openForm': 'CRUD', 4 | 5 | // 首页菜单 6 | 'home': 'Home', 7 | 'dashboard': 'Dashboard', 8 | 'userCenter': 'User Center', 9 | 'message': 'Message Center', 10 | 'setting:config': 'System Setting', 11 | 'demo': 'Component Demo', 12 | 13 | // 权限 14 | 'permission': 'Permission', 15 | 'system:user': 'User Manage', 16 | 'system:role': 'Role Manage', 17 | 'system:dept': 'Department Manage', 18 | 'system:menu': 'Menu Manage', 19 | 'system:post': 'Post Manage', 20 | 21 | 'dataCenter': 'Data Center', 22 | 'system:dict': 'Dictionary', 23 | 'system:attachment': 'Attached', 24 | 'system:dataMaintain': 'Table Maintenance', 25 | 'system:notice': 'Notice', 26 | 'apps': 'App Center', 27 | 'system:appGroup': 'App Group', 28 | 'system:app': 'App Manage', 29 | 'apis': 'Api Center', 30 | 'system:apiGroup': 'Api Group', 31 | 'system:api': 'Api Manage', 32 | 33 | // 监控 34 | 'monitor': 'Monitor', 35 | 'system:monitor:server': 'Server Monitor', 36 | 'system:onlineUser': 'Online User', 37 | 'system:cache': 'Cache Monitor', 38 | 'system:monitor:rely': 'Reliance Monitor', 39 | 'logs': 'Logs Monitor', 40 | 'system:queueLog': 'Queue Logs', 41 | 'system:loginLog': 'Login Logs', 42 | 'system:operLog': 'Operation Logs', 43 | 'system:apiLog': 'Apis Logs', 44 | 45 | // 工具 46 | 'devTools': 'Tools', 47 | 'setting:module': 'Module Manage', 48 | 'setting:code': 'Code Generator', 49 | 'setting:code:update': 'Edit the build information', 50 | 'setting:crontab': 'Crontab', 51 | 'setting:table': 'Table Designer', 52 | 'systemInterface': 'System Apis', 53 | } -------------------------------------------------------------------------------- /src/i18n/en/skin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | mine: 'Mine', 3 | businessGray: 'Business gray', 4 | city: 'City', 5 | 6 | mineDesc: 'Predominantly pure white, Mine defaults to skin', 7 | businessGrayDesc: 'Gray versatility and atmosphere, creating business and stability', 8 | cityDesc: 'May there be a warmth in every angle of the city', 9 | 10 | activated: 'Activated', 11 | use: 'Use' 12 | } -------------------------------------------------------------------------------- /src/i18n/en/upload.js: -------------------------------------------------------------------------------- 1 | export default { 2 | fileHashFail: 'Get file hash failed, please try again!', 3 | sizeLimit: 'The file size exceeds the upload limit', 4 | uploadFailed: 'File upload failed', 5 | buttonText: 'Local upload', 6 | clickUpload: 'Click upload', 7 | uploadDesc: 'Drag the file here, or ', 8 | } -------------------------------------------------------------------------------- /src/i18n/en/user.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/src/i18n/en/user.js -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import { createI18n } from 'vue-i18n' 2 | import tool from '@/utils/tool' 3 | 4 | const setting = tool.local.get('setting') 5 | 6 | const getLanguage = () => { 7 | const loadFile = () => { 8 | if (setting.language === 'zh_CN') { 9 | return import.meta.glob('./zh_CN/**/*.js', { eager:true }) 10 | } else if (setting.language === 'en') { 11 | return import.meta.glob('./en/**/*.js', { eager:true }) 12 | } 13 | } 14 | 15 | const generateLanguage = (fileNames, fileContent, generateLanguages = {}) => { 16 | const fileName = fileNames.shift() 17 | if (fileNames.length > 0) { 18 | if (typeof generateLanguages[fileName] == 'undefined') { 19 | generateLanguages[fileName] = {} 20 | } 21 | generateLanguages[fileName] = generateLanguage(fileNames, fileContent, generateLanguages[fileName]) 22 | }else{ 23 | generateLanguages[fileName] = fileContent 24 | } 25 | return generateLanguages 26 | } 27 | 28 | const files = loadFile() 29 | let messages = { [setting.language]: {} } 30 | for (let path in files) { 31 | const names = path.match(/([A-Za-z0-9_]+)/g) 32 | //去除语言文件夹和文件后缀名 33 | names.shift() 34 | names.pop() 35 | if (files[path].default) { 36 | messages[setting.language] = generateLanguage(names, files[path].default, messages[setting.language]) 37 | } 38 | } 39 | return messages 40 | } 41 | 42 | const i18n = createI18n({ 43 | locale: setting.language, 44 | legacy: false, 45 | globalInjection: true, 46 | fallbackLocale: 'zh_CN', 47 | messages: getLanguage() 48 | }) 49 | 50 | export default i18n -------------------------------------------------------------------------------- /src/i18n/zh_CN/crud.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } -------------------------------------------------------------------------------- /src/i18n/zh_CN/maResource.js: -------------------------------------------------------------------------------- 1 | export default { 2 | loadingText: '数据加载中...', 3 | searchFileNotice: '文件名搜索', 4 | searchResource: '搜索资源类型', 5 | saveNetworkImage: '保存网络图片', 6 | networkImageNotice: '请粘贴网络图片地址', 7 | ok: '确定' 8 | } -------------------------------------------------------------------------------- /src/i18n/zh_CN/menus.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 特殊页 3 | 'openForm': '公共表单', 4 | 5 | // 首页菜单 6 | 'home': '首页', 7 | 'dashboard': '仪表盘', 8 | 'userCenter': '个人中心', 9 | 'message': '消息中心', 10 | 'setting:config': '系统配置', 11 | 'demo': '组件演示', 12 | 13 | // 权限 14 | 'permission': '权限', 15 | 'system:user': '用户管理', 16 | 'system:role': '角色管理', 17 | 'system:dept': '部门管理', 18 | 'system:menu': '菜单管理', 19 | 'system:post': '岗位管理', 20 | 21 | 'dataCenter': '数据', 22 | 'system:dict': '数据字典', 23 | 'system:attachment': '附件管理', 24 | 'system:dataMaintain': '数据表维护', 25 | 'system:notice': '系统公告', 26 | 'apps': '应用中心', 27 | 'system:appGroup': '应用分组', 28 | 'system:app': '应用管理', 29 | 'apis': '应用接口', 30 | 'system:apiGroup': '接口分组', 31 | 'system:api': '接口管理', 32 | 33 | // 监控 34 | 'monitor': '监控', 35 | 'system:monitor:server': '服务监控', 36 | 'system:onlineUser': '在线用户', 37 | 'system:cache': '缓存监控', 38 | 'system:monitor:rely': '依赖监控', 39 | 'logs': '日志监控', 40 | 'system:queueLog': '队列日志', 41 | 'system:loginLog': '登录日志', 42 | 'system:operLog': '操作日志', 43 | 'system:apiLog': '接口日志', 44 | 45 | // 工具 46 | 'devTools': '工具', 47 | 'setting:module': '模块管理', 48 | 'setting:code': '代码生成器', 49 | 'setting:code:update': '编辑生成信息', 50 | 'setting:crontab': '定时任务', 51 | 'setting:table': '数据表设计器', 52 | 'systemInterface': '系统接口', 53 | } -------------------------------------------------------------------------------- /src/i18n/zh_CN/skin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | mine: 'Mine', 3 | businessGray: '商务灰', 4 | city: '城市', 5 | 6 | mineDesc: '以纯净的白色为主,Mine默认皮肤', 7 | businessGrayDesc: '灰色的百搭与大气,营造商务与稳重', 8 | cityDesc: '愿城市每一个角度,都有一份温馨', 9 | 10 | activated: '已激活', 11 | use: '使用' 12 | } -------------------------------------------------------------------------------- /src/i18n/zh_CN/sys.js: -------------------------------------------------------------------------------- 1 | export default { 2 | pageSetting: '页面设置', 3 | chinese: '简体中文', 4 | english: 'English', 5 | search: '搜索', 6 | store: '应用市场', 7 | fullScreen: '全屏', 8 | closeFullScreen: '关闭全屏', 9 | changeSkin: '换肤', 10 | skin: '当前皮肤', 11 | layouts: '布局', 12 | language: '语言', 13 | dark: '黑夜模式', 14 | tag: '多标签', 15 | menuFold: '菜单折叠', 16 | menuWidth: '菜单宽度', 17 | skinHelp: '设置后台皮肤', 18 | layoutsHelp: '设置后台显示方式', 19 | languageHelp: '设置页面语言和请求后台语言', 20 | darkHelp: '设置页面显示模式', 21 | tagHelp: '是否启用多标签方式', 22 | menuFoldHelp: '系统左侧菜单是否折叠起来', 23 | menuWidthHelp: '设置左侧菜单的显示宽度', 24 | saveToBackend: '保存到后台', 25 | backendSettingTitle: '后台设置', 26 | systemPrimaryColor: '系统主色调', 27 | personalizedConfig: '个性化配置 ', 28 | layout: { 29 | classic: '经典', 30 | columns: '分栏', 31 | banner: '通栏', 32 | mixed: '混合', 33 | }, 34 | userCenter: '个人中心', 35 | clearCache: '清除缓存', 36 | logout: '退出系统', 37 | logoutAlert: '退出提示', 38 | logoutMessage: '确定要退出登录吗?', 39 | operationMessage: { 40 | message: '消息', 41 | notification: '通知', 42 | todo: '待办', 43 | }, 44 | goHome: '回到首页', 45 | notFoundPage: '啊哦,访问的页面被火星人劫走了...', 46 | login: { 47 | slogan: '开箱即用的高质量中后台管理系统', 48 | title: '登录', 49 | username: '账户', 50 | usernameNotice: '请输入账户', 51 | password: '密码', 52 | passwordNotice: '请输入密码', 53 | verifyCode: '请输入验证码', 54 | verifyCodeNotice: '请输入正确的验证码', 55 | loginBtn: '登录', 56 | otherLoginType: '其他登录方式' 57 | }, 58 | verifyCode: { 59 | switch: '点击切换验证码', 60 | error: '验证码错误', 61 | notice: '请输入验证码' 62 | }, 63 | i18n: '开启多语言', 64 | i18nHelp: '是否开启多语言功能', 65 | ws: '开启Ws', 66 | wsHelp: '是否开启Websocket连接', 67 | animation: '切换动画', 68 | animationHelp: '工作区页面切换的进场和出场动画效果', 69 | animate: { 70 | fade: '页面渐隐渐出', 71 | sliderLeft: '页面向左渐出', 72 | sliderRight:'页面向右渐出', 73 | sliderDown:'页面向下渐出', 74 | sliderUp:'页面向上渐出', 75 | }, 76 | tags: { 77 | refresh: '刷新', 78 | fullscreen: '全屏', 79 | closeRightTag: '关闭右侧标签', 80 | closeLeftTag: '关闭左侧标签', 81 | closeTag: '关闭当前标签', 82 | closeOtherTag: '关闭其他标签', 83 | }, 84 | noticeTitle: '系统提示', 85 | save: '保存', 86 | cancel: '取消', 87 | } 88 | -------------------------------------------------------------------------------- /src/i18n/zh_CN/upload.js: -------------------------------------------------------------------------------- 1 | export default { 2 | fileHashFail: '获取文件Hash失败,请重试', 3 | sizeLimit: '文件大小超过了限制', 4 | uploadFailed: '文件上传失败', 5 | buttonText: '本地上传', 6 | clickUpload: '点击上传', 7 | uploadDesc: '将文件拖到此处,或', 8 | } -------------------------------------------------------------------------------- /src/i18n/zh_CN/user.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: '菜单管理', 3 | 'system:cache': '系统缓存' 4 | } -------------------------------------------------------------------------------- /src/layout/404.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | {{ $t('sys.notFoundPage') }} 16 | 17 | {{ $t('sys.goHome') }} 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/layout/components/classic/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 31 | -------------------------------------------------------------------------------- /src/layout/components/classic/ma-classic-header.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /src/layout/components/classic/ma-classic-slider.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 17 | {{ $title }} 18 | 19 | 24 | 25 | 26 | 27 | 43 | 44 | 47 | -------------------------------------------------------------------------------- /src/layout/components/columns/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 49 | -------------------------------------------------------------------------------- /src/layout/components/columns/ma-columns-header.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /src/layout/components/components/iframe-view.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/layout/components/components/search.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/layout/components/components/skin.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | {{ $t('sys.changeSkin') }} 13 | 14 | 20 | 21 | 22 | {{ $t(`skin.${item.name}`) }} 23 | 24 | 25 | 26 | 27 | 28 | {{ $t(`skin.${item.name}Desc`) }} 29 | 30 | 31 | 36 | {{ appStore.skin === item.name ? $t('skin.activated') : $t('skin.use') }} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 62 | 63 | -------------------------------------------------------------------------------- /src/layout/components/ma-breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ $t('menus.dashboard') }} 6 | 7 | 8 | 11 | {{ appStore.i18n ? ( $t('menus.' + r.name).indexOf('.') > 0 ? r.meta.title : $t('menus.' + r.name) ) : r.meta.title }} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | -------------------------------------------------------------------------------- /src/layout/components/ma-buttonMenu.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /src/layout/components/ma-workerArea.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/layout/components/mixed/top-menu.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {{ appStore.i18n ? ( $t(`menus.${menu.name}`).indexOf('.') > 0 ? menu.meta.title : $t(`menus.${menu.name}`) ) : menu.meta.title }} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 51 | 52 | -------------------------------------------------------------------------------- /src/layout/empty.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import ArcoVue from '@arco-design/web-vue' 3 | import ArcoVueIcon from '@arco-design/web-vue/es/icon' 4 | 5 | import globalComponents from '@/components' 6 | import App from './App.vue' 7 | import router from './router' 8 | import store from './store' 9 | import i18n from '@/i18n' 10 | import directives from './directives' 11 | import { request } from '@/utils/request' 12 | import dayjs from 'dayjs' 13 | import zhCn from 'dayjs/locale/zh-cn' 14 | import relativeTime from 'dayjs/plugin/relativeTime' 15 | dayjs.locale(zhCn) 16 | dayjs.extend(relativeTime) 17 | 18 | // 官方样式 19 | // import '@arco-design/web-vue/dist/arco.css' 20 | // MineAdmin-V2样式 21 | import '@arco-themes/vue-mine-admin-v2/index.less' 22 | import './style/skin.less' 23 | import './style/index.css' 24 | import './style/global.less' 25 | 26 | import tool from '@/utils/tool' 27 | import * as common from '@/utils/common' 28 | import packageJson from '../package.json' 29 | 30 | const app = createApp(App) 31 | 32 | app.use(ArcoVue, {}) 33 | .use(ArcoVueIcon) 34 | .use(router) 35 | .use(store) 36 | .use(i18n) 37 | .use(directives) 38 | .use(globalComponents) 39 | 40 | // 注册ma-icon图标 41 | const modules = import.meta.glob('./assets/ma-icons/*.vue', { eager: true }) 42 | for (const path in modules) { 43 | const name = path.match(/([A-Za-z0-9_-]+)/g)[2] 44 | const componentName = `MaIcon${name}` 45 | app.component(componentName, modules[path].default) 46 | } 47 | 48 | app.config.globalProperties.$tool = tool 49 | app.config.globalProperties.$common = common 50 | app.config.globalProperties.$title = import.meta.env.VITE_APP_TITLE 51 | app.config.globalProperties.$url = import.meta.env.VITE_APP_BASE 52 | window.Request = request 53 | 54 | app.mount('#app') 55 | 56 | tool.capsule('MineAdmin', `v${packageJson.version} release`) 57 | console.log('MineAdmin 官网 https://www.mineadmin.com') 58 | console.log('MineAdmin 文档 https://doc.mineadmin.com') 59 | console.log('MineAdmin Github https://github.com/kanyxmo/MineAdmin') 60 | console.log('MineAdmin-Vue Github https://github.com/kanyxmo/MineAdmin-Vue') 61 | console.log('请不要吝啬您的 star,谢谢 ~ 🤩🤩🤩') -------------------------------------------------------------------------------- /src/plugin/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | install: (Vue) => { 3 | const pluginList = import.meta.glob('./*/main.js') 4 | Object.keys(pluginList).forEach((path) => { 5 | pluginList[path]().then(plugin => Vue.use(plugin.default || plugin)) 6 | }) 7 | } 8 | } -------------------------------------------------------------------------------- /src/router/homePageRoutes.js: -------------------------------------------------------------------------------- 1 | const homePageRoutes = [ 2 | { 3 | name: 'dashboard', 4 | path: '/dashboard', 5 | meta: { 6 | title: '仪表盘', 7 | icon: 'icon-dashboard', 8 | type: 'M', 9 | affix: true 10 | }, 11 | component: () => import('@/views/dashboard/index.vue'), 12 | }, { 13 | name: 'userCenter', 14 | path: '/usercenter', 15 | meta: { 16 | title: '个人信息', 17 | icon: 'icon-user', 18 | type: 'M', 19 | }, 20 | component: () => import('@/views/userCenter/index.vue'), 21 | }, { 22 | name: 'message', 23 | path: '/message', 24 | meta: { 25 | title: '消息中心', 26 | icon: 'icon-message', 27 | type: 'M', 28 | }, 29 | component: () => import('@/views/userCenter/message.vue'), 30 | }, { 31 | name: 'store', 32 | path: '/store', 33 | component: () => import('@/views/appStore/index.vue'), 34 | meta: { title: '应用市场', hidden: true } 35 | }, 36 | ] 37 | 38 | export const homePage = { 39 | name: 'home', 40 | path: '/home', 41 | meta: { title: '首页', icon: 'icon-home', hidden: false, type: 'M' } 42 | } 43 | 44 | export default homePageRoutes -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' 2 | import { useUserStore } from '@/store' 3 | import NProgress from 'nprogress' 4 | import tool from '@/utils/tool' 5 | import 'nprogress/nprogress.css' 6 | 7 | import routes from './webRouter.js' 8 | 9 | const title = import.meta.env.VITE_APP_TITLE 10 | const defaultRoutePath = '/' 11 | const whiteRoute = ['login', 'mineDoc', 'interfaceList', 'interfaceCode', 'signature'] 12 | 13 | const router = createRouter({ 14 | history: createWebHashHistory(), 15 | routes 16 | }) 17 | 18 | router.beforeEach(async (to, from, next) => { 19 | NProgress.start() 20 | const userStore = useUserStore() 21 | let toTitle = to.meta.title ? to.meta.title : to.name 22 | document.title = `${toTitle} - ${title}` 23 | const token = tool.local.get(import.meta.env.VITE_APP_TOKEN_PREFIX) 24 | 25 | // 登录状态下 26 | if (token) { 27 | if (to.name === 'login') { 28 | next({ path: defaultRoutePath }) 29 | return 30 | } 31 | 32 | if (! userStore.user && userStore.user == undefined ) { 33 | const data = await userStore.requestUserInfo() 34 | data && next({ path: to.path, query: to.query }) 35 | } else { 36 | next() 37 | } 38 | } else { 39 | // 未登录的情况下允许访问的路由 40 | if (! whiteRoute.includes(to.name)) { 41 | next({ name: 'login', query: { redirect: to.fullPath } }) 42 | } else { 43 | next() 44 | } 45 | } 46 | }) 47 | 48 | router.afterEach((to, from) => { 49 | NProgress.done() 50 | }) 51 | 52 | router.onError(error => { 53 | console.log(error) 54 | NProgress.done(); 55 | }); 56 | 57 | 58 | export default router -------------------------------------------------------------------------------- /src/router/webRouter.js: -------------------------------------------------------------------------------- 1 | import homePageRoutes from './homePageRoutes' 2 | //系统路由 3 | const routes = [ 4 | { 5 | name: 'layout', 6 | path: '/', 7 | component: () => import('@/layout/index.vue'), 8 | redirect: 'dashboard', 9 | children: homePageRoutes 10 | }, { 11 | name: 'formLayout', 12 | path: '/formLayout', 13 | component: () => import('@/layout/index.vue'), 14 | redirect: 'openForm', 15 | children: [{ 16 | name: 'openForm', 17 | path: '/openForm/:id', 18 | meta: { 19 | title: '公共表单', 20 | type: 'M', 21 | }, 22 | component: () => import('@/layout/form.vue'), 23 | }] 24 | }, { 25 | name: 'autoform', 26 | path: '/autoform', 27 | component: () => import('@/layout/index.vue'), 28 | redirect: '/autoform/:id', 29 | children: [{ 30 | name: 'autoformList', 31 | path: '/autoform:/:id', 32 | meta: { 33 | title: '自动表单', 34 | type: 'M', 35 | }, 36 | component: () => import('@/views/setting/autoform/index.vue'), 37 | }] 38 | }, { 39 | name: 'login', 40 | path: '/login', 41 | component: () => import('@/views/login.vue'), 42 | meta: { title: '登录' } 43 | }, { 44 | name: 'mineDoc', 45 | path: '/mineDoc', 46 | component: () => import('@/views/mineDoc/index.vue'), 47 | meta: { title: '接口文档' }, 48 | children: [ 49 | { 50 | path: '/interfaceList', 51 | name: 'interfaceList', 52 | meta: { title: '接口列表' }, 53 | component: () => import('@/views/mineDoc/page/interfaceList.vue'), 54 | }, 55 | { 56 | path: '/interfaceCode', 57 | name: 'interfaceCode', 58 | meta: { title: '代码释义' }, 59 | component: () => import('@/views/mineDoc/page/interfaceCode.vue'), 60 | }, 61 | { 62 | path: '/signature', 63 | name: 'signature', 64 | meta: { title: '签名算法' }, 65 | component: () => import('@/views/mineDoc/page/signature.vue'), 66 | } 67 | ] 68 | } 69 | , { 70 | path: "/:pathMatch(.*)*", 71 | hidden: true, 72 | meta: { title: '访问的页面不存在' }, 73 | component: () => import('@/layout/404.vue'), 74 | } 75 | ] 76 | 77 | export default routes -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia' 2 | import useUserStore from './modules/user' 3 | import useAppStore from './modules/app' 4 | import useTagStore from './modules/tag' 5 | import useKeepAliveStore from './modules/keepAlive' 6 | import useIframeStore from './modules/iframe' 7 | import useConfigStore from './modules/config' 8 | import useMessageStore from './modules/message' 9 | import useDocStore from './modules/doc' 10 | import useFormStore from './modules/form' 11 | 12 | const pinia = createPinia() 13 | 14 | export { 15 | useUserStore, 16 | useAppStore, 17 | useTagStore, 18 | useKeepAliveStore, 19 | useIframeStore, 20 | useConfigStore, 21 | useMessageStore, 22 | useDocStore, 23 | useFormStore, 24 | } 25 | export default pinia 26 | -------------------------------------------------------------------------------- /src/store/modules/config.js: -------------------------------------------------------------------------------- 1 | 2 | import { defineStore } from 'pinia' 3 | 4 | let defaultConfig = { 5 | site_name: 'MineAdmin', 6 | site_keywords: '', 7 | site_desc: '', 8 | site_record_number: '', 9 | site_copyright: '', 10 | site_storage_mode: '', 11 | web_close: '', 12 | } 13 | 14 | const useConfigStore = defineStore('config', { 15 | state: () => ({ ...defaultConfig }), 16 | 17 | getters: { 18 | appCurrentConfig() { 19 | return { ...this.$state } 20 | }, 21 | }, 22 | 23 | actions: { 24 | updateSettings(partial) { 25 | this.$patch(partial); 26 | }, 27 | }, 28 | }) 29 | 30 | export default useConfigStore -------------------------------------------------------------------------------- /src/store/modules/doc.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | const useDocStore = defineStore('doc', { 4 | 5 | state: () => ({ 6 | auth: undefined, 7 | appId: undefined, 8 | appSecret: undefined, 9 | globalParams: undefined, 10 | }), 11 | 12 | getters: { 13 | getState() { 14 | return { ...this.$state } 15 | }, 16 | }, 17 | 18 | actions: { 19 | setInfo(data) { this.$patch(data) }, 20 | } 21 | }) 22 | 23 | export default useDocStore -------------------------------------------------------------------------------- /src/store/modules/form.js: -------------------------------------------------------------------------------- 1 | 2 | import { defineStore } from 'pinia' 3 | 4 | let defaultConfig = { 5 | formList: [], 6 | crudList: {}, 7 | } 8 | 9 | const useFormStore = defineStore('form', { 10 | state: () => ({ ...defaultConfig }), 11 | 12 | getters: { 13 | getState() { 14 | return { ...this.$state } 15 | }, 16 | }, 17 | 18 | actions: { 19 | updateSettings(partial) { 20 | this.$patch(partial); 21 | }, 22 | }, 23 | }) 24 | 25 | export default useFormStore -------------------------------------------------------------------------------- /src/store/modules/iframe.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | const useIframeStore = defineStore('iframe', { 4 | state: () => ({ 5 | iframes: [], 6 | name: null, 7 | show: true 8 | }), 9 | 10 | getters: { 11 | getState() { 12 | return { ...this.$state } 13 | }, 14 | }, 15 | 16 | actions: { 17 | 18 | addIframe (component) { 19 | if (! this.iframes.includes(component)) { 20 | this.iframes.push(component) 21 | } 22 | }, 23 | 24 | removeIframe (component) { 25 | const idx = this.iframes.indexOf(component) 26 | if (idx !== -1) { 27 | this.iframes.splice(idx, 1) 28 | } 29 | }, 30 | 31 | display () { this.show = true }, 32 | 33 | hidden () { this.show = false }, 34 | 35 | setName (name) { this.name = name }, 36 | 37 | clearIframe() { this.iframes = [] }, 38 | }, 39 | }) 40 | 41 | export default useIframeStore -------------------------------------------------------------------------------- /src/store/modules/keepAlive.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | const useKeepAliveStore = defineStore('keepAlive', { 4 | state: () => ({ 5 | keepAlives: [], 6 | show: true, 7 | menuLoader: false, 8 | }), 9 | 10 | getters: { 11 | getState() { 12 | return { ...this.$state } 13 | }, 14 | }, 15 | 16 | actions: { 17 | 18 | addKeepAlive (component) { 19 | if (component.path.indexOf('maIframe') > -1) { 20 | return 21 | } 22 | if (! this.keepAlives.includes(component.name)) { 23 | this.keepAlives.push(component.name) 24 | } 25 | }, 26 | 27 | removeKeepAlive (component) { 28 | const idx = this.keepAlives.indexOf(component.name) 29 | if (idx !== -1) { 30 | this.keepAlives.splice(idx, 1) 31 | } 32 | }, 33 | 34 | display () { this.show = true }, 35 | 36 | hidden () { this.show = false }, 37 | 38 | clearKeepAlive() { this.keepAlives = [] }, 39 | }, 40 | }) 41 | 42 | export default useKeepAliveStore -------------------------------------------------------------------------------- /src/store/modules/message.js: -------------------------------------------------------------------------------- 1 | 2 | import { defineStore } from 'pinia' 3 | 4 | let defaultType = { 5 | messageList: [], 6 | } 7 | 8 | const useMessageStore = defineStore('message', { 9 | state: () => ({ ...defaultType }), 10 | 11 | getters: { 12 | getState() { 13 | return { ...this.$state } 14 | }, 15 | }, 16 | 17 | actions: { 18 | updateMessage(partial) { 19 | this.$patch(partial); 20 | }, 21 | }, 22 | }) 23 | 24 | export default useMessageStore -------------------------------------------------------------------------------- /src/store/modules/tag.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import tool from '@/utils/tool' 3 | 4 | const defaultTag = [ { name: 'dashboard', title: '仪表盘', path: '/dashboard', affix: true } ] 5 | const useTagStore = defineStore('tag', { 6 | state: () => ({ 7 | tags: (! tool.local.get('tags') || tool.local.get('tags').length === 0 ) ? defaultTag : tool.local.get('tags') 8 | }), 9 | 10 | getters: { 11 | getState() { 12 | return { ...this.$state } 13 | }, 14 | }, 15 | 16 | actions: { 17 | 18 | addTag(tag) { 19 | const target = this.tags.find( item => item.path === tag.path ) 20 | if (! target && tag.path ) { 21 | this.tags.push(tag) 22 | } 23 | this.updateTagsToLocal() 24 | }, 25 | 26 | removeTag(tag) { 27 | let index = 0 28 | this.tags.map((item, idx) => { 29 | if ( item.path === tag.path && ! item.affix ) { 30 | if (this.tags[(idx + 1)]) { 31 | index = idx 32 | } else if ( idx > 0) { 33 | index = idx - 1 34 | } 35 | this.tags.splice(idx, 1) 36 | } 37 | }) 38 | this.updateTagsToLocal() 39 | return this.tags[index] 40 | }, 41 | 42 | updateTag(tag) { 43 | this.tags.map(item => { 44 | if (item.path == tag.path) { 45 | item = Object.assign(item, tag) 46 | } 47 | }) 48 | this.updateTagsToLocal() 49 | }, 50 | 51 | updateTagTitle(path, title) { 52 | this.tags.map(item => { 53 | if (item.path == path) { 54 | item.customTitle = title 55 | } 56 | }) 57 | this.updateTagsToLocal() 58 | }, 59 | 60 | updateTagsToLocal() { 61 | tool.local.set('tags', this.tags) 62 | }, 63 | 64 | clearTags() { 65 | this.tags = defaultTag 66 | tool.local.set('tags', defaultTag) 67 | }, 68 | }, 69 | }) 70 | 71 | export default useTagStore -------------------------------------------------------------------------------- /src/style/animation.less: -------------------------------------------------------------------------------- 1 | .ma-fade-enter-active, 2 | .ma-fade-leave-active { 3 | transition: opacity 0.15s ease; 4 | } 5 | 6 | .ma-fade-enter-from, 7 | .ma-fade-leave-to { 8 | opacity: 0; 9 | } 10 | .ma-slide-right-enter-active, 11 | .ma-slide-right-leave-active, 12 | .ma-slide-left-enter-active, 13 | .ma-slide-left-leave-active { 14 | will-change: transform; 15 | transition: all 0.2s ease; 16 | } 17 | // ma-slide-right 18 | .ma-slide-right-enter-from { 19 | opacity: 0; 20 | transform: translateX(-10px); 21 | } 22 | .ma-slide-right-leave-to { 23 | opacity: 0; 24 | transform: translateX(10px); 25 | } 26 | // ma-slide-left 27 | .ma-slide-left-enter-from { 28 | &:extend(.ma-slide-right-leave-to); 29 | } 30 | .ma-slide-left-leave-to { 31 | &:extend(.ma-slide-right-enter-from); 32 | } 33 | 34 | .ma-slide-down-enter-active, 35 | .ma-slide-down-leave-active, 36 | .ma-slide-up-enter-active, 37 | .ma-slide-up-leave-active { 38 | will-change: transform; 39 | transition: all 0.2s ease; 40 | } 41 | // ma-slide-down 42 | .ma-slide-down-enter-from { 43 | opacity: 0; 44 | transform: translateY(-10px); 45 | } 46 | .ma-slide-down-leave-to { 47 | opacity: 0; 48 | transform: translateY(10px); 49 | } 50 | // ma-slide-up 51 | .ma-slide-up-enter-from { 52 | &:extend(.ma-slide-down-leave-to); 53 | } 54 | .ma-slide-up-leave-to { 55 | &:extend(.ma-slide-down-enter-from); 56 | } -------------------------------------------------------------------------------- /src/style/dark.less: -------------------------------------------------------------------------------- 1 | [arco-theme="dark"] { 2 | .menu-title { color: #efefef } 3 | .logo { span { color: #efefef } } 4 | 5 | .sys-search-container .results li .title, 6 | .sys-search-container .arco-icon 7 | { 8 | color: #efefef; 9 | } 10 | 11 | .sys-search-container .icon { 12 | fill: #efefef; 13 | } 14 | } -------------------------------------------------------------------------------- /src/style/index.css: -------------------------------------------------------------------------------- 1 | /* ./src/index.css */ 2 | @tailwind base; 3 | @tailwind components; 4 | @tailwind utilities; -------------------------------------------------------------------------------- /src/style/skin.less: -------------------------------------------------------------------------------- 1 | @import './skins/mine/index.less'; 2 | @import './skins/city/index.less'; 3 | @import './skins/businessGray/index.less'; -------------------------------------------------------------------------------- /src/style/skins/city/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineadmin/MineAdmin-Vue/0c619f2f1101fd8883c7971bb21d4a0bf7b2968d/src/style/skins/city/background.jpg -------------------------------------------------------------------------------- /src/style/skins/mine/index.less: -------------------------------------------------------------------------------- 1 | [mine-skin="mine"] { 2 | 3 | .arco-menu-light .arco-menu-item .arco-icon, 4 | .arco-menu-inline-header .arco-icon { 5 | color: var(--color-text-1); 6 | } 7 | 8 | .arco-trigger-menu .arco-trigger-menu-has-icon .arco-trigger-menu-icon, 9 | .sys-menus .arco-menu-icon .icon { 10 | fill: var(--color-text-2); 11 | } 12 | 13 | .arco-menu-light .arco-menu-item.arco-menu-selected .arco-icon { 14 | color: rgb(var(--primary-6)); 15 | } 16 | 17 | .layout-banner-header .banner-menus li.active { 18 | background-color: rgb(var(--primary-1)); 19 | color: rgb(var(--primary-6)); 20 | fill: rgb(var(--primary-6)); 21 | } 22 | 23 | .layout-columns-left-panel .sider { 24 | background-color: var(--color-bg-1); 25 | } 26 | 27 | .parent-menu { 28 | color: var(--color-text-2); 29 | fill: var(--color-text-2); 30 | } 31 | 32 | .parent-menu:hover { 33 | background-color: var(--color-fill-2); 34 | fill: var(--color-text-2); 35 | } 36 | 37 | 38 | .parent-menu.active { 39 | background-color: rgb(var(--primary-1)); 40 | color: rgb(var(--primary-6)); 41 | fill: rgb(var(--primary-6)); 42 | } 43 | 44 | .sys-menus .arco-menu-item.arco-menu-selected .icon { 45 | fill: rgb(var(--primary-6)); 46 | } 47 | } -------------------------------------------------------------------------------- /src/views/appStore/components/noDev.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 应用市场只在开发环境开放使用。 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/views/appStore/components/notice.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 请按照以下步骤设置: 13 | 14 | 1. 进入MineAdmin官网设置页面,获取 AccessToken 15 | 2. 打开后端 .env 配置文件 16 | 3. 添加此行配置:MINE_ACCESS_TOKEN = 获取到的AccessToken 17 | 4. 重启后端服务,完成配置 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/views/appStore/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/views/dashboard/components/components/st-announced.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 系统公告 14 | 更多 15 | 16 | 17 | 18 | {{ record.title }} 19 | 20 | 21 | 22 | 23 | 公告详情 24 | 25 | 26 | {{ row?.title }} 27 | 28 | 29 | 30 | 创建时间:{{ row?.created_at }} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/views/dashboard/components/statistics.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | -------------------------------------------------------------------------------- /src/views/dashboard/components/work-panel.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 员工工作台页面,需自行开发 14 | 15 | -------------------------------------------------------------------------------- /src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 26 | -------------------------------------------------------------------------------- /src/views/mineDoc/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /src/views/mineDoc/page/interfaceCode.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/views/setting/code/components/preview.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 预览代码 13 | 14 | 19 | 20 | 21 | 复制 22 | 23 | 24 | 25 | 26 | 27 | 28 | 54 | 55 | -------------------------------------------------------------------------------- /src/views/setting/config/components/addGroup.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 添加配置组 13 | 14 | 15 | 16 | 17 | 18 | 66 | -------------------------------------------------------------------------------- /src/views/setting/config/components/js/configDefine.js: -------------------------------------------------------------------------------- 1 | export const inputComponent = [ 2 | { label: '文本框', value: 'input' }, 3 | { label: '文本域', value: 'textarea' }, 4 | { label: '下拉选择框', value: 'select' }, 5 | { label: '单选框', value: 'radio' }, 6 | { label: '复选框', value: 'checkbox' }, 7 | { label: '开关', value: 'switch' }, 8 | { label: '图片上传', value: 'upload' }, 9 | { label: '键值对', value: 'key-value' }, 10 | { label: '富文本编辑器', value: 'editor' }, 11 | ] -------------------------------------------------------------------------------- /src/views/setting/systemInterface/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/system/logs/loginLog.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 49 | 50 | 53 | 54 | -------------------------------------------------------------------------------- /src/views/system/monitor/onlineUser/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 强制退出 17 | 18 | 19 | 20 | 21 | 22 | 23 | 51 | 52 | 55 | 56 | -------------------------------------------------------------------------------- /src/views/userCenter/components/userInfomation.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 保存 29 | 30 | 31 | 32 | 33 | 55 | -------------------------------------------------------------------------------- /src/ws-serve/message.js: -------------------------------------------------------------------------------- 1 | import Wsocket from "@/utils/Wsocket" 2 | import tool from '@/utils/tool' 3 | 4 | class Message { 5 | 6 | ws 7 | 8 | timer = null 9 | 10 | interval = 10 * 1000 11 | 12 | constructor() { 13 | this.ws = new Wsocket( 14 | import.meta.env.VITE_APP_WS_URL + '?token=' + tool.local.get(import.meta.env.VITE_APP_TOKEN_PREFIX), { 15 | onOpen: _ => { console.log('已成功连接到消息服务器...') }, 16 | onError: _ => { 17 | this.ws = undefined 18 | console.log('未成功连接到消息服务器...') 19 | }, 20 | onClose: _ => { 21 | this.ws = undefined 22 | console.log('与消息服务器断开...') 23 | }, 24 | } 25 | ) 26 | 27 | this.ws.heartbeat.openHeartbeat = false 28 | } 29 | 30 | getMessage() { 31 | this.timer = setInterval(() => { 32 | this.ws && this.ws.send({ event: 'get_unread_message' }) 33 | }, this.interval) 34 | } 35 | 36 | connection() { 37 | this.ws.connection() 38 | } 39 | 40 | } 41 | 42 | export default Message -------------------------------------------------------------------------------- /tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | const colors = require('tailwindcss/colors') 2 | module.exports = { 3 | content: [ './src/**/*.{js,jxs,vue}' ], 4 | darkMode: 'class', // or 'media' or 'class' 5 | theme: { 6 | fontFamily: { 7 | sans: ['Graphik', 'sans-serif'], 8 | serif: ['Merriweather', 'serif'], 9 | }, 10 | extend: { 11 | spacing: { 12 | '128': '32rem', 13 | '144': '36rem', 14 | }, 15 | borderRadius: { 16 | '4xl': '2rem', 17 | } 18 | } 19 | }, 20 | variants: { 21 | extend: { 22 | borderColor: ['focus-visible'], 23 | opacity: ['disabled'], 24 | } 25 | }, 26 | plugins: [ 27 | ], 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": false, 4 | "declaration": true, 5 | "declarationMap": true, 6 | "esModuleInterop": true, 7 | "jsx": "preserve", 8 | "allowJs": true, 9 | "strictFunctionTypes": false, 10 | "allowSyntheticDefaultImports": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "inlineSources": false, 13 | "isolatedModules": true, 14 | "moduleResolution": "node", 15 | "noUnusedLocals": false, 16 | "noUnusedParameters": false, 17 | "preserveWatchOutput": true, 18 | "skipLibCheck": true, 19 | "strict": true, 20 | "resolveJsonModule": true, 21 | "removeComments": true, 22 | "noImplicitAny": false, 23 | "experimentalDecorators": true, 24 | "target": "esnext", 25 | "module": "esnext", 26 | "baseUrl": ".", 27 | "paths": { 28 | "@/*": ["src/*"], 29 | "@cps/*": ["src/components/*"], 30 | "vue-i18n": ["vue-i18n/dist/vue-i18n.cjs.js"] 31 | }, 32 | "lib": ["dom", "esnext"], 33 | "types": ["vite/client"] 34 | }, 35 | "include": ["src", "mock", "vite.config.ts","node_modules", "dist", "build"] 36 | } 37 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig, loadEnv } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import { resolve } from 'path' 4 | import vueJsx from '@vitejs/plugin-vue-jsx' 5 | export default ({ mode }) => { 6 | const env = loadEnv(mode, process.cwd()) 7 | const proxyPrefix = env.VITE_APP_PROXY_PREFIX 8 | 9 | return defineConfig({ 10 | base: env.VITE_APP_BASE, 11 | plugins: [vue(), vueJsx()], 12 | resolve: { 13 | alias: { 14 | '@': resolve(__dirname, 'src'), 15 | '@cps': resolve(__dirname, 'src/components'), 16 | 'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js', 17 | }, 18 | }, 19 | 20 | build: { 21 | chunkSizeWarningLimit: 1500, 22 | // rollupOptions: { 23 | // output: { 24 | // manualChunks(id) { 25 | // if (id.includes('node_modules')) { 26 | // return id.toString().split("node_modules/")[1].split("/")[0].toString(); 27 | // } 28 | // } 29 | // } 30 | // } 31 | }, 32 | 33 | server: { 34 | host: '0.0.0.0', 35 | port: env.VITE_APP_PORT || process.env.port, 36 | proxy: { 37 | [proxyPrefix]: { 38 | target: env.VITE_APP_BASE_URL, 39 | changeOrigin: true, 40 | ws: true, 41 | toProxy: true, 42 | rewrite: path => path.replace(new RegExp(`^${proxyPrefix}`), ''), 43 | }, 44 | }, 45 | }, 46 | }) 47 | } 48 | --------------------------------------------------------------------------------