commit 57556026022d873349f2b3ae596700d593ca0f1a Author: zjf <1799650030@qq.com> Date: Fri May 23 11:40:05 2025 +0800 初始化 diff --git a/.cursor/rules/project.mdc b/.cursor/rules/project.mdc new file mode 100644 index 0000000..7dbb286 --- /dev/null +++ b/.cursor/rules/project.mdc @@ -0,0 +1,34 @@ +--- +description: Project technology stack description +globs: *.ts,**.vue,*.scss,*.css +--- +You are an expert in TypeScript, Vite, Vue3, Vue Router, Pinia, VueUse ,Daisy UI, Element Plus, and Tailwind, with a deep understanding of best practices and performance optimization techniques in these technologies. + +Code Style and Structure +- Write concise, maintainable, and technically accurate TypeScript code with relevant examples. +- Use functional and declarative programming patterns; avoid classes. +- Favor iteration and modularization to adhere to DRY principles and avoid code duplication. +- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError). +- Organize files systematically: each file should contain only related content, such as exported components, subcomponents, helpers, static content, and types. + +Naming Conventions +- Use lowercase with dashes for directories (e.g., components/auth-wizard). +- Favor named exports for functions. + +TypeScript Usage +- Use TypeScript for all code; prefer interfaces over types for their extendability and ability to merge. +- Avoid enums; use maps instead for better type safety and flexibility. +- Use functional components with TypeScript interfaces. + +Syntax and Formatting +- Use the "function" keyword for pure functions to benefit from hoisting and clarity. +- Always use the Vue Composition API script setup style. +- The order is template , typescript , Sass + +UI and Styling +- Use Element Plus,Daisyui, and Tailwind for components and styling. +- Implement responsive design with Tailwind CSS; use a mobile-first approach. + +Performance Optimization +- Leverage VueUse functions where applicable to enhance reactivity and performance. + \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 0000000..3dcb7d0 --- /dev/null +++ b/.env @@ -0,0 +1,56 @@ +# 网站主标题 +VITE_GLOBAL_TITLE= 'PIGX ADMIN' + +# footer +VITE_FOOTER_TITLE= '©2025 pig4cloud.com' + +# 是否是微服务架构(重要) +VITE_IS_MICRO= true + +# 前端访问前缀 +VITE_PUBLIC_PATH = / + +# 后端请求前缀 +VITE_API_URL = /api + +# ADMIN 服务地址 +VITE_ADMIN_PROXY_PATH = http://localhost:9999 + +# 前端加密密钥 +VITE_PWD_ENC_KEY='pigxpigxpigxpigx' + +# OAUTH2 密码模式客户端信息 +VITE_OAUTH2_PASSWORD_CLIENT='pig:pig' + +# OAUTH2 短信客户端信息 +VITE_OAUTH2_MOBILE_CLIENT='app:app' + +# OAUTH2 社交登录客户端信息 +VITE_OAUTH2_SOCIAL_CLIENT='social:social' + +# 是否开启前端滑块验证码 +VITE_VERIFY_ENABLE = true + +# 是否开启前端图形验证码 +VITE_VERIFY_IMAGE_ENABLE = false + +# 是否开启websocket 消息接受, +VITE_WEBSOCKET_ENABLE = false + +# 是否开启注册 +VITE_REGISTER_ENABLE = true + +# 是否开启租户自动选择 (根据租户域名) +VITE_AUTO_TENANT = false + +# 是否开启多语言切换 +VITE_I18N_ENABLE = true + +# 是否开启暗黑模式切换 +VITE_DARK_MODE_ENABLE = true + +# 是否启用禁用浏览器调试功能(反爬) +VITE_ENABLE_ANTI_DEBUG=false + +# 绕过反爬参数值 url?ddtk=参数值 +VITE_ANTI_DEBUG_KEY=pig diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..10202a2 --- /dev/null +++ b/.env.development @@ -0,0 +1,11 @@ +# port 端口号 +VITE_PORT = 8888 + +#浏览器自动打开 +VITE_OPEN = true + +# 本地环境 +ENV = 'development' + +# ADMIN 服务地址 +VITE_ADMIN_PROXY_PATH = http://127.0.0.1:9999 \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..cfc877d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,18 @@ + +*.sh +node_modules +lib +*.md +*.scss +*.woff +*.ttf +.vscode +.idea +dist +mock +public +bin +build +config +index.html +src/assets \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..f096e46 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,78 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + node: true, + }, + parser: 'vue-eslint-parser', + parserOptions: { + ecmaVersion: 12, + parser: '@typescript-eslint/parser', + sourceType: 'module', + }, + extends: ['plugin:vue/vue3-essential', 'plugin:vue/essential', 'eslint:recommended'], + plugins: ['vue', '@typescript-eslint'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.vue'], + rules: { + 'no-undef': 'off', + }, + }, + ], + rules: { + // http://eslint.cn/docs/rules/ + // https://eslint.vuejs.org/rules/ + // https://typescript-eslint.io/rules/no-unused-vars/ + '@typescript-eslint/ban-ts-ignore': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-redeclare': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + '@typescript-eslint/no-unused-vars': [2], + 'vue/custom-event-name-casing': 'off', + 'vue/attributes-order': 'off', + 'vue/one-component-per-file': 'off', + 'vue/html-closing-bracket-newline': 'off', + 'vue/max-attributes-per-line': 'off', + 'vue/multiline-html-element-content-newline': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/attribute-hyphenation': 'off', + 'vue/html-self-closing': 'off', + 'vue/no-multiple-template-root': 'off', + 'vue/require-default-prop': 'off', + 'vue/no-v-model-argument': 'off', + 'vue/no-arrow-functions-in-watch': 'off', + 'vue/no-template-key': 'off', + 'vue/no-v-html': 'off', + 'vue/comment-directive': 'off', + 'vue/no-mutating-props': 'off', + 'vue/no-parsing-error': 'off', + 'vue/no-deprecated-v-on-native-modifier': 'off', + 'vue/multi-word-component-names': 'off', + 'no-useless-escape': 'off', + 'no-sparse-arrays': 'off', + 'no-prototype-builtins': 'off', + 'no-constant-condition': 'off', + 'no-use-before-define': 'off', + 'no-restricted-globals': 'off', + 'no-restricted-syntax': 'off', + 'generator-star-spacing': 'off', + 'no-unreachable': 'off', + 'no-multiple-template-root': 'off', + 'no-unused-vars': 'error', + 'no-v-model-argument': 'off', + 'no-case-declarations': 'off', + 'no-console': 'error', + 'no-redeclare': 'off', + 'no-mixed-spaces-and-tabs': 'off', + }, +}; diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..c1882a9 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,50 @@ +name: build + +on: + push: + branches: + - master + - dev + +jobs: + task: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, macOS-latest, ubuntu-latest] + node-version: [16.x, 18.x, 20.x] + npm-client: [npm, yarn, pnpm] + + steps: + - uses: pnpm/action-setup@v2 + if: matrix.npm-client == 'pnpm' + name: Install pnpm + with: + version: 8 + run_install: false + + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + + - name: Check out code + uses: actions/checkout@v2 + + - name: Install dependencies + run: ${{ matrix.npm-client }} install + + - name: Build + run: ${{ matrix.npm-client }} run build + + - name: Notify failure + if: ${{ failure() }} + env: + QYWX_ROBOT_URL: ${{ secrets.QYWX_ROBOT_URL }} + run: | + curl -H "Content-Type: application/json" -X POST -d '{ + "msgtype": "text", + "text": { + "content": "Job failed! Click here for details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } + }' $QYWX_ROBOT_URL diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75c2983 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +.DS_Store +node_modules +/dist +dist.zip +docker/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# lock +package-lock.json +yarn.lock +pnpm-lock.yaml diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..cff490a --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,39 @@ +module.exports = { + // 一行最多多少个字符 + printWidth: 150, + // 指定每个缩进级别的空格数 + tabWidth: 2, + // 使用制表符而不是空格缩进行 + useTabs: true, + // 在语句末尾打印分号 + semi: true, + // 使用单引号而不是双引号 + singleQuote: true, + // 更改引用对象属性的时间 可选值"" + quoteProps: 'as-needed', + // 在JSX中使用单引号而不是双引号 + jsxSingleQuote: false, + // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"",默认none + trailingComma: 'es5', + // 在对象文字中的括号之间打印空格 + bracketSpacing: true, + // jsx 标签的反尖括号需要换行 + jsxBracketSameLine: false, + // 在单独的箭头函数参数周围包括括号 always:(x) => x \ avoid:x => x + arrowParens: 'always', + // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码 + rangeStart: 0, + rangeEnd: Infinity, + // 指定要使用的解析器,不需要写文件开头的 @prettier + requirePragma: false, + // 不需要自动在文件开头插入 @prettier + insertPragma: false, + // 使用默认的折行标准 always\never\preserve + proseWrap: 'preserve', + // 指定HTML文件的全局空格敏感度 css\strict\ignore + htmlWhitespaceSensitivity: 'css', + // Vue文件脚本和样式标签缩进 + vueIndentScriptAndStyle: false, + // 换行符使用 lf 结尾是 可选值"" + endOfLine: 'lf', +}; diff --git a/auto-imports.d.ts b/auto-imports.d.ts new file mode 100644 index 0000000..2b4704b --- /dev/null +++ b/auto-imports.d.ts @@ -0,0 +1,73 @@ +// Generated by 'unplugin-auto-import' +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const resolveDirective: typeof import('vue')['resolveDirective'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useLink: typeof import('vue-router')['useLink'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e08e60d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,9 @@ +FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/nginx + +COPY ./dist /data + +RUN rm /etc/nginx/conf.d/default.conf + +ADD jhkj-ui.conf /etc/nginx/conf.d/default.conf + +RUN /bin/bash -c 'echo init ok' diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml new file mode 100644 index 0000000..9e0266c --- /dev/null +++ b/docker/docker-compose.yaml @@ -0,0 +1,19 @@ +version: '3' +services: + jhkj-ui: + build: + context: . + restart: always + container_name: jhkj-ui + image: jhkj-ui + networks: + - spring_cloud_default + external_links: + - jhkj-gateway + ports: + - 80:80 + +# 加入到后端网络, 默认为 jhkj_default | docker network ls 查看 +networks: + spring_cloud_default: + external: true diff --git a/docker/jhkj-ui.conf b/docker/jhkj-ui.conf new file mode 100644 index 0000000..0bebaba --- /dev/null +++ b/docker/jhkj-ui.conf @@ -0,0 +1,39 @@ +server_tokens off; # Nginx 版本信息关闭,避免攻击 +client_max_body_size 64m; # 最大上传文件大小! +server { + listen 80; + server_name localhost; + + gzip on; + gzip_static on; # 需要http_gzip_static_module 模块 + gzip_min_length 1k; + gzip_comp_level 4; + gzip_proxied any; + gzip_types text/plain text/xml text/css; + gzip_vary on; + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + + # 前端打包好的dist目录文件 + root /data/; + + location ^~/api/ { + proxy_pass http://jhkj-gateway:9999/; #注意/后缀 + proxy_connect_timeout 60s; + proxy_read_timeout 120s; + proxy_send_timeout 120s; + proxy_set_header from ""; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto http; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_set_header from ""; + } + + # 屏蔽所有敏感路径,不用改代码配置开关,双重保护 + location ~* ^/(actuator|swagger-ui|v3/api-docs|swagger-resources|webjars|doc.html) { + return 403; # 禁止访问 + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..e2e0ef1 --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ + + + + + + + + + + + + + PIGX 微服务快速开发平台 + + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..d6d4723 --- /dev/null +++ b/package.json @@ -0,0 +1,116 @@ +{ + "name": "jhkj-ui", + "version": "5.8.0", + "description": "PIGCLOUD微服务开发平台", + "author": "pig4cloud", + "license": "不对外分发 pig4cloud 版权所有,请购买商业版权", + "scripts": { + "dev": "vite --force", + "build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build", + "build:docker": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build --outDir ./docker/dist/", + "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src", + "prettier": "prettier --write ." + }, + "dependencies": { + "@axolo/json-editor-vue": "^0.3.2", + "@chenfengyuan/vue-qrcode": "^2.0.0", + "@element-plus/icons-vue": "^2.0.10", + "@popperjs/core": "2.11.8", + "@vueuse/core": "^10.4.1", + "@wangeditor/editor": "5.1.23", + "@wangeditor/editor-for-vue": "5.1.12", + "@microsoft/fetch-event-source": "^2.0.1", + "marked": "^12.0.2", + "markmap-common": "0.15.6", + "markmap-lib": "0.15.8", + "markmap-view": "0.15.8", + "@form-create/element-ui": "3.2.16", + "form-create-designer": "3.2.10-oem", + "autoprefixer": "^10.4.7", + "axios": "^1.3.3", + "codemirror": "5.65.5", + "crypto-js": "^3.1.9-1", + "disable-devtool": "^0.3.8", + "driver.js": "^0.9.8", + "echarts": "^5.4.1", + "element-plus": "2.5.5", + "highlight.js": "^11.7.0", + "js-base64": "^3.7.7", + "js-cookie": "^3.0.1", + "json-editor-vue3": "^1.1.1", + "lodash": "^4.17.21", + "mitt": "^3.0.0", + "nprogress": "^0.2.0", + "pinia": "2.0.32", + "postcss": "8.4.40", + "qrcode": "1.5.1", + "qs": "^6.11.0", + "screenfull": "^6.0.2", + "sm-crypto": "^0.3.12", + "sortablejs": "^1.15.0", + "splitpanes": "^3.1.5", + "tailwindcss": "3.4.17", + "v-calendar": "3.1.2", + "vue": "3.4.15", + "vue-clipboard3": "^2.0.0", + "vue-echarts": "6.6.1", + "vue-i18n": "9.2.2", + "vue-router": "^4.1.6", + "vue3-tree-org": "^4.2.2", + "vue3-video-play": "1.3.1-beta.6", + "vuedraggable": "^4.1.0" + }, + "devDependencies": { + "@swc/core": "1.6.13", + "@types/crypto-js": "^4.2.2", + "@types/markdown-it": "^14.1.1", + "@types/node": "^18.14.0", + "@types/nprogress": "^0.2.0", + "@types/sm-crypto": "^0.3.4", + "@types/sortablejs": "^1.15.0", + "@typescript-eslint/eslint-plugin": "^5.53.0", + "@typescript-eslint/parser": "^5.53.0", + "@vitejs/plugin-vue": "^4.0.0", + "@vue/compiler-sfc": "^3.2.47", + "consola": "^2.15.3", + "cross-env": "7.0.3", + "daisyui": "4.11.1", + "eslint": "^8.34.0", + "eslint-plugin-vue": "^9.9.0", + "pinia-plugin-persist": "^1.0.0", + "prettier": "2.8.4", + "sass": "1.58.3", + "terser": "^5.31.1", + "typescript": "^4.9.5", + "unplugin-auto-import": "^0.13.0", + "vite": "^4.3.3", + "vite-plugin-compression": "^0.5.1", + "vite-plugin-style-import": "^2.0.0", + "vite-plugin-top-level-await": "^1.3.0", + "vite-plugin-vue-setup-extend": "^0.4.0", + "vue-eslint-parser": "^9.1.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ], + "bugs": { + "url": "https://pig4cloud.com" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">= 7.0.0" + }, + "keywords": [ + "vue", + "vue3", + "vuejs/vue-next", + "element-ui", + "element-plus" + ], + "repository": { + "type": "git", + "url": "https://gitee.com/log4j/pig" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..e873f1a --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/public/assets/fonts/FontAwesome.otf b/public/assets/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/public/assets/fonts/FontAwesome.otf differ diff --git a/public/assets/fonts/fontawesome-webfont.eot b/public/assets/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/public/assets/fonts/fontawesome-webfont.eot differ diff --git a/public/assets/fonts/fontawesome-webfont.svg b/public/assets/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/public/assets/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/fonts/fontawesome-webfont.ttf b/public/assets/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/public/assets/fonts/fontawesome-webfont.ttf differ diff --git a/public/assets/fonts/fontawesome-webfont.woff b/public/assets/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/public/assets/fonts/fontawesome-webfont.woff differ diff --git a/public/assets/fonts/fontawesome-webfont.woff2 b/public/assets/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/public/assets/fonts/fontawesome-webfont.woff2 differ diff --git a/public/assets/styles/font-awesome.min.css b/public/assets/styles/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/public/assets/styles/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e70bfa0 Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..d59f175 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,86 @@ + + + diff --git a/src/api/admin/audit.ts b/src/api/admin/audit.ts new file mode 100644 index 0000000..e42519d --- /dev/null +++ b/src/api/admin/audit.ts @@ -0,0 +1,24 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/audit/page', + method: 'get', + params: query, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/audit/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/audit/delete', + method: 'delete', + data: ids, + }); +} diff --git a/src/api/admin/client.ts b/src/api/admin/client.ts new file mode 100644 index 0000000..614a7e4 --- /dev/null +++ b/src/api/admin/client.ts @@ -0,0 +1,68 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/client/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/client', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/client/' + id, + method: 'get', + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/admin/client', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/client', + method: 'put', + data: obj, + }); +} + +export function refreshCache() { + return request({ + url: '/admin/client/sync', + method: 'put', + }); +} + +export function getDetails(obj: Object) { + return request({ + url: '/admin/client/getClientDetailsById/' + obj, + method: 'get', + }); +} + +export function validateclientId(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getDetails(value).then((res) => { + const result = res.data; + if (result !== null) { + callback(new Error('编号已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/config.ts b/src/api/admin/config.ts new file mode 100644 index 0000000..5b5ea17 --- /dev/null +++ b/src/api/admin/config.ts @@ -0,0 +1,64 @@ +import request from "/@/utils/request" + +export function fetchList(query?: Object) { + return request({ + url: '/admin/system-config/page', + method: 'get', + params: query + }) +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/system-config', + method: 'post', + data: obj + }) +} + +export function getObj(obj: Object) { + return request({ + url: '/admin/system-config/details', + method: 'get', + params: obj + }) +} + +export function refreshObj() { + return request({ + url: '/admin/system-config/refresh', + method: 'get' + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/system-config', + method: 'delete', + data: ids + }) +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/system-config', + method: 'put', + data: obj + }) +} + + +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObj({configKey: value}).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/dept.ts b/src/api/admin/dept.ts new file mode 100644 index 0000000..0a54b72 --- /dev/null +++ b/src/api/admin/dept.ts @@ -0,0 +1,83 @@ +import request from '/@/utils/request'; + +export const deptTree = (params?: Object) => { + return request({ + url: '/admin/dept/tree', + method: 'get', + params, + }); +}; + +export const addObj = (obj: Object) => { + return request({ + url: '/admin/dept', + method: 'post', + data: obj, + }); +}; + +export const getObj = (id: string) => { + return request({ + url: '/admin/dept/' + id, + method: 'get', + }); +}; + +export const delObj = (id: string) => { + return request({ + url: '/admin/dept/' + id, + method: 'delete', + }); +}; + +export const putObj = (obj: Object) => { + return request({ + url: '/admin/dept', + method: 'put', + data: obj, + }); +}; + +export const syncUser = () => { + return request({ + url: '/admin/connect/sync/ding/user', + method: 'post', + }); +}; + +export const syncDept = () => { + return request({ + url: '/admin/connect/sync/ding/dept', + method: 'post', + }); +}; + +export const syncCpUser = () => { + return request({ + url: '/admin/connect/sync/cp/user', + method: 'post', + }); +}; + +export const syncCpDept = () => { + return request({ + url: '/admin/connect/sync/cp/dept', + method: 'post', + }); +}; + +export const orgTree = (type: String, deptId: Number) => { + return request({ + url: '/admin/dept/org', + method: 'get', + params: {type: type, parentDeptId: deptId}, + }); +} + +export const orgTreeSearcheUser = (param: Object) => { + return request({ + url: '/admin/dept/org/user/search', + method: 'get', + params: param + }); +} diff --git a/src/api/admin/dict.ts b/src/api/admin/dict.ts new file mode 100644 index 0000000..a821eac --- /dev/null +++ b/src/api/admin/dict.ts @@ -0,0 +1,138 @@ +import request from '/@/utils/request'; + +export const getDicts = (type: String) => { + return request({ + url: `/admin/dict/type/${type}`, + method: 'get', + }); +}; + +export function fetchList(query: any) { + return request({ + url: '/admin/dict/list', + method: 'get', + params: query, + }); +} + +export function fetchItemList(query: any) { + return request({ + url: '/admin/dict/item/page', + method: 'get', + params: query, + }); +} + +export function addItemObj(obj: any) { + return request({ + url: '/admin/dict/item', + method: 'post', + data: obj, + }); +} + +export function getItemObj(id: string) { + return request({ + url: '/admin/dict/item/details/' + id, + method: 'get', + }); +} + +export function getItemDetails(obj: object) { + return request({ + url: '/admin/dict/item/details', + method: 'get', + params: obj, + }); +} + +export function delItemObj(id: string) { + return request({ + url: '/admin/dict/item/' + id, + method: 'delete', + }); +} + +export function putItemObj(obj: any) { + return request({ + url: '/admin/dict/item', + method: 'put', + data: obj, + }); +} + +export function addObj(obj: any) { + return request({ + url: '/admin/dict', + method: 'post', + data: obj, + }); +} + +export function getObj(id: string) { + return request({ + url: '/admin/dict/details/' + id, + method: 'get', + }); +} + +export function getObjDetails(obj: object) { + return request({ + url: '/admin/dict/details', + method: 'get', + params: obj, + }); +} + +export function delObj(ids: Object) { + return request({ + url: '/admin/dict', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj: any) { + return request({ + url: '/admin/dict', + method: 'put', + data: obj, + }); +} + +export function refreshCache() { + return request({ + url: '/admin/dict/sync', + method: 'put', + }); +} + +export function validateDictType(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ dictType: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('字典已经存在')); + } else { + callback(); + } + }); +} + +export function validateDictItemLabel(rule: any, value: any, callback: any, type: string, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getItemDetails({ dictType: type, label: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('标签已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/file.ts b/src/api/admin/file.ts new file mode 100644 index 0000000..3e09ee2 --- /dev/null +++ b/src/api/admin/file.ts @@ -0,0 +1,92 @@ +import request from '/@/utils/request'; + +export function fileList(query?: Object) { + return request({ + url: '/admin/sys-file/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/sys-file', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/sys-file/' + id, + method: 'get', + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/sys-file', + method: 'put', + data: obj, + }); +} + +export function fileGroupAdd(params: Record) { + return request({ + url: '/admin/sys-file/group/add', + method: 'post', + data: params, + }); +} + +export function fileGroupUpdate(params: Record) { + return request({ + url: '/admin/sys-file/group/update', + method: 'put', + data: params, + }); +} + +// 文件分类删除 +export function fileGroupDelete(params: Record) { + return request({ + url: '/admin/sys-file/group/delete/' + params.id, + method: 'delete', + }); +} + +// 文件分类列表 +export function fileCateLists(params: Record) { + return request({ + url: '/admin/sys-file/group/list', + method: 'get', + params: params, + }); +} + +// 文件删除 +export function fileDelete(params: Record) { + return request({ + url: '/admin/sys-file', + method: 'delete', + data: params.ids, + }); +} + +// 文件移动 +export function fileMove(params: Record) { + return request({ + url: '/admin/sys-file/group/move', + method: 'put', + data: params, + }); +} + +// 文件重命名 +export function fileRename(params: { id: number; original: string }) { + return request({ + url: '/admin/sys-file/rename', + method: 'put', + data: params, + }); +} diff --git a/src/api/admin/i18n.ts b/src/api/admin/i18n.ts new file mode 100644 index 0000000..efd442b --- /dev/null +++ b/src/api/admin/i18n.ts @@ -0,0 +1,115 @@ +import request from '/@/utils/request'; +import axios from 'axios'; +import { decrypt } from '/@/utils/apiCrypto'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/i18n/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/i18n', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/i18n/details/' + id, + method: 'get', + }); +} + +export function getObjDetails(obj?: object) { + return request({ + url: '/admin/i18n/details', + method: 'get', + params: obj, + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/admin/i18n', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/i18n', + method: 'put', + data: obj, + }); +} + +export function refreshCache() { + return request({ + url: '/admin/i18n/sync', + method: 'put', + }); +} + +/** + * 注意这里使用原声axios对象进行操作,request 实例中依赖i18n 所以还没有初始化会报错 + * @returns + */ +export function info() { + return axios.get(import.meta.env.VITE_API_URL + '/admin/i18n/info').then((response) => { + if (response.data.encryption) { + response.data = decrypt(response.data.encryption); + } + return response; + }); +} + +export function validateName(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ name: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('国际化编码已经存在')); + } else { + callback(); + } + }); +} + +export function validateZhCn(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ zhCn: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('国际化中文已经存在')); + } else { + callback(); + } + }); +} + +export function validateEn(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ en: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('国际化英文已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/log.ts b/src/api/admin/log.ts new file mode 100644 index 0000000..5b3b7c0 --- /dev/null +++ b/src/api/admin/log.ts @@ -0,0 +1,26 @@ +import request from '/@/utils/request'; + +export const pageList = (params?: Object) => { + return request({ + url: '/admin/log/page', + method: 'get', + params, + }); +}; + +export const delObj = (ids: object) => { + return request({ + url: '/admin/log', + method: 'delete', + data: ids, + }); +}; + + +export const getSum = (params?: Object) => { + return request({ + url: '/admin/log/sum', + method: 'get', + params, + }); +}; diff --git a/src/api/admin/menu.ts b/src/api/admin/menu.ts new file mode 100644 index 0000000..714b93b --- /dev/null +++ b/src/api/admin/menu.ts @@ -0,0 +1,78 @@ +import request from '/@/utils/request'; + +export const pageList = (params?: Object) => { + return request({ + url: '/admin/menu/tree', + method: 'get', + params, + }); +}; + +export const getObj = (obj: object) => { + return request({ + url: `/admin/menu/details`, + method: 'get', + params: obj + }); +}; + +export const save = (data: Object) => { + return request({ + url: '/admin/menu', + method: 'post', + data: data, + }); +}; + +export const putObj = (data: Object) => { + return request({ + url: '/admin/menu', + method: 'put', + data: data, + }); +}; + +export const addObj = (data: Object) => { + return request({ + url: '/admin/menu', + method: 'post', + data: data, + }); +}; + +export const delObj = (id: string) => { + return request({ + url: '/admin/menu/' + id, + method: 'delete', + }); +}; + +/** + * 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 + * @method getAdminMenu 获取后端动态路由菜单(admin) + */ +export function useMenuApi() { + return { + getAdminMenu: (params?: object) => { + return request({ + url: '/admin/menu', + method: 'get', + params, + }); + }, + }; +} + +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getObj({[rule.field]: value}).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/message.ts b/src/api/admin/message.ts new file mode 100644 index 0000000..38070a6 --- /dev/null +++ b/src/api/admin/message.ts @@ -0,0 +1,104 @@ +import request from '/@/utils/request'; + +export function fetchUserMessageReadList(query?: Object) { + return request({ + url: '/admin/sysMessage/user/read/page', + method: 'get', + params: query, + }); +} + +export function readUserMessage(params?: object) { + return request({ + url: '/admin/sysMessage/read', + method: 'post', + params: params, + }); +} + +export function fetchUserMessageList(query?: Object) { + return request({ + url: '/admin/sysMessage/user/page', + method: 'get', + params: query, + }); +} + +export function fetchList(query?: Object) { + return request({ + url: '/admin/sysMessage/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/sysMessage', + method: 'post', + data: obj, + }); +} + +export function sendObj(params?: object) { + return request({ + url: '/admin/sysMessage/send', + method: 'post', + params: params, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/sysMessage/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/sysMessage', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/sysMessage', + method: 'put', + data: obj, + }); +} + +export function sendSms(params?: object) { + return request({ + url: '/admin/sysMessage/send/sms', + method: 'post', + data: params, + }); +} + +export function sendEmail(params?: object) { + return request({ + url: '/admin/sysMessage/send/email', + method: 'post', + data: params, + }); +} + +export function sendHook(params?: object) { + return request({ + url: '/admin/sysMessage/send/webhook', + method: 'post', + data: params, + }); +} + +export function list(params?: object) { + return request({ + url: '/admin/sysMessage/list/hook', + method: 'get', + params: params, + }); +} diff --git a/src/api/admin/param.ts b/src/api/admin/param.ts new file mode 100644 index 0000000..e47081b --- /dev/null +++ b/src/api/admin/param.ts @@ -0,0 +1,92 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/param/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/param', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/param/details/' + id, + method: 'get', + }); +} + +export function delObj(ids?: Object) { + return request({ + url: '/admin/param', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/param', + method: 'put', + data: obj, + }); +} + +export function refreshCache() { + return request({ + url: '/admin/param/sync', + method: 'put', + }); +} + +export function getObjDetails(obj?: object) { + return request({ + url: '/admin/param/details', + method: 'get', + params: obj, + }); +} + +export function getValue(key?: String) { + return request({ + url: '/admin/param/publicValue/' + key, + method: 'get' + }); +} + +export function validateParamsCode(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({publicKey: value}).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('参数编码已经存在')); + } else { + callback(); + } + }); +} + +export function validateParamsName(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({publicName: value}).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('参数名称已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/post.ts b/src/api/admin/post.ts new file mode 100644 index 0000000..05960b2 --- /dev/null +++ b/src/api/admin/post.ts @@ -0,0 +1,86 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/post/page', + method: 'get', + params: query, + }); +} + +export const list = (params?: Object) => { + return request({ + url: '/admin/post/list', + method: 'get', + params, + }); +}; + +export function addObj(obj?: Object) { + return request({ + url: '/admin/post', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/post/details/' + id, + method: 'get', + }); +} + +export function getObjDetails(obj?: object) { + return request({ + url: '/admin/post/details', + method: 'get', + params: obj, + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/admin/post', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/post', + method: 'put', + data: obj, + }); +} + +export function validatePostName(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ postName: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('岗位名称已经存在')); + } else { + callback(); + } + }); +} + +export function validatePostCode(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ postCode: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('岗位编码已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/role.ts b/src/api/admin/role.ts new file mode 100644 index 0000000..b47cb38 --- /dev/null +++ b/src/api/admin/role.ts @@ -0,0 +1,111 @@ +import request from '/@/utils/request'; + +export const list = (params?: Object) => { + return request({ + url: '/admin/role/list', + method: 'get', + params, + }); +}; + +export const pageList = (params?: Object) => { + return request({ + url: '/admin/role/page', + method: 'get', + params, + }); +}; + +export const deptRoleList = () => { + return request({ + url: '/admin/role/list', + method: 'get', + }); +}; + +export const getObj = (id: string) => { + return request({ + url: '/admin/role/details/' + id, + method: 'get', + }); +}; + +export const getObjDetails = (obj: object) => { + return request({ + url: '/admin/role/details', + method: 'get', + params: obj, + }); +}; + +export const addObj = (obj: Object) => { + return request({ + url: '/admin/role', + method: 'post', + data: obj, + }); +}; + +export const putObj = (obj: Object) => { + return request({ + url: '/admin/role', + method: 'put', + data: obj, + }); +}; + +export const delObj = (ids: Object) => { + return request({ + url: '/admin/role', + method: 'delete', + data: ids, + }); +}; + +export const permissionUpd = (roleId: string, menuIds: string) => { + return request({ + url: '/admin/role/menu', + method: 'put', + data: { + roleId: roleId, + menuIds: menuIds, + }, + }); +}; + +export const fetchRoleTree = (roleId: string) => { + return request({ + url: '/admin/menu/tree/' + roleId, + method: 'get', + }); +}; + +export function validateRoleCode(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ roleCode: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('角色标识已经存在')); + } else { + callback(); + } + }); +} + +export function validateRoleName(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ roleName: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('角色名称已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/route.ts b/src/api/admin/route.ts new file mode 100644 index 0000000..9b0ee82 --- /dev/null +++ b/src/api/admin/route.ts @@ -0,0 +1,38 @@ +import request from '/@/utils/request'; + +export const fetchList = (query?: Object) => { + return request({ + url: '/admin/route', + method: 'get', + params: query, + }); +}; + +export const addObj = (obj?: object) => { + return request({ + url: '/admin/route', + method: 'post', + data: obj, + }); +}; + +export const deleteObj = (routeId?: string) => { + return request({ + url: '/admin/route/' + routeId, + method: 'delete' + }); +}; + +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + fetchList({[rule.field]: value}).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/schedule.ts b/src/api/admin/schedule.ts new file mode 100644 index 0000000..9fefccb --- /dev/null +++ b/src/api/admin/schedule.ts @@ -0,0 +1,48 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/schedule/page', + method: 'get', + params: query, + }); +} + +export function list(query?: Object) { + return request({ + url: '/admin/schedule/list', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/schedule', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/schedule/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/schedule', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/schedule', + method: 'put', + data: obj, + }); +} diff --git a/src/api/admin/sensitive.ts b/src/api/admin/sensitive.ts new file mode 100644 index 0000000..5f68542 --- /dev/null +++ b/src/api/admin/sensitive.ts @@ -0,0 +1,71 @@ +import request from "/@/utils/request" + +export function fetchList(query?: Object) { + return request({ + url: '/admin/sysSensitiveWord/page', + method: 'get', + params: query + }) +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/sysSensitiveWord', + method: 'post', + data: obj + }) +} + +export function getObj(obj: Object) { + return request({ + url: '/admin/sysSensitiveWord/details', + method: 'get', + params: obj + }) +} + +export function refreshObj() { + return request({ + url: '/admin/sysSensitiveWord/refresh', + method: 'get' + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/sysSensitiveWord', + method: 'delete', + data: ids + }) +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/sysSensitiveWord', + method: 'put', + data: obj + }) +} + +export function testObj(obj?: Object) { + return request({ + url: '/admin/sysSensitiveWord/match', + method: 'post', + data: obj + }) +} + +export function validateWord(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObj({ sensitiveWord: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('敏感词已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/social.ts b/src/api/admin/social.ts new file mode 100644 index 0000000..93bc8fe --- /dev/null +++ b/src/api/admin/social.ts @@ -0,0 +1,47 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/admin/social/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/social', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/social/getById/' + id, + method: 'get', + }); +} + +export function delObj(ids?: Object) { + return request({ + url: '/admin/social', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/social', + method: 'put', + data: obj, + }); +} + +export function getLoginAppList(id?: string) { + return request({ + url: '/admin/social/getLoginAppList', + method: 'get', + }); +} diff --git a/src/api/admin/sysArea.ts b/src/api/admin/sysArea.ts new file mode 100644 index 0000000..8e80a10 --- /dev/null +++ b/src/api/admin/sysArea.ts @@ -0,0 +1,63 @@ +import request from "/@/utils/request" + +export function fetchTree(query?: Object) { + return request({ + url: '/admin/sysArea/tree', + method: 'get', + params: query + }) +} + +export function fetchList(query?: Object) { + return request({ + url: '/admin/sysArea/page', + method: 'get', + params: query + }) +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/sysArea', + method: 'post', + data: obj + }) +} + +export function getObj(query?: Object,) { + return request({ + url: '/admin/sysArea/details', + method: 'get', + params: query + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: '/admin/sysArea', + method: 'delete', + data: ids + }) +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/sysArea', + method: 'put', + data: obj + }) +} + +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getObj({ [rule.field] : value }).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/admin/system.ts b/src/api/admin/system.ts new file mode 100644 index 0000000..9bb097b --- /dev/null +++ b/src/api/admin/system.ts @@ -0,0 +1,9 @@ +import request from '/@/utils/request'; + +// 系统缓存监控 +export function systemCache() { + return request({ + url: '/admin/system/cache', + method: 'get', + }); +} diff --git a/src/api/admin/tenant.ts b/src/api/admin/tenant.ts new file mode 100644 index 0000000..8920227 --- /dev/null +++ b/src/api/admin/tenant.ts @@ -0,0 +1,93 @@ +import request from '/@/utils/request'; + +export function fetchPage(query?: Object) { + return request({ + url: '/admin/tenant/page', + method: 'get', + params: query, + }); +} + +export function fetchList(query?: object) { + return request({ + url: '/admin/tenant/list', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/admin/tenant', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/admin/tenant/details/' + id, + method: 'get', + }); +} + +export function getObjDetails(obj?: object) { + return request({ + url: '/admin/tenant/details', + method: 'get', + params: obj, + }); +} + +export function delObj(ids?: Object) { + return request({ + url: '/admin/tenant', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/admin/tenant', + method: 'put', + data: obj, + }); +} + +export function validateTenantName(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ name: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('租户名称已经存在')); + } else { + callback(); + } + }); +} + +export function validateTenantCode(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ code: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('租户编码已经存在')); + } else { + callback(); + } + }); +} + +export function treemenu() { + return request({ + url: '/admin/tenant/tree/menu', + method: 'get', + }); +} diff --git a/src/api/admin/token.ts b/src/api/admin/token.ts new file mode 100644 index 0000000..e373718 --- /dev/null +++ b/src/api/admin/token.ts @@ -0,0 +1,17 @@ +import request from '/@/utils/request'; + +export function fetchList(query: object) { + return request({ + url: '/admin/sys-token/page', + method: 'post', + data: query, + }); +} + +export function delObj(accessTokens: string[]) { + return request({ + url: '/admin/sys-token/delete', + method: 'delete', + data: accessTokens, + }); +} diff --git a/src/api/admin/user.ts b/src/api/admin/user.ts new file mode 100644 index 0000000..e2f8abf --- /dev/null +++ b/src/api/admin/user.ts @@ -0,0 +1,145 @@ +import request from '/@/utils/request'; + +export const list = () => { + return request({ + url: '/admin/user/list', + method: 'get', + }); +}; +export const pageList = (params?: Object) => { + return request({ + url: '/admin/user/page', + method: 'get', + params, + }); +}; + +export const addObj = (obj: Object) => { + return request({ + url: '/admin/user', + method: 'post', + data: obj, + }); +}; + +export const getObj = (id: String) => { + return request({ + url: '/admin/user/details/' + id, + method: 'get', + }); +}; + +export const delObj = (ids: Object) => { + return request({ + url: '/admin/user', + method: 'delete', + data: ids, + }); +}; + +export const putObj = (obj: Object) => { + return request({ + url: '/admin/user', + method: 'put', + data: obj, + }); +}; + +export function getDetails(obj: Object) { + return request({ + url: '/admin/user/details', + method: 'get', + params: obj, + }); +} + +// 更改个人信息 +export function editInfo(obj: Object) { + return request({ + url: '/admin/user/personal/edit', + method: 'put', + data: obj, + }); +} + +// 更改个人密码 +export function password(obj: Object) { + return request({ + url: '/admin/user/personal/password', + method: 'put', + data: obj, + }); +} + +export function unbindingUser(type) { + return request({ + url: '/admin/user/unbinding', + method: 'post', + params: { + type, + }, + }); +} + +export function checkPassword(password: string) { + return request({ + url: '/admin/user/check', + method: 'post', + params: { + password, + }, + }); +} + +/** + * 注册用户 + */ +export const registerUser = (userInfo: object) => { + return request({ + url: '/admin/register/user', + method: 'post', + data: userInfo, + }); +}; + +export const resetUserPassword = (userInfo: object) => { + return request({ + url: '/admin/register/password', + method: 'post', + data: userInfo, + }); +}; + +export function validateUsername(rule: any, value: any, callback: any, isEdit: boolean) { + const flag = new RegExp(/^([a-z\d]+?)$/).test(value); + if (!flag) { + callback(new Error('用户名支持小写英文、数字')); + } + + if (isEdit) { + return callback(); + } + + getDetails({ username: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('用户名已经存在')); + } else { + callback(); + } + }); +} + +export function validatePhone(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getDetails({ phone: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('手机号已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/app/appArticle.ts b/src/api/app/appArticle.ts new file mode 100644 index 0000000..f2ec723 --- /dev/null +++ b/src/api/app/appArticle.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/app/appArticle/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/app/appArticle', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: `/app/appArticle/details/${id}/1`, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/app/appArticle', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/app/appArticle', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/appArticleCategory.ts b/src/api/app/appArticleCategory.ts new file mode 100644 index 0000000..f5db5f2 --- /dev/null +++ b/src/api/app/appArticleCategory.ts @@ -0,0 +1,47 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/app/appArticleCategory/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/app/appArticleCategory', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/app/appArticleCategory/' + id, + method: 'get', + }); +} + +export function getObjList() { + return request({ + url: '/app/appArticleCategory/list', + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/app/appArticleCategory', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/app/appArticleCategory', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/approle.ts b/src/api/app/approle.ts new file mode 100644 index 0000000..efdc94b --- /dev/null +++ b/src/api/app/approle.ts @@ -0,0 +1,113 @@ +import request from '/@/utils/request'; + +export function fetchList(query: any) { + return request({ + url: '/app/approle/page', + method: 'get', + params: query, + }); +} + +export function list() { + return request({ + url: '/app/approle/list', + method: 'get', + }); +} + +export function addObj(obj: any) { + return request({ + url: '/app/approle', + method: 'post', + data: obj, + }); +} + +export function getObj(id: string) { + return request({ + url: '/app/approle/' + id, + method: 'get', + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/app/approle', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj: any) { + return request({ + url: '/app/approle', + method: 'put', + data: obj, + }); +} + +export function fetchRoleTree(roleId: string) { + return request({ + url: '/app/appmenu/tree/' + roleId, + method: 'get', + }); +} + +export function permissionUpd(roleId: string, menuIds: string) { + return request({ + url: '/app/approle/menu', + method: 'put', + data: { + roleId: roleId, + menuIds: menuIds, + }, + }); +} + +export function getDetails(obj: Object) { + return request({ + url: '/app/approle/details/' + obj, + method: 'get', + }); +} + +export function getDetailsByCode(obj: Object) { + return request({ + url: '/app/approle/detailsByCode/' + obj, + method: 'get', + }); +} + +export function validateApproleName(rule: any, value: any, callback: any, isEdit: boolean) { + const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value); + if (!flag) { + callback(new Error('用户名支持小写英文、数字、中文')); + } + + if (isEdit) { + return callback(); + } + + getDetails(value).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('用户名已经存在')); + } else { + callback(); + } + }); +} + +export function validateAppRoleCode(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getDetailsByCode(value).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('角色标识已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/app/approlemenu.ts b/src/api/app/approlemenu.ts new file mode 100644 index 0000000..d1dea83 --- /dev/null +++ b/src/api/app/approlemenu.ts @@ -0,0 +1,39 @@ +import request from '/@/utils/request'; + +export function fetchList(query: any) { + return request({ + url: '/app/approlemenu/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj: any) { + return request({ + url: '/app/approlemenu', + method: 'post', + data: obj, + }); +} + +export function getObj(id: string) { + return request({ + url: '/app/approlemenu/' + id, + method: 'get', + }); +} + +export function delObj(id: string) { + return request({ + url: '/app/approlemenu/' + id, + method: 'delete', + }); +} + +export function putObj(obj: string) { + return request({ + url: '/app/approlemenu', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/appsocial.ts b/src/api/app/appsocial.ts new file mode 100644 index 0000000..02d932a --- /dev/null +++ b/src/api/app/appsocial.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/app/appsocial/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/app/appsocial', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/app/appsocial/' + id, + method: 'get', + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/app/appsocial', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/app/appsocial', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/appuser.ts b/src/api/app/appuser.ts new file mode 100644 index 0000000..722bfb0 --- /dev/null +++ b/src/api/app/appuser.ts @@ -0,0 +1,86 @@ +import request from '/@/utils/request'; + +export function fetchList(query: any) { + return request({ + url: '/app/appuser/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj: any) { + return request({ + url: '/app/appuser', + method: 'post', + data: obj, + }); +} + +export function getObj(id: string) { + return request({ + url: '/app/appuser/details/' + id, + method: 'get', + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/app/appuser', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj: any) { + return request({ + url: '/app/appuser', + method: 'put', + data: obj, + }); +} + +export function getDetails(obj: Object) { + return request({ + url: '/app/appuser/details', + method: 'get', + params: obj, + }); +} + +export function validateUsername(rule: any, value: any, callback: any, isEdit: boolean) { + const flag = new RegExp(/^([a-z\d]+?)$/).test(value); + if (!flag) { + callback(new Error('用户名支持小写英文、数字')); + } + + if (isEdit) { + return callback(); + } + + getDetails({ + username: value, + }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('用户名已经存在')); + } else { + callback(); + } + }); +} + +export function validatePhone(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + getDetails({ + phone: value, + }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('手机号已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/app/appuserrole.ts b/src/api/app/appuserrole.ts new file mode 100644 index 0000000..d355ce6 --- /dev/null +++ b/src/api/app/appuserrole.ts @@ -0,0 +1,39 @@ +import request from '/@/utils/request'; + +export function fetchList(query: any) { + return request({ + url: '/app/appuserrole/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj: any) { + return request({ + url: '/app/appuserrole', + method: 'post', + data: obj, + }); +} + +export function getObj(id: string) { + return request({ + url: '/app/appuserrole/' + id, + method: 'get', + }); +} + +export function delObj(id: string) { + return request({ + url: '/app/appuserrole/' + id, + method: 'delete', + }); +} + +export function putObj(obj: any) { + return request({ + url: '/app/appuserrole', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/page.ts b/src/api/app/page.ts new file mode 100644 index 0000000..2943370 --- /dev/null +++ b/src/api/app/page.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/app/page/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/app/appPage', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/app/appPage/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/app/page', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/app/appPage', + method: 'put', + data: obj, + }); +} diff --git a/src/api/app/tabbar.ts b/src/api/app/tabbar.ts new file mode 100644 index 0000000..96a3943 --- /dev/null +++ b/src/api/app/tabbar.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/app/appTabbar/list', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/app/appTabbar', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/app/appTabbar/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/app/appTabbar', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/app/appTabbar', + method: 'put', + data: obj, + }); +} diff --git a/src/api/daemon/job-log.ts b/src/api/daemon/job-log.ts new file mode 100644 index 0000000..9c961a2 --- /dev/null +++ b/src/api/daemon/job-log.ts @@ -0,0 +1,17 @@ +import request from '/@/utils/request'; + +export function fetchList(query: any) { + return request({ + url: '/job/sys-job-log/page', + method: 'get', + params: query, + }); +} + +export function delObjs(ids: object) { + return request({ + url: '/job/sys-job-log', + method: 'delete', + data: ids, + }); +} diff --git a/src/api/daemon/job.ts b/src/api/daemon/job.ts new file mode 100644 index 0000000..deb2ed5 --- /dev/null +++ b/src/api/daemon/job.ts @@ -0,0 +1,74 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/job/sys-job/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/job/sys-job', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/job/sys-job/' + id, + method: 'get', + }); +} + +export function delObj(id?: string) { + return request({ + url: '/job/sys-job/' + id, + method: 'delete', + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/job/sys-job', + method: 'put', + data: obj, + }); +} + +export function startJobRa(jobId: string) { + return request({ + url: '/job/sys-job/start-job/' + jobId, + method: 'post', + }); +} + +export function runJobRa(jobId: string) { + return request({ + url: '/job/sys-job/run-job/' + jobId, + method: 'post', + }); +} + +export function shutDownJobRa(jobId: string) { + return request({ + url: '/job/sys-job/shutdown-job/' + jobId, + method: 'post', + }); +} + +export function validateJob(rule: any, value: any, callback: any, form: any) { + request({ + url: '/job/sys-job/validate', + method: 'get', + params: Object.assign(form, { field: rule.field }), + }).then(({ data }) => { + if (data) { + callback(new Error(data)); + } else { + callback(); + } + }); +} diff --git a/src/api/flow/flow/index.ts b/src/api/flow/flow/index.ts new file mode 100644 index 0000000..6efc6f8 --- /dev/null +++ b/src/api/flow/flow/index.ts @@ -0,0 +1,76 @@ +import request from '/@/utils/request'; + +/** + * 创建流程 + * + * @param data + */ +export function addFlow(data: any) { + return request({ + url: '/task/process/create', + method: 'post', + data: data, + }); +} + +/** + * 获取流程详细信息 + * + * @param data + */ +export function getFlowDetail(flowId: string) { + return request({ + url: '/task/process/getDetail', + method: 'get', + params: {flowId}, + }); +} + +/** + * 停用流程 + * + * @param data + */ +export function disableFlow(flowId: string) { + return request({ + url: '/task/process/update/' + flowId + '?type=stop', + method: 'put', + }); +} + +/** + * 删除流程 + * + * @param data + */ +export function deleteFlow(flowId: string) { + return request({ + url: '/task/process/update/' + flowId + '?type=delete', + method: 'put', + }); +} + +/** + * 启用流程 + * + * @param data + */ +export function enableFlow(flowId: string) { + return request({ + url: '/task/process/update/' + flowId + '?type=using', + method: 'put', + }); +} + +/** + * 发起流程 + * + * @param data + */ +export function startFlow(obj: any) { + return request({ + url: '/task/process-instance/startProcessInstance', + method: 'post', + data: obj, + }); +} diff --git a/src/api/flow/flow/types.ts b/src/api/flow/flow/types.ts new file mode 100644 index 0000000..7ba65c9 --- /dev/null +++ b/src/api/flow/flow/types.ts @@ -0,0 +1,16 @@ +/** + * 菜单视图对象类型 + */ +export interface FlowVO { + stop?: boolean; + updated?: string; + + /** + * 菜单ID + */ + formId?: string; + /** + * 菜单名称 + */ + formName?: string; +} diff --git a/src/api/flow/group/index.ts b/src/api/flow/group/index.ts new file mode 100644 index 0000000..b9e0ef4 --- /dev/null +++ b/src/api/flow/group/index.ts @@ -0,0 +1,63 @@ +import request from '/@/utils/request'; +import { AxiosPromise } from 'axios'; +import { Group, GroupVO } from './types'; + +/** + * 添加分组 + * + * @param data + */ +export function addGroup(data: Group) { + return request({ + url: '/task/processGroup/create', + method: 'post', + data: data, + }); +} + +/** + * 删除分组 + * + * @param data + */ +export function delGroup(id: number) { + return request({ + url: '/task/processGroup/delete/' + id, + method: 'delete', + }); +} + +/** + * 查询分组列表 + */ + +export function queryGroupList(): AxiosPromise { + return request({ + url: '/task/processGroup/list', + method: 'get', + }); +} + +/** + * 查询分组和流程列表 + */ + +export function queryGroupFlowList(params?: Object) { + return request({ + url: '/task/combination/group/listGroupWithProcess', + method: 'get', + params: params, + }); +} + +/** + * 查询我可发起的组和流程 + */ + +export function queryMineStartGroupFlowList(hidden?: string): AxiosPromise { + return request({ + url: '/task/combination/group/listCurrentUserStartGroup', + method: 'get', + params: { hidden: hidden }, + }); +} diff --git a/src/api/flow/group/types.ts b/src/api/flow/group/types.ts new file mode 100644 index 0000000..ae9bfed --- /dev/null +++ b/src/api/flow/group/types.ts @@ -0,0 +1,27 @@ +import { FlowVO } from '/@/api/flow/flow/types'; + +/** + * 菜单查询参数类型 + */ +export interface Group { + groupName?: string; +} + +/** + * 菜单视图对象类型 + */ +export interface GroupVO { + /** + * 子菜单 + */ + items?: FlowVO[]; + + /** + * 菜单ID + */ + id?: number; + /** + * 菜单名称 + */ + name?: string; +} diff --git a/src/api/flow/processInstance/index.ts b/src/api/flow/processInstance/index.ts new file mode 100644 index 0000000..614e08f --- /dev/null +++ b/src/api/flow/processInstance/index.ts @@ -0,0 +1,10 @@ +import request from '/@/utils/request'; + +// 流程详情 +export function detail(param: any) { + return request({ + url: '/task/process-instance/detail', + method: 'get', + params: param, + }); +} diff --git a/src/api/flow/task/index.ts b/src/api/flow/task/index.ts new file mode 100644 index 0000000..2a0e6b7 --- /dev/null +++ b/src/api/flow/task/index.ts @@ -0,0 +1,115 @@ +import request from '/@/utils/request'; + +// 查询用户首页数据看板 +export function queryTaskData() { + return request({ + url: '/task/task/queryTaskData', + method: 'get', + }); +} + +// 查询抄送详细信息 +export function queryMineCCDetail(param: any) { + return request({ + url: '/task/processCopy/querySingleDetail', + method: 'get', + params: param, + }); +} + +/** + * 抄送给我的 + * + * @param data + */ +export function queryMineCC(data: any) { + return request({ + url: '/task/process-instance/queryMineCC', + method: 'post', + data: data, + }); +} + +/** + * 查询待办任务 + * + * @param data + */ +export function queryMineTask(data: any) { + return request({ + url: '/task/process-instance/queryMineTask', + method: 'post', + data: data, + }); +} + +// 结束流程 +export function stopProcessInstance(param: any) { + return request({ + url: '/task/task/stopProcessInstance', + method: 'post', + data: param, + }); +} + +/** + * 查询我发起的任务 + * + * @param data + */ +export function queryMineStarted(data: any) { + return request({ + url: '/task/process-instance/queryMineStarted', + method: 'post', + data: data, + }); +} + +// 查询当前用户已办任务 +export function queryMineEndTask(param) { + return request({ + url: '/task/process-instance/queryMineEndTask', + method: 'post', + data: param, + }); +} + +/** + * 查询任务详细信息 + * + * @param data + */ +export function queryTask(taskId: string, view: boolean) { + return request({ + url: '/task/task/queryTask', + method: 'get', + params: {taskId, view}, + }); +} + +// 完成任务 +export function completeTask(param: Object) { + return request({ + url: '/task/task/completeTask', + method: 'post', + data: param, + }); +} + +// 完成任务 +export function transferTask(param: Object) { + return request({ + url: '/task/task/setAssignee', + method: 'post', + data: param, + }); +} + +// 格式化流程节点显示 +export function formatStartNodeShow(param: Object) { + return request({ + url: '/task/process-instance/formatStartNodeShow', + method: 'post', + data: param, + }); +} diff --git a/src/api/gen/create-table.ts b/src/api/gen/create-table.ts new file mode 100644 index 0000000..e0ccd1a --- /dev/null +++ b/src/api/gen/create-table.ts @@ -0,0 +1,55 @@ +import request from "/@/utils/request" + +export function fetchList(query?: Object) { + return request({ + url: '/gen/create-table/page', + method: 'get', + params: query + }) +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/create-table', + method: 'post', + data: obj + }) +} + +export function tempStore(obj: any) { + return request({ + url: '/gen/create-table/temp-store', + method: 'post', + data: obj + }) +} + +export function getObj(id: any) { + return request({ + url: '/gen/create-table/' + id, + method: 'get' + }) +} + +export function delObj(id: any) { + return request({ + url: '/gen/create-table/' + id, + method: 'delete' + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: '/gen/create-table', + method: 'delete', + data: ids + }) +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/create-table', + method: 'put', + data: obj + }) +} diff --git a/src/api/gen/datasource.ts b/src/api/gen/datasource.ts new file mode 100644 index 0000000..7e90360 --- /dev/null +++ b/src/api/gen/datasource.ts @@ -0,0 +1,56 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/gen/dsconf/page', + method: 'get', + params: query, + }); +} + +export function list(query?: Object) { + return request({ + url: '/gen/dsconf/list', + method: 'get', + params: query, + }); +} + +export function listTable(query?: Object) { + return request({ + url: '/gen/dsconf/table/list', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/dsconf', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/gen/dsconf/' + id, + method: 'get', + }); +} + +export function delObj(ids?: Object) { + return request({ + url: '/gen/dsconf', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/dsconf', + method: 'put', + data: obj, + }); +} diff --git a/src/api/gen/fieldtype.ts b/src/api/gen/fieldtype.ts new file mode 100644 index 0000000..2dc77a7 --- /dev/null +++ b/src/api/gen/fieldtype.ts @@ -0,0 +1,71 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/gen/fieldtype/page', + method: 'get', + params: query, + }); +} + +export function list(query?: Object) { + return request({ + url: '/gen/fieldtype/list', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/fieldtype', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/gen/fieldtype/details/' + id, + method: 'get', + }); +} + +export function getObjDetails(obj?: object) { + return request({ + url: '/gen/fieldtype/details', + method: 'get', + params: obj, + }); +} + +export function delObj(ids?: object) { + return request({ + url: '/gen/fieldtype', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/fieldtype', + method: 'put', + data: obj, + }); +} + +export function validateColumnType(rule: any, value: any, callback: any, isEdit: boolean) { + if (isEdit) { + return callback(); + } + + getObjDetails({ columnType: value }).then((response) => { + const result = response.data; + if (result !== null) { + callback(new Error('类型已经存在')); + } else { + callback(); + } + }); +} diff --git a/src/api/gen/group.ts b/src/api/gen/group.ts new file mode 100644 index 0000000..02cd459 --- /dev/null +++ b/src/api/gen/group.ts @@ -0,0 +1,47 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/gen/group/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/group', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/gen/group/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/gen/group', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/group', + method: 'put', + data: obj, + }); +} + +export function list() { + return request({ + url: '/gen/group/list', + method: 'get', + }); +} diff --git a/src/api/gen/table.ts b/src/api/gen/table.ts new file mode 100644 index 0000000..4b3213b --- /dev/null +++ b/src/api/gen/table.ts @@ -0,0 +1,128 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/gen/table/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/table', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/gen/table/' + id, + method: 'get', + }); +} + +export function delObj(id?: string) { + return request({ + url: '/gen/table/' + id, + method: 'delete', + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/table', + method: 'put', + data: obj, + }); +} + +export const useSyncTableApi = (dsName: string, tableName: string) => { + return request.get('/gen/table/sync/' + dsName + '/' + tableName); +}; + +export const useTableApi = (dsName: string, tableName: string) => { + return request.get('/gen/table/' + dsName + '/' + tableName); +}; + +export const useListTableApi = (dsName: string) => { + return request.get('/gen/table/list/' + dsName); +}; + +export const useListTableColumnApi = (dsName: string, tableName: string) => { + return request.get('/gen/table/column/' + dsName + '/' + tableName); +}; + +export const useTableFieldSubmitApi = (dsName: string, tableName: string, fieldList: any) => { + return request.put('/gen/table/field/' + dsName + '/' + tableName, fieldList); +}; + +export const useGeneratorCodeApi = (tableIds: any) => { + return request({ + url: '/gen/generator/code', + method: 'get', + params: { tableIds: tableIds }, + }); +}; + +export const useGeneratorVFormApi = (dsName: any, tableName: any) => { + return request({ + url: '/gen/generator/vform', + method: 'get', + params: { dsName: dsName, tableName: tableName }, + }); +}; + +export const useGeneratorVFormSfcApi = (id: string) => { + return request({ + url: '/gen/generator/vform/sfc', + method: 'get', + params: { formId: id }, + }); +}; + +export const useGeneratorPreviewApi = (tableId: any) => { + return request({ + url: '/gen/generator/preview', + method: 'get', + params: { tableId: tableId }, + }); +}; + +export function fetchDictList() { + return request({ + url: '/admin/dict/list', + method: 'get', + }); +} + +export function useFormConfSaveApi(obj?: Object) { + return request({ + url: '/gen/form', + method: 'post', + data: obj, + }); +} + +export function fetchFormList(query?: Object) { + return request({ + url: '/gen/form/page', + method: 'get', + params: query, + }); +} + +export function fetchFormById(id?: string) { + return request({ + url: '/gen/form/' + id, + method: 'get', + }); +} + +export function delFormObj(id?: string) { + return request({ + url: '/gen/form/' + id, + method: 'delete', + }); +} diff --git a/src/api/gen/template.ts b/src/api/gen/template.ts new file mode 100644 index 0000000..b124046 --- /dev/null +++ b/src/api/gen/template.ts @@ -0,0 +1,61 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/gen/template/page', + method: 'get', + params: query, + }); +} + +export function list() { + return request({ + url: '/gen/template/list', + method: 'get', + }); +} + +export function online() { + return request({ + url: '/gen/template/online', + method: 'get', + }); +} + +export function checkVersion() { + return request({ + url: '/gen/template/checkVersion', + method: 'get', + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/gen/template', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/gen/template/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/gen/template', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/gen/template', + method: 'put', + data: obj, + }); +} diff --git a/src/api/login/index.ts b/src/api/login/index.ts new file mode 100644 index 0000000..aee98f3 --- /dev/null +++ b/src/api/login/index.ts @@ -0,0 +1,188 @@ +import request from '/@/utils/request'; +import { Session } from '/@/utils/storage'; +import { validateNull } from '/@/utils/validate'; +import { useUserInfo } from '/@/stores/userInfo'; +import other from '/@/utils/other'; + +/** + * https://www.ietf.org/rfc/rfc6749.txt + * OAuth 协议 4.3.1 要求格式为 form 而不是 JSON 注意! + */ +const FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded'; + +// 登录方式 +export enum LoginTypeEnum { + PASSWORD, + MOBILE, + REGISTER, + EXPIRE, +} + +// 登录错误信息 +export enum LoginErrorEnum { + CREDENTIALS_EXPIRED = 'credentials_expired', // 密码过期 +} + +/** + * 社交登录方式枚举 + */ +export enum SocialLoginEnum { + SMS = 'SMS', // 验证码登录 + DINGTALK = 'DINGTALK', // 钉钉 + WEIXIN_CP = 'WEIXIN_CP', // 企业微信 + APP_SMS = 'APP-SMS', // APP验证码登录 + QQ = 'QQ', // QQ登录 + WECHAT = 'WX', // 微信登录 + MINI_APP = 'MINI', // 微信小程序 + GITEE = 'GITEE', // 码云登录 + OSC = 'OSC', // 开源中国登录 + CAS = 'CAS' // CAS 登录 +} + + +/** + * 登录 + * @param data + */ +export const login = (data: any) => { + const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_PASSWORD_CLIENT); + Session.set('basicAuth', basicAuth); + // 密码加密 + const encPassword = other.encryption(data.password, import.meta.env.VITE_PWD_ENC_KEY); + const { username, randomStr, code, grant_type, scope } = data; + return request({ + url: '/auth/oauth2/token', + method: 'post', + params: { username, randomStr, code, grant_type, scope }, + data: { password: encPassword }, + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': FORM_CONTENT_TYPE, + "Enc-Flag": "false", + }, + }); +}; + +export const loginByMobile = (mobile: any, code: any) => { + const grant_type = 'mobile'; + const scope = 'server'; + const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_MOBILE_CLIENT); + Session.set('basicAuth', basicAuth); + + return request({ + url: '/auth/oauth2/token', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': FORM_CONTENT_TYPE, + }, + method: 'post', + params: { mobile: `${SocialLoginEnum.SMS}@${mobile}`, code: code, grant_type, scope }, + }); +}; + +export const loginBySocial = (state: SocialLoginEnum, code: string) => { + const grant_type = 'mobile'; + const scope = 'server'; + const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_SOCIAL_CLIENT); + Session.set('basicAuth', basicAuth); + + return request({ + url: '/auth/oauth2/token', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': FORM_CONTENT_TYPE, + }, + method: 'post', + params: { mobile: `${state}@${code}`, code: code, grant_type, scope }, + }); +}; + +export const sendMobileCode = (mobile: string) => { + return request({ + url: '/admin/sysMessage/send/smsCode', + method: 'get', + params: { mobile }, + }); +}; + +export const refreshTokenApi = (refresh_token: string) => { + const grant_type = 'refresh_token'; + const scope = 'server'; + // 获取当前选中的 basic 认证信息 + const basicAuth = Session.get('basicAuth'); + + return request({ + url: '/auth/oauth2/token', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': FORM_CONTENT_TYPE, + }, + method: 'post', + params: { refresh_token, grant_type, scope }, + }); +}; + +/** + * 校验令牌,若有效期小于半小时自动续期 + * @param refreshLock + */ +export const checkToken = (refreshTime: number, refreshLock: boolean) => { + const basicAuth = Session.get('basicAuth'); + request({ + url: '/auth/token/check_token', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': FORM_CONTENT_TYPE, + }, + method: 'get', + params: { token: Session.getToken() }, + }) + .then((response) => { + if (validateNull(response) || response.code === 1) { + clearInterval(refreshTime); + return; + } + const expire = Date.parse(response.data.expiresAt); + if (expire) { + const expiredPeriod = expire - new Date().getTime(); + //小于半小时自动续约 + if (expiredPeriod <= 30 * 60 * 1000) { + if (!refreshLock) { + refreshLock = true; + useUserInfo() + .refreshToken() + .catch(() => { + clearInterval(refreshTime); + }); + refreshLock = false; + } + } + } + }) + .catch(() => { + // 发生异常关闭定时器 + clearInterval(refreshTime); + }); +}; + +/** + * 获取用户信息 + */ +export const getUserInfo = () => { + return request({ + url: '/admin/user/info', + method: 'get', + }); +}; + +export const logout = () => { + return request({ + url: '/auth/token/logout', + method: 'delete', + }); +}; diff --git a/src/api/mp/wx-account-fans.ts b/src/api/mp/wx-account-fans.ts new file mode 100644 index 0000000..9fff06e --- /dev/null +++ b/src/api/mp/wx-account-fans.ts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018-2025, jhkj All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: jhkj + */ + +import request from '/@/utils/request'; + +export function fetchList(query) { + return request({ + url: '/mp/wx-account-fans/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-account-fans', + method: 'post', + data: obj, + }); +} + +export function sync(appId) { + return request({ + url: '/mp/wx-account-fans/sync/' + appId, + method: 'post', + }); +} + +export function getObj(id) { + return request({ + url: '/mp/wx-account-fans/' + id, + method: 'get', + }); +} + +export function delObjs(id) { + return request({ + url: '/mp/wx-account-fans/' + id, + method: 'delete', + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wx-account-fans', + method: 'put', + data: obj, + }); +} + +export function black(obj, appid) { + return request({ + url: '/mp/wx-account-fans/black/' + appid, + method: 'post', + data: obj, + }); +} + +export function unblack(obj, appid) { + return request({ + url: '/mp/wx-account-fans/unblack/' + appid, + method: 'post', + data: obj, + }); +} diff --git a/src/api/mp/wx-account-tag.ts b/src/api/mp/wx-account-tag.ts new file mode 100644 index 0000000..1e15b89 --- /dev/null +++ b/src/api/mp/wx-account-tag.ts @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-2025, jhkj All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: jhkj + */ + +import request from '/@/utils/request'; + +export function getPage(query) { + return request({ + url: '/mp/wx-account-tag/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-account-tag', + method: 'post', + data: obj, + }); +} + +export function delObjs(obj) { + return request({ + url: '/mp/wx-account-tag', + method: 'delete', + data: obj, + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wx-account-tag', + method: 'put', + data: obj, + }); +} + +export function sync(appId) { + return request({ + url: '/mp/wx-account-tag/sync/' + appId, + method: 'post', + }); +} + +export function list(appId) { + return request({ + url: '/mp/wx-account-tag/list', + method: 'get', + params: { wxAccountAppid: appId }, + }); +} diff --git a/src/api/mp/wx-account.ts b/src/api/mp/wx-account.ts new file mode 100644 index 0000000..9baa01d --- /dev/null +++ b/src/api/mp/wx-account.ts @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-2025, jhkj All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: jhkj + */ + +import request from '/@/utils/request'; + +export function fetchList(query) { + return request({ + url: '/mp/wx-account/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-account', + method: 'post', + data: obj, + }); +} + +export function getObj(id) { + return request({ + url: '/mp/wx-account/' + id, + method: 'get', + }); +} + +export function generateQr(appid) { + return request({ + url: '/mp/wx-account/qr/' + appid, + method: 'post', + }); +} + +export function clearQuota(appid) { + return request({ + url: '/mp/wx-account/clear-quota/' + appid, + method: 'post', + }); +} + +export function delObjs(id) { + return request({ + url: '/mp/wx-account/' + id, + method: 'delete', + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wx-account', + method: 'put', + data: obj, + }); +} + +export function fetchAccountList(obj?: object) { + return request({ + url: '/mp/wx-account/list', + method: 'get', + params: obj, + }); +} + +export function fetchStatistics(q) { + return request({ + url: '/mp/wx-account/statistics', + method: 'get', + params: q, + }); +} diff --git a/src/api/mp/wx-auto-reply.ts b/src/api/mp/wx-auto-reply.ts new file mode 100644 index 0000000..2519c0c --- /dev/null +++ b/src/api/mp/wx-auto-reply.ts @@ -0,0 +1,39 @@ +import request from '/@/utils/request'; + +export function getPage(query) { + return request({ + url: '/mp/wx-auto-reply/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-auto-reply', + method: 'post', + data: obj, + }); +} + +export function getObj(id) { + return request({ + url: '/mp/wx-auto-reply/' + id, + method: 'get', + }); +} + +export function delObj(id) { + return request({ + url: '/mp/wx-auto-reply/' + id, + method: 'delete', + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wx-auto-reply', + method: 'put', + data: obj, + }); +} diff --git a/src/api/mp/wx-fans-msg.ts b/src/api/mp/wx-fans-msg.ts new file mode 100644 index 0000000..b7b9ad4 --- /dev/null +++ b/src/api/mp/wx-fans-msg.ts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018-2025, jhkj All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: jhkj + */ + +import request from '/@/utils/request'; + +export function fetchList(query) { + return request({ + url: '/mp/wx-fans-msg/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-fans-msg', + method: 'post', + data: obj, + }); +} + +export function getObj(id) { + return request({ + url: '/mp/wxfansmsg/' + id, + method: 'get', + }); +} + +export function delObjs(id) { + return request({ + url: '/mp/wxfansmsg/' + id, + method: 'delete', + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wxfansmsg', + method: 'put', + data: obj, + }); +} + +export function fetchResList(query) { + return request({ + url: '/mp/wx-fans-msg/page', + method: 'get', + params: query, + }); +} + +export function addResObj(obj) { + return request({ + url: '/mp/wx-fans-msg', + method: 'post', + data: obj, + }); +} + +export function delResObj(id) { + return request({ + url: '/mp/wx-fans-msg/' + id, + method: 'delete', + }); +} diff --git a/src/api/mp/wx-material.ts b/src/api/mp/wx-material.ts new file mode 100644 index 0000000..31aa02e --- /dev/null +++ b/src/api/mp/wx-material.ts @@ -0,0 +1,74 @@ +import request from '/@/utils/request'; + +export function getPage(query) { + return request({ + url: '/mp/wx-material/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj) { + return request({ + url: '/mp/wx-material/materialNews', + method: 'post', + data: obj, + }); +} + +export function materialNewsUpdate(obj) { + return request({ + url: '/mp/wx-material/materialNews', + method: 'put', + data: obj, + }); +} + +export function getObj(id) { + return request({ + url: '/mp/wx-material/' + id, + method: 'get', + }); +} + +export function delObj(query) { + return request({ + url: '/mp/wx-material', + method: 'delete', + params: query, + }); +} + +export function putObj(obj) { + return request({ + url: '/mp/wx-material', + method: 'put', + data: obj, + }); +} + +export function getMaterialOther(query) { + return request({ + url: '/mp/wx-material/materialOther', + method: 'get', + params: query, + responseType: 'blob', + }); +} + +export function getMaterialVideo(query) { + return request({ + url: '/mp/wx-material/materialVideo', + method: 'get', + params: query, + }); +} + +export function getTempMaterialOther(query) { + return request({ + url: '/mp/wx-material/tempMaterialOther', + method: 'get', + params: query, + responseType: 'blob', + }); +} diff --git a/src/api/mp/wx-menu.ts b/src/api/mp/wx-menu.ts new file mode 100644 index 0000000..406ade7 --- /dev/null +++ b/src/api/mp/wx-menu.ts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-2025, jhkj All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: jhkj + */ + +import request from '/@/utils/request'; + +export function getObj(id) { + return request({ + url: '/mp/wx-menu/' + id, + method: 'get', + }); +} + +export function saveObj(appId, data) { + return request({ + url: '/mp/wx-menu/' + appId, + method: 'post', + data: data, + }); +} + +export function publishObj(id) { + return request({ + url: '/mp/wx-menu/' + id, + method: 'put', + }); +} diff --git a/src/api/pay/cd.ts b/src/api/pay/cd.ts new file mode 100644 index 0000000..bc1645c --- /dev/null +++ b/src/api/pay/cd.ts @@ -0,0 +1,9 @@ +import request from '/@/utils/request'; + +export function useBuyApi(amount?: any) { + return request({ + url: '/pay/goods/merge/buy', + method: 'get', + params: { amount: amount }, + }); +} diff --git a/src/api/pay/channel.ts b/src/api/pay/channel.ts new file mode 100644 index 0000000..036b9a0 --- /dev/null +++ b/src/api/pay/channel.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/pay/channel/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/pay/channel', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/pay/channel/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/pay/channel', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/pay/channel', + method: 'put', + data: obj, + }); +} diff --git a/src/api/pay/goods.ts b/src/api/pay/goods.ts new file mode 100644 index 0000000..ddeada8 --- /dev/null +++ b/src/api/pay/goods.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/pay/goods/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/pay/goods', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/pay/goods/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/pay/goods', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/pay/goods', + method: 'put', + data: obj, + }); +} diff --git a/src/api/pay/record.ts b/src/api/pay/record.ts new file mode 100644 index 0000000..036259a --- /dev/null +++ b/src/api/pay/record.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/pay/notify/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/pay/notify', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/pay/notify/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/pay/notify', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/pay/notify', + method: 'put', + data: obj, + }); +} diff --git a/src/api/pay/refund.ts b/src/api/pay/refund.ts new file mode 100644 index 0000000..fc0f928 --- /dev/null +++ b/src/api/pay/refund.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/pay/refund/page', + method: 'get', + params: query, + }); +} + +export function useRefundApi(obj?: Object) { + return request({ + url: '/pay/refund', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/pay/refund/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/pay/refund', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/pay/refund', + method: 'put', + data: obj, + }); +} diff --git a/src/api/pay/trade.ts b/src/api/pay/trade.ts new file mode 100644 index 0000000..8592b29 --- /dev/null +++ b/src/api/pay/trade.ts @@ -0,0 +1,40 @@ +import request from '/@/utils/request'; + +export function fetchList(query?: Object) { + return request({ + url: '/pay/trade/page', + method: 'get', + params: query, + }); +} + +export function addObj(obj?: Object) { + return request({ + url: '/pay/trade', + method: 'post', + data: obj, + }); +} + +export function getObj(id?: string) { + return request({ + url: '/pay/trade/' + id, + method: 'get', + }); +} + +export function delObjs(ids?: Object) { + return request({ + url: '/pay/trade', + method: 'delete', + data: ids, + }); +} + +export function putObj(obj?: Object) { + return request({ + url: '/pay/trade', + method: 'put', + data: obj, + }); +} diff --git a/src/assets/404.png b/src/assets/404.png new file mode 100644 index 0000000..2e69005 Binary files /dev/null and b/src/assets/404.png differ diff --git a/src/assets/excel.png b/src/assets/excel.png new file mode 100644 index 0000000..2487244 Binary files /dev/null and b/src/assets/excel.png differ diff --git a/src/assets/icon_folder.png b/src/assets/icon_folder.png new file mode 100644 index 0000000..99b800f Binary files /dev/null and b/src/assets/icon_folder.png differ diff --git a/src/assets/icons/cas.svg b/src/assets/icons/cas.svg new file mode 100644 index 0000000..80e9736 --- /dev/null +++ b/src/assets/icons/cas.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/gitee.svg b/src/assets/icons/gitee.svg new file mode 100644 index 0000000..a64ed64 --- /dev/null +++ b/src/assets/icons/gitee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/oschina.svg b/src/assets/icons/oschina.svg new file mode 100644 index 0000000..916f99f --- /dev/null +++ b/src/assets/icons/oschina.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/qq.svg b/src/assets/icons/qq.svg new file mode 100644 index 0000000..c4ea713 --- /dev/null +++ b/src/assets/icons/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/tenant.svg b/src/assets/icons/tenant.svg new file mode 100644 index 0000000..2202650 --- /dev/null +++ b/src/assets/icons/tenant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/wechat.svg b/src/assets/icons/wechat.svg new file mode 100644 index 0000000..704737a --- /dev/null +++ b/src/assets/icons/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/wx-video.svg b/src/assets/icons/wx-video.svg new file mode 100644 index 0000000..7a73a3c --- /dev/null +++ b/src/assets/icons/wx-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/wx-voice.svg b/src/assets/icons/wx-voice.svg new file mode 100644 index 0000000..53dcfd5 --- /dev/null +++ b/src/assets/icons/wx-voice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/lockScreen.png b/src/assets/lockScreen.png new file mode 100644 index 0000000..68ff0d9 Binary files /dev/null and b/src/assets/lockScreen.png differ diff --git a/src/assets/login-bg.svg b/src/assets/login-bg.svg new file mode 100644 index 0000000..a345a54 --- /dev/null +++ b/src/assets/login-bg.svg @@ -0,0 +1,19 @@ + + + Layer 1 + + + + + + Layer 1 + + + + + + + + \ No newline at end of file diff --git a/src/assets/login/bg.png b/src/assets/login/bg.png new file mode 100644 index 0000000..8cdd300 Binary files /dev/null and b/src/assets/login/bg.png differ diff --git a/src/assets/login/login_bg.svg b/src/assets/login/login_bg.svg new file mode 100644 index 0000000..e0b80e8 --- /dev/null +++ b/src/assets/login/login_bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/login/mini_qr.png b/src/assets/login/mini_qr.png new file mode 100644 index 0000000..5c83f09 Binary files /dev/null and b/src/assets/login/mini_qr.png differ diff --git a/src/assets/logo-mini.svg b/src/assets/logo-mini.svg new file mode 100644 index 0000000..7bdeb97 --- /dev/null +++ b/src/assets/logo-mini.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/pdf.png b/src/assets/pdf.png new file mode 100644 index 0000000..aa3d6b8 Binary files /dev/null and b/src/assets/pdf.png differ diff --git a/src/assets/pigx-app.png b/src/assets/pigx-app.png new file mode 100644 index 0000000..2418c4f Binary files /dev/null and b/src/assets/pigx-app.png differ diff --git a/src/assets/ppt.png b/src/assets/ppt.png new file mode 100644 index 0000000..84ec961 Binary files /dev/null and b/src/assets/ppt.png differ diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss new file mode 100644 index 0000000..d43b407 --- /dev/null +++ b/src/assets/styles/variables.module.scss @@ -0,0 +1,65 @@ +// base color +$blue: #324157; +$light-blue: #3a71a8; +$red: #c03639; +$pink: #e65d6e; +$green: #30b08f; +$tiffany: #4ab7bd; +$yellow: #fec171; +$panGreen: #30b08f; + +// 默认菜单主题风格 +$base-menu-color: #bfcbd9; +$base-menu-color-active: #f4f4f5; +$base-menu-background: #304156; +$base-logo-title-color: #ffffff; + +$base-menu-light-color: rgba(0, 0, 0, 0.7); +$base-menu-light-background: #ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background: #1f2d3d; +$base-sub-menu-hover: #001528; + +// 自定义暗色菜单风格 +/** +$base-menu-color:hsla(0,0%,100%,.65); +$base-menu-color-active:#fff; +$base-menu-background:#001529; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#000c17; +$base-sub-menu-hover:#001528; +*/ + +$--color-primary: #409eff; +$--color-success: #67c23a; +$--color-warning: #e6a23c; +$--color-danger: #f56c6c; +$--color-info: #909399; + +$base-sidebar-width: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color; + primaryColor: $--color-primary; + successColor: $--color-success; + dangerColor: $--color-danger; + infoColor: $--color-info; + warningColor: $--color-warning; +} diff --git a/src/assets/txt.png b/src/assets/txt.png new file mode 100644 index 0000000..7501303 Binary files /dev/null and b/src/assets/txt.png differ diff --git a/src/assets/word.png b/src/assets/word.png new file mode 100644 index 0000000..de3871f Binary files /dev/null and b/src/assets/word.png differ diff --git a/src/components/Chat/chat.ts b/src/components/Chat/chat.ts new file mode 100644 index 0000000..cc653b8 --- /dev/null +++ b/src/components/Chat/chat.ts @@ -0,0 +1,9 @@ +import request from "/@/utils/request"; + +export const turbo = (content: string) => { + return request({ + url: '/admin/chat/msg', + method: 'post', + data: {content: content}, + }); +}; diff --git a/src/components/Chat/i18n/en.ts b/src/components/Chat/i18n/en.ts new file mode 100644 index 0000000..aaf10a1 --- /dev/null +++ b/src/components/Chat/i18n/en.ts @@ -0,0 +1,16 @@ +export default { + chat: { + send: 'Send', + inputPlaceholder: 'Type a message...', + title: 'AI Assistant', + clearChat: 'Clear Chat', + webSearchEnabled: 'Web Search Enabled', + webSearchDisabled: 'Web Search Disabled', + welcome: 'Hello! I am a general AI model. How can I help you?', + thinking: 'Thinking...', + thinkingCompleted: 'Thinking Completed', + thinkingTime: 'Time taken', + connectionError: 'Connection lost, please try again', + seconds: 'seconds', + }, +}; diff --git a/src/components/Chat/i18n/zh-cn.ts b/src/components/Chat/i18n/zh-cn.ts new file mode 100644 index 0000000..a2522e0 --- /dev/null +++ b/src/components/Chat/i18n/zh-cn.ts @@ -0,0 +1,16 @@ +export default { + chat: { + send: '发送', + inputPlaceholder: '请输入消息...', + title: 'AI 助手', + clearChat: '清空会话', + webSearchEnabled: '已开启联网搜索', + webSearchDisabled: '已关闭联网搜索', + welcome: '您好!我是通用大模型,请问有什么可以帮助您?', + thinking: '正在思考...', + thinkingCompleted: '已完成思考', + thinkingTime: '用时', + connectionError: '连接已断开,请重试', + seconds: '秒', + }, +}; diff --git a/src/components/Chat/index.vue b/src/components/Chat/index.vue new file mode 100644 index 0000000..78ff5f7 --- /dev/null +++ b/src/components/Chat/index.vue @@ -0,0 +1,464 @@ + + + + + diff --git a/src/components/CheckToken/index.vue b/src/components/CheckToken/index.vue new file mode 100644 index 0000000..2bc3da7 --- /dev/null +++ b/src/components/CheckToken/index.vue @@ -0,0 +1,19 @@ + + diff --git a/src/components/ChinaArea/index.vue b/src/components/ChinaArea/index.vue new file mode 100644 index 0000000..c34a972 --- /dev/null +++ b/src/components/ChinaArea/index.vue @@ -0,0 +1,85 @@ + + + diff --git a/src/components/CodeEditor/index.vue b/src/components/CodeEditor/index.vue new file mode 100644 index 0000000..3f3b733 --- /dev/null +++ b/src/components/CodeEditor/index.vue @@ -0,0 +1,121 @@ + + + + + + + diff --git a/src/components/ColorPicker/index.vue b/src/components/ColorPicker/index.vue new file mode 100644 index 0000000..8c32082 --- /dev/null +++ b/src/components/ColorPicker/index.vue @@ -0,0 +1,33 @@ + + diff --git a/src/components/Crontab/index.vue b/src/components/Crontab/index.vue new file mode 100644 index 0000000..32a0ada --- /dev/null +++ b/src/components/Crontab/index.vue @@ -0,0 +1,806 @@ + + + + + + + diff --git a/src/components/DelWrap/index.vue b/src/components/DelWrap/index.vue new file mode 100644 index 0000000..f93a284 --- /dev/null +++ b/src/components/DelWrap/index.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/components/DictTag/Select.vue b/src/components/DictTag/Select.vue new file mode 100644 index 0000000..b47aa9a --- /dev/null +++ b/src/components/DictTag/Select.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue new file mode 100644 index 0000000..229b682 --- /dev/null +++ b/src/components/DictTag/index.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue new file mode 100644 index 0000000..5ab7b8a --- /dev/null +++ b/src/components/Editor/index.vue @@ -0,0 +1,141 @@ + + + diff --git a/src/components/FormTable/index.vue b/src/components/FormTable/index.vue new file mode 100644 index 0000000..0a6d0fb --- /dev/null +++ b/src/components/FormTable/index.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/src/components/IconSelector/index.ts b/src/components/IconSelector/index.ts new file mode 100644 index 0000000..55817c1 --- /dev/null +++ b/src/components/IconSelector/index.ts @@ -0,0 +1,71 @@ +import { readFileSync, readdirSync } from 'fs'; + +let idPerfix = ''; +const iconNames: string[] = []; +const svgTitle = /+].*?)>/; +const clearHeightWidth = /(width|height)="([^>+].*?)"/g; +const hasViewBox = /(viewBox="[^>+].*?")/g; +const clearReturn = /(\r)|(\n)/g; +// 清理 svg 的 fill +const clearFill = /(fill="[^>+].*?")/g; + +function findSvgFile(dir: string): string[] { + const svgRes = [] as any; + const dirents = readdirSync(dir, { + withFileTypes: true, + }); + for (const dirent of dirents) { + iconNames.push(`${idPerfix}-${dirent.name.replace('.svg', '')}`); + if (dirent.isDirectory()) { + svgRes.push(...findSvgFile(dir + dirent.name + '/')); + } else { + const svg = readFileSync(dir + dirent.name) + .toString() + .replace(clearReturn, '') + .replace(clearFill, 'fill=""') + .replace(svgTitle, ($1, $2) => { + let width = 0; + let height = 0; + let content = $2.replace(clearHeightWidth, (s1: string, s2: string, s3: number) => { + if (s2 === 'width') { + width = s3; + } else if (s2 === 'height') { + height = s3; + } + return ''; + }); + if (!hasViewBox.test($2)) { + content += `viewBox="0 0 ${width} ${height}"`; + } + return ``; + }) + .replace('', ''); + svgRes.push(svg); + } + } + return svgRes; +} + +export const svgBuilder = (path: string, perfix = 'local') => { + if (path === '') return; + idPerfix = perfix; + const res = findSvgFile(path); + return { + name: 'svg-transform', + transformIndexHtml(html: string) { + /* eslint-disable */ + return html.replace( + '', + ` + + + ${res.join('')} + + ` + ); + /* eslint-enable */ + }, + }; +}; diff --git a/src/components/IconSelector/index.vue b/src/components/IconSelector/index.vue new file mode 100644 index 0000000..653d260 --- /dev/null +++ b/src/components/IconSelector/index.vue @@ -0,0 +1,254 @@ + + + diff --git a/src/components/IconSelector/list.vue b/src/components/IconSelector/list.vue new file mode 100644 index 0000000..8bf837b --- /dev/null +++ b/src/components/IconSelector/list.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/components/Link/custom-link.vue b/src/components/Link/custom-link.vue new file mode 100644 index 0000000..3665609 --- /dev/null +++ b/src/components/Link/custom-link.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/Link/index.ts b/src/components/Link/index.ts new file mode 100644 index 0000000..fd20602 --- /dev/null +++ b/src/components/Link/index.ts @@ -0,0 +1,11 @@ +export enum LinkTypeEnum { + 'SHOP_PAGES' = 'shop', + 'CUSTOM_LINK' = 'custom', +} + +export interface Link { + path: string; + name?: string; + type: string; + query?: Record; +} diff --git a/src/components/Link/index.vue b/src/components/Link/index.vue new file mode 100644 index 0000000..eaec2b6 --- /dev/null +++ b/src/components/Link/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/Link/picker.vue b/src/components/Link/picker.vue new file mode 100644 index 0000000..59a5fae --- /dev/null +++ b/src/components/Link/picker.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/Link/shop-pages.vue b/src/components/Link/shop-pages.vue new file mode 100644 index 0000000..1d82fb4 --- /dev/null +++ b/src/components/Link/shop-pages.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/components/Material/file.vue b/src/components/Material/file.vue new file mode 100644 index 0000000..334194a --- /dev/null +++ b/src/components/Material/file.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/Material/hook.ts b/src/components/Material/hook.ts new file mode 100644 index 0000000..a98f536 --- /dev/null +++ b/src/components/Material/hook.ts @@ -0,0 +1,200 @@ +import { fileGroupAdd, fileGroupDelete, fileGroupUpdate, fileCateLists, fileDelete, fileList, fileMove, fileRename } from '/@/api/admin/file'; +import { usePaging } from './usePaging'; +import { ElMessage, ElTree, type CheckboxValueType } from 'element-plus'; +import { shallowRef, type Ref } from 'vue'; +import { useMessageBox } from '/@/hooks/message'; + +// 左侧分组的钩子函数 +export function useCate(type: number) { + const treeRef = shallowRef>(); + // 分组列表 + const cateLists = ref([]); + + // 选中的分组id + const cateId = ref(''); + + // 获取分组列表 + const getCateLists = async () => { + const { data } = await fileCateLists({ + type, + }); + const item: any[] = [ + { + name: '全部', + id: '', + }, + { + name: '未分组', + id: -1, + }, + ]; + cateLists.value = data; + cateLists.value?.unshift(...item); + setTimeout(() => { + treeRef.value?.setCurrentKey(cateId.value); + }, 0); + }; + + // 添加分组 + const handleAddCate = async (value: string) => { + await fileGroupAdd({ + type, + name: value, + pid: -1, + }); + getCateLists(); + }; + + // 编辑分组 + const handleEditCate = async (value: string, id: number) => { + await fileGroupUpdate({ + id, + name: value, + }); + getCateLists(); + }; + + // 删除分组 + const handleDeleteCate = async (id: number) => { + try { + await useMessageBox().confirm('确定要删除?'); + } catch (error) { + return; + } + await fileGroupDelete({ id }); + cateId.value = ''; + getCateLists(); + }; + + //选中分类 + const handleCatSelect = (item: any) => { + cateId.value = item.id; + }; + + return { + treeRef, + cateId, + cateLists, + handleAddCate, + handleEditCate, + handleDeleteCate, + getCateLists, + handleCatSelect, + }; +} + +// 处理文件的钩子函数 +export function useFile(cateId: Ref, type: Ref, limit: Ref, size: number) { + const tableRef = shallowRef(); + const listShowType = ref('normal'); + const moveId = ref(-1); + const select = ref([]); + const isCheckAll = ref(false); + const isIndeterminate = ref(false); + const fileParams = reactive({ + original: '', + type: type, + groupId: cateId, + }); + const { pager, getLists, resetPage } = usePaging({ + fetchFun: fileList, + params: fileParams, + firstLoading: true, + size, + }); + + const getFileList = () => { + getLists(); + }; + const refresh = () => { + resetPage(); + }; + + const isSelect = (id: number) => { + return !!select.value.find((item: any) => item.id == id); + }; + + const batchFileDelete = async (id?: number[]) => { + try { + await useMessageBox().confirm('确认删除后本地将同步删除,如文件已被使用,请谨慎操作!'); + } catch { + return; + } + const ids = id ? id : select.value.map((item: any) => item.id); + await fileDelete({ ids }); + getFileList(); + clearSelect(); + }; + + const batchFileMove = async () => { + const ids = select.value.map((item: any) => item.id); + await fileMove({ ids, groupId: moveId.value }); + moveId.value = -1; + getFileList(); + clearSelect(); + }; + + const selectFile = (item: any) => { + const index = select.value.findIndex((items: any) => items.id == item.id); + if (index != -1) { + select.value.splice(index, 1); + return; + } + if (select.value.length == limit.value) { + if (limit.value == 1) { + select.value = []; + select.value.push(item); + return; + } + ElMessage.warning('已达到选择上限'); + return; + } + select.value.push(item); + }; + + const clearSelect = () => { + select.value = []; + }; + + const cancelSelete = (id: number) => { + select.value = select.value.filter((item: any) => item.id != id); + }; + + const selectAll = (value: CheckboxValueType) => { + isIndeterminate.value = false; + tableRef.value?.toggleAllSelection(); + if (value) { + select.value = [...pager.lists]; + return; + } + clearSelect(); + }; + + const handleFileRename = async (value: string, id: number) => { + await fileRename({ + id, + original: value, + }); + getFileList(); + }; + return { + listShowType, + tableRef, + moveId, + pager, + fileParams, + select, + isCheckAll, + isIndeterminate, + getFileList, + refresh, + batchFileDelete, + batchFileMove, + selectFile, + isSelect, + clearSelect, + cancelSelete, + selectAll, + handleFileRename, + }; +} diff --git a/src/components/Material/i18n/en.ts b/src/components/Material/i18n/en.ts new file mode 100644 index 0000000..383f004 --- /dev/null +++ b/src/components/Material/i18n/en.ts @@ -0,0 +1,18 @@ +export default { + material: { + uploadFileTip: 'upload', + addGroup: 'add group', + editGroup: 'edit group', + delGroup: 'del group', + moveBtn: 'move', + preview: 'preview', + edit: 'edit', + view: 'view', + add: 'add', + allCheck: 'all check', + rename: 'rename', + download: 'download', + list: 'list', + grid: 'grid', + }, +}; diff --git a/src/components/Material/i18n/zh-cn.ts b/src/components/Material/i18n/zh-cn.ts new file mode 100644 index 0000000..710b582 --- /dev/null +++ b/src/components/Material/i18n/zh-cn.ts @@ -0,0 +1,18 @@ +export default { + material: { + uploadFileTip: '上传', + addGroup: '新增分组', + editGroup: '修改分组', + delGroup: '删除分组', + moveBtn: '移动', + preview: '预览', + edit: '修改', + view: '查看', + add: '添加', + allCheck: '全选', + rename: '重命名', + download: '下载', + list: '列表', + grid: '平铺', + }, +}; diff --git a/src/components/Material/index.vue b/src/components/Material/index.vue new file mode 100644 index 0000000..a8d7b1e --- /dev/null +++ b/src/components/Material/index.vue @@ -0,0 +1,518 @@ + + + + + diff --git a/src/components/Material/picker.vue b/src/components/Material/picker.vue new file mode 100644 index 0000000..dfe83a1 --- /dev/null +++ b/src/components/Material/picker.vue @@ -0,0 +1,283 @@ + + + + + diff --git a/src/components/Material/preview.vue b/src/components/Material/preview.vue new file mode 100644 index 0000000..470687c --- /dev/null +++ b/src/components/Material/preview.vue @@ -0,0 +1,93 @@ + + + diff --git a/src/components/Material/usePaging.ts b/src/components/Material/usePaging.ts new file mode 100644 index 0000000..8195ce0 --- /dev/null +++ b/src/components/Material/usePaging.ts @@ -0,0 +1,76 @@ +import { isFunction } from 'lodash'; +import { reactive, toRaw } from 'vue'; + +// 分页钩子函数 +interface Options { + page?: number; + size?: number; + fetchFun: (_arg: any) => Promise; + params?: Record; + firstLoading?: boolean; + beforeRequest?(params: Record): Record; + afterRequest?(res: Record): void; +} + +export function usePaging(options: Options) { + const { page = 1, size = 15, fetchFun, params = {}, firstLoading = false, beforeRequest, afterRequest } = options; + // 记录分页初始参数 + const paramsInit: Record = Object.assign({}, toRaw(params)); + // 分页数据 + const pager = reactive({ + current: page, + size, + loading: firstLoading, + count: 0, + total: 0, + lists: [] as any[], + extend: {} as Record, + }); + // 请求分页接口 + const getLists = () => { + pager.loading = true; + let requestParams = params; + if (isFunction(beforeRequest)) { + requestParams = beforeRequest(params); + } + return fetchFun({ + current: pager.current, + size: pager.size, + ...requestParams, + }) + .then(({ data }) => { + pager.count = data?.total; + pager.total = data?.total; + pager.lists = data?.records; + pager.extend = data?.extend; + if (isFunction(afterRequest)) { + afterRequest(data); + } + return Promise.resolve(data); + }) + .catch((err: any) => { + return Promise.reject(err); + }) + .finally(() => { + pager.loading = false; + }); + }; + // 重置为第一页 + const resetPage = () => { + pager.current = 1; + getLists(); + }; + // 重置参数 + const resetParams = () => { + Object.keys(paramsInit).forEach((item) => { + params[item] = paramsInit[item]; + }); + getLists(); + }; + return { + pager, + getLists, + resetParams, + resetPage, + }; +} diff --git a/src/components/NameAvatar/base.scss b/src/components/NameAvatar/base.scss new file mode 100644 index 0000000..f8f4708 --- /dev/null +++ b/src/components/NameAvatar/base.scss @@ -0,0 +1,129 @@ +$d-type: ( + flex: flex, + block: block, + none: none, +); + +$flex-jc: ( + start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, +); + +$flex-ai: ( + start: flex-start, + end: flex-end, + center: center, + stretch: stretch, +); + +//spacing +$spacing-types: ( + m: margin, + p: padding, +); + +$spacing-directions: ( + t: top, + r: right, + b: bottom, + l: left, +); + +$spacing-base-size: 5px; + +$spacing-sizes: ( + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, +); + +@each $key, $value in $d-type { + .d-#{$key} { + display: $value; + } +} + +.flex-column { + flex-direction: column; +} + +.text-ellipsis { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.flex-grow-1 { + flex: 1; +} + +@each $dir in(top, bottom, right, left) { + .border-#{$dir} { + border-#{$dir}: 1px solid; + } +} + +@each $key, $value in $flex-jc { + .jc-#{$key} { + justify-content: $value; + } +} + +@each $key, $value in $flex-ai { + .ai-#{$key} { + align-items: $value; + } +} +//text +@each $var in (left, center, right) { + .text-#{$var} { + text-align: $var !important; + } +} + +@each $typeKey, $type in $spacing-types { + @each $sizeKey, $size in $spacing-sizes { + .#{$typeKey}-#{$sizeKey} { + #{$type}: $size * $spacing-base-size; + } + } + + @each $sizeKey, $size in $spacing-sizes { + .#{$typeKey}x-#{$sizeKey} { + #{$type}-left: $size * $spacing-base-size; + #{$type}-right: $size * $spacing-base-size; + } + + .#{$typeKey}y-#{$sizeKey} { + #{$type}-top: $size * $spacing-base-size; + #{$type}-bottom: $size * $spacing-base-size; + } + } + + @each $directionKey, $direction in $spacing-directions { + @each $sizeKey, $size in $spacing-sizes { + .#{$typeKey}#{$directionKey}-#{$sizeKey} { + #{$type}-#{$direction}: $size * $spacing-base-size; + } + } + } +} diff --git a/src/components/NameAvatar/index.vue b/src/components/NameAvatar/index.vue new file mode 100644 index 0000000..227d425 --- /dev/null +++ b/src/components/NameAvatar/index.vue @@ -0,0 +1,105 @@ + + + + diff --git a/src/components/NoticeBar/index.vue b/src/components/NoticeBar/index.vue new file mode 100644 index 0000000..8198bce --- /dev/null +++ b/src/components/NoticeBar/index.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/src/components/OrgSelector/assets/check_box.png b/src/components/OrgSelector/assets/check_box.png new file mode 100644 index 0000000..fb89fe2 Binary files /dev/null and b/src/components/OrgSelector/assets/check_box.png differ diff --git a/src/components/OrgSelector/assets/jiaojiao.png b/src/components/OrgSelector/assets/jiaojiao.png new file mode 100644 index 0000000..4e3c7fe Binary files /dev/null and b/src/components/OrgSelector/assets/jiaojiao.png differ diff --git a/src/components/OrgSelector/common.ts b/src/components/OrgSelector/common.ts new file mode 100644 index 0000000..a09245a --- /dev/null +++ b/src/components/OrgSelector/common.ts @@ -0,0 +1,42 @@ +/* + * @Date: 2022-08-29 14:00:42 + * @LastEditors: StavinLi 495727881@qq.com + * @LastEditTime: 2023-03-29 15:53:05 + * @FilePath: /Workflow-Vue3/src/components/dialog/common.js + */ + +import {deptRoleList} from '/@/api/admin/role'; +import {orgTree, orgTreeSearcheUser} from '/@/api/admin/dept'; + +export const searchVal = ref(''); +export const departments = ref({ + titleDepartments: [], childDepartments: [], roleList: [], employees: [], +}); +export const roles = ref({}); +export const getRoleList = async () => { + let { + data: {list}, + } = await deptRoleList(); + roles.value = list; +}; +export const getDepartmentList = async (parentId = 0, type = 'org') => { + // let { data } = await getDepartments({ parentId }) + + let {data} = await orgTree(type, parentId); + + departments.value = data; +}; +export const getDebounceData = async (event: any, type = 1) => { + if (event) { + let data = { + username: event, pageNum: 1, pageSize: 30, + }; + if (type === 1) { + departments.value.childDepartments = []; + let res = await orgTreeSearcheUser(data); + departments.value.employees = res.data; + } + } else { + type === 1 ? await getDepartmentList() : await getRoleList(); + } +}; diff --git a/src/components/OrgSelector/dialog.css b/src/components/OrgSelector/dialog.css new file mode 100644 index 0000000..6a00854 --- /dev/null +++ b/src/components/OrgSelector/dialog.css @@ -0,0 +1,30 @@ +.person_body { + border: 1px solid #f5f5f5; + height: 500px; + display: flex; +} +.tree_nav span { + display: inline-block; + padding-right: 10px; + margin-right: 5px; + max-width: 6em; + color: #38adff; + font-size: 12px; + cursor: pointer; + background: url(./assets/jiaojiao.png) no-repeat right center; +} + +.tree_nav span:last-of-type { + background: none; +} + +.person_tree { + padding: 10px 12px 0 8px; + width: 280px; + height: 100%; + border-right: 1px solid #f5f5f5; +} + +.l { + float: left; +} diff --git a/src/components/OrgSelector/employeesDialog.vue b/src/components/OrgSelector/employeesDialog.vue new file mode 100644 index 0000000..5c18bbd --- /dev/null +++ b/src/components/OrgSelector/employeesDialog.vue @@ -0,0 +1,179 @@ + + + + diff --git a/src/components/OrgSelector/i18n/en.ts b/src/components/OrgSelector/i18n/en.ts new file mode 100644 index 0000000..1620489 --- /dev/null +++ b/src/components/OrgSelector/i18n/en.ts @@ -0,0 +1,10 @@ +export default { + orgSelecotr: { + org: 'org', + user: 'user', + dept: 'dept', + role: 'role', + select: 'select', + search: 'search' + }, +}; diff --git a/src/components/OrgSelector/i18n/zh-cn.ts b/src/components/OrgSelector/i18n/zh-cn.ts new file mode 100644 index 0000000..b6d9e92 --- /dev/null +++ b/src/components/OrgSelector/i18n/zh-cn.ts @@ -0,0 +1,10 @@ +export default { + orgSelecotr: { + org: '组织', + user: '用户', + dept: '部门', + role: '角色', + select: '选择', + search: '搜索' + }, +}; diff --git a/src/components/OrgSelector/index.vue b/src/components/OrgSelector/index.vue new file mode 100644 index 0000000..efcf56e --- /dev/null +++ b/src/components/OrgSelector/index.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/components/OrgSelector/orgItem.vue b/src/components/OrgSelector/orgItem.vue new file mode 100644 index 0000000..2d04e20 --- /dev/null +++ b/src/components/OrgSelector/orgItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/src/components/OrgSelector/roleDialog.vue b/src/components/OrgSelector/roleDialog.vue new file mode 100644 index 0000000..d351dee --- /dev/null +++ b/src/components/OrgSelector/roleDialog.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/components/OrgSelector/selectBox.vue b/src/components/OrgSelector/selectBox.vue new file mode 100644 index 0000000..24a3bfb --- /dev/null +++ b/src/components/OrgSelector/selectBox.vue @@ -0,0 +1,291 @@ + + + diff --git a/src/components/OrgSelector/selectResult.vue b/src/components/OrgSelector/selectResult.vue new file mode 100644 index 0000000..e5078be --- /dev/null +++ b/src/components/OrgSelector/selectResult.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/src/components/OrgSelector/types.ts b/src/components/OrgSelector/types.ts new file mode 100644 index 0000000..47ea409 --- /dev/null +++ b/src/components/OrgSelector/types.ts @@ -0,0 +1,5 @@ +export interface OrgItem { + id: string | number; + name: string; + [key: string]: any; +} diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..0c78b20 --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,52 @@ + + + diff --git a/src/components/PopoverInput/index.vue b/src/components/PopoverInput/index.vue new file mode 100644 index 0000000..6bc497e --- /dev/null +++ b/src/components/PopoverInput/index.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/src/components/Popup/index.vue b/src/components/Popup/index.vue new file mode 100644 index 0000000..18c5c7b --- /dev/null +++ b/src/components/Popup/index.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/QueryTree/i18n/en.ts b/src/components/QueryTree/i18n/en.ts new file mode 100644 index 0000000..73b1180 --- /dev/null +++ b/src/components/QueryTree/i18n/en.ts @@ -0,0 +1,9 @@ +export default { + queryTree: { + hideSearch: 'hideSearch', + displayTheSearch: 'displayTheSearch', + refresh: 'refresh', + print: 'print', + view: 'view' + }, +}; diff --git a/src/components/QueryTree/i18n/zh-cn.ts b/src/components/QueryTree/i18n/zh-cn.ts new file mode 100644 index 0000000..9cc82ec --- /dev/null +++ b/src/components/QueryTree/i18n/zh-cn.ts @@ -0,0 +1,9 @@ +export default { + queryTree: { + hideSearch: '隐藏搜索', + displayTheSearch: '显示搜索', + refresh: '刷新', + print: '打印', + view: '视图' + }, +}; diff --git a/src/components/QueryTree/index.vue b/src/components/QueryTree/index.vue new file mode 100644 index 0000000..c51194c --- /dev/null +++ b/src/components/QueryTree/index.vue @@ -0,0 +1,188 @@ + + + + diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..808658a --- /dev/null +++ b/src/components/RightToolbar/index.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/src/components/SSE/index.vue b/src/components/SSE/index.vue new file mode 100644 index 0000000..3b546c2 --- /dev/null +++ b/src/components/SSE/index.vue @@ -0,0 +1,111 @@ + + diff --git a/src/components/ShortcutCard/index.vue b/src/components/ShortcutCard/index.vue new file mode 100644 index 0000000..aad9ef2 --- /dev/null +++ b/src/components/ShortcutCard/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/src/components/Sign/index.vue b/src/components/Sign/index.vue new file mode 100644 index 0000000..09740b4 --- /dev/null +++ b/src/components/Sign/index.vue @@ -0,0 +1,295 @@ + + + diff --git a/src/components/Sign/types.ts b/src/components/Sign/types.ts new file mode 100644 index 0000000..7c937cd --- /dev/null +++ b/src/components/Sign/types.ts @@ -0,0 +1,21 @@ +export interface SignProps { + width?: number; + height?: number; + lineWidth?: number; + lineColor?: string; + bgColor?: string; + isCrop?: boolean; + isClearBgColor?: boolean; + modelValue?: string; + disabled?: boolean; +} + +export interface Point { + x: number; + y: number; +} + +export interface SignInstance { + reset: () => void; + generate: () => Promise; +} diff --git a/src/components/StrengthMeter/index.vue b/src/components/StrengthMeter/index.vue new file mode 100644 index 0000000..c548004 --- /dev/null +++ b/src/components/StrengthMeter/index.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..9b3956f --- /dev/null +++ b/src/components/SvgIcon/index.vue @@ -0,0 +1,68 @@ + + + diff --git a/src/components/TagList/index.vue b/src/components/TagList/index.vue new file mode 100644 index 0000000..bc5067d --- /dev/null +++ b/src/components/TagList/index.vue @@ -0,0 +1,82 @@ + + + diff --git a/src/components/Tip/index.vue b/src/components/Tip/index.vue new file mode 100644 index 0000000..423c9c2 --- /dev/null +++ b/src/components/Tip/index.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/TreeSelect/index.vue b/src/components/TreeSelect/index.vue new file mode 100644 index 0000000..f48c1e5 --- /dev/null +++ b/src/components/TreeSelect/index.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/components/Upload/Excel.vue b/src/components/Upload/Excel.vue new file mode 100644 index 0000000..6800047 --- /dev/null +++ b/src/components/Upload/Excel.vue @@ -0,0 +1,165 @@ + + + + + + diff --git a/src/components/Upload/Image.vue b/src/components/Upload/Image.vue new file mode 100644 index 0000000..55ce226 --- /dev/null +++ b/src/components/Upload/Image.vue @@ -0,0 +1,320 @@ + + + + diff --git a/src/components/Upload/i18n/en.ts b/src/components/Upload/i18n/en.ts new file mode 100644 index 0000000..eca6dd5 --- /dev/null +++ b/src/components/Upload/i18n/en.ts @@ -0,0 +1,19 @@ +export default { + excel: { + downloadTemplate: 'downloading the template', + fileFormat: 'only xls, xlsx format files are allowed', + operationNotice: 'Drag the file here and', + clickUpload: 'click upload', + lineNumbers: 'line numbers', + misDescription: 'misDescription', + validationFailureData: 'validation failure data', + pleaseUpload: 'please upload', + size: 'size not exceeding', + format: 'format', + file: 'file', + sizeErrorText: 'file size error, max ', + typeErrorText: 'file type error, upload ', + uploadLimit: 'Upload limit exceeded. Maximum', + files: 'files allowed', + }, +}; diff --git a/src/components/Upload/i18n/zh-cn.ts b/src/components/Upload/i18n/zh-cn.ts new file mode 100644 index 0000000..3cdf75e --- /dev/null +++ b/src/components/Upload/i18n/zh-cn.ts @@ -0,0 +1,19 @@ +export default { + excel: { + downloadTemplate: '下载模板', + fileFormat: '仅允许导入xls、xlsx格式文件。', + operationNotice: '将文件拖到此处,或', + clickUpload: '点击上传', + lineNumbers: '行号', + misDescription: '错误描述', + validationFailureData: '校验失败数据', + pleaseUpload: '请上传', + size: '大小不超过', + format: '格式为', + file: '的文件', + sizeErrorText: '文件大小不超过', + typeErrorText: '文件类型错误,请上传 ', + uploadLimit: '上传文件数量超出限制,最多允许上传', + files: '个文件', + }, +}; diff --git a/src/components/Upload/index.vue b/src/components/Upload/index.vue new file mode 100644 index 0000000..acc5ba7 --- /dev/null +++ b/src/components/Upload/index.vue @@ -0,0 +1,327 @@ + + + + diff --git a/src/components/Verifition/Verify.vue b/src/components/Verifition/Verify.vue new file mode 100644 index 0000000..4e72244 --- /dev/null +++ b/src/components/Verifition/Verify.vue @@ -0,0 +1,524 @@ + + + diff --git a/src/components/Verifition/Verify/VerifyPoints.vue b/src/components/Verifition/Verify/VerifyPoints.vue new file mode 100644 index 0000000..bbd1abe --- /dev/null +++ b/src/components/Verifition/Verify/VerifyPoints.vue @@ -0,0 +1,274 @@ + + diff --git a/src/components/Verifition/Verify/VerifySlide.vue b/src/components/Verifition/Verify/VerifySlide.vue new file mode 100644 index 0000000..bdbeeed --- /dev/null +++ b/src/components/Verifition/Verify/VerifySlide.vue @@ -0,0 +1,516 @@ + + + + diff --git a/src/components/Verifition/api/index.ts b/src/components/Verifition/api/index.ts new file mode 100644 index 0000000..6800408 --- /dev/null +++ b/src/components/Verifition/api/index.ts @@ -0,0 +1,23 @@ +/** + * 此处可直接引用自己项目封装好的 axios 配合后端联调 + */ + +import request from '/@/utils/request'; + +//获取验证图片 以及token +export function reqGet(data: Object) { + return request({ + url: '/auth/code/create', + method: 'get', + data, + }); +} + +//滑动或者点选验证 +export function reqCheck(data: Object) { + return request({ + url: '/auth/code/check', + method: 'post', + params: data, + }); +} diff --git a/src/components/Verifition/i18n/en.ts b/src/components/Verifition/i18n/en.ts new file mode 100644 index 0000000..7c10712 --- /dev/null +++ b/src/components/Verifition/i18n/en.ts @@ -0,0 +1,11 @@ +export default { + verify: { + complete: 'Please complete security verification', + slide: { + explain: 'Slide right to verify', + success: 'Verification successful', + fail: 'Verification failed', + time: 'Verified in {time}s' + } + } +}; diff --git a/src/components/Verifition/i18n/zh-cn.ts b/src/components/Verifition/i18n/zh-cn.ts new file mode 100644 index 0000000..274d7d6 --- /dev/null +++ b/src/components/Verifition/i18n/zh-cn.ts @@ -0,0 +1,11 @@ +export default { + verify: { + complete: '请完成安全验证', + slide: { + explain: '向右滑动完成验证', + success: '验证成功', + fail: '验证失败', + time: '{time}s验证成功' + } + } +} diff --git a/src/components/Verifition/utils/ase.js b/src/components/Verifition/utils/ase.js new file mode 100644 index 0000000..c704da7 --- /dev/null +++ b/src/components/Verifition/utils/ase.js @@ -0,0 +1,11 @@ +import CryptoJS from 'crypto-js'; +/** + * @word 要加密的内容 + * @keyWord String 服务器随机返回的关键字 + * */ +export function aesEncrypt(word, keyWord = 'XwKsGlMcdPMEhR1B') { + var key = CryptoJS.enc.Utf8.parse(keyWord); + var srcs = CryptoJS.enc.Utf8.parse(word); + var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); + return encrypted.toString(); +} diff --git a/src/components/Verifition/utils/util.js b/src/components/Verifition/utils/util.js new file mode 100644 index 0000000..4ba9fcf --- /dev/null +++ b/src/components/Verifition/utils/util.js @@ -0,0 +1,97 @@ +export function resetSize(vm) { + var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度 + + var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth; + var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight; + if (vm.imgSize.width.indexOf('%') != -1) { + img_width = (parseInt(vm.imgSize.width) / 100) * parentWidth + 'px'; + } else { + img_width = vm.imgSize.width; + } + + if (vm.imgSize.height.indexOf('%') != -1) { + img_height = (parseInt(vm.imgSize.height) / 100) * parentHeight + 'px'; + } else { + img_height = vm.imgSize.height; + } + + if (vm.barSize.width.indexOf('%') != -1) { + bar_width = (parseInt(vm.barSize.width) / 100) * parentWidth + 'px'; + } else { + bar_width = vm.barSize.width; + } + + if (vm.barSize.height.indexOf('%') != -1) { + bar_height = (parseInt(vm.barSize.height) / 100) * parentHeight + 'px'; + } else { + bar_height = vm.barSize.height; + } + + return { imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height }; +} + +export const _code_chars = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', +]; +export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']; +export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']; diff --git a/src/components/VideoPlayer/index.vue b/src/components/VideoPlayer/index.vue new file mode 100644 index 0000000..8a49f31 --- /dev/null +++ b/src/components/VideoPlayer/index.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/components/Websocket/index.vue b/src/components/Websocket/index.vue new file mode 100644 index 0000000..55475a4 --- /dev/null +++ b/src/components/Websocket/index.vue @@ -0,0 +1,160 @@ + + diff --git a/src/components/Wechat/fileUpload/index.vue b/src/components/Wechat/fileUpload/index.vue new file mode 100644 index 0000000..f7af19f --- /dev/null +++ b/src/components/Wechat/fileUpload/index.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/src/components/Wechat/wx-material-select/main.vue b/src/components/Wechat/wx-material-select/main.vue new file mode 100644 index 0000000..7fd962e --- /dev/null +++ b/src/components/Wechat/wx-material-select/main.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/src/components/Wechat/wx-msg/card.scss b/src/components/Wechat/wx-msg/card.scss new file mode 100644 index 0000000..4563d4f --- /dev/null +++ b/src/components/Wechat/wx-msg/card.scss @@ -0,0 +1,101 @@ +.avue-card { + &__item { + margin-bottom: 16px; + border: 1px solid #e8e8e8; + background-color: #fff; + box-sizing: border-box; + color: rgba(0, 0, 0, 0.65); + font-size: 14px; + font-variant: tabular-nums; + line-height: 1.5; + list-style: none; + font-feature-settings: 'tnum'; + cursor: pointer; + height: 200px; + &:hover { + border-color: rgba(0, 0, 0, 0.09); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); + } + &--add { + border: 1px dashed #000; + width: 100%; + color: rgba(0, 0, 0, 0.45); + background-color: #fff; + border-color: #d9d9d9; + border-radius: 2px; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + i { + margin-right: 10px; + } + &:hover { + color: #40a9ff; + background-color: #fff; + border-color: #40a9ff; + } + } + } + &__body { + display: flex; + padding: 24px; + } + &__detail { + flex: 1; + } + &__avatar { + width: 48px; + height: 48px; + border-radius: 48px; + overflow: hidden; + margin-right: 12px; + img { + width: 100%; + height: 100%; + } + } + &__title { + color: rgba(0, 0, 0, 0.85); + margin-bottom: 12px; + font-size: 16px; + &:hover { + color: #1890ff; + } + } + &__info { + color: rgba(0, 0, 0, 0.45); + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + height: 64px; + } + &__menu { + display: flex; + justify-content: space-around; + height: 50px; + background: #f7f9fa; + color: rgba(0, 0, 0, 0.45); + text-align: center; + line-height: 50px; + &:hover { + color: #1890ff; + } + } +} + +/** joolun 额外加的 */ +.avue-comment__main { + flex: unset !important; + border-radius: 5px !important; + margin: 0 8px !important; +} +.avue-comment__header { + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} +.avue-comment__body { + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; +} diff --git a/src/components/Wechat/wx-msg/comment.scss b/src/components/Wechat/wx-msg/comment.scss new file mode 100644 index 0000000..38be87a --- /dev/null +++ b/src/components/Wechat/wx-msg/comment.scss @@ -0,0 +1,92 @@ +/* 来自 https://github.com/nmxiaowei/avue/blob/master/styles/src/element-ui/comment.scss */ +.avue-comment { + margin-bottom: 30px; + display: flex; + align-items: flex-start; + &--reverse { + flex-direction: row-reverse; + .avue-comment__main { + &:before, + &:after { + left: auto; + right: -8px; + border-width: 8px 0 8px 8px; + } + &:before { + border-left-color: #dedede; + } + &:after { + border-left-color: #f8f8f8; + margin-right: 1px; + margin-left: auto; + } + } + } + &__avatar { + width: 48px; + height: 48px; + border-radius: 50%; + border: 1px solid transparent; + box-sizing: border-box; + vertical-align: middle; + } + &__header { + padding: 5px 15px; + background: #f8f8f8; + border-bottom: 1px solid #eee; + display: flex; + align-items: center; + justify-content: space-between; + } + &__author { + font-weight: 700; + font-size: 14px; + color: #999; + } + &__main { + flex: 1; + margin: 0 20px; + position: relative; + border: 1px solid #dedede; + border-radius: 2px; + &:before, + &:after { + position: absolute; + top: 10px; + left: -8px; + right: 100%; + width: 0; + height: 0; + display: block; + content: ' '; + border-color: transparent; + border-style: solid solid outset; + border-width: 8px 8px 8px 0; + pointer-events: none; + } + &:before { + border-right-color: #dedede; + z-index: 1; + } + &:after { + border-right-color: #f8f8f8; + margin-left: 1px; + z-index: 2; + } + } + &__body { + padding: 15px; + overflow: hidden; + background: #fff; + font-family: Segoe UI, Lucida Grande, Helvetica, Arial, Microsoft YaHei, FreeSans, Arimo, Droid Sans, wenquanyi micro hei, Hiragino Sans GB, + Hiragino Sans GB W3, FontAwesome, sans-serif; + color: #333; + font-size: 14px; + } + blockquote { + margin: 0; + font-family: Georgia, Times New Roman, Times, Kai, Kaiti SC, KaiTi, BiauKai, FontAwesome, serif; + padding: 1px 0 1px 15px; + border-left: 4px solid #ddd; + } +} diff --git a/src/components/Wechat/wx-msg/index.vue b/src/components/Wechat/wx-msg/index.vue new file mode 100644 index 0000000..61be10b --- /dev/null +++ b/src/components/Wechat/wx-msg/index.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/src/components/Wechat/wx-news/index.vue b/src/components/Wechat/wx-news/index.vue new file mode 100644 index 0000000..0bd84be --- /dev/null +++ b/src/components/Wechat/wx-news/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/src/components/Wechat/wx-reply/index.vue b/src/components/Wechat/wx-reply/index.vue new file mode 100644 index 0000000..a802358 --- /dev/null +++ b/src/components/Wechat/wx-reply/index.vue @@ -0,0 +1,309 @@ + + + + + diff --git a/src/components/auth/auth.vue b/src/components/auth/auth.vue new file mode 100644 index 0000000..0585888 --- /dev/null +++ b/src/components/auth/auth.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/components/auth/authAll.vue b/src/components/auth/authAll.vue new file mode 100644 index 0000000..54c8d58 --- /dev/null +++ b/src/components/auth/authAll.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/components/auth/auths.vue b/src/components/auth/auths.vue new file mode 100644 index 0000000..41b8b27 --- /dev/null +++ b/src/components/auth/auths.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..caf8402 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,69 @@ +import Pagination from '/@/components/Pagination/index.vue'; +import RightToolbar from '/@/components/RightToolbar/index.vue'; +import DictTag from '/@/components/DictTag/index.vue'; +import DictSelect from '/@/components/DictTag/Select.vue'; +import UploadExcel from '/@/components/Upload/Excel.vue'; +import UploadFile from '/@/components/Upload/index.vue'; +import UploadImg from '/@/components/Upload/Image.vue'; +import DelWrap from '/@/components/DelWrap/index.vue'; +import Editor from '/@/components/Editor/index.vue'; +import Tip from '/@/components/Tip/index.vue'; +import TagList from '/@/components/TagList/index.vue'; +import SvgIcon from '/@/components/SvgIcon/index.vue'; +import Sign from '/@/components/Sign/index.vue'; +import ChinaArea from '/@/components/ChinaArea/index.vue'; +import OrgSelector from '/@/components/OrgSelector/index.vue'; + +// 第三方组件 +import ElementPlus from 'element-plus'; +import * as ElementPlusIconsVue from '@element-plus/icons-vue'; +import 'element-plus/dist/index.css'; +import { Pane, Splitpanes } from 'splitpanes'; +import 'splitpanes/dist/splitpanes.css'; +// 日历组件 +import { setupCalendar } from 'v-calendar'; + +// 部门树组件 +import vue3TreeOrg from 'vue3-tree-org'; +import 'vue3-tree-org/lib/vue3-tree-org.css'; + +// 导入 FcDesigner +import FcDesigner from 'form-create-designer'; + +// 导入声明 +import { App } from 'vue'; + +export default { + install(app: App) { + app.component('DictTag', DictTag); + app.component('DictSelect', DictSelect); + app.component('Pagination', Pagination); + app.component('RightToolbar', RightToolbar); + app.component('uploadExcel', UploadExcel); + app.component('UploadFile', UploadFile); + app.component('UploadImg', UploadImg); + app.component('Editor', Editor); + app.component('Tip', Tip); + app.component('DelWrap', DelWrap); + app.component('TagList', TagList); + app.component('SvgIcon', SvgIcon); + app.component('ChinaArea', ChinaArea); + app.component('OrgSelector', OrgSelector); + app.component('Sign', Sign); + + // 导入全部的elmenet-plus的图标 + for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component); + // 兼容性 + app.component(`ele-${key}`, component); + } + // 导入布局插件 + app.component('Splitpanes', Splitpanes); + app.component('Pane', Pane); + app.use(ElementPlus); // ELEMENT 组件 + app.use(setupCalendar, {}); // 日历组件 + app.use(vue3TreeOrg); // 组织架构组件 + app.use(FcDesigner); + app.use(FcDesigner.formCreate); + }, +}; diff --git a/src/directive/authDirective.ts b/src/directive/authDirective.ts new file mode 100644 index 0000000..5971e64 --- /dev/null +++ b/src/directive/authDirective.ts @@ -0,0 +1,40 @@ +import type { App } from 'vue'; +import { useUserInfo } from '/@/stores/userInfo'; +import { judementSameArr } from '/@/utils/arrayOperation'; + +/** + * 用户权限指令 + * @directive 单个权限验证(v-auth="xxx") + * @directive 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]") + * @directive 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]") + */ +export function authDirective(app: App) { + // 单个权限验证(v-auth="xxx") + app.directive('auth', { + mounted(el, binding) { + const stores = useUserInfo(); + if (!stores.userInfos.authBtnList.some((v: string) => v === binding.value)) el.parentNode.removeChild(el); + }, + }); + // 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]") + app.directive('auths', { + mounted(el, binding) { + let flag = false; + const stores = useUserInfo(); + stores.userInfos.authBtnList.map((val: string) => { + binding.value.map((v: string) => { + if (val === v) flag = true; + }); + }); + if (!flag) el.parentNode.removeChild(el); + }, + }); + // 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]") + app.directive('auth-all', { + mounted(el, binding) { + const stores = useUserInfo(); + const flag = judementSameArr(binding.value, stores.userInfos.authBtnList); + if (!flag) el.parentNode.removeChild(el); + }, + }); +} diff --git a/src/directive/customDirective.ts b/src/directive/customDirective.ts new file mode 100644 index 0000000..abad5d8 --- /dev/null +++ b/src/directive/customDirective.ts @@ -0,0 +1,54 @@ +import type { App } from 'vue'; + +/** + * 按钮波浪指令 + * @directive 默认方式:v-waves,如 `
` + * @directive 参数方式:v-waves=" |light|red|orange|purple|green|teal",如 `
` + */ +export function wavesDirective(app: App) { + app.directive('waves', { + mounted(el, binding) { + el.classList.add('waves-effect'); + binding.value && el.classList.add(`waves-${binding.value}`); + function setConvertStyle(obj: { [key: string]: unknown }) { + let style: string = ''; + for (let i in obj) { + if (obj.hasOwnProperty(i)) style += `${i}:${obj[i]};`; + } + return style; + } + function onCurrentClick(e: { [key: string]: unknown }) { + let elDiv = document.createElement('div'); + elDiv.classList.add('waves-ripple'); + el.appendChild(elDiv); + let styles = { + left: `${e.layerX}px`, + top: `${e.layerY}px`, + opacity: 1, + transform: `scale(${(el.clientWidth / 100) * 10})`, + 'transition-duration': `750ms`, + 'transition-timing-function': `cubic-bezier(0.250, 0.460, 0.450, 0.940)`, + }; + elDiv.setAttribute('style', setConvertStyle(styles)); + setTimeout(() => { + elDiv.setAttribute( + 'style', + setConvertStyle({ + opacity: 0, + transform: styles.transform, + left: styles.left, + top: styles.top, + }) + ); + setTimeout(() => { + elDiv && el.removeChild(elDiv); + }, 750); + }, 450); + } + el.addEventListener('mousedown', onCurrentClick, false); + }, + unmounted(el) { + el.addEventListener('mousedown', () => {}); + }, + }); +} diff --git a/src/directive/index.ts b/src/directive/index.ts new file mode 100644 index 0000000..3e04a79 --- /dev/null +++ b/src/directive/index.ts @@ -0,0 +1,21 @@ +import type { App } from 'vue'; +import { authDirective } from '/@/directive/authDirective'; +import { wavesDirective } from '/@/directive/customDirective'; + +/** + * 导出指令方法:v-xxx + * @methods authDirective 用户权限指令,用法:v-auth + * @methods wavesDirective 按钮波浪指令,用法:v-waves + */ +export function directive(app: App) { + // 用户权限指令 + authDirective(app); + // 按钮波浪指令 + wavesDirective(app); + // focus + app.directive('focus', { + mounted(el) { + el.focus(); + }, + }); +} diff --git a/src/hooks/dict.ts b/src/hooks/dict.ts new file mode 100644 index 0000000..a7f4c9a --- /dev/null +++ b/src/hooks/dict.ts @@ -0,0 +1,29 @@ +import { dict } from '/@/stores/dict'; +import { getDicts } from '/@/api/admin/dict'; +import { ref, toRefs } from 'vue'; + +/** + * 获取字典数据 + */ +export function useDict(...args: any): any { + const res = ref({}); + return (() => { + args.forEach((dictType: String) => { + // @ts-ignore + res.value[dictType] = []; + const dicts = dict().getDict(dictType); + if (dicts) { + // @ts-ignore + res.value[dictType] = dicts; + } else { + getDicts(dictType).then((resp) => { + // @ts-ignore + res.value[dictType] = resp.data.map((p: any) => ({ label: p.label, value: p.value, elTagType: p.listClass, elTagClass: p.cssClass })); + // @ts-ignore + dict().setDict(dictType, res.value[dictType]); + }); + } + }); + return toRefs(res.value); + })(); +} diff --git a/src/hooks/message.ts b/src/hooks/message.ts new file mode 100644 index 0000000..0492aac --- /dev/null +++ b/src/hooks/message.ts @@ -0,0 +1,103 @@ +import { ElMessage, ElMessageBox } from 'element-plus'; +import { i18n } from '../i18n'; + +const { t } = i18n.global; + +const defaultOptions = { + duration: 3000, // 显示时间为3秒 + showClose: true, // 显示关闭按钮 + offset: 20, // 消息距离顶部的偏移量 +}; + +interface MessageImplements { + info(title: string): void; + warning(title: string): void; + success(title: string): void; + error(title: string): void; +} + +export function useMessage() { + class MessageClass implements MessageImplements { + // 普通提示 + info(title: string): void { + ElMessage({ + ...defaultOptions, + message: title, + type: 'info', + }); + } + + // 警告提示 + warning(title: string): void { + ElMessage({ + ...defaultOptions, + message: title, + type: 'warning', + }); + } + + // 成功提示 + success(title: string): void { + ElMessage({ + ...defaultOptions, + message: title, + type: 'success', + }); + } + + // 错误提示 + error(title: string): void { + ElMessage({ + ...defaultOptions, + message: title, + type: 'error', + duration: 2000, // 错误提示显示时间延长到5秒 + }); + } + } + + return new MessageClass(); +} + +export function useMessageBox() { + class MessageBoxClass implements MessageImplements { + // 普通提示 + info(msg: string): void { + ElMessageBox.alert(msg, t('message.box.title')); + } + + // 警告提示 + warning(msg: string): void { + ElMessageBox.alert(msg, t('message.box.title'), { type: 'warning' }); + } + + // 成功提示 + success(msg: string): void { + ElMessageBox.alert(msg, t('message.box.title'), { type: 'success' }); + } + + // 错误提示 + error(msg: string): void { + ElMessageBox.alert(msg, t('message.box.title'), { type: 'error' }); + } + + // 确认窗体 + confirm(msg: string) { + return ElMessageBox.confirm(msg, t('message.box.title'), { + confirmButtonText: t('common.confirmButtonText'), + cancelButtonText: t('common.cancelButtonText'), + type: 'warning', + }); + } + // 提交内容 + prompt(msg: string) { + return ElMessageBox.prompt(msg, t('message.box.title'), { + confirmButtonText: t('common.confirmButtonText'), + cancelButtonText: t('common.cancelButtonText'), + type: 'warning', + }); + } + } + + return new MessageBoxClass(); +} diff --git a/src/hooks/param.ts b/src/hooks/param.ts new file mode 100644 index 0000000..9e72775 --- /dev/null +++ b/src/hooks/param.ts @@ -0,0 +1,35 @@ +import {param} from '/@/stores/param'; +import {getValue} from '/@/api/admin/param'; + +/** + * 获取参数数据 + * @function + * @param {string} args - 参数类型 + * @returns {Object} - 返回参数数据 + */ +export function useParam(...args: any): string { + let res = ''; + + for (const paramType of args) { + const params = param().getParam(paramType); + if (params) { + res = params; + } else { + // 这里使用同步的获取值方法 + let data = ''; + const fetchData = async () => { + const result = await getValue(paramType); + data = result.data; + }; + + fetchData().then(() => { + if (data) { + res = data; + param().setParam(paramType, data); + } + }) + } + } + + return res; +} diff --git a/src/hooks/table.ts b/src/hooks/table.ts new file mode 100644 index 0000000..3a80609 --- /dev/null +++ b/src/hooks/table.ts @@ -0,0 +1,246 @@ +import { CellStyle, ElMessage } from 'element-plus'; +import other from '/@/utils/other'; + +/** + * 表格组件基础配置属性 + */ +export interface BasicTableProps { + // 是否在创建页面时即调用数据列表接口,默认为true + createdIsNeed?: boolean; + // 是否需要分页,默认为true + isPage?: boolean; + // 查询条件表单对象,类型为any + queryForm?: any; + // 数据列表数组 + dataList?: any[]; + // 分页属性对象 + pagination?: Pagination; + // 数据列表,loading状态标志,默认为false + dataListLoading?: boolean; + // 数据列表多选项数组 + dataListSelections?: any[]; + // 数据列表查询接口api方法,接收任意数量参数,返回Promise + pageList?: (...arg: any) => Promise; + // loading标志,默认为false + loading?: Boolean; + // 多选结果数组 + selectObjs?: any[]; + // 排序字段数组 + descs?: string[]; + // 排序方式数组 + ascs?: string[]; + // props属性对象,类型为any + props?: any; +} + +/** + * 表格样式。 + */ +export interface TableStyle { + cellStyle: CellStyle; + headerCellStyle: CellStyle; +} + +/** + * 分页属性配置接口 + */ +export interface Pagination { + // 当前页码,默认为1 + current?: number; + // 每页显示条数,默认为10 + size?: number; + // 总条数,默认为0 + total?: number; + // 每页显示条数选择器的选项数组,默认为[10,20,30,40] + pageSizes?: any[]; + // 分页组件布局方式,可选值有 total,sizes,prev,jump,next,默认为'total,sizes,prev,jump,next' + layout?: String; +} + +export function useTable(options?: BasicTableProps) { + const defaultOptions: BasicTableProps = { + // 列表数据是否正在加载中,默认为false + dataListLoading: false, + // 是否需要自动请求创建接口来获取表格数据,默认为true + createdIsNeed: true, + // 是否展示分页组件,默认为true + isPage: true, + // 查询表单对象,用于提交条件查询时的参数传递,默认为空对象 + queryForm: {}, + // 表格展示的数据数组,默认为空数组 + dataList: [], + // 分页组件属性配置,如当前页码、每页展示数据条数等,默认值为 {current:1, size:10,total:0,pageSizes:[1, 10, 20, 50, 100, 200],layout:'total, sizes, prev, pager, next, jumper'} + pagination: { + current: 1, + size: 10, + total: 0, + pageSizes: [1, 10, 20, 50, 100, 200], + layout: 'total, sizes, prev, pager, next, jumper', + } as Pagination, + // 当前选中的数据项,默认为空数组 + dataListSelections: [], + // 是否正在从服务器加载数据,默认为false + loading: false, + // 表格数据项的选择数据,默认为空数组 + selectObjs: [], + // 排序时使用的字段名数组,如 ['id','name'],默认为空数组 + descs: [], + // 排序方向数组,如 ['asc', 'desc'],默认为空数组 + ascs: [], + // props属性配置对象,用于自定义数据属性,默认值为 {item:'records',totalCount:'total'} + props: { + item: 'records', + totalCount: 'total', + }, + }; + + /** + * 合并默认属性配置和自定义属性配置 + * @param options 默认属性配置对象 + * @param props 自定义属性配置对象 + * @returns 合并后的属性配置对象 + */ + const mergeDefaultOptions = (options: any, props: any): BasicTableProps => { + for (const key in options) { + if (!Object.getOwnPropertyDescriptor(props, key)) { + props[key] = options[key]; + } + } + return props; + }; + + // 覆盖默认值 + const state = mergeDefaultOptions(defaultOptions, options); + + /** + * 发起分页查询,并设置表格数据和分页信息 + */ + const query = async () => { + // 判断是否存在state.pageList属性 + if (state.pageList) { + try { + // 开始加载数据,设置state.loading为true + state.loading = true; + + // 调用state.pageList方法发起分页查询 + const res = await state.pageList({ + ...state.queryForm, + current: state.pagination?.current, + size: state.pagination?.size, + descs: state.descs?.join(','), + ascs: state.ascs?.join(','), + }); + + // 设置表格展示的数据数组 + state.dataList = state.isPage ? res.data[state.props.item] : res.data; + // 设置分页信息中的总数据条数 + state.pagination!.total = state.isPage ? res.data[state.props.totalCount] : 0; + } catch (err: any) { + // 捕获异常并显示错误提示 + ElMessage.error(err.msg || err.data.msg); + } finally { + // 结束加载数据,设置state.loading为false + state.loading = false; + } + } + }; + + onMounted(() => { + if (state.createdIsNeed) { + query(); + } + }); + + /** + * 分页大小改变事件处理函数 + * @param val 新的分页大小 + */ + const sizeChangeHandle = (val: number) => { + // 修改state.pagination中的size属性 + state.pagination!.size = val; + // 再次发起查询操作 + query(); + }; + + /** + * 当前页码改变事件处理函数 + * @param val 新的页码 + */ + const currentChangeHandle = (val: number) => { + // 修改state.pagination中的current属性 + state.pagination!.current = val; + // 再次发起查询操作 + query(); + }; + + // 排序触发事件 + const sortChangeHandle = (column: any) => { + const prop = other.toUnderline(column.prop); + if (column.order === 'descending') { + state.descs?.push(prop); + if (state.ascs!.includes(prop)) { + state.ascs?.splice(state.ascs.indexOf(prop), 1); + } + } else if (column.order === 'ascending') { + state.ascs?.push(prop); + if (state.descs!.includes(prop)) { + state.descs?.splice(state.descs.indexOf(prop), 1); + } + } else { + if (state.ascs!.includes(prop)) { + state.ascs?.splice(state.ascs.indexOf(prop), 1); + } + if (state.descs!.includes(prop)) { + state.descs?.splice(state.descs.indexOf(prop), 1); + } + } + query(); + }; + + /** + * 获取数据列表,并可选择是否刷新当前页码 + * 刷新后不跳转第一页,则入参 getDataList(false) + * @param refresh 是否刷新当前页码 + */ + const getDataList = (refresh?: any) => { + // 如果需要刷新,则将state.pagination.current重置为1 + if (refresh !== false) { + state.pagination!.current = 1; + } + // 再次发起查询操作 + query(); + }; + + /** + * 下载文件 + * @param url 文件下载地址 + * @param query 请求参数(可能包含token) + * @param fileName 文件名 + * @returns 返回一个Promise对象,用于异步处理结果 + */ + const downBlobFile = (url: string, query: any, fileName: string) => { + return other.downBlobFile(url, query, fileName); + }; + + /** + * 定义表格通用样式 + * @returns css + */ + const tableStyle: TableStyle = { + cellStyle: { textAlign: 'center' }, + headerCellStyle: { + textAlign: 'center', + background: 'var(--el-table-row-hover-bg-color)', + color: 'var(--el-text-color-primary)', + }, + }; + + return { + tableStyle, + getDataList, + sizeChangeHandle, + currentChangeHandle, + sortChangeHandle, + downBlobFile, + }; +} diff --git a/src/i18n/index.ts b/src/i18n/index.ts new file mode 100644 index 0000000..2221bf0 --- /dev/null +++ b/src/i18n/index.ts @@ -0,0 +1,91 @@ +import {createI18n} from 'vue-i18n'; +import pinia from '/@/stores/index'; +import {storeToRefs} from 'pinia'; +import {useThemeConfig} from '/@/stores/themeConfig'; +import {info} from '/@/api/admin/i18n'; + +// 定义语言国际化内容 + +/** + * 说明: + * 须在 pages 下新建文件夹(建议 `要国际化界面目录` 与 `i18n 目录` 相同,方便查找), + * 注意国际化定义的字段,不要与原有的定义字段相同。 + * 1、/src/i18n/lang 下的 ts 为框架的国际化内容 + * 2、/src/i18n/pages 下的 ts 为各界面的国际化内容 + */ + +// element plus 自带国际化 +import enLocale from 'element-plus/es/locale/lang/en'; +import zhcnLocale from 'element-plus/es/locale/lang/zh-cn'; + +// 定义变量内容 +const messages = {}; +const element = {en: enLocale, 'zh-cn': zhcnLocale}; +const itemize = {en: [] as any[], 'zh-cn': [] as any[]}; +const modules: Record = import.meta.glob('./**/*.ts', {eager: true}); +const pages: Record = import.meta.glob('./../../**/**/**/i18n/*.ts', {eager: true}); + +// 对自动引入的 modules 进行分类 en、zh-cn、zh-tw +for (const path in modules) { + const key = path.match(/(\S+)\/(\S+).ts/); + if (itemize[key![2]]) itemize[key![2]].push(modules[path].default); + else itemize[key![2]] = modules[path]; +} +for (const path in pages) { + const key = path.match(/(\S+)\/(\S+).ts/); + if (itemize[key![2]]) itemize[key![2]].push(pages[path].default); + else itemize[key![2]] = pages[path]; +} + +// 合并数组对象(非标准数组对象,数组中对象的每项 key、value 都不同) +function mergeArrObj(list: T, key: string) { + let obj = {}; + list[key].forEach((i: EmptyObjectType) => { + obj = Object.assign({}, obj, i); + }); + return obj; +} + +for (const key in itemize) { + messages[key] = { + name: key, + el: element[key].el, + ...mergeArrObj(itemize, key), + }; +} + +// 读取 pinia 默认语言 +const stores = useThemeConfig(pinia); +const {themeConfig} = storeToRefs(stores); + +// 导出语言国际化 +export const i18n = createI18n({ + legacy: false, + silentTranslationWarn: true, + missingWarn: false, + silentFallbackWarn: true, + fallbackWarn: false, + locale: themeConfig.value.globalI18n, + fallbackLocale: zhcnLocale.name, + messages, +}); + +await fetchI18n() + +// 远程获取i18n +async function fetchI18n() { + const infoI18n = await info(); + const messageLocal = {}; + const itemizeLocal = {en: [] as any[], 'zh-cn': [] as any[]}; + itemizeLocal['zh-cn'].push(...infoI18n.data.data['zh-cn']); + itemizeLocal.en.push(...infoI18n.data.data.en); + for (const key in itemizeLocal) { + messageLocal[key] = { + name: key, + ...mergeArrObj(itemizeLocal, key), + }; + } + i18n.global.mergeLocaleMessage('zh-cn', messageLocal['zh-cn']); + i18n.global.mergeLocaleMessage('en', messageLocal['en']); + i18n.global.locale.value = themeConfig.value.globalI18n; +} diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts new file mode 100644 index 0000000..5736056 --- /dev/null +++ b/src/i18n/lang/en.ts @@ -0,0 +1,194 @@ +export default { + router: { + home: 'Home', + system: 'System', + systemMenu: 'System Menu', + systemRole: 'System Role', + systemUser: 'System User', + systemDept: 'System Department', + systemDic: 'System Dictionary', + limits: 'Permissions', + limitsFrontEnd: 'Front End', + limitsFrontEndPage: 'Front End Page', + limitsFrontEndBtn: 'Front End Button', + limitsBackEnd: 'Back End', + limitsBackEndEndPage: 'Back End Page', + menu: 'Menu', + menu1: 'Menu 1', + menu11: 'Menu 1-1', + menu12: 'Menu 1-2', + menu121: 'Menu 1-2-1', + menu122: 'Menu 1-2-2', + menu13: 'Menu 1-3', + menu2: 'Menu 2', + funIndex: 'Functions', + funTagsView: 'Tags View', + funCountup: 'Count Up', + funWangEditor: 'Wang Editor', + funCropper: 'Cropper', + funQrcode: 'QR Code', + funEchartsMap: 'Echarts Map', + funPrintJs: 'PrintJS', + funClipboard: 'Copy and Cut', + funGridLayout: 'Drag Layout', + funSplitpanes: 'Split Pane', + funDragVerify: 'Validator', + pagesIndex: 'Pages', + pagesFiltering: 'Filtering', + pagesFilteringDetails: 'Filtering Details', + pagesFilteringDetails1: 'Filtering Details 1', + pagesIocnfont: 'Icon Font Icon', + pagesElement: 'Element Icon', + pagesAwesome: 'Awesome Icon', + pagesFormAdapt: 'Form Adapt', + pagesTableRules: 'Table Rules', + pagesFormI18n: 'Form I18n', + pagesFormRules: 'Multi-Form Validation', + pagesDynamicForm: 'Dynamic Complex Form', + pagesWorkflow: 'Workflow', + pagesListAdapt: 'List Adapt', + pagesWaterfall: 'Waterfall', + pagesSteps: 'Steps', + pagesPreview: 'Large Preview', + pagesWaves: 'Wave Effect', + pagesTree: 'Tree Alter Table', + pagesDrag: 'Drag Command', + pagesLazyImg: 'Image Lazy Loading', + makeIndex: 'Make Index', + makeSelector: 'Icon Selector', + makeNoticeBar: 'Notification Bar', + makeSvgDemo: 'Svgicon Demo', + makeTableDemo: 'Table Demo', + paramsIndex: 'Routing Parameters', + paramsCommon: 'General Routing', + paramsDynamic: 'Dynamic Routing', + paramsCommonDetails: 'General Routing Details', + paramsDynamicDetails: 'Dynamic Routing Details', + chartIndex: 'Chart Index', + visualizingIndex: 'Visualizing Index', + visualizingLinkDemo1: 'Visualizing Link Demo 1', + visualizingLinkDemo2: 'Visualizing Link Demo 2', + personal: 'Personal', + tools: 'Tools', + layoutLinkView: 'Link View', + layoutIframeViewOne: 'Iframe View One', + layoutIframeViewTwo: 'Iframe View Two', + }, + staticRoutes: { + login: 'Login', + authredirect: 'Auth Redirect', + expire: 'Password Expire', + signIn: 'Sign In', + notFound: 'Not Found', + noPower: 'No Power', + }, + user: { + title0: 'Component Size', + title1: 'Language Switching', + title2: 'Menu Search', + title3: 'Layout Configuration', + title4: 'News', + title5: 'Full Screen On', + title6: 'Full Screen Off', + dropdownLarge: 'Large', + dropdownDefault: 'Default', + dropdownSmall: 'Small', + dropdown1: 'Home Page', + dropdown2: 'Personal Center', + dropdown5: 'Log Out', + searchPlaceholder: 'Menu Search: Supports Chinese and Routing Path', + newTitle: 'Notice', + newBtn: 'All', + newGo: 'Go to the Notification Center', + newDesc: 'No Notice', + logOutTitle: 'Tips', + logOutMessage: 'This Operation Will Log Out. Do You Want to Continue?', + logOutConfirm: 'Determine', + logOutCancel: 'Cancel', + logOutExit: 'Exiting', + }, + tagsView: { + refresh: 'Refresh', + close: 'Close', + closeOther: 'Close Other', + closeAll: 'Close All', + fullscreen: 'Fullscreen', + closeFullscreen: 'Close Fullscreen', + favorite: 'Favorite', + favoriteMax: 'The number of shortcut navigation exceeds the upper limit. Please remove some shortcuts' + }, + notFound: { + foundTitle: 'Wrong Address Input, Please Re-enter the Address~', + foundMsg: 'You Can Check the Web Address First, and Then Re-enter or Give Us Feedback.', + foundBtn: 'Back to Home Page', + }, + noAccess: { + accessTitle: 'You Are Not Authorized to Operate~', + accessMsg: 'Contact Information: Add QQ Group Discussion 665452019', + accessBtn: 'Reauthorization', + }, + layout: { + configTitle: 'Layout Configuration', + oneTitle: 'Global Themes', + twoTopTitle: 'Top Bar Set Up', + twoMenuTitle: 'Menu Set Up', + twoColumnsTitle: 'Columns Set Up', + twoTopBar: 'Top Bar Background', + twoTopBarColor: 'Top Bar Default Font Color', + twoIsTopBarColorGradual: 'Top Bar Gradient', + twoMenuBar: 'Menu Background', + twoMenuBarColor: 'Menu Default Font Color', + twoMenuBarActiveColor: 'Menu Highlight Color', + twoIsMenuBarColorGradual: 'Menu Gradient', + twoColumnsMenuBar: 'Column Menu Background', + twoColumnsMenuBarColor: 'Default Font Color Bar Menu', + twoIsColumnsMenuBarColorGradual: 'Column Gradient', + twoIsColumnsMenuHoverPreload: 'Column Menu Hover Preload', + threeTitle: 'Interface Settings', + threeIsCollapse: 'Menu Horizontal Collapse', + threeIsUniqueOpened: 'Menu Accordion', + threeIsFixedHeader: 'Fixed Header', + threeIsClassicSplitMenu: 'Classic Layout Split Menu', + threeIsLockScreen: 'Open the Lock Screen', + threeLockScreenTime: 'Screen Locking (s/s)', + fourTitle: 'Interface Display', + fourIsShowLogo: 'Sidebar Logo', + fourIsBreadcrumb: 'Open Breadcrumb', + fourIsBreadcrumbIcon: 'Open Breadcrumb Icon', + fourIsTagsview: 'Open Tagsview', + fourIsTagsviewIcon: 'Open Tagsview Icon', + fourIsCacheTagsView: 'Enable Tagsview Cache', + fourIsSortableTagsView: 'Enable Tagsview Drag', + fourIsShareTagsView: 'Enable Tagsview Sharing', + fourIsFooter: 'Open Footer', + fourIsGrayscale: 'Grey Model', + fourIsInvert: 'Color Weak Mode', + fourIsDark: 'Dark Mode', + fourIsWartermark: 'Turn on Watermark', + fourWartermarkText: 'Watermark Copy', + fourIsChat: 'LLaMA Chat', + fiveTitle: 'Other Settings', + fiveTagsStyle: 'Tagsview Style', + fiveAnimation: 'Page Animation', + fiveColumnsAsideStyle: 'Column Style', + fiveColumnsAsideLayout: 'Column Layout', + sixTitle: 'Layout Switch', + sixDefaults: 'One', + sixClassic: 'Two', + sixTransverse: 'Three', + sixColumns: 'Four', + tipText: 'Click the Button Below to Copy the Layout Configuration to `/src/stores/themeConfig.ts`. It Has Been Modified In.', + copyText: 'Replication Configuration', + resetText: 'Restore Default', + copyTextSuccess: 'Copy Succeeded!', + copyTextError: 'Copy Failed!', + }, + upgrade: { + title: 'New Version', + msg: 'The New Version is Available, Please Update It Now! Dont Worry, the Update is Fast!', + desc: 'Prompt: Update Will Restore the Default Configuration', + btnOne: 'Cruel Refusal', + btnTwo: 'Update Now', + btnTwoLoading: 'Updating', + }, +}; diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts new file mode 100644 index 0000000..7c85e50 --- /dev/null +++ b/src/i18n/lang/zh-cn.ts @@ -0,0 +1,187 @@ +// 定义内容 +export default { + router: { + home: '首页', + system: '系统设置', + systemMenu: '菜单管理', + systemRole: '角色管理', + systemUser: '用户管理', + systemDept: '部门管理', + systemDic: '字典管理', + limits: '权限管理', + limitsFrontEnd: '前端控制', + limitsFrontEndPage: '页面权限', + limitsFrontEndBtn: '按钮权限', + limitsBackEnd: '后端控制', + limitsBackEndEndPage: '页面权限', + funIndex: '功能', + funTagsView: 'tagsView 操作', + funCountup: '数字滚动', + funWangEditor: 'Editor 编辑器', + funCropper: '图片裁剪', + funQrcode: '二维码生成', + funEchartsMap: '地理坐标/地图', + funPrintJs: '页面打印', + funClipboard: '复制剪切', + funGridLayout: '拖拽布局', + funSplitpanes: '窗格拆分器', + funDragVerify: '验证器', + pagesIndex: '页面', + pagesFiltering: '过滤筛选组件', + pagesFilteringDetails: '过滤筛选组件详情', + pagesFilteringDetails1: '过滤筛选组件详情111', + pagesIocnfont: 'ali 字体图标', + pagesElement: 'ele 字体图标', + pagesAwesome: 'awe 字体图标', + pagesFormAdapt: '表单自适应', + pagesTableRules: '表单表格验证', + pagesFormI18n: '表单国际化', + pagesFormRules: '多表单验证', + pagesDynamicForm: '动态复杂表单', + pagesWorkflow: '工作流', + pagesListAdapt: '列表自适应', + pagesWaterfall: '瀑布屏', + pagesSteps: '步骤条', + pagesPreview: '大图预览', + pagesWaves: '波浪效果', + pagesTree: '树形改表格', + pagesDrag: '拖动指令', + pagesLazyImg: '图片懒加载', + makeIndex: '组件封装', + makeSelector: '图标选择器', + makeNoticeBar: '滚动通知栏', + makeSvgDemo: 'svgIcon 演示', + makeTableDemo: '表格封装演示', + paramsIndex: '路由参数', + paramsCommon: '普通路由', + paramsDynamic: '动态路由', + paramsCommonDetails: '普通路由详情', + paramsDynamicDetails: '动态路由详情', + chartIndex: '大数据图表', + visualizingIndex: '数据可视化', + visualizingLinkDemo1: '数据可视化演示1', + visualizingLinkDemo2: '数据可视化演示2', + personal: '个人中心', + tools: '工具类集合', + layoutLinkView: '外链', + layoutIframeViewOne: '内嵌 iframe1', + layoutIframeViewTwo: '内嵌 iframe2', + }, + staticRoutes: { + login: '登录', + authredirect: '回调页', + expire: '密码过期', + signIn: '登录', + notFound: '找不到此页面', + noPower: '没有权限', + }, + user: { + title0: '组件大小', + title1: '语言切换', + title2: '菜单搜索', + title3: '布局配置', + title4: '消息', + title5: '开全屏', + title6: '关全屏', + dropdownLarge: '大型', + dropdownDefault: '默认', + dropdownSmall: '小型', + dropdown1: '首页', + dropdown2: '个人中心', + dropdown5: '退出登录', + searchPlaceholder: '菜单搜索:支持中文、路由路径', + newTitle: '通知', + newBtn: '全部', + newGo: '前往通知中心', + newDesc: '暂无通知', + logOutTitle: '提示', + logOutMessage: '此操作将退出登录, 是否继续?', + logOutConfirm: '确定', + logOutCancel: '取消', + logOutExit: '退出中', + }, + tagsView: { + refresh: '刷新', + close: '关闭', + closeOther: '关闭其它', + closeAll: '全部关闭', + fullscreen: '当前页全屏', + closeFullscreen: '关闭全屏', + favorite: '收藏', + favoriteMax: '快捷导航数量超过上限,请移除部分' + }, + notFound: { + foundTitle: '地址输入错误,请重新输入地址~', + foundMsg: '您可以先检查网址,然后重新输入或给我们反馈问题。', + foundBtn: '返回首页', + }, + noAccess: { + accessTitle: '您未被授权,没有操作权限~', + accessMsg: '联系方式:加QQ群探讨 665452019', + accessBtn: '重新授权', + }, + layout: { + configTitle: '布局配置', + oneTitle: '全局主题', + twoTopTitle: '顶栏设置', + twoMenuTitle: '菜单设置', + twoColumnsTitle: '分栏设置', + twoTopBar: '顶栏背景', + twoTopBarColor: '顶栏默认字体颜色', + twoIsTopBarColorGradual: '顶栏背景渐变', + twoMenuBar: '菜单背景', + twoMenuBarColor: '菜单默认字体颜色', + twoMenuBarActiveColor: '菜单高亮背景色', + twoIsMenuBarColorGradual: '菜单背景渐变', + twoColumnsMenuBar: '分栏菜单背景', + twoColumnsMenuBarColor: '分栏菜单默认字体颜色', + twoIsColumnsMenuBarColorGradual: '分栏菜单背景渐变', + twoIsColumnsMenuHoverPreload: '分栏菜单鼠标悬停预加载', + threeTitle: '界面设置', + threeIsCollapse: '菜单水平折叠', + threeIsUniqueOpened: '菜单手风琴', + threeIsFixedHeader: '固定 Header', + threeIsClassicSplitMenu: '经典布局顶部菜单', + threeIsLockScreen: '开启锁屏', + threeLockScreenTime: '自动锁屏(s/秒)', + fourTitle: '界面显示', + fourIsShowLogo: '侧边栏 Logo', + fourIsBreadcrumb: '开启 Breadcrumb', + fourIsBreadcrumbIcon: '开启 Breadcrumb 图标', + fourIsTagsview: '开启 Tagsview', + fourIsTagsviewIcon: '开启 Tagsview 图标', + fourIsCacheTagsView: '开启 TagsView 缓存', + fourIsSortableTagsView: '开启 TagsView 拖拽', + fourIsShareTagsView: '开启 TagsView 共用', + fourIsFooter: '开启 Footer', + fourIsGrayscale: '灰色模式', + fourIsInvert: '色弱模式', + fourIsDark: '深色模式', + fourIsWartermark: '开启水印', + fourIsChat: '开启AI助手', + fourWartermarkText: '水印文案', + fiveTitle: '其它设置', + fiveTagsStyle: 'Tagsview 风格', + fiveAnimation: '主页面切换动画', + fiveColumnsAsideStyle: '分栏高亮风格', + fiveColumnsAsideLayout: '分栏布局风格', + sixTitle: '布局切换', + sixDefaults: '左侧', + sixClassic: '左顶', + sixTransverse: '横向', + sixColumns: '分栏', + tipText: '点击下方按钮,复制布局配置去 `src/stores/themeConfig.ts` 中修改。', + copyText: '一键复制配置', + resetText: '一键恢复默认', + copyTextSuccess: '复制成功!', + copyTextError: '复制失败!', + }, + upgrade: { + title: '新版本升级', + msg: '新版本来啦,马上更新尝鲜吧!不用担心,更新很快的哦!', + desc: '提示:更新会还原默认配置', + btnOne: '残忍拒绝', + btnTwo: '马上更新', + btnTwoLoading: '更新中', + }, +}; diff --git a/src/i18n/pages/form/en.ts b/src/i18n/pages/form/en.ts new file mode 100644 index 0000000..43ce0fe --- /dev/null +++ b/src/i18n/pages/form/en.ts @@ -0,0 +1,36 @@ +// Improved versions of each word or sentence +export default { + common: { + queryBtn: 'Query', + addBtn: 'Add', + editBtn: 'Edit', + delBtn: 'Delete', + viewBtn: 'View', + detailBtn: 'Details', + exportBtn: 'Export', + expandBtn: 'expand/phrase ', + refreshCacheBtn: 'Refresh cache', + importBtn: 'Import', + importUserTip: 'Import user', + queryDeptTip: 'Enter department name', + resetBtn: 'Reset', + copyBtn:'Copy', + action: 'Action', + optSuccessText: 'Operation successful', + optConfirmText: 'Confirm this operation?', + editSuccessText: 'Successfully edited', + addSuccessText: 'Successfully added', + delSuccessText: 'Successfully deleted', + delConfirmText: 'This operation will permanently delete', + confirmButtonText: 'Confirm', + cancelButtonText: 'Cancel', + download: 'Download', + expand: 'Expand', + selectAll: 'SelectAll', + }, + message: { + box: { + title: 'System prompt', + }, + }, +}; diff --git a/src/i18n/pages/form/zh-cn.ts b/src/i18n/pages/form/zh-cn.ts new file mode 100644 index 0000000..0352912 --- /dev/null +++ b/src/i18n/pages/form/zh-cn.ts @@ -0,0 +1,35 @@ +// 定义通用内容 +export default { + common: { + queryBtn: '查询', + addBtn: '新 增', + editBtn: '修 改', + expandBtn: '展开/折叠', + delBtn: '删除', + viewBtn: '查看', + detailBtn: '详情', + refreshCacheBtn: '刷新缓存', + exportBtn: '导出', + importBtn: '导入', + queryDeptTip: '请输入部门名称', + resetBtn: '重置', + copyBtn: '复制', + action: '操作', + optSuccessText: '操作成功', + editSuccessText: '修改成功', + addSuccessText: '添加成功', + delSuccessText: '删除成功', + delConfirmText: '此操作将永久删除', + optConfirmText: '是否确认本操作', + confirmButtonText: '确认', + cancelButtonText: '取消', + download: '下载', + expand: '展开/折叠', + selectAll: '全选/不全选', + }, + message: { + box: { + title: '系统提示', + }, + }, +}; diff --git a/src/i18n/pages/login/en.ts b/src/i18n/pages/login/en.ts new file mode 100644 index 0000000..d456b20 --- /dev/null +++ b/src/i18n/pages/login/en.ts @@ -0,0 +1,87 @@ +export default { + label: { + one1: 'Account login', + two2: 'SMS login', + three3: 'Social login', + register: 'Create account', + }, + link: { + one3: 'Third party login', + two4: 'Links', + }, + password: { + accountPlaceholder1: 'The username "admin" is common, please use another', + accountPlaceholder2: 'Password', + accountPlaceholder3: 'Please enter the verification code', + phonePlaceholder4: 'Please enter your phone number', + accountBtnText: 'Sign in', + resetBtnText: 'Reset', + registerBtnText: 'Create account', + readAccept: 'I have read and accept', + privacyPolicy: 'the Privacy Policy', + oldPassword: 'Please enter old password', + newPassword: 'Please enter new password', + confirmPassword: 'Please confirm new password', + backToLogin: 'Back to login', + mobileLogin: 'Mobile Login', + createAccount: 'Create Account', + imageCodeTip: 'Please enter code', + }, + mobile: { + placeholder1: 'Please enter your mobile number', + placeholder2: 'Please enter the verification code', + codeText: 'Get code', + btnText: 'Sign in', + mobileLogin: 'Mobile Login', + backToLogin: 'Back to login', + createAccount: 'Create Account', + sendSuccess: 'Verification code sent successfully', + seconds: 'seconds to resend', + mobileRequired: 'Please enter your mobile number', + codeRequired: 'Please enter verification code', + codeLength: 'Verification code must be 4 digits', + sendFailed: 'Failed to send verification code', + loginSuccess: 'Login successful', + loginFailed: 'Login failed', + signIn: 'Sign In', + }, + scan: { + text: 'Use your mobile device to scan and quickly log in or create an account', + wechatApp: 'Scan with WeChat', + appErrorTip: 'The login fails because the application is not configured', + }, + signInText: 'Welcome back!', + browserMsgText: + 'Tip: For best results, we recommend using Google Chrome, Microsoft Edge (version 80 or higher), or the 360 browser with speed mode enabled.', + expire: { + oldPassword: 'Please enter old password', + newPassword: 'Please enter new password', + confirmPassword: 'Please confirm new password', + passwordRule: 'The two passwords do not match', + passwordScore: 'Password strength is too low', + resetSuccess: 'Password reset successfully', + }, + tenantSelect: { + select: 'Select Tenant', + loadError: 'Failed to get tenant list', + }, + verify: { + imageCode: 'Please enter verification code', + }, + register: { + usernameEmpty: 'Username cannot be empty', + usernameLength: 'Username length must be between 5 and 20 characters', + phoneEmpty: 'Phone number cannot be empty', + passwordEmpty: 'Password cannot be empty', + passwordLength: 'Password length must be between 6 and 20 characters', + passwordStrength: 'Password strength is too low', + termsRequired: 'Please read and accept the terms', + }, + divider: { + or: 'or', + }, + socialLogin: { + wechatWork: 'WeCom', + dingtalk: 'DingTalk', + }, +}; diff --git a/src/i18n/pages/login/zh-cn.ts b/src/i18n/pages/login/zh-cn.ts new file mode 100644 index 0000000..729ded2 --- /dev/null +++ b/src/i18n/pages/login/zh-cn.ts @@ -0,0 +1,84 @@ +// 定义内容 +export default { + label: { + one1: '用户名登录', + two2: '手机号登录', + three3: '社交登录', + register: '注册账号', + }, + link: { + one3: '第三方登录', + two4: '友情链接', + }, + password: { + accountPlaceholder1: '请输入用户名', + accountPlaceholder2: '请输入密码', + accountPlaceholder3: '请输入验证码', + phonePlaceholder4: '请输入手机号', + accountBtnText: '登 录', + registerBtnText: '注 册', + resetBtnText: '重 置', + readAccept: '我已仔细阅读并接受', + privacyPolicy: '《隐私政策》', + oldPassword: '请输入原密码', + newPassword: '请输入新密码', + confirmPassword: '请确认新密码', + backToLogin: '返回登录', + mobileLogin: '验证码登录', + createAccount: '注册账号', + imageCodeTip: '请输入验证码', + }, + mobile: { + placeholder1: '请输入手机号', + placeholder2: '请输入验证码', + codeText: '获取验证码', + btnText: '登 录', + mobileLogin: '验证码登录', + backToLogin: '返回登录', + createAccount: '注册账号', + sendSuccess: '验证码发送功', + seconds: '秒后重发', + mobileRequired: '请输入手机号码', + codeRequired: '请输入验证码', + codeLength: '验证码必须是4位数字', + sendFailed: '发送验证码失败', + loginSuccess: '登录成功', + loginFailed: '登录失败', + signIn: '登 录', + }, + scan: { + text: '打开手机扫一扫,快速登录/注册', + wechatApp: '微信扫码体验移动端', + appErrorTip: '应用未配置,登录失败', + }, + signInText: '欢迎回来!', + browserMsgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 80 及以上浏览器,360浏览器请使用极速模式', + expire: { + oldPassword: '请输入原密码', + newPassword: '请输入新密码', + confirmPassword: '请确认新密码', + passwordRule: '两次输入的密码不一致', + passwordScore: '密码强度太低', + resetSuccess: '密码重置成功', + }, + tenantSelect: { + select: '选择租户', + loadError: '获取租户列表失败', + }, + register: { + usernameEmpty: '用户名不能为空', + usernameLength: '用户名称长度必须介于 5 和 20 之间', + phoneEmpty: '手机号不能为空', + passwordEmpty: '密码不能为空', + passwordLength: '用户密码长度必须介于 6 和 20 之间', + passwordStrength: '密码强度太低', + termsRequired: '请阅读并同意条款', + }, + divider: { + or: '或', + }, + socialLogin: { + wechatWork: '企微', + dingtalk: '钉钉', + }, +}; diff --git a/src/layout/component/aside.vue b/src/layout/component/aside.vue new file mode 100644 index 0000000..fd32d3d --- /dev/null +++ b/src/layout/component/aside.vue @@ -0,0 +1,174 @@ + + + diff --git a/src/layout/component/columnsAside.vue b/src/layout/component/columnsAside.vue new file mode 100644 index 0000000..735e425 --- /dev/null +++ b/src/layout/component/columnsAside.vue @@ -0,0 +1,300 @@ + + + + + diff --git a/src/layout/component/header.vue b/src/layout/component/header.vue new file mode 100644 index 0000000..29aa179 --- /dev/null +++ b/src/layout/component/header.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/layout/component/main.vue b/src/layout/component/main.vue new file mode 100644 index 0000000..0abd8fc --- /dev/null +++ b/src/layout/component/main.vue @@ -0,0 +1,60 @@ + + + diff --git a/src/layout/index.vue b/src/layout/index.vue new file mode 100644 index 0000000..f4ee956 --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,50 @@ + + + diff --git a/src/layout/lockScreen/index.vue b/src/layout/lockScreen/index.vue new file mode 100644 index 0000000..c1344a4 --- /dev/null +++ b/src/layout/lockScreen/index.vue @@ -0,0 +1,382 @@ + + + + + diff --git a/src/layout/logo/index.vue b/src/layout/logo/index.vue new file mode 100644 index 0000000..284e39c --- /dev/null +++ b/src/layout/logo/index.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/layout/main/classic.vue b/src/layout/main/classic.vue new file mode 100644 index 0000000..3e0a74c --- /dev/null +++ b/src/layout/main/classic.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/layout/main/columns.vue b/src/layout/main/columns.vue new file mode 100644 index 0000000..22c0ff5 --- /dev/null +++ b/src/layout/main/columns.vue @@ -0,0 +1,68 @@ + + + diff --git a/src/layout/main/defaults.vue b/src/layout/main/defaults.vue new file mode 100644 index 0000000..17497d8 --- /dev/null +++ b/src/layout/main/defaults.vue @@ -0,0 +1,68 @@ + + + diff --git a/src/layout/main/transverse.vue b/src/layout/main/transverse.vue new file mode 100644 index 0000000..0cde251 --- /dev/null +++ b/src/layout/main/transverse.vue @@ -0,0 +1,55 @@ + + + diff --git a/src/layout/navBars/breadcrumb/breadcrumb.vue b/src/layout/navBars/breadcrumb/breadcrumb.vue new file mode 100644 index 0000000..8d022c7 --- /dev/null +++ b/src/layout/navBars/breadcrumb/breadcrumb.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/closeFull.vue b/src/layout/navBars/breadcrumb/closeFull.vue new file mode 100644 index 0000000..fad7894 --- /dev/null +++ b/src/layout/navBars/breadcrumb/closeFull.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/index.vue b/src/layout/navBars/breadcrumb/index.vue new file mode 100644 index 0000000..8042036 --- /dev/null +++ b/src/layout/navBars/breadcrumb/index.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/search.vue b/src/layout/navBars/breadcrumb/search.vue new file mode 100644 index 0000000..5f9cc4c --- /dev/null +++ b/src/layout/navBars/breadcrumb/search.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/setings.vue b/src/layout/navBars/breadcrumb/setings.vue new file mode 100644 index 0000000..611c0b3 --- /dev/null +++ b/src/layout/navBars/breadcrumb/setings.vue @@ -0,0 +1,838 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue new file mode 100644 index 0000000..a696baf --- /dev/null +++ b/src/layout/navBars/breadcrumb/user.vue @@ -0,0 +1,288 @@ + + + + + diff --git a/src/layout/navBars/breadcrumb/userNews.vue b/src/layout/navBars/breadcrumb/userNews.vue new file mode 100644 index 0000000..5d05cb6 --- /dev/null +++ b/src/layout/navBars/breadcrumb/userNews.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/layout/navBars/index.vue b/src/layout/navBars/index.vue new file mode 100644 index 0000000..aa8edb9 --- /dev/null +++ b/src/layout/navBars/index.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/layout/navBars/tagsView/contextmenu.vue b/src/layout/navBars/tagsView/contextmenu.vue new file mode 100644 index 0000000..8cf3114 --- /dev/null +++ b/src/layout/navBars/tagsView/contextmenu.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/layout/navBars/tagsView/tagsView.vue b/src/layout/navBars/tagsView/tagsView.vue new file mode 100644 index 0000000..9308817 --- /dev/null +++ b/src/layout/navBars/tagsView/tagsView.vue @@ -0,0 +1,730 @@ + + + + + diff --git a/src/layout/navMenu/horizontal.vue b/src/layout/navMenu/horizontal.vue new file mode 100644 index 0000000..92ccdbe --- /dev/null +++ b/src/layout/navMenu/horizontal.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/src/layout/navMenu/subItem.vue b/src/layout/navMenu/subItem.vue new file mode 100644 index 0000000..45a173c --- /dev/null +++ b/src/layout/navMenu/subItem.vue @@ -0,0 +1,49 @@ + + + diff --git a/src/layout/navMenu/vertical.vue b/src/layout/navMenu/vertical.vue new file mode 100644 index 0000000..b76c17b --- /dev/null +++ b/src/layout/navMenu/vertical.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/layout/routerView/iframes.vue b/src/layout/routerView/iframes.vue new file mode 100644 index 0000000..4500092 --- /dev/null +++ b/src/layout/routerView/iframes.vue @@ -0,0 +1,98 @@ +