diff --git a/.docker-compose/nginx/conf.d/my.conf b/.docker-compose/nginx/conf.d/my.conf
new file mode 100644
index 0000000..9a1685d
--- /dev/null
+++ b/.docker-compose/nginx/conf.d/my.conf
@@ -0,0 +1,26 @@
+server {
+ listen 8080;
+ server_name localhost;
+
+ #charset koi8-r;
+ #access_log logs/host.access.log main;
+
+ location / {
+ root /usr/share/nginx/html;
+ add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
+ try_files $uri $uri/ /index.html;
+ }
+
+ location /api {
+ proxy_set_header Host $http_host;
+ 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 $scheme;
+ rewrite ^/api/(.*)$ /$1 break; #重写
+ proxy_pass http://177.7.0.12:8888; # 设置代理服务器的协议和地址
+ }
+
+ location /api/swagger/index.html {
+ proxy_pass http://127.0.0.1:8888/swagger/index.html;
+ }
+ }
\ No newline at end of file
diff --git a/.docker-compose/nginx/conf.d/nginx.conf b/.docker-compose/nginx/conf.d/nginx.conf
new file mode 100644
index 0000000..29f68b8
--- /dev/null
+++ b/.docker-compose/nginx/conf.d/nginx.conf
@@ -0,0 +1,32 @@
+server {
+ listen 80;
+ server_name localhost;
+
+ #charset koi8-r;
+ #access_log logs/host.access.log main;
+
+ location / {
+ root /usr/share/nginx/html/dist;
+ add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
+ try_files $uri $uri/ /index.html;
+ }
+
+ location /api {
+ proxy_set_header Host $http_host;
+ 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 $scheme;
+ rewrite ^/api/(.*)$ /$1 break; #重写
+ proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址
+ }
+ location /form-generator {
+ proxy_set_header Host $http_host;
+ 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 $scheme;
+ proxy_pass http://127.0.0.1:8888;
+ }
+ location /api/swagger/index.html {
+ proxy_pass http://127.0.0.1:8888/swagger/index.html;
+ }
+ }
\ No newline at end of file
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..40b878d
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+node_modules/
\ No newline at end of file
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..ad07c38
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,11 @@
+ENV = 'development'
+VITE_CLI_PORT = 8080
+VITE_SERVER_PORT = 8888
+VITE_BASE_API = /api
+VITE_FILE_API = /api
+VITE_BASE_PATH = http://127.0.0.1
+VITE_POSITION = close
+VITE_EDITOR = vscode
+// VITE_EDITOR = webstorm 如果使用webstorm开发且要使用dom定位到代码行功能 请先自定添加 webstorm到环境变量 再将VITE_EDITOR值修改为webstorm
+// 如果使用docker-compose开发模式,设置为下面的地址或本机主机IP
+//VITE_BASE_PATH = http://177.7.0.12
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..9345df2
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,7 @@
+ENV = 'production'
+
+#下方为上线需要用到的程序代理前缀,一般用于nginx代理转发
+VITE_BASE_API = /api
+VITE_FILE_API = /api
+#下方修改为你的线上ip(如果需要在线使用表单构建工具时使用,其余情况无需使用以下环境变量)
+VITE_BASE_PATH = https://demo.gin-vue-admin.com
diff --git a/.gitignore b/.gitignore
index a19f004..ea890fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,6 @@
-# ---> Vue
-# gitignore template for Vue.js projects
-#
-# Recommended template: Node.gitignore
-
-# TODO: where does this rule come from?
-docs/_book
-
-# TODO: where does this rule come from?
-test/
-
+node_modules/*
+package-lock.json
+yarn.lock
+bun.lockb
+config.yaml
+.idea
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..bc61a53
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,12 @@
+{
+ "printWidth": 80,
+ "tabWidth": 2,
+ "useTabs": false,
+ "semi": false,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "bracketSpacing": true,
+ "arrowParens": "always",
+ "vueIndentScriptAndStyle": true,
+ "endOfLine": "lf"
+}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..af4464e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,25 @@
+# 如果需要用 cicd ,请设置环境变量:
+# variables:
+# DOCKER_BUILDKIT: 1
+
+FROM node:20-slim AS base
+ENV PNPM_HOME="/pnpm"
+ENV PATH="$PNPM_HOME:$PATH"
+RUN corepack enable
+COPY . /app
+WORKDIR /app
+
+
+FROM base AS prod-deps
+RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod
+
+FROM base AS build
+COPY --from=prod-deps /app/node_modules /app/node_modules
+RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install && pnpm run build
+
+
+FROM nginx:alpine
+LABEL MAINTAINER="bypanghu@163.com"
+COPY --from=base /app/.docker-compose/nginx/conf.d/my.conf /etc/nginx/conf.d/my.conf
+COPY --from=build /app/dist /usr/share/nginx/html
+RUN ls -al /usr/share/nginx/html
diff --git a/README.md b/README.md
index b724201..06f1a8c 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,106 @@
-# lckt-admin
+# gin-vue-admin web
-老陈课堂-管理后台
\ No newline at end of file
+## Project setup
+
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+
+```
+npm run build
+```
+
+### Run your tests
+
+```
+npm run test
+```
+
+### Lints and fixes files
+
+```
+npm run lint
+```
+
+整理代码结构
+
+```lua
+web
+ ├── babel.config.js
+ ├── Dockerfile
+ ├── favicon.ico
+ ├── index.html -- 主页面
+ ├── limit.js -- 助手代码
+ ├── package.json -- 包管理器代码
+ ├── src -- 源代码
+ │ ├── api -- api 组
+ │ ├── App.vue -- 主页面
+ │ ├── assets -- 静态资源
+ │ ├── components -- 全局组件
+ │ ├── core -- gva 组件包
+ │ │ ├── config.js -- gva网站配置文件
+ │ │ ├── gin-vue-admin.js -- 注册欢迎文件
+ │ │ └── global.js -- 统一导入文件
+ │ ├── directive -- v-auth 注册文件
+ │ ├── main.js -- 主文件
+ │ ├── permission.js -- 路由中间件
+ │ ├── pinia -- pinia 状态管理器,取代vuex
+ │ │ ├── index.js -- 入口文件
+ │ │ └── modules -- modules
+ │ │ ├── dictionary.js
+ │ │ ├── router.js
+ │ │ └── user.js
+ │ ├── router -- 路由声明文件
+ │ │ └── index.js
+ │ ├── style -- 全局样式
+ │ │ ├── base.scss
+ │ │ ├── basics.scss
+ │ │ ├── element_visiable.scss -- 此处可以全局覆盖 element-plus 样式
+ │ │ ├── iconfont.css -- 顶部几个icon的样式文件
+ │ │ ├── main.scss
+ │ │ ├── mobile.scss
+ │ │ └── newLogin.scss
+ │ ├── utils -- 方法包库
+ │ │ ├── asyncRouter.js -- 动态路由相关
+ │ │ ├── bus.js -- 全局mitt声明文件
+ │ │ ├── date.js -- 日期相关
+ │ │ ├── dictionary.js -- 获取字典方法
+ │ │ ├── downloadImg.js -- 下载图片方法
+ │ │ ├── format.js -- 格式整理相关
+ │ │ ├── image.js -- 图片相关方法
+ │ │ ├── page.js -- 设置页面标题
+ │ │ ├── request.js -- 请求
+ │ │ └── stringFun.js -- 字符串文件
+ | ├── view -- 主要view代码
+ | | ├── about -- 关于我们
+ | | ├── dashboard -- 面板
+ | | ├── error -- 错误
+ | | ├── example --上传案例
+ | | ├── iconList -- icon列表
+ | | ├── init -- 初始化数据
+ | | | ├── index -- 新版本
+ | | | ├── init -- 旧版本
+ | | ├── layout -- layout约束页面
+ | | | ├── aside
+ | | | ├── bottomInfo -- bottomInfo
+ | | | ├── screenfull -- 全屏设置
+ | | | ├── setting -- 系统设置
+ | | | └── index.vue -- base 约束
+ | | ├── login --登录
+ | | ├── person --个人中心
+ | | ├── superAdmin -- 超级管理员操作
+ | | ├── system -- 系统检测页面
+ | | ├── systemTools -- 系统配置相关页面
+ | | └── routerHolder.vue -- page 入口页面
+ ├── vite.config.js -- vite 配置文件
+ └── yarn.lock
+
+```
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..b1becff
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ presets: [],
+ plugins: []
+}
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..3b443c5
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,29 @@
+import js from '@eslint/js'
+import pluginVue from 'eslint-plugin-vue'
+import globals from 'globals'
+
+export default [
+ js.configs.recommended,
+ ...pluginVue.configs['flat/essential'],
+ {
+ name: 'app/files-to-lint',
+ files: ['**/*.{js,mjs,jsx,vue}'],
+ languageOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ globals: globals.node
+ },
+ rules: {
+ 'vue/max-attributes-per-line': 0,
+ 'vue/no-v-model-argument': 0,
+ 'vue/multi-word-component-names': 'off',
+ 'no-lone-blocks': 'off',
+ 'no-extend-native': 'off',
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }]
+ }
+ },
+ {
+ name: 'app/files-to-ignore',
+ ignores: ['**/dist/**', '**/build/*.js', '**/src/assets/**', '**/public/**']
+ }
+]
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..1d8d87a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..ca45014
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"],
+ "include": ["src/**/*"]
+}
diff --git a/limit.js b/limit.js
new file mode 100644
index 0000000..6ba9d46
--- /dev/null
+++ b/limit.js
@@ -0,0 +1,37 @@
+// 运行项目前通过node执行此脚本 (此脚本与 node_modules 目录同级)
+const fs = require('fs')
+const path = require('path')
+const wfPath = path.resolve(__dirname, './node_modules/.bin')
+
+fs.readdir(wfPath, (err, files) => {
+ if (err) {
+ console.log(err)
+ } else {
+ if (files.length !== 0) {
+ files.forEach((item) => {
+ if (item.split('.')[1] === 'cmd') {
+ replaceStr(`${wfPath}/${item}`, /"%_prog%"/, '%_prog%')
+ }
+ })
+ }
+ }
+})
+
+// 参数:[文件路径、 需要修改的字符串、修改后的字符串] (替换对应文件内字符串的公共函数)
+function replaceStr(filePath, sourceRegx, targetSrt) {
+ fs.readFile(filePath, (err, data) => {
+ if (err) {
+ console.log(err)
+ } else {
+ let str = data.toString()
+ str = str.replace(sourceRegx, targetSrt)
+ fs.writeFile(filePath, str, (err) => {
+ if (err) {
+ console.log(err)
+ } else {
+ console.log('\x1B[42m%s\x1B[0m', '文件修改成功')
+ }
+ })
+ }
+ })
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..9bc5be3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,75 @@
+{
+ "name": "gin-vue-admin",
+ "version": "2.8.0",
+ "private": true,
+ "scripts": {
+ "serve": "vite --host --mode development",
+ "build": "vite build --mode production",
+ "limit-build": "npm install increase-memory-limit-fixbug cross-env -g && npm run fix-memory-limit && node ./limit && npm run build",
+ "preview": "vite preview",
+ "fix-memory-limit": "cross-env LIMIT=4096 increase-memory-limit"
+ },
+ "dependencies": {
+ "@element-plus/icons-vue": "^2.3.1",
+ "@form-create/designer": "^3.2.6",
+ "@form-create/element-ui": "^3.2.10",
+ "@vue-office/docx": "^1.6.2",
+ "@vue-office/excel": "^1.7.11",
+ "@vue-office/pdf": "^2.0.2",
+ "@vueuse/core": "^11.0.3",
+ "@vueuse/integrations": "^12.0.0",
+ "@wangeditor/editor": "^5.1.23",
+ "@wangeditor/editor-for-vue": "^5.1.12",
+ "ace-builds": "^1.36.4",
+ "axios": "^1.7.7",
+ "chokidar": "^4.0.0",
+ "core-js": "^3.38.1",
+ "echarts": "5.5.1",
+ "element-plus": "^2.8.5",
+ "highlight.js": "^11.10.0",
+ "marked": "14.1.1",
+ "marked-highlight": "^2.1.4",
+ "mitt": "^3.0.1",
+ "nprogress": "^0.2.0",
+ "path": "^0.12.7",
+ "pinia": "^2.2.2",
+ "qs": "^6.13.0",
+ "screenfull": "^6.0.2",
+ "sortablejs": "^1.15.3",
+ "spark-md5": "^3.0.2",
+ "tailwindcss": "^3.4.10",
+ "universal-cookie": "^7",
+ "vform3-builds": "^3.0.10",
+ "vite-auto-import-svg": "^1.1.0",
+ "vue": "^3.5.7",
+ "vue-cropper": "^1.1.4",
+ "vue-echarts": "^7.0.3",
+ "vue-qr": "^4.0.9",
+ "vue-router": "^4.4.3",
+ "vue3-ace-editor": "^2.2.4",
+ "vuedraggable": "^4.1.0"
+ },
+ "devDependencies": {
+ "@babel/eslint-parser": "^7.25.1",
+ "@eslint/js": "^9.14.0",
+ "@vitejs/plugin-legacy": "^5.4.2",
+ "@vitejs/plugin-vue": "^5.1.4",
+ "@vue/cli-plugin-babel": "~5.0.8",
+ "@vue/cli-plugin-eslint": "~5.0.8",
+ "@vue/cli-plugin-router": "~5.0.8",
+ "@vue/cli-plugin-vuex": "~5.0.8",
+ "@vue/cli-service": "~5.0.8",
+ "@vue/compiler-sfc": "^3.5.1",
+ "babel-plugin-import": "^1.13.8",
+ "chalk": "^5.3.0",
+ "dotenv": "^16.4.5",
+ "eslint": "^9.14.0",
+ "eslint-plugin-vue": "^9.30.0",
+ "sass": "^1.78.0",
+ "terser": "^5.31.6",
+ "vite": "^5.4.3",
+ "vite-plugin-banner": "^0.8.0",
+ "vite-plugin-importer": "^0.2.5",
+ "vite-plugin-vue-devtools": "^7.4.4"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..85f717c
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {}
+ }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..ee520ce
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..468cdab
Binary files /dev/null and b/public/logo.png differ
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..6048a3f
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/api/api.js b/src/api/api.js
new file mode 100644
index 0000000..7eed8fc
--- /dev/null
+++ b/src/api/api.js
@@ -0,0 +1,176 @@
+import service from '@/utils/request'
+
+// @Tags api
+// @Summary 分页获取角色列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getApiList [post]
+// {
+// page int
+// pageSize int
+// }
+export const getApiList = (data) => {
+ return service({
+ url: '/api/getApiList',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Api
+// @Summary 创建基础api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "创建api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/createApi [post]
+export const createApi = (data) => {
+ return service({
+ url: '/api/createApi',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getApiById [post]
+export const getApiById = (data) => {
+ return service({
+ url: '/api/getApiById',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/updateApi [post]
+export const updateApi = (data) => {
+ return service({
+ url: '/api/updateApi',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/setAuthApi [post]
+export const setAuthApi = (data) => {
+ return service({
+ url: '/api/setAuthApi',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Api
+// @Summary 获取所有的Api 不分页
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getAllApis [post]
+export const getAllApis = (data) => {
+ return service({
+ url: '/api/getAllApis',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Api
+// @Summary 删除指定api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.Api true "删除api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApi [post]
+export const deleteApi = (data) => {
+ return service({
+ url: '/api/deleteApi',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysApi
+// @Summary 删除选中Api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "ID"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApisByIds [delete]
+export const deleteApisByIds = (data) => {
+ return service({
+ url: '/api/deleteApisByIds',
+ method: 'delete',
+ data
+ })
+}
+
+// FreshCasbin
+// @Tags SysApi
+// @Summary 刷新casbin缓存
+// @accept application/json
+// @Produce application/json
+// @Success 200 {object} response.Response{msg=string} "刷新成功"
+// @Router /api/freshCasbin [get]
+export const freshCasbin = () => {
+ return service({
+ url: '/api/freshCasbin',
+ method: 'get'
+ })
+}
+
+export const syncApi = () => {
+ return service({
+ url: '/api/syncApi',
+ method: 'get'
+ })
+}
+
+export const getApiGroups = () => {
+ return service({
+ url: '/api/getApiGroups',
+ method: 'get'
+ })
+}
+
+export const ignoreApi = (data) => {
+ return service({
+ url: '/api/ignoreApi',
+ method: 'post',
+ data
+ })
+}
+
+export const enterSyncApi = (data) => {
+ return service({
+ url: '/api/enterSyncApi',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/attachmentCategory.js b/src/api/attachmentCategory.js
new file mode 100644
index 0000000..58980f6
--- /dev/null
+++ b/src/api/attachmentCategory.js
@@ -0,0 +1,26 @@
+import service from '@/utils/request'
+// 分类列表
+export const getCategoryList = () => {
+ return service({
+ url: '/attachmentCategory/getCategoryList',
+ method: 'get',
+ })
+}
+
+// 添加/编辑分类
+export const addCategory = (data) => {
+ return service({
+ url: '/attachmentCategory/addCategory',
+ method: 'post',
+ data
+ })
+}
+
+// 删除分类
+export const deleteCategory = (data) => {
+ return service({
+ url: '/attachmentCategory/deleteCategory',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/authority.js b/src/api/authority.js
new file mode 100644
index 0000000..0401273
--- /dev/null
+++ b/src/api/authority.js
@@ -0,0 +1,85 @@
+import service from '@/utils/request'
+// @Router /authority/getAuthorityList [post]
+export const getAuthorityList = (data) => {
+ return service({
+ url: '/authority/getAuthorityList',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 删除角色
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body {authorityId uint} true "删除角色"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /authority/deleteAuthority [post]
+export const deleteAuthority = (data) => {
+ return service({
+ url: '/authority/deleteAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 创建角色
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateAuthorityPatams true "创建角色"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /authority/createAuthority [post]
+export const createAuthority = (data) => {
+ return service({
+ url: '/authority/createAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags authority
+// @Summary 拷贝角色
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateAuthorityPatams true "拷贝角色"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"拷贝成功"}"
+// @Router /authority/copyAuthority [post]
+export const copyAuthority = (data) => {
+ return service({
+ url: '/authority/copyAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 设置角色资源权限
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body sysModel.SysAuthority true "设置角色资源权限"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
+// @Router /authority/setDataAuthority [post]
+export const setDataAuthority = (data) => {
+ return service({
+ url: '/authority/setDataAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 修改角色
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysAuthority true "修改角色"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
+// @Router /authority/setDataAuthority [post]
+export const updateAuthority = (data) => {
+ return service({
+ url: '/authority/updateAuthority',
+ method: 'put',
+ data
+ })
+}
diff --git a/src/api/authorityBtn.js b/src/api/authorityBtn.js
new file mode 100644
index 0000000..e12db47
--- /dev/null
+++ b/src/api/authorityBtn.js
@@ -0,0 +1,25 @@
+import service from '@/utils/request'
+
+export const getAuthorityBtnApi = (data) => {
+ return service({
+ url: '/authorityBtn/getAuthorityBtn',
+ method: 'post',
+ data
+ })
+}
+
+export const setAuthorityBtnApi = (data) => {
+ return service({
+ url: '/authorityBtn/setAuthorityBtn',
+ method: 'post',
+ data
+ })
+}
+
+export const canRemoveAuthorityBtnApi = (params) => {
+ return service({
+ url: '/authorityBtn/canRemoveAuthorityBtn',
+ method: 'post',
+ params
+ })
+}
diff --git a/src/api/autoCode.js b/src/api/autoCode.js
new file mode 100644
index 0000000..8994b3c
--- /dev/null
+++ b/src/api/autoCode.js
@@ -0,0 +1,198 @@
+import service from '@/utils/request'
+
+export const preview = (data) => {
+ return service({
+ url: '/autoCode/preview',
+ method: 'post',
+ data
+ })
+}
+
+export const createTemp = (data) => {
+ return service({
+ url: '/autoCode/createTemp',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysApi
+// @Summary 获取当前所有数据库
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getDatabase [get]
+export const getDB = (params) => {
+ return service({
+ url: '/autoCode/getDB',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysApi
+// @Summary 获取当前数据库所有表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getTables [get]
+export const getTable = (params) => {
+ return service({
+ url: '/autoCode/getTables',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysApi
+// @Summary 获取当前数据库所有表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getColumn [get]
+export const getColumn = (params) => {
+ return service({
+ url: '/autoCode/getColumn',
+ method: 'get',
+ params
+ })
+}
+
+export const getSysHistory = (data) => {
+ return service({
+ url: '/autoCode/getSysHistory',
+ method: 'post',
+ data
+ })
+}
+
+export const rollback = (data) => {
+ return service({
+ url: '/autoCode/rollback',
+ method: 'post',
+ data
+ })
+}
+
+export const getMeta = (data) => {
+ return service({
+ url: '/autoCode/getMeta',
+ method: 'post',
+ data
+ })
+}
+
+export const delSysHistory = (data) => {
+ return service({
+ url: '/autoCode/delSysHistory',
+ method: 'post',
+ data
+ })
+}
+
+export const createPackageApi = (data) => {
+ return service({
+ url: '/autoCode/createPackage',
+ method: 'post',
+ data
+ })
+}
+
+export const getPackageApi = () => {
+ return service({
+ url: '/autoCode/getPackage',
+ method: 'post'
+ })
+}
+
+export const deletePackageApi = (data) => {
+ return service({
+ url: '/autoCode/delPackage',
+ method: 'post',
+ data
+ })
+}
+
+export const getTemplatesApi = () => {
+ return service({
+ url: '/autoCode/getTemplates',
+ method: 'get'
+ })
+}
+
+export const installPlug = (data) => {
+ return service({
+ url: '/autoCode/installPlug',
+ method: 'post',
+ data
+ })
+}
+
+export const pubPlug = (params) => {
+ return service({
+ url: '/autoCode/pubPlug',
+ method: 'post',
+ params
+ })
+}
+
+export const llmAuto = (data) => {
+ return service({
+ url: '/autoCode/llmAuto',
+ method: 'post',
+ data: { ...data, mode: 'ai' },
+ timeout: 1000 * 60 * 10,
+ loadingOption: {
+ lock: true,
+ fullscreen: true,
+ text: `小淼正在思考,请稍候...`
+ }
+ })
+}
+
+export const butler = (data) => {
+ return service({
+ url: '/autoCode/llmAuto',
+ method: 'post',
+ data: { ...data, mode: 'butler' },
+ timeout: 1000 * 60 * 10
+ })
+}
+
+
+export const eye = (data) => {
+ return service({
+ url: '/autoCode/llmAuto',
+ method: 'post',
+ data: { ...data, mode: 'eye' },
+ timeout: 1000 * 60 * 10
+ })
+}
+
+
+export const addFunc = (data) => {
+ return service({
+ url: '/autoCode/addFunc',
+ method: 'post',
+ data
+ })
+}
+
+export const initMenu = (data) => {
+ return service({
+ url: '/autoCode/initMenu',
+ method: 'post',
+ data
+ })
+}
+
+export const initAPI = (data) => {
+ return service({
+ url: '/autoCode/initAPI',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/bot/bot.js b/src/api/bot/bot.js
new file mode 100644
index 0000000..b159323
--- /dev/null
+++ b/src/api/bot/bot.js
@@ -0,0 +1,110 @@
+import service from '@/utils/request'
+// @Tags Bot
+// @Summary 创建机器人
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Bot true "创建机器人"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /bt/createBot [post]
+export const createBot = (data) => {
+ return service({
+ url: '/bt/createBot',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Bot
+// @Summary 删除机器人
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Bot true "删除机器人"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /bt/deleteBot [delete]
+export const deleteBot = (params) => {
+ return service({
+ url: '/bt/deleteBot',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Bot
+// @Summary 批量删除机器人
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除机器人"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /bt/deleteBot [delete]
+export const deleteBotByIds = (params) => {
+ return service({
+ url: '/bt/deleteBotByIds',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Bot
+// @Summary 更新机器人
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Bot true "更新机器人"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /bt/updateBot [put]
+export const updateBot = (data) => {
+ return service({
+ url: '/bt/updateBot',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags Bot
+// @Summary 用id查询机器人
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data query model.Bot true "用id查询机器人"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /bt/findBot [get]
+export const findBot = (params) => {
+ return service({
+ url: '/bt/findBot',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags Bot
+// @Summary 分页获取机器人列表
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data query request.PageInfo true "分页获取机器人列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /bt/getBotList [get]
+export const getBotList = (params) => {
+ return service({
+ url: '/bt/getBotList',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags Bot
+// @Summary 不需要鉴权的机器人接口
+// @Accept application/json
+// @Produce application/json
+// @Param data query botReq.BotSearch true "分页获取机器人列表"
+// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
+// @Router /bt/getBotPublic [get]
+export const getBotPublic = () => {
+ return service({
+ url: '/bt/getBotPublic',
+ method: 'get',
+ })
+}
diff --git a/src/api/breakpoint.js b/src/api/breakpoint.js
new file mode 100644
index 0000000..1dbfba2
--- /dev/null
+++ b/src/api/breakpoint.js
@@ -0,0 +1,43 @@
+import service from '@/utils/request'
+// @Summary 设置角色资源权限
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body sysModel.SysAuthority true "设置角色资源权限"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
+// @Router /authority/setDataAuthority [post]
+
+export const findFile = (params) => {
+ return service({
+ url: '/fileUploadAndDownload/findFile',
+ method: 'get',
+ params
+ })
+}
+
+export const breakpointContinue = (data) => {
+ return service({
+ url: '/fileUploadAndDownload/breakpointContinue',
+ method: 'post',
+ donNotShowLoading: true,
+ headers: { 'Content-Type': 'multipart/form-data' },
+ data
+ })
+}
+
+export const breakpointContinueFinish = (params) => {
+ return service({
+ url: '/fileUploadAndDownload/breakpointContinueFinish',
+ method: 'post',
+ params
+ })
+}
+
+export const removeChunk = (data, params) => {
+ return service({
+ url: '/fileUploadAndDownload/removeChunk',
+ method: 'post',
+ data,
+ params
+ })
+}
diff --git a/src/api/casbin.js b/src/api/casbin.js
new file mode 100644
index 0000000..802e130
--- /dev/null
+++ b/src/api/casbin.js
@@ -0,0 +1,32 @@
+import service from '@/utils/request'
+// @Tags authority
+// @Summary 更改角色api权限
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateAuthorityPatams true "更改角色api权限"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /casbin/UpdateCasbin [post]
+export const UpdateCasbin = (data) => {
+ return service({
+ url: '/casbin/updateCasbin',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags casbin
+// @Summary 获取权限列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateAuthorityPatams true "获取权限列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /casbin/getPolicyPathByAuthorityId [post]
+export const getPolicyPathByAuthorityId = (data) => {
+ return service({
+ url: '/casbin/getPolicyPathByAuthorityId',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/category/category.js b/src/api/category/category.js
new file mode 100644
index 0000000..701ec6d
--- /dev/null
+++ b/src/api/category/category.js
@@ -0,0 +1,110 @@
+import service from '@/utils/request'
+// @Tags Category
+// @Summary 创建类别
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Category true "创建类别"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /cat/createCategory [post]
+export const createCategory = (data) => {
+ return service({
+ url: '/cat/createCategory',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Category
+// @Summary 删除类别
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Category true "删除类别"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /cat/deleteCategory [delete]
+export const deleteCategory = (params) => {
+ return service({
+ url: '/cat/deleteCategory',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Category
+// @Summary 批量删除类别
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除类别"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /cat/deleteCategory [delete]
+export const deleteCategoryByIds = (params) => {
+ return service({
+ url: '/cat/deleteCategoryByIds',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Category
+// @Summary 更新类别
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data body model.Category true "更新类别"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /cat/updateCategory [put]
+export const updateCategory = (data) => {
+ return service({
+ url: '/cat/updateCategory',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags Category
+// @Summary 用id查询类别
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data query model.Category true "用id查询类别"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /cat/findCategory [get]
+export const findCategory = (params) => {
+ return service({
+ url: '/cat/findCategory',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags Category
+// @Summary 分页获取类别列表
+// @Security ApiKeyAuth
+// @Accept application/json
+// @Produce application/json
+// @Param data query request.PageInfo true "分页获取类别列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /cat/getCategoryList [get]
+export const getCategoryList = (params) => {
+ return service({
+ url: '/cat/getCategoryList',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags Category
+// @Summary 不需要鉴权的类别接口
+// @Accept application/json
+// @Produce application/json
+// @Param data query categoryReq.CategorySearch true "分页获取类别列表"
+// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
+// @Router /cat/getCategoryPublic [get]
+export const getCategoryPublic = () => {
+ return service({
+ url: '/cat/getCategoryPublic',
+ method: 'get',
+ })
+}
diff --git a/src/api/customer.js b/src/api/customer.js
new file mode 100644
index 0000000..4776f1c
--- /dev/null
+++ b/src/api/customer.js
@@ -0,0 +1,80 @@
+import service from '@/utils/request'
+// @Tags SysApi
+// @Summary 删除客户
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.ExaCustomer true "删除客户"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /customer/customer [post]
+export const createExaCustomer = (data) => {
+ return service({
+ url: '/customer/customer',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysApi
+// @Summary 更新客户信息
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.ExaCustomer true "更新客户信息"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /customer/customer [put]
+export const updateExaCustomer = (data) => {
+ return service({
+ url: '/customer/customer',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags SysApi
+// @Summary 创建客户
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.ExaCustomer true "创建客户"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /customer/customer [delete]
+export const deleteExaCustomer = (data) => {
+ return service({
+ url: '/customer/customer',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysApi
+// @Summary 获取单一客户信息
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.ExaCustomer true "获取单一客户信息"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /customer/customer [get]
+export const getExaCustomer = (params) => {
+ return service({
+ url: '/customer/customer',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysApi
+// @Summary 获取权限客户列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "获取权限客户列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /customer/customerList [get]
+export const getExaCustomerList = (params) => {
+ return service({
+ url: '/customer/customerList',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/email.js b/src/api/email.js
new file mode 100644
index 0000000..c2f16f4
--- /dev/null
+++ b/src/api/email.js
@@ -0,0 +1,14 @@
+import service from '@/utils/request'
+// @Tags email
+// @Summary 发送测试邮件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /email/emailTest [post]
+export const emailTest = (data) => {
+ return service({
+ url: '/email/emailTest',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/exportTemplate.js b/src/api/exportTemplate.js
new file mode 100644
index 0000000..9f8729b
--- /dev/null
+++ b/src/api/exportTemplate.js
@@ -0,0 +1,128 @@
+import service from '@/utils/request'
+
+// @Tags SysExportTemplate
+// @Summary 创建导出模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysExportTemplate true "创建导出模板"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /sysExportTemplate/createSysExportTemplate [post]
+export const createSysExportTemplate = (data) => {
+ return service({
+ url: '/sysExportTemplate/createSysExportTemplate',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysExportTemplate
+// @Summary 删除导出模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysExportTemplate true "删除导出模板"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysExportTemplate/deleteSysExportTemplate [delete]
+export const deleteSysExportTemplate = (data) => {
+ return service({
+ url: '/sysExportTemplate/deleteSysExportTemplate',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysExportTemplate
+// @Summary 批量删除导出模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除导出模板"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysExportTemplate/deleteSysExportTemplate [delete]
+export const deleteSysExportTemplateByIds = (data) => {
+ return service({
+ url: '/sysExportTemplate/deleteSysExportTemplateByIds',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysExportTemplate
+// @Summary 更新导出模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysExportTemplate true "更新导出模板"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysExportTemplate/updateSysExportTemplate [put]
+export const updateSysExportTemplate = (data) => {
+ return service({
+ url: '/sysExportTemplate/updateSysExportTemplate',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags SysExportTemplate
+// @Summary 用id查询导出模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query model.SysExportTemplate true "用id查询导出模板"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysExportTemplate/findSysExportTemplate [get]
+export const findSysExportTemplate = (params) => {
+ return service({
+ url: '/sysExportTemplate/findSysExportTemplate',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysExportTemplate
+// @Summary 分页获取导出模板列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query request.PageInfo true "分页获取导出模板列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysExportTemplate/getSysExportTemplateList [get]
+export const getSysExportTemplateList = (params) => {
+ return service({
+ url: '/sysExportTemplate/getSysExportTemplateList',
+ method: 'get',
+ params
+ })
+}
+
+
+// ExportExcel 导出表格token
+// @Tags SysExportTemplate
+// @Summary 导出表格
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Router /sysExportTemplate/exportExcel [get]
+export const exportExcel = (params) => {
+ return service({
+ url: '/sysExportTemplate/exportExcel',
+ method: 'get',
+ params
+ })
+}
+
+// ExportTemplate 导出表格模板
+// @Tags SysExportTemplate
+// @Summary 导出表格模板
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Router /sysExportTemplate/exportTemplate [get]
+export const exportTemplate = (params) => {
+ return service({
+ url: '/sysExportTemplate/exportTemplate',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/fileUploadAndDownload.js b/src/api/fileUploadAndDownload.js
new file mode 100644
index 0000000..0f260b6
--- /dev/null
+++ b/src/api/fileUploadAndDownload.js
@@ -0,0 +1,67 @@
+import service from '@/utils/request'
+// @Tags FileUploadAndDownload
+// @Summary 分页文件列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取文件户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /fileUploadAndDownload/getFileList [post]
+export const getFileList = (data) => {
+ return service({
+ url: '/fileUploadAndDownload/getFileList',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags FileUploadAndDownload
+// @Summary 删除文件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param data body dbModel.FileUploadAndDownload true "传入文件里面id即可"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /fileUploadAndDownload/deleteFile [post]
+export const deleteFile = (data) => {
+ return service({
+ url: '/fileUploadAndDownload/deleteFile',
+ method: 'post',
+ data
+ })
+}
+
+/**
+ * 编辑文件名或者备注
+ * @param data
+ * @returns {*}
+ */
+export const editFileName = (data) => {
+ return service({
+ url: '/fileUploadAndDownload/editFileName',
+ method: 'post',
+ data
+ })
+}
+
+/**
+ * 导入URL
+ * @param data
+ * @returns {*}
+ */
+export const importURL = (data) => {
+ return service({
+ url: '/fileUploadAndDownload/importURL',
+ method: 'post',
+ data
+ })
+}
+
+
+// 上传文件 暂时用于头像上传
+export const uploadFile = (data) => {
+ return service({
+ url: "/fileUploadAndDownload/upload",
+ method: "post",
+ data,
+ });
+};
\ No newline at end of file
diff --git a/src/api/github.js b/src/api/github.js
new file mode 100644
index 0000000..38e1067
--- /dev/null
+++ b/src/api/github.js
@@ -0,0 +1,19 @@
+import axios from 'axios'
+
+const service = axios.create()
+
+export function Commits(page) {
+ return service({
+ url:
+ 'https://api.github.com/repos/flipped-aurora/gin-vue-admin/commits?page=' +
+ page,
+ method: 'get'
+ })
+}
+
+export function Members() {
+ return service({
+ url: 'https://api.github.com/orgs/FLIPPED-AURORA/members',
+ method: 'get'
+ })
+}
diff --git a/src/api/initdb.js b/src/api/initdb.js
new file mode 100644
index 0000000..f1eb2f4
--- /dev/null
+++ b/src/api/initdb.js
@@ -0,0 +1,27 @@
+import service from '@/utils/request'
+// @Tags InitDB
+// @Summary 初始化用户数据库
+// @Produce application/json
+// @Param data body request.InitDB true "初始化数据库参数"
+// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
+// @Router /init/initdb [post]
+export const initDB = (data) => {
+ return service({
+ url: '/init/initdb',
+ method: 'post',
+ data,
+ donNotShowLoading: true
+ })
+}
+
+// @Tags CheckDB
+// @Summary 初始化用户数据库
+// @Produce application/json
+// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
+// @Router /init/checkdb [post]
+export const checkDB = () => {
+ return service({
+ url: '/init/checkdb',
+ method: 'post'
+ })
+}
diff --git a/src/api/jwt.js b/src/api/jwt.js
new file mode 100644
index 0000000..811ffc4
--- /dev/null
+++ b/src/api/jwt.js
@@ -0,0 +1,14 @@
+import service from '@/utils/request'
+// @Tags jwt
+// @Summary jwt加入黑名单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}"
+// @Router /jwt/jsonInBlacklist [post]
+export const jsonInBlacklist = () => {
+ return service({
+ url: '/jwt/jsonInBlacklist',
+ method: 'post'
+ })
+}
diff --git a/src/api/menu.js b/src/api/menu.js
new file mode 100644
index 0000000..163b5a6
--- /dev/null
+++ b/src/api/menu.js
@@ -0,0 +1,113 @@
+import service from '@/utils/request'
+// @Summary 用户登录 获取动态路由
+// @Produce application/json
+// @Param 可以什么都不填 调一下即可
+// @Router /menu/getMenu [post]
+export const asyncMenu = () => {
+ return service({
+ url: '/menu/getMenu',
+ method: 'post'
+ })
+}
+
+// @Summary 获取menu列表
+// @Produce application/json
+// @Param {
+// page int
+// pageSize int
+// }
+// @Router /menu/getMenuList [post]
+export const getMenuList = (data) => {
+ return service({
+ url: '/menu/getMenuList',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 新增基础menu
+// @Produce application/json
+// @Param menu Object
+// @Router /menu/getMenuList [post]
+export const addBaseMenu = (data) => {
+ return service({
+ url: '/menu/addBaseMenu',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 获取基础路由列表
+// @Produce application/json
+// @Param 可以什么都不填 调一下即可
+// @Router /menu/getBaseMenuTree [post]
+export const getBaseMenuTree = () => {
+ return service({
+ url: '/menu/getBaseMenuTree',
+ method: 'post'
+ })
+}
+
+// @Summary 添加用户menu关联关系
+// @Produce application/json
+// @Param menus Object authorityId string
+// @Router /menu/getMenuList [post]
+export const addMenuAuthority = (data) => {
+ return service({
+ url: '/menu/addMenuAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 获取用户menu关联关系
+// @Produce application/json
+// @Param authorityId string
+// @Router /menu/getMenuAuthority [post]
+export const getMenuAuthority = (data) => {
+ return service({
+ url: '/menu/getMenuAuthority',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 删除menu
+// @Produce application/json
+// @Param ID float64
+// @Router /menu/deleteBaseMenu [post]
+export const deleteBaseMenu = (data) => {
+ return service({
+ url: '/menu/deleteBaseMenu',
+ method: 'post',
+ data
+ })
+}
+
+// @Summary 修改menu列表
+// @Produce application/json
+// @Param menu Object
+// @Router /menu/updateBaseMenu [post]
+export const updateBaseMenu = (data) => {
+ return service({
+ url: '/menu/updateBaseMenu',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getBaseMenuById [post]
+export const getBaseMenuById = (data) => {
+ return service({
+ url: '/menu/getBaseMenuById',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/sysDictionary.js b/src/api/sysDictionary.js
new file mode 100644
index 0000000..f5d6c86
--- /dev/null
+++ b/src/api/sysDictionary.js
@@ -0,0 +1,80 @@
+import service from '@/utils/request'
+// @Tags SysDictionary
+// @Summary 创建SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "创建SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/createSysDictionary [post]
+export const createSysDictionary = (data) => {
+ return service({
+ url: '/sysDictionary/createSysDictionary',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysDictionary
+// @Summary 删除SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "删除SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionary/deleteSysDictionary [delete]
+export const deleteSysDictionary = (data) => {
+ return service({
+ url: '/sysDictionary/deleteSysDictionary',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysDictionary
+// @Summary 更新SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "更新SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionary/updateSysDictionary [put]
+export const updateSysDictionary = (data) => {
+ return service({
+ url: '/sysDictionary/updateSysDictionary',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags SysDictionary
+// @Summary 用id查询SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "用id查询SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionary/findSysDictionary [get]
+export const findSysDictionary = (params) => {
+ return service({
+ url: '/sysDictionary/findSysDictionary',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysDictionary
+// @Summary 分页获取SysDictionary列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysDictionary列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/getSysDictionaryList [get]
+export const getSysDictionaryList = (params) => {
+ return service({
+ url: '/sysDictionary/getSysDictionaryList',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/sysDictionaryDetail.js b/src/api/sysDictionaryDetail.js
new file mode 100644
index 0000000..d4f8772
--- /dev/null
+++ b/src/api/sysDictionaryDetail.js
@@ -0,0 +1,80 @@
+import service from '@/utils/request'
+// @Tags SysDictionaryDetail
+// @Summary 创建SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "创建SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
+export const createSysDictionaryDetail = (data) => {
+ return service({
+ url: '/sysDictionaryDetail/createSysDictionaryDetail',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 删除SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
+export const deleteSysDictionaryDetail = (data) => {
+ return service({
+ url: '/sysDictionaryDetail/deleteSysDictionaryDetail',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 更新SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
+export const updateSysDictionaryDetail = (data) => {
+ return service({
+ url: '/sysDictionaryDetail/updateSysDictionaryDetail',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 用id查询SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
+export const findSysDictionaryDetail = (params) => {
+ return service({
+ url: '/sysDictionaryDetail/findSysDictionaryDetail',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 分页获取SysDictionaryDetail列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysDictionaryDetail列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
+export const getSysDictionaryDetailList = (params) => {
+ return service({
+ url: '/sysDictionaryDetail/getSysDictionaryDetailList',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/sysOperationRecord.js b/src/api/sysOperationRecord.js
new file mode 100644
index 0000000..4428c03
--- /dev/null
+++ b/src/api/sysOperationRecord.js
@@ -0,0 +1,48 @@
+import service from '@/utils/request'
+// @Tags SysOperationRecord
+// @Summary 删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
+export const deleteSysOperationRecord = (data) => {
+ return service({
+ url: '/sysOperationRecord/deleteSysOperationRecord',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysOperationRecord
+// @Summary 删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
+export const deleteSysOperationRecordByIds = (data) => {
+ return service({
+ url: '/sysOperationRecord/deleteSysOperationRecordByIds',
+ method: 'delete',
+ data
+ })
+}
+
+// @Tags SysOperationRecord
+// @Summary 分页获取SysOperationRecord列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysOperationRecord列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysOperationRecord/getSysOperationRecordList [get]
+export const getSysOperationRecordList = (params) => {
+ return service({
+ url: '/sysOperationRecord/getSysOperationRecordList',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/sysParams.js b/src/api/sysParams.js
new file mode 100644
index 0000000..348f1b5
--- /dev/null
+++ b/src/api/sysParams.js
@@ -0,0 +1,111 @@
+import service from '@/utils/request'
+// @Tags SysParams
+// @Summary 创建参数
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysParams true "创建参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /sysParams/createSysParams [post]
+export const createSysParams = (data) => {
+ return service({
+ url: '/sysParams/createSysParams',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags SysParams
+// @Summary 删除参数
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysParams true "删除参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysParams/deleteSysParams [delete]
+export const deleteSysParams = (params) => {
+ return service({
+ url: '/sysParams/deleteSysParams',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags SysParams
+// @Summary 批量删除参数
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysParams/deleteSysParams [delete]
+export const deleteSysParamsByIds = (params) => {
+ return service({
+ url: '/sysParams/deleteSysParamsByIds',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags SysParams
+// @Summary 更新参数
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysParams true "更新参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysParams/updateSysParams [put]
+export const updateSysParams = (data) => {
+ return service({
+ url: '/sysParams/updateSysParams',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags SysParams
+// @Summary 用id查询参数
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query model.SysParams true "用id查询参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysParams/findSysParams [get]
+export const findSysParams = (params) => {
+ return service({
+ url: '/sysParams/findSysParams',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysParams
+// @Summary 分页获取参数列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query request.PageInfo true "分页获取参数列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysParams/getSysParamsList [get]
+export const getSysParamsList = (params) => {
+ return service({
+ url: '/sysParams/getSysParamsList',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags SysParams
+// @Summary 不需要鉴权的参数接口
+// @accept application/json
+// @Produce application/json
+// @Param data query systemReq.SysParamsSearch true "分页获取参数列表"
+// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
+// @Router /sysParams/getSysParam [get]
+export const getSysParam = (params) => {
+ return service({
+ url: '/sysParams/getSysParam',
+ method: 'get',
+ params
+ })
+}
diff --git a/src/api/system.js b/src/api/system.js
new file mode 100644
index 0000000..9395519
--- /dev/null
+++ b/src/api/system.js
@@ -0,0 +1,55 @@
+import service from '@/utils/request'
+// @Tags systrm
+// @Summary 获取配置文件内容
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /system/getSystemConfig [post]
+export const getSystemConfig = () => {
+ return service({
+ url: '/system/getSystemConfig',
+ method: 'post'
+ })
+}
+
+// @Tags system
+// @Summary 设置配置文件内容
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param data body sysModel.System true
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /system/setSystemConfig [post]
+export const setSystemConfig = (data) => {
+ return service({
+ url: '/system/setSystemConfig',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags system
+// @Summary 获取服务器运行状态
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
+// @Router /system/getServerInfo [post]
+export const getSystemState = () => {
+ return service({
+ url: '/system/getServerInfo',
+ method: 'post',
+ donNotShowLoading: true
+ })
+}
+
+/**
+ * 重启服务
+ * @param data
+ * @returns {*}
+ */
+export const reloadSystem = (data) => {
+ return service({
+ url: '/system/reloadSystem',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/user.js b/src/api/user.js
new file mode 100644
index 0000000..2b357d0
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,181 @@
+import service from '@/utils/request'
+// @Summary 用户登录
+// @Produce application/json
+// @Param data body {username:"string",password:"string"}
+// @Router /base/login [post]
+export const login = (data) => {
+ return service({
+ url: '/base/login',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Summary 获取验证码
+// @Produce application/json
+// @Param data body {username:"string",password:"string"}
+// @Router /base/captcha [post]
+export const captcha = () => {
+ return service({
+ url: '/base/captcha',
+ method: 'post'
+ })
+}
+
+// @Summary 用户注册
+// @Produce application/json
+// @Param data body {username:"string",password:"string"}
+// @Router /base/resige [post]
+export const register = (data) => {
+ return service({
+ url: '/user/admin_register',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Summary 修改密码
+// @Produce application/json
+// @Param data body {username:"string",password:"string",newPassword:"string"}
+// @Router /user/changePassword [post]
+export const changePassword = (data) => {
+ return service({
+ url: '/user/changePassword',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Tags User
+// @Summary 分页获取用户列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /user/getUserList [post]
+export const getUserList = (data) => {
+ return service({
+ url: '/user/getUserList',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Tags User
+// @Summary 设置用户权限
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.SetUserAuth true "设置用户权限"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/setUserAuthority [post]
+export const setUserAuthority = (data) => {
+ return service({
+ url: '/user/setUserAuthority',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Tags SysUser
+// @Summary 删除用户
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SetUserAuth true "删除用户"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/deleteUser [delete]
+export const deleteUser = (data) => {
+ return service({
+ url: '/user/deleteUser',
+ method: 'delete',
+ data: data
+ })
+}
+
+// @Tags SysUser
+// @Summary 设置用户信息
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysUser true "设置用户信息"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/setUserInfo [put]
+export const setUserInfo = (data) => {
+ return service({
+ url: '/user/setUserInfo',
+ method: 'put',
+ data: data
+ })
+}
+
+// @Tags SysUser
+// @Summary 设置用户信息
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysUser true "设置用户信息"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/setSelfInfo [put]
+export const setSelfInfo = (data) => {
+ return service({
+ url: '/user/setSelfInfo',
+ method: 'put',
+ data: data
+ })
+}
+
+// @Tags SysUser
+// @Summary 设置自身界面配置
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysUser true "设置自身界面配置"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/setSelfSetting [put]
+export const setSelfSetting = (data) => {
+ return service({
+ url: '/user/setSelfSetting',
+ method: 'put',
+ data: data
+ })
+}
+
+// @Tags User
+// @Summary 设置用户权限
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.setUserAuthorities true "设置用户权限"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
+// @Router /user/setUserAuthorities [post]
+export const setUserAuthorities = (data) => {
+ return service({
+ url: '/user/setUserAuthorities',
+ method: 'post',
+ data: data
+ })
+}
+
+// @Tags User
+// @Summary 获取用户信息
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /user/getUserInfo [get]
+export const getUserInfo = () => {
+ return service({
+ url: '/user/getUserInfo',
+ method: 'get'
+ })
+}
+
+export const resetPassword = (data) => {
+ return service({
+ url: '/user/resetPassword',
+ method: 'post',
+ data: data
+ })
+}
diff --git a/src/assets/404.png b/src/assets/404.png
new file mode 100644
index 0000000..f803724
Binary files /dev/null and b/src/assets/404.png differ
diff --git a/src/assets/background.svg b/src/assets/background.svg
new file mode 100644
index 0000000..7375bb5
--- /dev/null
+++ b/src/assets/background.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/banner.jpg b/src/assets/banner.jpg
new file mode 100644
index 0000000..675411e
Binary files /dev/null and b/src/assets/banner.jpg differ
diff --git a/src/assets/banner2.jpg b/src/assets/banner2.jpg
new file mode 100644
index 0000000..62e08a4
Binary files /dev/null and b/src/assets/banner2.jpg differ
diff --git a/src/assets/dashboard.png b/src/assets/dashboard.png
new file mode 100644
index 0000000..64981d0
Binary files /dev/null and b/src/assets/dashboard.png differ
diff --git a/src/assets/docs.png b/src/assets/docs.png
new file mode 100644
index 0000000..bb98d6e
Binary files /dev/null and b/src/assets/docs.png differ
diff --git a/src/assets/flipped-aurora.png b/src/assets/flipped-aurora.png
new file mode 100644
index 0000000..c94033b
Binary files /dev/null and b/src/assets/flipped-aurora.png differ
diff --git a/src/assets/github.png b/src/assets/github.png
new file mode 100644
index 0000000..d1d200e
Binary files /dev/null and b/src/assets/github.png differ
diff --git a/src/assets/icons/ai-gva.svg b/src/assets/icons/ai-gva.svg
new file mode 100644
index 0000000..fcbea93
--- /dev/null
+++ b/src/assets/icons/ai-gva.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/customer-gva.svg b/src/assets/icons/customer-gva.svg
new file mode 100644
index 0000000..1e72201
--- /dev/null
+++ b/src/assets/icons/customer-gva.svg
@@ -0,0 +1 @@
+
diff --git a/src/assets/kefu.png b/src/assets/kefu.png
new file mode 100644
index 0000000..47cab15
Binary files /dev/null and b/src/assets/kefu.png differ
diff --git a/src/assets/login_background.jpg b/src/assets/login_background.jpg
new file mode 100644
index 0000000..e601f24
Binary files /dev/null and b/src/assets/login_background.jpg differ
diff --git a/src/assets/login_background.svg b/src/assets/login_background.svg
new file mode 100644
index 0000000..0a9514b
--- /dev/null
+++ b/src/assets/login_background.svg
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/src/assets/login_left.svg b/src/assets/login_left.svg
new file mode 100644
index 0000000..9c48b0b
--- /dev/null
+++ b/src/assets/login_left.svg
@@ -0,0 +1,123 @@
+
+
\ No newline at end of file
diff --git a/src/assets/login_right_banner.jpg b/src/assets/login_right_banner.jpg
new file mode 100644
index 0000000..0a597c1
Binary files /dev/null and b/src/assets/login_right_banner.jpg differ
diff --git a/src/assets/logo.jpg b/src/assets/logo.jpg
new file mode 100644
index 0000000..09502d5
Binary files /dev/null and b/src/assets/logo.jpg differ
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..b497ee0
Binary files /dev/null and b/src/assets/logo.png differ
diff --git a/src/assets/logo_login.png b/src/assets/logo_login.png
new file mode 100644
index 0000000..e330458
Binary files /dev/null and b/src/assets/logo_login.png differ
diff --git a/src/assets/nav_logo.png b/src/assets/nav_logo.png
new file mode 100644
index 0000000..468cdab
Binary files /dev/null and b/src/assets/nav_logo.png differ
diff --git a/src/assets/noBody.png b/src/assets/noBody.png
new file mode 100644
index 0000000..e16488e
Binary files /dev/null and b/src/assets/noBody.png differ
diff --git a/src/assets/notFound.png b/src/assets/notFound.png
new file mode 100644
index 0000000..59ca9f0
Binary files /dev/null and b/src/assets/notFound.png differ
diff --git a/src/assets/qm.png b/src/assets/qm.png
new file mode 100644
index 0000000..9f598ca
Binary files /dev/null and b/src/assets/qm.png differ
diff --git a/src/assets/video.png b/src/assets/video.png
new file mode 100644
index 0000000..af4d35f
Binary files /dev/null and b/src/assets/video.png differ
diff --git a/src/components/arrayCtrl/arrayCtrl.vue b/src/components/arrayCtrl/arrayCtrl.vue
new file mode 100644
index 0000000..1296cf7
--- /dev/null
+++ b/src/components/arrayCtrl/arrayCtrl.vue
@@ -0,0 +1,67 @@
+
+
+
+ {{ tag }}
+
+
+
+
+ + 新增
+
+
+
+
+
+
diff --git a/src/components/bottomInfo/bottomInfo.vue b/src/components/bottomInfo/bottomInfo.vue
new file mode 100644
index 0000000..376de05
--- /dev/null
+++ b/src/components/bottomInfo/bottomInfo.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
Powered by
+
+ Gin-Vue-Admin
+
+
+
+
+
Copyright
+
+ flipped-aurora团队
+
+
+
+
+
+
diff --git a/src/components/charts/index.vue b/src/components/charts/index.vue
new file mode 100644
index 0000000..0895434
--- /dev/null
+++ b/src/components/charts/index.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/commandMenu/index.vue b/src/components/commandMenu/index.vue
new file mode 100644
index 0000000..27ef93f
--- /dev/null
+++ b/src/components/commandMenu/index.vue
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+ {{ option.label }}
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/customPic/index.vue b/src/components/customPic/index.vue
new file mode 100644
index 0000000..6a265de
--- /dev/null
+++ b/src/components/customPic/index.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
diff --git a/src/components/exportExcel/exportExcel.vue b/src/components/exportExcel/exportExcel.vue
new file mode 100644
index 0000000..6c1189e
--- /dev/null
+++ b/src/components/exportExcel/exportExcel.vue
@@ -0,0 +1,75 @@
+
+ 导出
+
+
+
diff --git a/src/components/exportExcel/exportTemplate.vue b/src/components/exportExcel/exportTemplate.vue
new file mode 100644
index 0000000..dd77f95
--- /dev/null
+++ b/src/components/exportExcel/exportTemplate.vue
@@ -0,0 +1,40 @@
+
+ 下载模板
+
+
+
diff --git a/src/components/exportExcel/importExcel.vue b/src/components/exportExcel/importExcel.vue
new file mode 100644
index 0000000..cd3a7d9
--- /dev/null
+++ b/src/components/exportExcel/importExcel.vue
@@ -0,0 +1,45 @@
+
+
+ 导入
+
+
+
+
diff --git a/src/components/office/docx.vue b/src/components/office/docx.vue
new file mode 100644
index 0000000..e607d0b
--- /dev/null
+++ b/src/components/office/docx.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
diff --git a/src/components/office/excel.vue b/src/components/office/excel.vue
new file mode 100644
index 0000000..5b22f91
--- /dev/null
+++ b/src/components/office/excel.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
diff --git a/src/components/office/index.vue b/src/components/office/index.vue
new file mode 100644
index 0000000..d22d6da
--- /dev/null
+++ b/src/components/office/index.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/office/pdf.vue b/src/components/office/pdf.vue
new file mode 100644
index 0000000..2ca4363
--- /dev/null
+++ b/src/components/office/pdf.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/src/components/richtext/rich-edit.vue b/src/components/richtext/rich-edit.vue
new file mode 100644
index 0000000..151b7df
--- /dev/null
+++ b/src/components/richtext/rich-edit.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/richtext/rich-view.vue b/src/components/richtext/rich-view.vue
new file mode 100644
index 0000000..b1de744
--- /dev/null
+++ b/src/components/richtext/rich-view.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/selectFile/selectFile.vue b/src/components/selectFile/selectFile.vue
new file mode 100644
index 0000000..61bad6f
--- /dev/null
+++ b/src/components/selectFile/selectFile.vue
@@ -0,0 +1,87 @@
+
+
+
+ 上传文件
+
+
+
+
+
diff --git a/src/components/selectImage/selectComponent.vue b/src/components/selectImage/selectComponent.vue
new file mode 100644
index 0000000..18cc64a
--- /dev/null
+++ b/src/components/selectImage/selectComponent.vue
@@ -0,0 +1,86 @@
+
+
+
+
diff --git a/src/components/selectImage/selectImage.vue b/src/components/selectImage/selectImage.vue
new file mode 100644
index 0000000..b517601
--- /dev/null
+++ b/src/components/selectImage/selectImage.vue
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.name }}
+
+
+
+
+
+
+ 添加分类
+ 编辑分类
+ 删除分类
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
diff --git a/src/components/svgIcon/svgIcon.vue b/src/components/svgIcon/svgIcon.vue
new file mode 100644
index 0000000..a72a421
--- /dev/null
+++ b/src/components/svgIcon/svgIcon.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/components/upload/QR-code.vue b/src/components/upload/QR-code.vue
new file mode 100644
index 0000000..2a166c2
--- /dev/null
+++ b/src/components/upload/QR-code.vue
@@ -0,0 +1,65 @@
+
+
+ 扫码上传
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/upload/common.vue b/src/components/upload/common.vue
new file mode 100644
index 0000000..f3d1fa1
--- /dev/null
+++ b/src/components/upload/common.vue
@@ -0,0 +1,90 @@
+
+
+
+ 普通上传
+
+
+
+
+
diff --git a/src/components/upload/cropper.vue b/src/components/upload/cropper.vue
new file mode 100644
index 0000000..1506a8f
--- /dev/null
+++ b/src/components/upload/cropper.vue
@@ -0,0 +1,237 @@
+
+
+ 裁剪上传
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
裁剪预览
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/upload/image.vue b/src/components/upload/image.vue
new file mode 100644
index 0000000..0b0ae5e
--- /dev/null
+++ b/src/components/upload/image.vue
@@ -0,0 +1,102 @@
+
+
+
+ 压缩上传
+
+
+
+
+
+
+
diff --git a/src/components/warningBar/warningBar.vue b/src/components/warningBar/warningBar.vue
new file mode 100644
index 0000000..9d01881
--- /dev/null
+++ b/src/components/warningBar/warningBar.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
diff --git a/src/core/config.js b/src/core/config.js
new file mode 100644
index 0000000..4cb3892
--- /dev/null
+++ b/src/core/config.js
@@ -0,0 +1,53 @@
+/**
+ * 网站配置文件
+ */
+const greenText = (text) => `\x1b[32m${text}\x1b[0m`
+
+const config = {
+ appName: 'Lckt-Admin',
+ appLogo: 'logo.png',
+ showViteLogo: true,
+ logs: []
+}
+
+export const viteLogo = (env) => {
+ if (config.showViteLogo) {
+ console.log(
+ greenText(
+ `> 欢迎使用Gin-Vue-Admin,开源地址:https://github.com/flipped-aurora/gin-vue-admin`
+ )
+ )
+ console.log(greenText(`> 当前版本:v2.8.0`))
+ console.log(greenText(`> 加群方式:微信:shouzi_1994 QQ群:470239250`))
+ console.log(
+ greenText(`> 项目地址:https://github.com/flipped-aurora/gin-vue-admin`)
+ )
+ console.log(greenText(`> 插件市场:https://plugin.gin-vue-admin.com`))
+ console.log(
+ greenText(`> GVA讨论社区:https://support.qq.com/products/371961`)
+ )
+ console.log(
+ greenText(
+ `> 默认自动化文档地址:http://127.0.0.1:${env.VITE_SERVER_PORT}/swagger/index.html`
+ )
+ )
+ console.log(
+ greenText(`> 默认前端文件运行地址:http://127.0.0.1:${env.VITE_CLI_PORT}`)
+ )
+ console.log(
+ greenText(
+ `--------------------------------------版权声明--------------------------------------`
+ )
+ )
+ console.log(greenText(`** 版权所有方:flipped-aurora开源团队 **`))
+ console.log(greenText(`** 版权持有公司:北京翻转极光科技有限责任公司 **`))
+ console.log(
+ greenText(
+ `** 剔除授权标识需购买商用授权:https://gin-vue-admin.com/empower/index.html **`
+ )
+ )
+ console.log('\n')
+ }
+}
+
+export default config
diff --git a/src/core/gin-vue-admin.js b/src/core/gin-vue-admin.js
new file mode 100644
index 0000000..764da3f
--- /dev/null
+++ b/src/core/gin-vue-admin.js
@@ -0,0 +1,27 @@
+/*
+ * gin-vue-admin web框架组
+ *
+ * */
+// 加载网站配置文件夹
+import { register } from './global'
+
+export default {
+ install: (app) => {
+ register(app)
+ console.log(`
+ 欢迎使用 Gin-Vue-Admin
+ 当前版本:v2.8.0
+ 加群方式:微信:shouzi_1994 QQ群:622360840
+ 项目地址:https://github.com/flipped-aurora/gin-vue-admin
+ 插件市场:https://plugin.gin-vue-admin.com
+ GVA讨论社区:https://support.qq.com/products/371961
+ 默认自动化文档地址:http://127.0.0.1:${import.meta.env.VITE_SERVER_PORT}/swagger/index.html
+ 默认前端文件运行地址:http://127.0.0.1:${import.meta.env.VITE_CLI_PORT}
+ 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html
+ --------------------------------------版权声明--------------------------------------
+ ** 版权所有方:flipped-aurora开源团队 **
+ ** 版权持有公司:北京翻转极光科技有限责任公司 **
+ ** 剔除授权标识需购买商用授权:https://gin-vue-admin.com/empower/index.html **
+ `)
+ }
+}
diff --git a/src/core/global.js b/src/core/global.js
new file mode 100644
index 0000000..b402b70
--- /dev/null
+++ b/src/core/global.js
@@ -0,0 +1,59 @@
+import config from './config'
+import { h } from 'vue'
+
+// 统一导入el-icon图标
+import * as ElIconModules from '@element-plus/icons-vue'
+import svgIcon from '@/components/svgIcon/svgIcon.vue'
+// 导入转换图标名称的函数
+
+const createIconComponent = (name) => ({
+ name: 'SvgIcon',
+ render() {
+ return h(svgIcon, {
+ name: name
+ })
+ }
+})
+
+const registerIcons = async (app) => {
+ const iconModules = import.meta.glob('@/assets/icons/**/*.svg') // 系统目录 svg 图标
+ const pluginIconModules = import.meta.glob(
+ '@/plugin/**/assets/icons/**/*.svg'
+ ) // 插件目录 svg 图标
+ const mergedIconModules = Object.assign({}, iconModules, pluginIconModules) // 合并所有 svg 图标
+ for (const path in mergedIconModules) {
+ let pluginName = ''
+ if (path.startsWith('/src/plugin/')) {
+ pluginName = `${path.split('/')[3]}-`
+ }
+ const iconName = path
+ .split('/')
+ .pop()
+ .replace(/\.svg$/, '')
+ // 如果iconName带空格则不加入到图标库中并且提示名称不合法
+ if (iconName.indexOf(' ') !== -1) {
+ console.error(`icon ${iconName}.svg includes whitespace in ${path}`)
+ continue
+ }
+ const key = `${pluginName}${iconName}`
+ // 开发模式下列出所有 svg 图标,方便开发者直接查找复制使用
+ import.meta.env.MODE == 'development' &&
+ console.log(`svg-icon-component: <${key} />`)
+ const iconComponent = createIconComponent(key)
+ config.logs.push({
+ key: key,
+ label: key
+ })
+ app.component(key, iconComponent)
+ }
+}
+
+export const register = (app) => {
+ // 统一注册el-icon图标
+ for (const iconName in ElIconModules) {
+ app.component(iconName, ElIconModules[iconName])
+ }
+ app.component('SvgIcon', svgIcon)
+ registerIcons(app)
+ app.config.globalProperties.$GIN_VUE_ADMIN = config
+}
diff --git a/src/directive/auth.js b/src/directive/auth.js
new file mode 100644
index 0000000..d2b9b6a
--- /dev/null
+++ b/src/directive/auth.js
@@ -0,0 +1,40 @@
+// 权限按钮展示指令
+import { useUserStore } from '@/pinia/modules/user'
+export default {
+ install: (app) => {
+ const userStore = useUserStore()
+ app.directive('auth', {
+ // 当被绑定的元素插入到 DOM 中时……
+ mounted: function (el, binding) {
+ const userInfo = userStore.userInfo
+ let type = ''
+ switch (Object.prototype.toString.call(binding.value)) {
+ case '[object Array]':
+ type = 'Array'
+ break
+ case '[object String]':
+ type = 'String'
+ break
+ case '[object Number]':
+ type = 'Number'
+ break
+ default:
+ type = ''
+ break
+ }
+ if (type === '') {
+ el.parentNode.removeChild(el)
+ return
+ }
+ const waitUse = binding.value.toString().split(',')
+ let flag = waitUse.some((item) => Number(item) === userInfo.authorityId)
+ if (binding.modifiers.not) {
+ flag = !flag
+ }
+ if (!flag) {
+ el.parentNode.removeChild(el)
+ }
+ }
+ })
+ }
+}
diff --git a/src/hooks/charts.js b/src/hooks/charts.js
new file mode 100644
index 0000000..b7f7bb3
--- /dev/null
+++ b/src/hooks/charts.js
@@ -0,0 +1,18 @@
+// 本组件参考 arco-pro 的实现
+// https://github.com/arco-design/arco-design-pro-vue/blob/main/arco-design-pro-vite/src/hooks/chart-option.ts
+
+import { computed } from 'vue'
+import { useAppStore } from '@/pinia'
+
+export default function useChartOption(sourceOption) {
+ const appStore = useAppStore()
+ const isDark = computed(() => {
+ return appStore.isDark
+ })
+ const chartOption = computed(() => {
+ return sourceOption(isDark.value)
+ })
+ return {
+ chartOption
+ }
+}
diff --git a/src/hooks/responsive.js b/src/hooks/responsive.js
new file mode 100644
index 0000000..e324c16
--- /dev/null
+++ b/src/hooks/responsive.js
@@ -0,0 +1,35 @@
+// 本组件参考 arco-pro 的实现
+// https://github.com/arco-design/arco-design-pro-vue/blob/main/arco-design-pro-vite/src/hooks/responsive.ts
+
+import { onMounted, onBeforeMount, onBeforeUnmount } from 'vue'
+import { useDebounceFn } from '@vueuse/core'
+import { useAppStore } from '@/pinia'
+import { addEventListen, removeEventListen } from '@/utils/event'
+
+const WIDTH = 992
+
+function queryDevice() {
+ const rect = document.body.getBoundingClientRect()
+ return rect.width - 1 < WIDTH
+}
+
+export default function useResponsive(immediate) {
+ const appStore = useAppStore()
+ function resizeHandler() {
+ if (!document.hidden) {
+ const isMobile = queryDevice()
+ appStore.toggleDevice(isMobile ? 'mobile' : 'desktop')
+ // appStore.toggleDevice(isMobile);
+ }
+ }
+ const debounceFn = useDebounceFn(resizeHandler, 100)
+ onMounted(() => {
+ if (immediate) debounceFn()
+ })
+ onBeforeMount(() => {
+ addEventListen(window, 'resize', debounceFn)
+ })
+ onBeforeUnmount(() => {
+ removeEventListen(window, 'resize', debounceFn)
+ })
+}
diff --git a/src/hooks/use-windows-resize.js b/src/hooks/use-windows-resize.js
new file mode 100644
index 0000000..a3e1490
--- /dev/null
+++ b/src/hooks/use-windows-resize.js
@@ -0,0 +1,23 @@
+// 监听 window 的 resize 事件,返回当前窗口的宽高
+import { shallowRef } from 'vue'
+import { tryOnMounted, useEventListener } from '@vueuse/core'
+
+const width = shallowRef(0)
+const height = shallowRef(0)
+
+export const useWindowResize = (cb) => {
+ const onResize = () => {
+ width.value = window.innerWidth
+ height.value = window.innerHeight
+ if (cb && typeof cb === 'function') {
+ cb(width.value, height.value)
+ }
+ }
+
+ tryOnMounted(onResize)
+ useEventListener('resize', onResize, { passive: true })
+ return {
+ width,
+ height
+ }
+}
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..372b491
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,21 @@
+import './style/element_visiable.scss'
+import 'element-plus/theme-chalk/dark/css-vars.css'
+import { createApp } from 'vue'
+import ElementPlus from 'element-plus'
+
+import 'element-plus/dist/index.css'
+// 引入gin-vue-admin前端初始化相关内容
+import './core/gin-vue-admin'
+// 引入封装的router
+import router from '@/router/index'
+import '@/permission'
+import run from '@/core/gin-vue-admin.js'
+import auth from '@/directive/auth'
+import { store } from '@/pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+app.config.productionTip = false
+
+app.use(run).use(ElementPlus).use(store).use(auth).use(router).mount('#app')
+export default app
diff --git a/src/pathInfo.json b/src/pathInfo.json
new file mode 100644
index 0000000..8205a95
--- /dev/null
+++ b/src/pathInfo.json
@@ -0,0 +1,74 @@
+{
+ "/src/view/about/index.vue": "About",
+ "/src/view/bot/bot/bot.vue": "Bot",
+ "/src/view/bot/bot/botForm.vue": "BotForm",
+ "/src/view/category/category/category.vue": "Category",
+ "/src/view/category/category/categoryForm.vue": "CategoryForm",
+ "/src/view/dashboard/components/banner.vue": "Banner",
+ "/src/view/dashboard/components/card.vue": "Card",
+ "/src/view/dashboard/components/charts-content-numbers.vue": "ChartsContentNumbers",
+ "/src/view/dashboard/components/charts-people-numbers.vue": "ChartsPeopleNumbers",
+ "/src/view/dashboard/components/charts.vue": "Charts",
+ "/src/view/dashboard/components/notice.vue": "Notice",
+ "/src/view/dashboard/components/pluginTable.vue": "PluginTable",
+ "/src/view/dashboard/components/quickLinks.vue": "QuickLinks",
+ "/src/view/dashboard/components/table.vue": "Table",
+ "/src/view/dashboard/components/wiki.vue": "Wiki",
+ "/src/view/dashboard/index.vue": "Dashboard",
+ "/src/view/error/index.vue": "Error",
+ "/src/view/error/reload.vue": "Reload",
+ "/src/view/example/breakpoint/breakpoint.vue": "BreakPoint",
+ "/src/view/example/customer/customer.vue": "Customer",
+ "/src/view/example/index.vue": "Example",
+ "/src/view/example/upload/scanUpload.vue": "scanUpload",
+ "/src/view/example/upload/upload.vue": "Upload",
+ "/src/view/init/index.vue": "Init",
+ "/src/view/layout/aside/asideComponent/asyncSubmenu.vue": "AsyncSubmenu",
+ "/src/view/layout/aside/asideComponent/index.vue": "AsideComponent",
+ "/src/view/layout/aside/asideComponent/menuItem.vue": "MenuItem",
+ "/src/view/layout/aside/combinationMode.vue": "GvaAside",
+ "/src/view/layout/aside/headMode.vue": "GvaAside",
+ "/src/view/layout/aside/index.vue": "Index",
+ "/src/view/layout/aside/normalMode.vue": "GvaAside",
+ "/src/view/layout/header/index.vue": "Index",
+ "/src/view/layout/header/tools.vue": "Tools",
+ "/src/view/layout/iframe.vue": "GvaLayoutIframe",
+ "/src/view/layout/index.vue": "GvaLayout",
+ "/src/view/layout/screenfull/index.vue": "Screenfull",
+ "/src/view/layout/search/search.vue": "BtnBox",
+ "/src/view/layout/setting/index.vue": "GvaSetting",
+ "/src/view/layout/setting/title.vue": "layoutSettingTitle",
+ "/src/view/layout/tabs/index.vue": "HistoryComponent",
+ "/src/view/login/index.vue": "Login",
+ "/src/view/person/person.vue": "Person",
+ "/src/view/routerHolder.vue": "RouterHolder",
+ "/src/view/superAdmin/api/api.vue": "Api",
+ "/src/view/superAdmin/authority/authority.vue": "Authority",
+ "/src/view/superAdmin/authority/components/apis.vue": "Apis",
+ "/src/view/superAdmin/authority/components/datas.vue": "Datas",
+ "/src/view/superAdmin/authority/components/menus.vue": "Menus",
+ "/src/view/superAdmin/dictionary/sysDictionary.vue": "SysDictionary",
+ "/src/view/superAdmin/dictionary/sysDictionaryDetail.vue": "SysDictionaryDetail",
+ "/src/view/superAdmin/index.vue": "SuperAdmin",
+ "/src/view/superAdmin/menu/components/components-cascader.vue": "ComponentsCascader",
+ "/src/view/superAdmin/menu/icon.vue": "Icon",
+ "/src/view/superAdmin/menu/menu.vue": "Menus",
+ "/src/view/superAdmin/operation/sysOperationRecord.vue": "SysOperationRecord",
+ "/src/view/superAdmin/params/sysParams.vue": "SysParams",
+ "/src/view/superAdmin/user/user.vue": "User",
+ "/src/view/system/state.vue": "State",
+ "/src/view/systemTools/autoCode/component/fieldDialog.vue": "FieldDialog",
+ "/src/view/systemTools/autoCode/component/previewCodeDialog.vue": "PreviewCodeDialog",
+ "/src/view/systemTools/autoCode/index.vue": "AutoCode",
+ "/src/view/systemTools/autoCodeAdmin/index.vue": "AutoCodeAdmin",
+ "/src/view/systemTools/autoPkg/autoPkg.vue": "AutoPkg",
+ "/src/view/systemTools/exportTemplate/exportTemplate.vue": "ExportTemplate",
+ "/src/view/systemTools/formCreate/index.vue": "FormGenerator",
+ "/src/view/systemTools/index.vue": "System",
+ "/src/view/systemTools/installPlugin/index.vue": "Index",
+ "/src/view/systemTools/pubPlug/pubPlug.vue": "PubPlug",
+ "/src/view/systemTools/system/system.vue": "Config",
+ "/src/plugin/announcement/form/info.vue": "InfoForm",
+ "/src/plugin/announcement/view/info.vue": "Info",
+ "/src/plugin/email/view/index.vue": "Email"
+}
\ No newline at end of file
diff --git a/src/permission.js b/src/permission.js
new file mode 100644
index 0000000..3b48995
--- /dev/null
+++ b/src/permission.js
@@ -0,0 +1,147 @@
+import { useUserStore } from '@/pinia/modules/user'
+import { useRouterStore } from '@/pinia/modules/router'
+import getPageTitle from '@/utils/page'
+import router from '@/router'
+import Nprogress from 'nprogress'
+import 'nprogress/nprogress.css'
+
+// 配置 NProgress
+Nprogress.configure({
+ showSpinner: false,
+ ease: 'ease',
+ speed: 500
+})
+
+// 白名单路由
+const WHITE_LIST = ['Login', 'Init']
+
+// 处理路由加载
+const setupRouter = async (userStore) => {
+ try {
+ const routerStore = useRouterStore()
+ await Promise.all([routerStore.SetAsyncRouter(), userStore.GetUserInfo()])
+
+ routerStore.asyncRouters.forEach((route) => router.addRoute(route))
+ return true
+ } catch (error) {
+ console.error('Setup router failed:', error)
+ return false
+ }
+}
+
+// 移除加载动画
+const removeLoading = () => {
+ const element = document.getElementById('gva-loading-box')
+ element?.remove()
+}
+
+// 处理组件缓存
+const handleKeepAlive = async (to) => {
+ if (!to.matched.some((item) => item.meta.keepAlive)) return
+
+ if (to.matched?.length > 2) {
+ for (let i = 1; i < to.matched.length; i++) {
+ const element = to.matched[i - 1]
+
+ if (element.name === 'layout') {
+ to.matched.splice(i, 1)
+ await handleKeepAlive(to)
+ continue
+ }
+
+ if (typeof element.components.default === 'function') {
+ await element.components.default()
+ await handleKeepAlive(to)
+ }
+ }
+ }
+}
+
+// 处理路由重定向
+const handleRedirect = (to, userStore) => {
+ if (router.hasRoute(userStore.userInfo.authority.defaultRouter)) {
+ return { ...to, replace: true }
+ }
+ return { path: '/layout/404' }
+}
+
+// 路由守卫
+router.beforeEach(async (to, from) => {
+ const userStore = useUserStore()
+ const routerStore = useRouterStore()
+ const token = userStore.token
+
+ Nprogress.start()
+
+ // 处理元数据和缓存
+ to.meta.matched = [...to.matched]
+ await handleKeepAlive(to)
+
+ // 设置页面标题
+ document.title = getPageTitle(to.meta.title, to)
+
+ if (to.meta.client) {
+ return true
+ }
+
+ // 白名单路由处理
+ if (WHITE_LIST.includes(to.name)) {
+ if (token) {
+ if(!routerStore.asyncRouterFlag){
+ await setupRouter(userStore)
+ }
+ if(userStore.userInfo.authority.defaultRouter){
+ return { name: userStore.userInfo.authority.defaultRouter }
+ }
+ }
+ return true
+ }
+
+ // 需要登录的路由处理
+ if (token) {
+ // 处理需要跳转到首页的情况
+ if (sessionStorage.getItem('needToHome') === 'true') {
+ sessionStorage.removeItem('needToHome')
+ return { path: '/' }
+ }
+
+ // 处理异步路由
+ if (!routerStore.asyncRouterFlag && !WHITE_LIST.includes(from.name)) {
+ const setupSuccess = await setupRouter(userStore)
+
+ if (setupSuccess && userStore.token) {
+ return handleRedirect(to, userStore)
+ }
+
+ return {
+ name: 'Login',
+ query: { redirect: to.href }
+ }
+ }
+
+ return to.matched.length ? true : { path: '/layout/404' }
+ }
+
+ // 未登录跳转登录页
+ return {
+ name: 'Login',
+ query: {
+ redirect: document.location.hash
+ }
+ }
+})
+
+// 路由加载完成
+router.afterEach(() => {
+ document.querySelector('.main-cont.main-right')?.scrollTo(0, 0)
+ Nprogress.done()
+})
+
+// 路由错误处理
+router.onError((error) => {
+ console.error('Router error:', error)
+ Nprogress.remove()
+})
+
+// 移除初始加载动画
+removeLoading()
diff --git a/src/pinia/index.js b/src/pinia/index.js
new file mode 100644
index 0000000..85e45e8
--- /dev/null
+++ b/src/pinia/index.js
@@ -0,0 +1,8 @@
+import { createPinia } from 'pinia'
+import { useAppStore } from '@/pinia/modules/app'
+import { useUserStore } from '@/pinia/modules/user'
+import { useDictionaryStore } from '@/pinia/modules/dictionary'
+
+const store = createPinia()
+
+export { store, useAppStore, useUserStore, useDictionaryStore }
diff --git a/src/pinia/modules/app.js b/src/pinia/modules/app.js
new file mode 100644
index 0000000..8b32235
--- /dev/null
+++ b/src/pinia/modules/app.js
@@ -0,0 +1,133 @@
+import { defineStore } from 'pinia'
+import { ref, watchEffect, reactive } from 'vue'
+import { setBodyPrimaryColor } from '@/utils/format'
+import { useDark, usePreferredDark } from '@vueuse/core'
+
+export const useAppStore = defineStore('app', () => {
+ const device = ref('')
+ const drawerSize = ref('')
+ const operateMinWith = ref('240')
+ const config = reactive({
+ weakness: false,
+ grey: false,
+ primaryColor: '#3b82f6',
+ showTabs: true,
+ darkMode: 'auto',
+ layout_side_width: 256,
+ layout_side_collapsed_width: 80,
+ layout_side_item_height: 48,
+ show_watermark: true,
+ side_mode: 'normal',
+ // 页面过渡动画配置
+ transition_type: 'slide'
+ })
+
+ const isDark = useDark({
+ selector: 'html',
+ attribute: 'class',
+ valueDark: 'dark',
+ valueLight: 'light'
+ })
+
+ const preferredDark = usePreferredDark()
+
+ const toggleTheme = (darkMode) => {
+ isDark.value = darkMode
+ }
+
+ const toggleWeakness = (e) => {
+ config.weakness = e
+ }
+
+ const toggleGrey = (e) => {
+ config.grey = e
+ }
+
+ const togglePrimaryColor = (e) => {
+ config.primaryColor = e
+ }
+
+ const toggleTabs = (e) => {
+ config.showTabs = e
+ }
+
+ const toggleDevice = (e) => {
+ if (e === 'mobile') {
+ drawerSize.value = '100%'
+ operateMinWith.value = '80'
+ } else {
+ drawerSize.value = '800'
+ operateMinWith.value = '240'
+ }
+ device.value = e
+ }
+
+ const toggleDarkMode = (e) => {
+ config.darkMode = e
+ }
+
+ // 监听系统主题变化
+ watchEffect(() => {
+ if (config.darkMode === 'auto') {
+ isDark.value = preferredDark.value
+ return
+ }
+ isDark.value = config.darkMode === 'dark'
+ })
+
+ const toggleConfigSideWidth = (e) => {
+ config.layout_side_width = e
+ }
+
+ const toggleConfigSideCollapsedWidth = (e) => {
+ config.layout_side_collapsed_width = e
+ }
+
+ const toggleConfigSideItemHeight = (e) => {
+ config.layout_side_item_height = e
+ }
+
+ const toggleConfigWatermark = (e) => {
+ config.show_watermark = e
+ }
+
+ const toggleSideMode = (e) => {
+ config.side_mode = e
+ }
+
+ const toggleTransition = (e) => {
+ config.transition_type = e
+ }
+
+ // 监听色弱模式和灰色模式
+ watchEffect(() => {
+ document.documentElement.classList.toggle('html-weakenss', config.weakness)
+ document.documentElement.classList.toggle('html-grey', config.grey)
+ })
+
+ // 监听主题色
+ watchEffect(() => {
+ setBodyPrimaryColor(config.primaryColor, isDark.value ? 'dark' : 'light')
+ })
+
+ return {
+ isDark,
+ device,
+ drawerSize,
+ operateMinWith,
+ config,
+ toggleTheme,
+ toggleDevice,
+ toggleWeakness,
+ toggleGrey,
+ togglePrimaryColor,
+ toggleTabs,
+ toggleDarkMode,
+ toggleConfigSideWidth,
+ toggleConfigSideCollapsedWidth,
+ toggleConfigSideItemHeight,
+ toggleConfigWatermark,
+ toggleSideMode,
+ toggleTransition
+ }
+})
diff --git a/src/pinia/modules/dictionary.js b/src/pinia/modules/dictionary.js
new file mode 100644
index 0000000..57a2844
--- /dev/null
+++ b/src/pinia/modules/dictionary.js
@@ -0,0 +1,41 @@
+import { findSysDictionary } from '@/api/sysDictionary'
+
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useDictionaryStore = defineStore('dictionary', () => {
+ const dictionaryMap = ref({})
+
+ const setDictionaryMap = (dictionaryRes) => {
+ dictionaryMap.value = { ...dictionaryMap.value, ...dictionaryRes }
+ }
+
+ const getDictionary = async (type) => {
+ if (dictionaryMap.value[type] && dictionaryMap.value[type].length) {
+ return dictionaryMap.value[type]
+ } else {
+ const res = await findSysDictionary({ type })
+ if (res.code === 0) {
+ const dictionaryRes = {}
+ const dict = []
+ res.data.resysDictionary.sysDictionaryDetails &&
+ res.data.resysDictionary.sysDictionaryDetails.forEach((item) => {
+ dict.push({
+ label: item.label,
+ value: item.value,
+ extend: item.extend
+ })
+ })
+ dictionaryRes[res.data.resysDictionary.type] = dict
+ setDictionaryMap(dictionaryRes)
+ return dictionaryMap.value[type]
+ }
+ }
+ }
+
+ return {
+ dictionaryMap,
+ setDictionaryMap,
+ getDictionary
+ }
+})
diff --git a/src/pinia/modules/params.js b/src/pinia/modules/params.js
new file mode 100644
index 0000000..54cdbf9
--- /dev/null
+++ b/src/pinia/modules/params.js
@@ -0,0 +1,31 @@
+import { getSysParam } from '@/api/sysParams'
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useParamsStore = defineStore('params', () => {
+ const paramsMap = ref({})
+
+ const setParamsMap = (paramsRes) => {
+ paramsMap.value = { ...paramsMap.value, ...paramsRes }
+ }
+
+ const getParams = async(key) => {
+ if (paramsMap.value[key] && paramsMap.value[key].length) {
+ return paramsMap.value[key]
+ } else {
+ const res = await getSysParam({ key })
+ if (res.code === 0) {
+ const paramsRes = {}
+ paramsRes[key] = res.data.value
+ setParamsMap(paramsRes)
+ return paramsMap.value[key]
+ }
+ }
+ }
+
+ return {
+ paramsMap,
+ setParamsMap,
+ getParams
+ }
+})
diff --git a/src/pinia/modules/router.js b/src/pinia/modules/router.js
new file mode 100644
index 0000000..33ebbc9
--- /dev/null
+++ b/src/pinia/modules/router.js
@@ -0,0 +1,144 @@
+import { asyncRouterHandle } from '@/utils/asyncRouter'
+import { emitter } from '@/utils/bus.js'
+import { asyncMenu } from '@/api/menu'
+import { defineStore } from 'pinia'
+import { ref, watchEffect } from 'vue'
+import pathInfo from '@/pathInfo.json'
+
+const notLayoutRouterArr = []
+const keepAliveRoutersArr = []
+const nameMap = {}
+
+const formatRouter = (routes, routeMap, parent) => {
+ routes &&
+ routes.forEach((item) => {
+ item.parent = parent
+ item.meta.btns = item.btns
+ item.meta.hidden = item.hidden
+ if (item.meta.defaultMenu === true) {
+ if (!parent) {
+ item = { ...item, path: `/${item.path}` }
+ notLayoutRouterArr.push(item)
+ }
+ }
+ routeMap[item.name] = item
+ if (item.children && item.children.length > 0) {
+ formatRouter(item.children, routeMap, item)
+ }
+ })
+}
+
+const KeepAliveFilter = (routes) => {
+ routes &&
+ routes.forEach((item) => {
+ // 子菜单中有 keep-alive 的,父菜单也必须 keep-alive,否则无效。这里将子菜单中有 keep-alive 的父菜单也加入。
+ if (
+ (item.children && item.children.some((ch) => ch.meta.keepAlive)) ||
+ item.meta.keepAlive
+ ) {
+ const path = item.meta.path
+ keepAliveRoutersArr.push(pathInfo[path])
+ nameMap[item.name] = pathInfo[path]
+ }
+ if (item.children && item.children.length > 0) {
+ KeepAliveFilter(item.children)
+ }
+ })
+}
+
+export const useRouterStore = defineStore('router', () => {
+ const keepAliveRouters = ref([])
+ const asyncRouterFlag = ref(0)
+ const setKeepAliveRouters = (history) => {
+ const keepArrTemp = []
+ history.forEach((item) => {
+ if (nameMap[item.name]) {
+ keepArrTemp.push(nameMap[item.name])
+ }
+ })
+ keepAliveRouters.value = Array.from(new Set(keepArrTemp))
+ }
+ emitter.on('setKeepAlive', setKeepAliveRouters)
+
+ const asyncRouters = ref([])
+
+ const topMenu = ref([])
+
+ const leftMenu = ref([])
+
+ const menuMap = {}
+
+ const topActive = ref('')
+
+ const setLeftMenu = (name) => {
+ sessionStorage.setItem('topActive', name)
+ topActive.value = name
+ leftMenu.value = []
+ if (menuMap[name]?.children) {
+ leftMenu.value = menuMap[name].children
+ }
+ return menuMap[name]?.children
+ }
+
+ watchEffect(() => {
+ let topActive = sessionStorage.getItem('topActive')
+ asyncRouters.value[0]?.children.forEach((item) => {
+ if (item.hidden) return
+ menuMap[item.name] = item
+ topMenu.value.push({ ...item, children: [] })
+ })
+
+ setLeftMenu(topActive)
+ })
+
+ const routeMap = {}
+ // 从后台获取动态路由
+ const SetAsyncRouter = async () => {
+ asyncRouterFlag.value++
+ const baseRouter = [
+ {
+ path: '/layout',
+ name: 'layout',
+ component: 'view/layout/index.vue',
+ meta: {
+ title: '底层layout'
+ },
+ children: []
+ }
+ ]
+ const asyncRouterRes = await asyncMenu()
+ const asyncRouter = asyncRouterRes.data.menus
+ asyncRouter &&
+ asyncRouter.push({
+ path: 'reload',
+ name: 'Reload',
+ hidden: true,
+ meta: {
+ title: '',
+ closeTab: true
+ },
+ component: 'view/error/reload.vue'
+ })
+ formatRouter(asyncRouter, routeMap)
+ baseRouter[0].children = asyncRouter
+ if (notLayoutRouterArr.length !== 0) {
+ baseRouter.push(...notLayoutRouterArr)
+ }
+ asyncRouterHandle(baseRouter)
+ KeepAliveFilter(asyncRouter)
+ asyncRouters.value = baseRouter
+ return true
+ }
+
+ return {
+ topActive,
+ setLeftMenu,
+ topMenu,
+ leftMenu,
+ asyncRouters,
+ keepAliveRouters,
+ asyncRouterFlag,
+ SetAsyncRouter,
+ routeMap
+ }
+})
diff --git a/src/pinia/modules/user.js b/src/pinia/modules/user.js
new file mode 100644
index 0000000..b103ec7
--- /dev/null
+++ b/src/pinia/modules/user.js
@@ -0,0 +1,144 @@
+import { login, getUserInfo } from '@/api/user'
+import { jsonInBlacklist } from '@/api/jwt'
+import router from '@/router/index'
+import { ElLoading, ElMessage } from 'element-plus'
+import { defineStore } from 'pinia'
+import { ref, computed } from 'vue'
+import { useRouterStore } from './router'
+import { useCookies } from '@vueuse/integrations/useCookies'
+import { useStorage } from '@vueuse/core'
+
+import { useAppStore } from '@/pinia'
+
+export const useUserStore = defineStore('user', () => {
+ const appStore = useAppStore()
+ const loadingInstance = ref(null)
+
+ const userInfo = ref({
+ uuid: '',
+ nickName: '',
+ headerImg: '',
+ authority: {}
+ })
+ const token = useStorage('token', '')
+ const xToken = useCookies('x-token')
+ const currentToken = computed(() => token.value || xToken.value || '')
+
+ const setUserInfo = (val) => {
+ userInfo.value = val
+ if (val.originSetting) {
+ Object.keys(appStore.config).forEach((key) => {
+ if (val.originSetting[key] !== undefined) {
+ appStore.config[key] = val.originSetting[key]
+ }
+ })
+ }
+ console.log(appStore.config)
+ }
+
+ const setToken = (val) => {
+ token.value = val
+ xToken.value = val
+ }
+
+ const NeedInit = async () => {
+ await ClearStorage()
+ await router.push({ name: 'Init', replace: true })
+ }
+
+ const ResetUserInfo = (value = {}) => {
+ userInfo.value = {
+ ...userInfo.value,
+ ...value
+ }
+ }
+ /* 获取用户信息*/
+ const GetUserInfo = async () => {
+ const res = await getUserInfo()
+ if (res.code === 0) {
+ setUserInfo(res.data.userInfo)
+ }
+ return res
+ }
+ /* 登录*/
+ const LoginIn = async (loginInfo) => {
+ try {
+ loadingInstance.value = ElLoading.service({
+ fullscreen: true,
+ text: '登录中,请稍候...'
+ })
+
+ const res = await login(loginInfo)
+
+ if (res.code !== 0) {
+ ElMessage.error(res.message || '登录失败')
+ return false
+ }
+ // 登陆成功,设置用户信息和权限相关信息
+ setUserInfo(res.data.user)
+ setToken(res.data.token)
+
+ // 初始化路由信息
+ const routerStore = useRouterStore()
+ await routerStore.SetAsyncRouter()
+ const asyncRouters = routerStore.asyncRouters
+
+ // 注册到路由表里
+ asyncRouters.forEach((asyncRouter) => {
+ router.addRoute(asyncRouter)
+ })
+
+ if (!router.hasRoute(userInfo.value.authority.defaultRouter)) {
+ ElMessage.error('请联系管理员进行授权')
+ } else {
+ await router.replace({ name: userInfo.value.authority.defaultRouter })
+ }
+
+ const isWindows = /windows/i.test(navigator.userAgent)
+ window.localStorage.setItem('osType', isWindows ? 'WIN' : 'MAC')
+
+ // 全部操作均结束,关闭loading并返回
+ return true
+ } catch (error) {
+ console.error('LoginIn error:', error)
+ return false
+ } finally {
+ loadingInstance.value?.close()
+ }
+ }
+ /* 登出*/
+ const LoginOut = async () => {
+ const res = await jsonInBlacklist()
+
+ // 登出失败
+ if (res.code !== 0) {
+ return
+ }
+
+ await ClearStorage()
+
+ // 把路由定向到登录页,无需等待直接reload
+ router.push({ name: 'Login', replace: true })
+ window.location.reload()
+ }
+ /* 清理数据 */
+ const ClearStorage = async () => {
+ token.value = ''
+ xToken.value = ''
+ sessionStorage.clear()
+ localStorage.removeItem('originSetting')
+ }
+
+ return {
+ userInfo,
+ token: currentToken,
+ NeedInit,
+ ResetUserInfo,
+ GetUserInfo,
+ LoginIn,
+ LoginOut,
+ setToken,
+ loadingInstance,
+ ClearStorage
+ }
+})
diff --git a/src/plugin/announcement/api/info.js b/src/plugin/announcement/api/info.js
new file mode 100644
index 0000000..e19770b
--- /dev/null
+++ b/src/plugin/announcement/api/info.js
@@ -0,0 +1,110 @@
+import service from '@/utils/request'
+
+// @Tags Info
+// @Summary 创建公告
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.Info true "创建公告"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /info/createInfo [post]
+export const createInfo = (data) => {
+ return service({
+ url: '/info/createInfo',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags Info
+// @Summary 删除公告
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.Info true "删除公告"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /info/deleteInfo [delete]
+export const deleteInfo = (params) => {
+ return service({
+ url: '/info/deleteInfo',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Info
+// @Summary 批量删除公告
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除公告"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /info/deleteInfo [delete]
+export const deleteInfoByIds = (params) => {
+ return service({
+ url: '/info/deleteInfoByIds',
+ method: 'delete',
+ params
+ })
+}
+
+// @Tags Info
+// @Summary 更新公告
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.Info true "更新公告"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /info/updateInfo [put]
+export const updateInfo = (data) => {
+ return service({
+ url: '/info/updateInfo',
+ method: 'put',
+ data
+ })
+}
+
+// @Tags Info
+// @Summary 用id查询公告
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query model.Info true "用id查询公告"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /info/findInfo [get]
+export const findInfo = (params) => {
+ return service({
+ url: '/info/findInfo',
+ method: 'get',
+ params
+ })
+}
+
+// @Tags Info
+// @Summary 分页获取公告列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data query request.PageInfo true "分页获取公告列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /info/getInfoList [get]
+export const getInfoList = (params) => {
+ return service({
+ url: '/info/getInfoList',
+ method: 'get',
+ params
+ })
+}
+// @Tags Info
+// @Summary 获取数据源
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /info/findInfoDataSource [get]
+export const getInfoDataSource = () => {
+ return service({
+ url: '/info/getInfoDataSource',
+ method: 'get'
+ })
+}
diff --git a/src/plugin/announcement/form/info.vue b/src/plugin/announcement/form/info.vue
new file mode 100644
index 0000000..9824048
--- /dev/null
+++ b/src/plugin/announcement/form/info.vue
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 返回
+
+
+
+
+
+
+
+
+
diff --git a/src/plugin/announcement/view/info.vue b/src/plugin/announcement/view/info.vue
new file mode 100644
index 0000000..a684e97
--- /dev/null
+++ b/src/plugin/announcement/view/info.vue
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+
+ 创建日期
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+
+
+ 查询
+
+ 重置
+
+ 展开
+
+
+ 收起
+
+
+
+
+
+
+
+ 新增
+
+
+ 删除
+
+
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+
+ {{
+ filterDataSource(dataSource.userID, scope.row.userID)
+ }}
+
+
+
+
+
+
+ {{ file.name }}
+
+
+
+
+
+
+
+ 变更
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
{{ type === 'create' ? '添加' : '修改' }}
+
+ 确 定
+ 取 消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugin/email/api/email.js b/src/plugin/email/api/email.js
new file mode 100644
index 0000000..c3f6c7b
--- /dev/null
+++ b/src/plugin/email/api/email.js
@@ -0,0 +1,29 @@
+import service from '@/utils/request'
+// @Tags System
+// @Summary 发送测试邮件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
+// @Router /email/emailTest [post]
+export const emailTest = (data) => {
+ return service({
+ url: '/email/emailTest',
+ method: 'post',
+ data
+ })
+}
+
+// @Tags System
+// @Summary 发送邮件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param data body email_response.Email true "发送邮件必须的参数"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
+// @Router /email/sendEmail [post]
+export const sendEmail = (data) => {
+ return service({
+ url: '/email/sendEmail',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/plugin/email/view/index.vue b/src/plugin/email/view/index.vue
new file mode 100644
index 0000000..188c45b
--- /dev/null
+++ b/src/plugin/email/view/index.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 发送测试邮件
+ 发送邮件
+
+
+
+
+
+
+
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..4181603
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,41 @@
+import { createRouter, createWebHashHistory } from 'vue-router'
+
+const routes = [
+ {
+ path: '/',
+ redirect: '/login'
+ },
+ {
+ path: '/init',
+ name: 'Init',
+ component: () => import('@/view/init/index.vue')
+ },
+ {
+ path: '/login',
+ name: 'Login',
+ component: () => import('@/view/login/index.vue')
+ },
+ {
+ path: '/scanUpload',
+ name: 'ScanUpload',
+ meta: {
+ title: '扫码上传',
+ client: true
+ },
+ component: () => import('@/view/example/upload/scanUpload.vue')
+ },
+ {
+ path: '/:catchAll(.*)',
+ meta: {
+ closeTab: true
+ },
+ component: () => import('@/view/error/index.vue')
+ },
+]
+
+const router = createRouter({
+ history: createWebHashHistory(),
+ routes
+})
+
+export default router
diff --git a/src/style/element/index.scss b/src/style/element/index.scss
new file mode 100644
index 0000000..0c2de8d
--- /dev/null
+++ b/src/style/element/index.scss
@@ -0,0 +1,24 @@
+@forward 'element-plus/theme-chalk/src/common/var.scss' with (
+ $colors: (
+ 'white': #ffffff,
+ 'black': #000000,
+ 'primary': (
+ 'base': #4d70ff
+ ),
+ 'success': (
+ 'base': #67c23a
+ ),
+ 'warning': (
+ 'base': #e6a23c
+ ),
+ 'danger': (
+ 'base': #f56c6c
+ ),
+ 'error': (
+ 'base': #f56c6c
+ ),
+ 'info': (
+ 'base': #909399
+ )
+ )
+);
diff --git a/src/style/element_visiable.scss b/src/style/element_visiable.scss
new file mode 100644
index 0000000..4d33aef
--- /dev/null
+++ b/src/style/element_visiable.scss
@@ -0,0 +1,136 @@
+@use '@/style/main.scss';
+@use '@/style/reset';
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.el-button {
+ font-weight: 400;
+ border-radius: 2px;
+}
+
+.gva-pagination {
+ @apply flex justify-end;
+ .el-pagination__editor {
+ .el-input__inner {
+ @apply h-8;
+ }
+ }
+
+ .is-active {
+ @apply rounded text-white;
+ background: var(--el-color-primary);
+ color: #ffffff !important;
+ }
+}
+
+.el-drawer__header {
+ margin-bottom: 0 !important;
+ padding-top: 16px !important;
+ padding-bottom: 16px !important;
+ @apply border-0 border-b border-solid border-gray-200;
+}
+
+.el-form--inline {
+ .el-form-item {
+ & > .el-input,
+ .el-cascader,
+ .el-select,
+ .el-date-editor,
+ .el-autocomplete {
+ @apply w-52;
+ }
+ }
+}
+
+.el-dropdown {
+ @apply overflow-hidden;
+}
+
+.el-table {
+ tr {
+ th {
+ @apply dark:bg-slate-900;
+ .cell {
+ @apply leading-[36px] text-gray-700 dark:text-gray-200;
+ }
+ }
+ }
+ .el-table__row {
+ td {
+ @apply dark:bg-slate-900;
+ .cell {
+ @apply leading-[32px] text-gray-600 dark:text-gray-300;
+ }
+ }
+ }
+ tr {
+ th {
+ &.is-leaf {
+ @apply dark:bg-slate-900;
+ }
+ }
+ }
+}
+
+// layout
+
+// table
+.el-pagination {
+ @apply mt-8;
+ .btn-prev,
+ .btn-next {
+ @apply border border-solid border-gray-300 dark:border-gray-700 rounded;
+ }
+ .el-pager {
+ li {
+ @apply border border-solid border-gray-300 dark:border-gray-600 rounded text-gray-600 text-sm mx-1;
+ }
+ }
+}
+.el-menu {
+ li {
+ @apply my-1;
+ }
+}
+.el-menu--vertical {
+ .el-menu-item {
+ border-radius: 2px;
+ &.is-active {
+ background-color: var(--el-color-primary) !important;
+ color: #fff !important;
+ }
+ }
+}
+
+.el-sub-menu.el-sub-menu__hide-arrow {
+ height: 44px;
+}
+
+.el-tabs__header {
+ margin: 0 0 1px !important;
+}
+
+.el-sub-menu.is-active {
+ > .el-sub-menu__title {
+ color: var(--el-color-primary) !important;
+ }
+}
+
+.el-sub-menu__title.el-tooltip__trigger,
+.el-menu-item .el-menu-tooltip__trigger {
+ justify-content: center;
+}
+
+.el-menu--horizontal .el-menu .el-sub-menu__title {
+ justify-content: flex-start;
+}
+
+html.dark {
+ /* 自定义深色背景颜色 */
+ --el-bg-color: rgb(30, 41, 59);
+ --el-bg-color-overlay: rgb(40, 51, 69);
+ --el-fill-color-light: rgb(15, 23, 42);
+ --el-fill-color: rgb(15, 23, 42);
+}
diff --git a/src/style/iconfont.css b/src/style/iconfont.css
new file mode 100644
index 0000000..623bf13
--- /dev/null
+++ b/src/style/iconfont.css
@@ -0,0 +1,47 @@
+@font-face {
+ font-family: 'gvaIcon';
+ src: url('data:font/ttf;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTZJUyU8AAA14AAAAHEdERUYAKQARAAANWAAAAB5PUy8yPJpJTAAAAVgAAABgY21hcM0T0L4AAAHYAAABWmdhc3D//wADAAANUAAAAAhnbHlmRk3UvwAAA0wAAAbYaGVhZB/a5jgAAADcAAAANmhoZWEHngOFAAABFAAAACRobXR4DaoBrAAAAbgAAAAebG9jYQbMCGgAAAM0AAAAGG1heHABGgB+AAABOAAAACBuYW1lXoIBAgAACiQAAAKCcG9zdN15OnUAAAyoAAAAqAABAAAAAQAA+a916l8PPPUACwQAAAAAAN5YUSMAAAAA3lhRIwBL/8ADwAM1AAAACAACAAAAAAAAAAEAAAOA/4AAXAQAAAAAAAPAAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAALAHIABQAAAAAAAgAAAAoACgAAAP8AAAAAAAAABAQAAZAABQAAAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZADA5mXmfQOA/4AAAAPcAIAAAAABAAAAAAAAAAAAAAAgAAEEAAAAAAAAAAQAAAAEAACLAIoAYAB1AHYASwBLAGAAAAAAAAMAAAADAAAAHAABAAAAAABUAAMAAQAAABwABAA4AAAACgAIAAIAAuZm5mrmduZ9//8AAOZl5mrmdeZ7//8ZnhmbGZEZjQABAAAAAAAAAAAAAAAAAQYAAAEAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEYAigEcAbgCUAK6AxoDbAACAIsAIANsAswAEQAjAAAlIicBJjQ3ATYeAQYHCQEeAQYhIicBJjQ3ATYeAQYHCQEeAQYDSw0J/qsLCwFVChsSAgr+xAE8CgIV/qkNCP6qCgoBVgkbEgIK/sUBOwoCFCAJATULGQsBNQoCExwI/uL+4ggbFAkBNQsZCwE1CgITHAj+4v7iCRoUAAAAAAIAigAgA2sCzAARACIAAAE0JwEmDgEWFwkBDgEWMjcBNiUBJg4BFhcJAQ4BFjI3ATY0AiAL/qsJHBECCQE8/sQJAhQZCQFVCwFA/qsKGxICCgE8/sQKAhUZCQFVCwF1DQsBNQoCExwI/uL+4gkaFAkBNQskATUKAhMcCP7i/uIJGhQJATULGQADAGD/wAOgAzUATABcAGwAAAE1NCcmJyYiBwYHBh0BDgEdARQWOwEyNj0BNCYrATU0NzY3NjIXFhcWHQEjIgYdARQWOwEGBwYHLgEjIgYUFjMyNjc2NzY3PgE9ATQmBRUUBisBIiY9ATQ2OwEyFgUUBisBIiY9ATQ2OwEyFhUDYDAvT1O+U08vMBslLB9VHi0tHiAoJkFDnENBJiggHi0tHhUPJC5SChwRHCQkHBEeCHJAMxAfKiX9kAYFVQUGBgVVBQYCVQYFVQUGBgVVBQYByQxgUlAuMDAuUFJgDAQqG6seLCweqx4tCk5DQScnJydBQ04KLR6rHiwrGiAGDxElNiUSEAc1KkUBKx6rGyhFqwQGBgSrBQYGsAQGBgSrBQYGBQAABAB1//UDjQMLABsANwBSAHEAABMyNj0BFxYyNjQvATMyNjQmKwEiBwYHBh0BFBYFIgYdAScmIgYUHwEjIgYUFjsBMjc2NzY9ATYmJQc1NCYiBh0BFBcWFxY7ATI2NCYrATc2NCYGATQ1FSYnJisBIgYUFjsBBwYUFjI/ARUUFjI2PQEnJpUNE7wJHRMKvIcMFBQM1ggCDAgCFALiDRPJCRoTCcmJDBQUDNYIAg8CAwES/gbJExkUAggKBAbWDBQUDInJCRMXAgEHCwQG2AwUFAyJvAkSHgi8ExoTAgEB9RQMibwIEhkKvBMZFAIGDAQI1gwU6hQMickJExoJyRMZFAIICgQG2AwUIsmHDBQUDNYIAg8CAxQZE8kKGRMBAcABAQIOAwMUGRO8ChkTCbyHDBQUDNYFBAAABAB2//cDjgMMABoANQBRAG0AAAEjIgYUFjsBMjc2NzY9ATQmIgYdAScmIgYUFwEzMjY0JisBIgcGBwYdARQWMjY9ARcWMjY0JyUmJyYrASIGFBY7AQcGFBYyPwEVFBYyNj0BLgE3FhcWOwEyNjQmKwE3NjQmIg8BNTQmIgYdAR4BATqJDRMTDdUJAg8CAhMaE7cKGRQKAjeJDRMTDdUJAg8CAhMaE8gJHhIK/i8HCgQH1w0TEw2JyQoTHQnIFBkTAQKoBwoEBtYNExMNibwKFBkKvBMZFAICAhoUGRMCBwoEBtYNExMNib4KExoK/iAUGRMCBwoEB9UNExMNickIEhkK8w8CAhMZFMgKGRMJyYkNExMN1QIJzQ8CAhMZFLsKGhMKvIkNExMN1QMIAAAAAAUAS//LA7UDNQAUACkAKgA3AEQAAAEiBwYHBhQXFhcWMjc2NzY0JyYnJgMiJyYnJjQ3Njc2MhcWFxYUBwYHBgMjFB4BMj4BNC4BIg4BFyIGHQEUFjI2PQE0JgIAd2ZiOzs7O2Jm7mZiOzs7O2Jmd2VXVDIzMzJUV8pXVDIzMzJUV2UrDBQWFAwMFBYUDCsNExMaExMDNTs7YmbuZmI7Ozs7YmbuZmI7O/zWMzJUV8pXVDIzMzJUV8pXVDIzAjULFAwMFBYUDAwUgBQM6w0TEw3rDBQAAQBL/+ADwAMgAD0AAAEmBg8BLgEjIgcGBwYUFxYXFjMyPgE3Ni4BBgcOAiMiJyYnJjQ3Njc2MzIeARcnJg4BFh8BMj8BNj8BNCYDpgwXAxc5yXZyY184Ojo4X2NyWaB4HgULGhcFGWaJS2FUUTAwMTBRU2FIhGQbgA0WBw4NwgUIBAwDMQ0CsQMODFhmeDk3XmHiYV43OUV9UQ0XCQsMRWo6MC9PUr9TTy8wNmNBJQMOGhYDMwMBCAu6DRYAAAAAAgBg/8YDugMiAB4AMwAABSc+ATU0JyYnJiIHBgcGFBcWFxYzMjc2NxcWMjc2JiUiJyYnJjQ3Njc2MhcWFxYUBwYHBgOxviouNDFVV8lXVTIzMzJVV2RDPzwzvgkeCAcB/hxUSEYpKiopRkioSEYpKyspRkgCvjB9RGRYVDIzNDJVWMlXVTE0GBYqvgkJChuBKylGSKhIRikqKilGSKhIRikrAAAAABIA3gABAAAAAAAAABMAKAABAAAAAAABAAgATgABAAAAAAACAAcAZwABAAAAAAADAAgAgQABAAAAAAAEAAgAnAABAAAAAAAFAAsAvQABAAAAAAAGAAgA2wABAAAAAAAKACsBPAABAAAAAAALABMBkAADAAEECQAAACYAAAADAAEECQABABAAPAADAAEECQACAA4AVwADAAEECQADABAAbwADAAEECQAEABAAigADAAEECQAFABYApQADAAEECQAGABAAyQADAAEECQAKAFYA5AADAAEECQALACYBaABDAHIAZQBhAHQAZQBkACAAYgB5ACAAaQBjAG8AbgBmAG8AbgB0AABDcmVhdGVkIGJ5IGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAABHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuAABoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAABodHRwOi8vZm9udGVsbG8uY29tAAAAAAIAAAAAAAAACgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAACwAAAAEAAgECAQMBBAEFAQYBBwEIAQkRYXJyb3ctZG91YmxlLWxlZnQSYXJyb3ctZG91YmxlLXJpZ2h0EGN1c3RvbWVyLXNlcnZpY2URZnVsbHNjcmVlbi1leHBhbmQRZnVsbHNjcmVlbi1zaHJpbmsGcHJvbXB0B3JlZnJlc2gGc2VhcmNoAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMACgABAAQAAAACAAAAAAAAAAEAAAAA1aQnCAAAAADeWFEjAAAAAN5YUSM=')
+ format('truetype');
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+.gvaIcon {
+ font-family: 'gvaIcon' !important;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 800;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.gvaIcon-arrow-double-left:before {
+ content: '\e665';
+}
+
+.gvaIcon-arrow-double-right:before {
+ content: '\e666';
+}
+
+.gvaIcon-fullscreen-shrink:before {
+ content: '\e676';
+}
+.gvaIcon-customer-service:before {
+ content: '\e66a';
+}
+
+.gvaIcon-fullscreen-expand:before {
+ content: '\e675';
+}
+
+.gvaIcon-prompt:before {
+ content: '\e67b';
+}
+
+.gvaIcon-refresh:before {
+ content: '\e67c';
+}
+
+.gvaIcon-search:before {
+ content: '\e67d';
+}
diff --git a/src/style/main.scss b/src/style/main.scss
new file mode 100644
index 0000000..a213d48
--- /dev/null
+++ b/src/style/main.scss
@@ -0,0 +1,51 @@
+@use '@/style/iconfont.css';
+@use "./transition.scss";
+
+.html-grey {
+ filter: grayscale(100%);
+}
+
+.html-weakenss {
+ filter: invert(80%);
+}
+
+.gva-table-box {
+ @apply p-4 bg-white text-slate-700 dark:text-slate-400 dark:bg-slate-900 rounded my-2;
+ .el-table {
+ @apply border-x border-t border-b-0 rounded border-table-border border-solid -mx-[1px];
+ }
+}
+
+.gva-btn-list {
+ @apply mb-3 flex items-center;
+}
+
+#nprogress .bar {
+ background: #29d !important;
+}
+.gva-customer-icon {
+ @apply w-4 h-4;
+}
+
+::-webkit-scrollbar {
+ @apply hidden;
+}
+
+.gva-search-box {
+ @apply p-4 bg-white text-slate-700 dark:text-slate-400 dark:bg-slate-900 rounded my-2;
+}
+
+.gva-form-box {
+ @apply p-4 bg-white text-slate-700 dark:text-slate-400 dark:bg-slate-900 rounded my-2;
+}
+
+.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
+ background: var(--el-color-primary-bg) !important;
+}
+
+.el-dropdown {
+ outline: none;
+ * {
+ outline: none;
+ }
+}
diff --git a/src/style/reset.scss b/src/style/reset.scss
new file mode 100644
index 0000000..2cd44c7
--- /dev/null
+++ b/src/style/reset.scss
@@ -0,0 +1,469 @@
+/* Document
+ ========================================================================== */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+html {
+ line-height: 1.15;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+}
+
+/* Sections
+ ========================================================================== */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+/**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box;
+ /* 1 */
+ height: 0;
+ /* 1 */
+ overflow: visible;
+ /* 2 */
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ border-bottom: none;
+ /* 1 */
+ text-decoration: underline;
+ /* 2 */
+ text-decoration: underline dotted;
+ /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove the border on images inside links in IE 10.
+ */
+
+img {
+ border-style: none;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ line-height: 1.15;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+}
+
+/**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+button,
+input {
+ /* 1 */
+ overflow: visible;
+}
+
+/**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+button,
+select {
+ /* 1 */
+ text-transform: none;
+}
+
+/**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+ -webkit-appearance: button;
+}
+
+/**
+ * Remove the inner border and padding in Firefox.
+ */
+
+button::-moz-focus-inner,
+[type='button']::-moz-focus-inner,
+[type='reset']::-moz-focus-inner,
+[type='submit']::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
+
+/**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+button:-moz-focusring,
+[type='button']:-moz-focusring,
+[type='reset']:-moz-focusring,
+[type='submit']:-moz-focusring {
+ outline: 1px dotted ButtonText;
+}
+
+/**
+ * Correct the padding in Firefox.
+ */
+
+fieldset {
+ padding: 0.35em 0.75em 0.625em;
+}
+
+/**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+legend {
+ box-sizing: border-box;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ display: table;
+ /* 1 */
+ max-width: 100%;
+ /* 1 */
+ padding: 0;
+ /* 3 */
+ white-space: normal;
+ /* 1 */
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+[type='checkbox'],
+[type='radio'] {
+ box-sizing: border-box;
+ /* 1 */
+ padding: 0;
+ /* 2 */
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type='number']::-webkit-inner-spin-button,
+[type='number']::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type='search']::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/* Misc
+ ========================================================================== */
+
+/**
+ * Add the correct display in IE 10+.
+ */
+
+template {
+ display: none;
+}
+
+/**
+ * Add the correct display in IE 10.
+ */
+
+[hidden] {
+ display: none;
+}
+
+HTML,
+body,
+div,
+ul,
+ol,
+dl,
+li,
+dt,
+dd,
+p,
+blockquote,
+pre,
+form,
+fieldset,
+table,
+th,
+td {
+ border: none;
+ font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
+ 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
+ font-size: 14px;
+ margin: 0px;
+ padding: 0px;
+}
+
+html,
+body {
+ height: 100%;
+ width: 100%;
+}
+
+address,
+caption,
+cite,
+code,
+th,
+var {
+ font-style: normal;
+ font-weight: normal;
+}
+
+a {
+ text-decoration: none;
+}
+
+input::-ms-clear {
+ display: none;
+}
+
+input::-ms-reveal {
+ display: none;
+}
+
+input {
+ -webkit-appearance: none;
+ margin: 0;
+ outline: none;
+ padding: 0;
+}
+
+input::-webkit-input-placeholder {
+ color: #ccc;
+}
+
+input::-ms-input-placeholder {
+ color: #ccc;
+}
+
+input::-moz-placeholder {
+ color: #ccc;
+}
+
+input[type='submit'],
+input[type='button'] {
+ cursor: pointer;
+}
+
+button[disabled],
+input[disabled] {
+ cursor: default;
+}
+
+img {
+ border: none;
+}
+
+ul,
+ol,
+li {
+ list-style-type: none;
+}
diff --git a/src/style/transition.scss b/src/style/transition.scss
new file mode 100644
index 0000000..09a2543
--- /dev/null
+++ b/src/style/transition.scss
@@ -0,0 +1,68 @@
+
+// 淡入淡出动画
+.fade-enter-active,
+.fade-leave-active {
+ transition: all 0.3s ease;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+ opacity: 0;
+ transform: translateY(10px);
+}
+
+.header {
+ border-radius: 0 0 10px 10px;
+}
+
+.body {
+ height: calc(100% - 6rem);
+}
+
+@keyframes slideDown {
+ from {
+ transform: translateY(-20px);
+ opacity: 0;
+ }
+
+ to {
+ transform: translateY(0);
+ opacity: 1;
+ }
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+// 缩放动画
+.zoom-enter-active,
+.zoom-leave-active {
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.zoom-enter-from,
+.zoom-leave-to {
+ opacity: 0;
+ transform: scale(0.95);
+}
+
+
+/* fade-slide */
+.slide-leave-active,
+.slide-enter-active {
+ transition: all 0.3s;
+}
+.slide-enter-from {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+.slide-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
diff --git a/src/utils/asyncRouter.js b/src/utils/asyncRouter.js
new file mode 100644
index 0000000..9e7a5ca
--- /dev/null
+++ b/src/utils/asyncRouter.js
@@ -0,0 +1,29 @@
+const viewModules = import.meta.glob('../view/**/*.vue')
+const pluginModules = import.meta.glob('../plugin/**/*.vue')
+
+export const asyncRouterHandle = (asyncRouter) => {
+ asyncRouter.forEach((item) => {
+ if (item.component && typeof item.component === 'string') {
+ item.meta.path = '/src/' + item.component
+ if (item.component.split('/')[0] === 'view') {
+ item.component = dynamicImport(viewModules, item.component)
+ } else if (item.component.split('/')[0] === 'plugin') {
+ item.component = dynamicImport(pluginModules, item.component)
+ }
+ }
+ if (item.children) {
+ asyncRouterHandle(item.children)
+ }
+ })
+}
+
+function dynamicImport(dynamicViewsModules, component) {
+ const keys = Object.keys(dynamicViewsModules)
+ const matchKeys = keys.filter((key) => {
+ const k = key.replace('../', '')
+ return k === component
+ })
+ const matchKey = matchKeys[0]
+
+ return dynamicViewsModules[matchKey]
+}
diff --git a/src/utils/btnAuth.js b/src/utils/btnAuth.js
new file mode 100644
index 0000000..f94fa9b
--- /dev/null
+++ b/src/utils/btnAuth.js
@@ -0,0 +1,6 @@
+import { useRoute } from 'vue-router'
+import { reactive } from 'vue'
+export const useBtnAuth = () => {
+ const route = useRoute()
+ return route.meta.btns || reactive({})
+}
diff --git a/src/utils/bus.js b/src/utils/bus.js
new file mode 100644
index 0000000..f2a3b92
--- /dev/null
+++ b/src/utils/bus.js
@@ -0,0 +1,4 @@
+// using ES6 modules
+import mitt from 'mitt'
+
+export const emitter = mitt()
diff --git a/src/utils/closeThisPage.js b/src/utils/closeThisPage.js
new file mode 100644
index 0000000..b2a0c05
--- /dev/null
+++ b/src/utils/closeThisPage.js
@@ -0,0 +1,5 @@
+import { emitter } from '@/utils/bus.js'
+
+export const closeThisPage = () => {
+ emitter.emit('closeThisPage')
+}
diff --git a/src/utils/date.js b/src/utils/date.js
new file mode 100644
index 0000000..987a40d
--- /dev/null
+++ b/src/utils/date.js
@@ -0,0 +1,44 @@
+// 对Date的扩展,将 Date 转化为指定格式的String
+// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
+// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
+// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
+// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
+// eslint-disable-next-line no-extend-native
+Date.prototype.Format = function(fmt) {
+ const o = {
+ 'M+': this.getMonth() + 1, // 月份
+ 'd+': this.getDate(), // 日
+ 'h+': this.getHours(), // 小时
+ 'm+': this.getMinutes(), // 分
+ 's+': this.getSeconds(), // 秒
+ 'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
+ 'S': this.getMilliseconds() // 毫秒
+ }
+ const reg = /(y+)/
+ if (reg.test(fmt)) {
+ const t = reg.exec(fmt)[1]
+ fmt = fmt.replace(
+ t,
+ (this.getFullYear() + '').substring(4 - t.length)
+ )
+ }
+ for (let k in o) {
+ const regx = new RegExp('(' + k + ')')
+ if (regx.test(fmt)) {
+ const t = regx.exec(fmt)[1]
+ fmt = fmt.replace(
+ t,
+ t.length === 1 ? o[k] : ('00' + o[k]).substring(('' + o[k]).length)
+ )
+ }
+ }
+ return fmt
+}
+
+export function formatTimeToStr(times, pattern) {
+ let d = new Date(times).Format('yyyy-MM-dd hh:mm:ss')
+ if (pattern) {
+ d = new Date(times).Format(pattern)
+ }
+ return d.toLocaleString()
+}
diff --git a/src/utils/dictionary.js b/src/utils/dictionary.js
new file mode 100644
index 0000000..89ec656
--- /dev/null
+++ b/src/utils/dictionary.js
@@ -0,0 +1,26 @@
+import { useDictionaryStore } from '@/pinia/modules/dictionary'
+// 获取字典方法 使用示例 getDict('sex').then(res) 或者 async函数下 const res = await getDict('sex')
+export const getDict = async (type) => {
+ const dictionaryStore = useDictionaryStore()
+ await dictionaryStore.getDictionary(type)
+ return dictionaryStore.dictionaryMap[type]
+}
+
+// 字典文字展示方法
+export const showDictLabel = (
+ dict,
+ code,
+ keyCode = 'value',
+ valueCode = 'label'
+) => {
+ if (!dict) {
+ return ''
+ }
+ const dictMap = {}
+ dict.forEach((item) => {
+ if (Reflect.has(item, keyCode) && Reflect.has(item, valueCode)) {
+ dictMap[item[keyCode]] = item[valueCode]
+ }
+ })
+ return Reflect.has(dictMap, code) ? dictMap[code] : ''
+}
diff --git a/src/utils/doc.js b/src/utils/doc.js
new file mode 100644
index 0000000..55a3949
--- /dev/null
+++ b/src/utils/doc.js
@@ -0,0 +1,3 @@
+export const toDoc = (url) => {
+ window.open(url, '_blank')
+}
diff --git a/src/utils/downloadImg.js b/src/utils/downloadImg.js
new file mode 100644
index 0000000..10506c7
--- /dev/null
+++ b/src/utils/downloadImg.js
@@ -0,0 +1,20 @@
+export const downloadImage = (imgsrc, name) => {
+ // 下载图片地址和图片名
+ var image = new Image()
+ image.setAttribute('crossOrigin', 'anonymous')
+ image.onload = function () {
+ var canvas = document.createElement('canvas')
+ canvas.width = image.width
+ canvas.height = image.height
+ var context = canvas.getContext('2d')
+ context.drawImage(image, 0, 0, image.width, image.height)
+ var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
+
+ var a = document.createElement('a') // 生成一个a元素
+ var event = new MouseEvent('click') // 创建一个单击事件
+ a.download = name || 'photo' // 设置图片名称
+ a.href = url // 将生成的URL设置为a.href属性
+ a.dispatchEvent(event) // 触发a的单击事件
+ }
+ image.src = imgsrc
+}
diff --git a/src/utils/event.js b/src/utils/event.js
new file mode 100644
index 0000000..4861bf7
--- /dev/null
+++ b/src/utils/event.js
@@ -0,0 +1,17 @@
+export function addEventListen(target, event, handler, capture = false) {
+ if (
+ target.addEventListener &&
+ typeof target.addEventListener === 'function'
+ ) {
+ target.addEventListener(event, handler, capture)
+ }
+}
+
+export function removeEventListen(target, event, handler, capture = false) {
+ if (
+ target.removeEventListener &&
+ typeof target.removeEventListener === 'function'
+ ) {
+ target.removeEventListener(event, handler, capture)
+ }
+}
diff --git a/src/utils/fmtRouterTitle.js b/src/utils/fmtRouterTitle.js
new file mode 100644
index 0000000..bcaeb67
--- /dev/null
+++ b/src/utils/fmtRouterTitle.js
@@ -0,0 +1,13 @@
+export const fmtTitle = (title, now) => {
+ const reg = /\$\{(.+?)\}/
+ const reg_g = /\$\{(.+?)\}/g
+ const result = title.match(reg_g)
+ if (result) {
+ result.forEach((item) => {
+ const key = item.match(reg)[1]
+ const value = now.params[key] || now.query[key]
+ title = title.replace(item, value)
+ })
+ }
+ return title
+}
diff --git a/src/utils/format.js b/src/utils/format.js
new file mode 100644
index 0000000..f5062e7
--- /dev/null
+++ b/src/utils/format.js
@@ -0,0 +1,146 @@
+import { formatTimeToStr } from '@/utils/date'
+import { getDict } from '@/utils/dictionary'
+import { ref } from 'vue'
+
+export const formatBoolean = (bool) => {
+ if (bool !== null) {
+ return bool ? '是' : '否'
+ } else {
+ return ''
+ }
+}
+export const formatDate = (time) => {
+ if (time !== null && time !== '') {
+ var date = new Date(time)
+ return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
+ } else {
+ return ''
+ }
+}
+
+export const filterDict = (value, options) => {
+ const rowLabel = options && options.filter((item) => item.value === value)
+ return rowLabel && rowLabel[0] && rowLabel[0].label
+}
+
+export const filterDataSource = (dataSource, value) => {
+ if (Array.isArray(value)) {
+ return value.map((item) => {
+ const rowLabel = dataSource && dataSource.find((i) => i.value === item)
+ return rowLabel?.label
+ })
+ }
+ const rowLabel = dataSource && dataSource.find((item) => item.value === value)
+ return rowLabel?.label
+}
+
+export const getDictFunc = async (type) => {
+ const dicts = await getDict(type)
+ return dicts
+}
+
+const path =
+ import.meta.env.VITE_BASE_PATH + ':' + import.meta.env.VITE_SERVER_PORT + '/'
+export const ReturnArrImg = (arr) => {
+ const imgArr = []
+ if (arr instanceof Array) {
+ // 如果是数组类型
+ for (const arrKey in arr) {
+ if (arr[arrKey].slice(0, 4) !== 'http') {
+ imgArr.push(path + arr[arrKey])
+ } else {
+ imgArr.push(arr[arrKey])
+ }
+ }
+ } else {
+ // 如果不是数组类型
+ if (arr?.slice(0, 4) !== 'http') {
+ imgArr.push(path + arr)
+ } else {
+ imgArr.push(arr)
+ }
+ }
+ return imgArr
+}
+
+export const returnArrImg = ReturnArrImg
+
+export const onDownloadFile = (url) => {
+ window.open(path + url)
+}
+const colorToHex = (u) => {
+ let e = u.replace('#', '').match(/../g)
+ for (let t = 0; t < 3; t++) e[t] = parseInt(e[t], 16)
+ return e
+}
+
+const hexToColor = (u, e, t) => {
+ let a = [u.toString(16), e.toString(16), t.toString(16)]
+ for (let n = 0; n < 3; n++) a[n].length === 1 && (a[n] = `0${a[n]}`)
+ return `#${a.join('')}`
+}
+const generateAllColors = (u, e) => {
+ let t = colorToHex(u)
+ const target = [10, 10, 30]
+ for (let a = 0; a < 3; a++) t[a] = Math.floor(t[a] * (1 - e) + target[a] * e)
+ return hexToColor(t[0], t[1], t[2])
+}
+
+const generateAllLightColors = (u, e) => {
+ let t = colorToHex(u)
+ const target = [240, 248, 255] // RGB for blue white color
+ for (let a = 0; a < 3; a++) t[a] = Math.floor(t[a] * (1 - e) + target[a] * e)
+ return hexToColor(t[0], t[1], t[2])
+}
+
+function addOpacityToColor(u, opacity) {
+ let t = colorToHex(u)
+ return `rgba(${t[0]}, ${t[1]}, ${t[2]}, ${opacity})`
+}
+
+export const setBodyPrimaryColor = (primaryColor, darkMode) => {
+ let fmtColorFunc = generateAllColors
+ if (darkMode === 'light') {
+ fmtColorFunc = generateAllLightColors
+ }
+
+ document.documentElement.style.setProperty('--el-color-primary', primaryColor)
+ document.documentElement.style.setProperty(
+ '--el-color-primary-bg',
+ addOpacityToColor(primaryColor, 0.4)
+ )
+ for (let times = 1; times <= 2; times++) {
+ document.documentElement.style.setProperty(
+ `--el-color-primary-dark-${times}`,
+ fmtColorFunc(primaryColor, times / 10)
+ )
+ }
+ for (let times = 1; times <= 10; times++) {
+ document.documentElement.style.setProperty(
+ `--el-color-primary-light-${times}`,
+ fmtColorFunc(primaryColor, times / 10)
+ )
+ }
+ document.documentElement.style.setProperty(
+ `--el-menu-hover-bg-color`,
+ addOpacityToColor(primaryColor, 0.2)
+ )
+}
+
+const baseUrl = ref(import.meta.env.VITE_BASE_API)
+
+export const getBaseUrl = () => {
+ return baseUrl.value === '/' ? '' : baseUrl.value
+}
+
+export const CreateUUID = () => {
+ let d = new Date().getTime()
+ if (window.performance && typeof window.performance.now === 'function') {
+ d += performance.now()
+ }
+ return '00000000-0000-0000-0000-000000000000'.replace(/0/g, (c) => {
+ const r = (d + Math.random() * 16) % 16 | 0 // d是随机种子
+ d = Math.floor(d / 16)
+ return (c === '0' ? r : (r & 0x3) | 0x8).toString(16)
+ })
+}
diff --git a/src/utils/image.js b/src/utils/image.js
new file mode 100644
index 0000000..8b65232
--- /dev/null
+++ b/src/utils/image.js
@@ -0,0 +1,126 @@
+export default class ImageCompress {
+ constructor(file, fileSize, maxWH = 1920) {
+ this.file = file
+ this.fileSize = fileSize
+ this.maxWH = maxWH // 最大长宽
+ }
+
+ compress() {
+ // 压缩
+ const fileType = this.file.type
+ const fileSize = this.file.size / 1024
+ return new Promise((resolve) => {
+ const reader = new FileReader()
+ reader.readAsDataURL(this.file)
+ reader.onload = () => {
+ const canvas = document.createElement('canvas')
+ const img = document.createElement('img')
+ img.src = reader.result
+ img.onload = () => {
+ const ctx = canvas.getContext('2d')
+ const _dWH = this.dWH(img.width, img.height, this.maxWH)
+ canvas.width = _dWH.width
+ canvas.height = _dWH.height
+
+ // 清空后, 重写画布
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
+
+ const newImgData = canvas.toDataURL(fileType, 0.9)
+
+ // 压缩宽高后的图像大小
+ const newImgSize = this.fileSizeKB(newImgData)
+
+ if (newImgSize > this.fileSize) {
+ console.log('图片尺寸太大!' + fileSize + ' >> ' + newImgSize)
+ }
+
+ const blob = this.dataURLtoBlob(newImgData, fileType)
+ const nfile = new File([blob], this.file.name)
+ resolve(nfile)
+ }
+ }
+ })
+ }
+
+ /**
+ * 长宽等比缩小
+ * 图像的一边(长或宽)为最大目标值
+ */
+ dWH(srcW, srcH, dMax) {
+ const defaults = {
+ width: srcW,
+ height: srcH
+ }
+ if (Math.max(srcW, srcH) > dMax) {
+ if (srcW > srcH) {
+ defaults.width = dMax
+ defaults.height = Math.round(srcH * (dMax / srcW))
+ return defaults
+ } else {
+ defaults.height = dMax
+ defaults.width = Math.round(srcW * (dMax / srcH))
+ return defaults
+ }
+ } else {
+ return defaults
+ }
+ }
+
+ fileSizeKB(dataURL) {
+ let sizeKB = 0
+ sizeKB = Math.round((dataURL.split(',')[1].length * 3) / 4 / 1024)
+ return sizeKB
+ }
+
+ /**
+ * 转为Blob
+ */
+ dataURLtoBlob(dataURL, fileType) {
+ const byteString = atob(dataURL.split(',')[1])
+ let mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0]
+ const ab = new ArrayBuffer(byteString.length)
+ const ia = new Uint8Array(ab)
+ for (let i = 0; i < byteString.length; i++) {
+ ia[i] = byteString.charCodeAt(i)
+ }
+ if (fileType) {
+ mimeString = fileType
+ }
+ return new Blob([ab], { type: mimeString, lastModifiedDate: new Date() })
+ }
+}
+
+const path = import.meta.env.VITE_FILE_API
+export const getUrl = (url) => {
+ if (url && url.slice(0, 4) !== 'http') {
+ if (path === '/') {
+ return url
+ }
+ if (url.slice(0, 1) === '/') {
+ return path + url
+ }
+ return path + '/' + url
+ } else {
+ return url
+ }
+}
+
+const VIDEO_EXTENSIONS = ['.mp4', '.mov', '.webm', '.ogg']
+const VIDEO_MIME_TYPES = ['video/mp4', 'video/webm', 'video/ogg']
+const IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml']
+
+export const isVideoExt = (url) => {
+ const urlLower = url?.toLowerCase() || ''
+ return urlLower !== '' && VIDEO_EXTENSIONS.some(ext => urlLower.endsWith(ext))
+}
+
+export const isVideoMime = (type) => {
+ const typeLower = type?.toLowerCase() || ''
+ return typeLower !== '' && VIDEO_MIME_TYPES.includes(typeLower)
+}
+
+export const isImageMime = (type) => {
+ const typeLower = type?.toLowerCase() || ''
+ return typeLower !== '' && IMAGE_MIME_TYPES.includes(typeLower)
+}
diff --git a/src/utils/page.js b/src/utils/page.js
new file mode 100644
index 0000000..6a3c6d8
--- /dev/null
+++ b/src/utils/page.js
@@ -0,0 +1,9 @@
+import { fmtTitle } from '@/utils/fmtRouterTitle'
+import config from '@/core/config'
+export default function getPageTitle(pageTitle, route) {
+ if (pageTitle) {
+ const title = fmtTitle(pageTitle, route)
+ return `${title} - ${config.appName}`
+ }
+ return `${config.appName}`
+}
diff --git a/src/utils/params.js b/src/utils/params.js
new file mode 100644
index 0000000..b03d539
--- /dev/null
+++ b/src/utils/params.js
@@ -0,0 +1,14 @@
+import { useParamsStore } from '@/pinia/modules/params'
+/*
+ * 获取参数方法 使用示例 getParams('key').then(res) 或者 async函数下 const res = await getParams('key')
+ * const res = ref('')
+ * const fun = async () => {
+ * res.value = await getParams('test')
+ * }
+ * fun()
+ */
+export const getParams = async(key) => {
+ const paramsStore = useParamsStore()
+ await paramsStore.getParams(key)
+ return paramsStore.paramsMap[key]
+}
diff --git a/src/utils/request.js b/src/utils/request.js
new file mode 100644
index 0000000..342ce8f
--- /dev/null
+++ b/src/utils/request.js
@@ -0,0 +1,172 @@
+import axios from 'axios' // 引入axios
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { useUserStore } from '@/pinia/modules/user'
+import router from '@/router/index'
+import { ElLoading } from 'element-plus'
+
+const service = axios.create({
+ baseURL: import.meta.env.VITE_BASE_API,
+ timeout: 99999
+})
+let activeAxios = 0
+let timer
+let loadingInstance
+const showLoading = (
+ option = {
+ target: null
+ }
+) => {
+ const loadDom = document.getElementById('gva-base-load-dom')
+ activeAxios++
+ if (timer) {
+ clearTimeout(timer)
+ }
+ timer = setTimeout(() => {
+ if (activeAxios > 0) {
+ if (!option.target) option.target = loadDom
+ loadingInstance = ElLoading.service(option)
+ }
+ }, 400)
+}
+
+const closeLoading = () => {
+ activeAxios--
+ if (activeAxios <= 0) {
+ clearTimeout(timer)
+ loadingInstance && loadingInstance.close()
+ }
+}
+// http request 拦截器
+service.interceptors.request.use(
+ (config) => {
+ if (!config.donNotShowLoading) {
+ showLoading(config.loadingOption)
+ }
+ const userStore = useUserStore()
+ config.headers = {
+ 'Content-Type': 'application/json',
+ 'x-token': userStore.token,
+ 'x-user-id': userStore.userInfo.ID,
+ ...config.headers
+ }
+ return config
+ },
+ (error) => {
+ if (!error.config.donNotShowLoading) {
+ closeLoading()
+ }
+ ElMessage({
+ showClose: true,
+ message: error,
+ type: 'error'
+ })
+ return error
+ }
+)
+
+// http response 拦截器
+service.interceptors.response.use(
+ (response) => {
+ const userStore = useUserStore()
+ if (!response.config.donNotShowLoading) {
+ closeLoading()
+ }
+ if (response.headers['new-token']) {
+ userStore.setToken(response.headers['new-token'])
+ }
+ if (response.data.code === 0 || response.headers.success === 'true') {
+ if (response.headers.msg) {
+ response.data.msg = decodeURI(response.headers.msg)
+ }
+ return response.data
+ } else {
+ ElMessage({
+ showClose: true,
+ message: response.data.msg || decodeURI(response.headers.msg),
+ type: 'error'
+ })
+ return response.data.msg ? response.data : response
+ }
+ },
+ (error) => {
+ if (!error.config.donNotShowLoading) {
+ closeLoading()
+ }
+
+ if (!error.response) {
+ ElMessageBox.confirm(
+ `
+ 检测到请求错误
+ ${error}
+ `,
+ '请求报错',
+ {
+ dangerouslyUseHTMLString: true,
+ distinguishCancelAndClose: true,
+ confirmButtonText: '稍后重试',
+ cancelButtonText: '取消'
+ }
+ )
+ return
+ }
+
+ switch (error.response.status) {
+ case 500:
+ ElMessageBox.confirm(
+ `
+ 检测到接口错误${error}
+ 错误码 500 :此类错误内容常见于后台panic,请先查看后台日志,如果影响您正常使用可强制登出清理缓存
+ `,
+ '接口报错',
+ {
+ dangerouslyUseHTMLString: true,
+ distinguishCancelAndClose: true,
+ confirmButtonText: '清理缓存',
+ cancelButtonText: '取消'
+ }
+ ).then(() => {
+ const userStore = useUserStore()
+ userStore.ClearStorage()
+ router.push({ name: 'Login', replace: true })
+ })
+ break
+ case 404:
+ ElMessageBox.confirm(
+ `
+ 检测到接口错误${error}
+ 错误码 404 :此类错误多为接口未注册(或未重启)或者请求路径(方法)与api路径(方法)不符--如果为自动化代码请检查是否存在空格
+ `,
+ '接口报错',
+ {
+ dangerouslyUseHTMLString: true,
+ distinguishCancelAndClose: true,
+ confirmButtonText: '我知道了',
+ cancelButtonText: '取消'
+ }
+ )
+ break
+ case 401:
+ ElMessageBox.confirm(
+ `
+ 无效的令牌
+ 错误码: 401 错误信息:${error}
+ `,
+ '身份信息',
+ {
+ dangerouslyUseHTMLString: true,
+ distinguishCancelAndClose: true,
+ confirmButtonText: '重新登录',
+ cancelButtonText: '取消'
+ }
+ ).then(() => {
+ const userStore = useUserStore()
+ userStore.ClearStorage()
+ router.push({ name: 'Login', replace: true })
+ })
+ break
+ }
+
+ return error
+ }
+)
+export default service
diff --git a/src/utils/stringFun.js b/src/utils/stringFun.js
new file mode 100644
index 0000000..baec83d
--- /dev/null
+++ b/src/utils/stringFun.js
@@ -0,0 +1,29 @@
+/* eslint-disable */
+export const toUpperCase = (str) => {
+ if (str[0]) {
+ return str.replace(str[0], str[0].toUpperCase())
+ } else {
+ return ''
+ }
+}
+
+export const toLowerCase = (str) => {
+ if (str[0]) {
+ return str.replace(str[0], str[0].toLowerCase())
+ } else {
+ return ''
+ }
+}
+
+// 驼峰转换下划线
+export const toSQLLine = (str) => {
+ if (str === 'ID') return 'ID'
+ return str.replace(/([A-Z])/g, '_$1').toLowerCase()
+}
+
+// 下划线转换驼峰
+export const toHump = (name) => {
+ return name.replace(/\_(\w)/g, function (all, letter) {
+ return letter.toUpperCase()
+ })
+}
diff --git a/src/view/about/index.vue b/src/view/about/index.vue
new file mode 100644
index 0000000..bf02bec
--- /dev/null
+++ b/src/view/about/index.vue
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+ gin-vue-admin
+
+
+
+
+
+ flipped-aurora团队
+
+
+
+
+
+
+
+ 提交记录
+
+
+
+
+
+ {{ item.title }}
+ {{ item.message }}
+
+
+
+
+
+
+ Load more
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/bot/bot/bot.vue b/src/view/bot/bot/bot.vue
new file mode 100644
index 0000000..cb278d8
--- /dev/null
+++ b/src/view/bot/bot/bot.vue
@@ -0,0 +1,411 @@
+
+
+
+
+
+
+
+
+ 创建日期
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+ 展开
+ 收起
+
+
+
+
+
+ 新增
+ 删除
+
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+ [富文本内容]
+
+
+
+
+ 查看
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
{{type==='create'?'新增':'编辑'}}
+
+ 确 定
+ 取 消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ detailFrom.keyword }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/bot/bot/botForm.vue b/src/view/bot/bot/botForm.vue
new file mode 100644
index 0000000..3afe384
--- /dev/null
+++ b/src/view/bot/bot/botForm.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 返回
+
+
+
+
+
+
+
+
+
diff --git a/src/view/category/category/category.vue b/src/view/category/category/category.vue
new file mode 100644
index 0000000..9209f81
--- /dev/null
+++ b/src/view/category/category/category.vue
@@ -0,0 +1,438 @@
+
+
+
+
+
+
+
+
+ 创建日期
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+ 展开
+ 收起
+
+
+
+
+
+ 新增
+ 删除
+
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+ {{ formatBoolean(scope.row.active) }}
+
+
+
+
+ 查看
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
{{type==='create'?'新增':'编辑'}}
+
+ 确 定
+ 取 消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ detailFrom.name }}
+
+
+ {{ detailFrom.order }}
+
+
+ {{ detailFrom.active }}
+
+
+ {{ detailFrom.parentId }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/category/category/categoryForm.vue b/src/view/category/category/categoryForm.vue
new file mode 100644
index 0000000..48a71ba
--- /dev/null
+++ b/src/view/category/category/categoryForm.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 返回
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/banner.vue b/src/view/dashboard/components/banner.vue
new file mode 100644
index 0000000..226dda9
--- /dev/null
+++ b/src/view/dashboard/components/banner.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/card.vue b/src/view/dashboard/components/card.vue
new file mode 100644
index 0000000..2a50b28
--- /dev/null
+++ b/src/view/dashboard/components/card.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ {{ title }}
+
+
+ 查看更多
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/charts-content-numbers.vue b/src/view/dashboard/components/charts-content-numbers.vue
new file mode 100644
index 0000000..4d7fb9e
--- /dev/null
+++ b/src/view/dashboard/components/charts-content-numbers.vue
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/charts-people-numbers.vue b/src/view/dashboard/components/charts-people-numbers.vue
new file mode 100644
index 0000000..3d10b3f
--- /dev/null
+++ b/src/view/dashboard/components/charts-people-numbers.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/charts.vue b/src/view/dashboard/components/charts.vue
new file mode 100644
index 0000000..650b5f1
--- /dev/null
+++ b/src/view/dashboard/components/charts.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/index.js b/src/view/dashboard/components/index.js
new file mode 100644
index 0000000..a59985b
--- /dev/null
+++ b/src/view/dashboard/components/index.js
@@ -0,0 +1,19 @@
+import GvaBanner from './banner.vue'
+import GvaCard from './card.vue'
+import GvaChart from './charts.vue'
+import GvaTable from './table.vue'
+import GvaNotice from './notice.vue'
+import GvaQuickLink from './quickLinks.vue'
+import GvaWiki from './wiki.vue'
+import GvaPluginTable from './pluginTable.vue'
+
+export {
+ GvaBanner,
+ GvaCard,
+ GvaChart,
+ GvaTable,
+ GvaNotice,
+ GvaQuickLink,
+ GvaWiki,
+ GvaPluginTable
+}
diff --git a/src/view/dashboard/components/notice.vue b/src/view/dashboard/components/notice.vue
new file mode 100644
index 0000000..6e81261
--- /dev/null
+++ b/src/view/dashboard/components/notice.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+ {{ item.typeTitle }}
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/pluginTable.vue b/src/view/dashboard/components/pluginTable.vue
new file mode 100644
index 0000000..e131cb9
--- /dev/null
+++ b/src/view/dashboard/components/pluginTable.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/quickLinks.vue b/src/view/dashboard/components/quickLinks.vue
new file mode 100644
index 0000000..5619b88
--- /dev/null
+++ b/src/view/dashboard/components/quickLinks.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/table.vue b/src/view/dashboard/components/table.vue
new file mode 100644
index 0000000..47c8dde
--- /dev/null
+++ b/src/view/dashboard/components/table.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/components/wiki.vue b/src/view/dashboard/components/wiki.vue
new file mode 100644
index 0000000..eea7240
--- /dev/null
+++ b/src/view/dashboard/components/wiki.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/dashboard/index.vue b/src/view/dashboard/index.vue
new file mode 100644
index 0000000..353bca6
--- /dev/null
+++ b/src/view/dashboard/index.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/error/index.vue b/src/view/error/index.vue
new file mode 100644
index 0000000..1f0079f
--- /dev/null
+++ b/src/view/error/index.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
diff --git a/src/view/error/reload.vue b/src/view/error/reload.vue
new file mode 100644
index 0000000..1fd027e
--- /dev/null
+++ b/src/view/error/reload.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/src/view/example/breakpoint/breakpoint.vue b/src/view/example/breakpoint/breakpoint.vue
new file mode 100644
index 0000000..dbda33d
--- /dev/null
+++ b/src/view/example/breakpoint/breakpoint.vue
@@ -0,0 +1,340 @@
+
+
+
+
大文件上传
+
+
请上传不超过5MB的文件
+
+
+
+
+
+
+ {{ file.name }}
+ {{ percentage }}%
+
+
+
+
+
+ 此版本为先行体验功能测试版,样式美化和性能优化正在进行中,上传切片文件和合成的完整文件分别再QMPlusserver目录的breakpointDir文件夹和fileDir文件夹
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/view/example/customer/customer.vue b/src/view/example/customer/customer.vue
new file mode 100644
index 0000000..f4a3104
--- /dev/null
+++ b/src/view/example/customer/customer.vue
@@ -0,0 +1,215 @@
+
+
+
+
+
+ 新增
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+
+
+ 变更
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/example/index.vue b/src/view/example/index.vue
new file mode 100644
index 0000000..0c3b58d
--- /dev/null
+++ b/src/view/example/index.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/example/upload/scanUpload.vue b/src/view/example/upload/scanUpload.vue
new file mode 100644
index 0000000..59845d7
--- /dev/null
+++ b/src/view/example/upload/scanUpload.vue
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ uploading ? '上传中...' : '上 传' }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/example/upload/upload.vue b/src/view/example/upload/upload.vue
new file mode 100644
index 0000000..eae676a
--- /dev/null
+++ b/src/view/example/upload/upload.vue
@@ -0,0 +1,448 @@
+
+
+
+
+
+
+
+ {{ data.name }}
+
+
+
+
+
+
+ 添加分类
+ 编辑分类
+ 删除分类
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 导入URL
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatDate(scope.row.UpdatedAt) }}
+
+
+
+
+
+ {{ scope.row.name }}
+
+
+
+
+
+
+ {{ scope.row.tag }}
+
+
+
+
+
+ 下载
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
diff --git a/src/view/init/index.vue b/src/view/init/index.vue
new file mode 100644
index 0000000..211ec4a
--- /dev/null
+++ b/src/view/init/index.vue
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+
+ GIN-VUE-ADMIN
+
+
初始化须知
+
+ 1.您需有用一定的VUE和GOLANG基础
+
+
+ 2.请您确认是否已经阅读过官方文档
+ 初始化视频
+
+
+ 3.请您确认是否了解后续的配置流程
+
+
+ 4.如果您使用mysql数据库,请确认数据库引擎为innoDB
+
+
+ 注:开发组不为文档中书写过的内容提供无偿服务
+
+
+
+ 阅读文档
+
+
+ 我已确认
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即初始化
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/asideComponent/asyncSubmenu.vue b/src/view/layout/aside/asideComponent/asyncSubmenu.vue
new file mode 100644
index 0000000..b9c4bf4
--- /dev/null
+++ b/src/view/layout/aside/asideComponent/asyncSubmenu.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/asideComponent/index.vue b/src/view/layout/aside/asideComponent/index.vue
new file mode 100644
index 0000000..32e7d41
--- /dev/null
+++ b/src/view/layout/aside/asideComponent/index.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/asideComponent/menuItem.vue b/src/view/layout/aside/asideComponent/menuItem.vue
new file mode 100644
index 0000000..b6b4ff7
--- /dev/null
+++ b/src/view/layout/aside/asideComponent/menuItem.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ {{ routerInfo.meta.title }}
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/combinationMode.vue b/src/view/layout/aside/combinationMode.vue
new file mode 100644
index 0000000..3e588ce
--- /dev/null
+++ b/src/view/layout/aside/combinationMode.vue
@@ -0,0 +1,146 @@
+
+
+
+
selectMenuItem(index, _, ele, true)"
+ >
+
+
+
+
+
+
+
+ selectMenuItem(index, _, ele, false)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/headMode.vue b/src/view/layout/aside/headMode.vue
new file mode 100644
index 0000000..dd8295f
--- /dev/null
+++ b/src/view/layout/aside/headMode.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/index.vue b/src/view/layout/aside/index.vue
new file mode 100644
index 0000000..c5e010a
--- /dev/null
+++ b/src/view/layout/aside/index.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/aside/normalMode.vue b/src/view/layout/aside/normalMode.vue
new file mode 100644
index 0000000..8c0fae1
--- /dev/null
+++ b/src/view/layout/aside/normalMode.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/header/index.vue b/src/view/layout/header/index.vue
new file mode 100644
index 0000000..bf7b5be
--- /dev/null
+++ b/src/view/layout/header/index.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
![]()
+
+ {{ $GIN_VUE_ADMIN.appName }}
+
+
+
+
+
+ {{ fmtTitle(item.meta.title, route) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ userStore.userInfo.nickName
+ }}
+
+
+
+
+
+
+
+
+
+ 当前角色:{{ userStore.userInfo.authority.authorityName }}
+
+
+
+
+ 切换为:{{ item.authorityName }}
+
+
+
+ 个人信息
+
+
+ 登 出
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/header/tools.vue b/src/view/layout/header/tools.vue
new file mode 100644
index 0000000..deba8d8
--- /dev/null
+++ b/src/view/layout/header/tools.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/iframe.vue b/src/view/layout/iframe.vue
new file mode 100644
index 0000000..137b520
--- /dev/null
+++ b/src/view/layout/iframe.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/index.vue b/src/view/layout/index.vue
new file mode 100644
index 0000000..8ce52a2
--- /dev/null
+++ b/src/view/layout/index.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
diff --git a/src/view/layout/screenfull/index.vue b/src/view/layout/screenfull/index.vue
new file mode 100644
index 0000000..da91a50
--- /dev/null
+++ b/src/view/layout/screenfull/index.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
diff --git a/src/view/layout/search/search.vue b/src/view/layout/search/search.vue
new file mode 100644
index 0000000..5375d70
--- /dev/null
+++ b/src/view/layout/search/search.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
diff --git a/src/view/layout/setting/index.vue b/src/view/layout/setting/index.vue
new file mode 100644
index 0000000..12a7f2a
--- /dev/null
+++ b/src/view/layout/setting/index.vue
@@ -0,0 +1,212 @@
+
+
+
+
+ 系统配置
+ 保存配置
+
+
+
+
+
+
+
+
+
diff --git a/src/view/layout/setting/title.vue b/src/view/layout/setting/title.vue
new file mode 100644
index 0000000..ea536ad
--- /dev/null
+++ b/src/view/layout/setting/title.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
diff --git a/src/view/layout/tabs/index.vue b/src/view/layout/tabs/index.vue
new file mode 100644
index 0000000..4ad54f3
--- /dev/null
+++ b/src/view/layout/tabs/index.vue
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+ {{ fmtTitle(item.meta.title, item) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/login/index.vue b/src/view/login/index.vue
new file mode 100644
index 0000000..4870b8a
--- /dev/null
+++ b/src/view/login/index.vue
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+ {{ $GIN_VUE_ADMIN.appName }}
+
+
+ A management platform using Golang and Vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![请输入验证码]()
+
+
+
+
+ 登 录
+
+
+ 前往初始化
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/person/person.vue b/src/view/person/person.vue
new file mode 100644
index 0000000..9920aae
--- /dev/null
+++ b/src/view/person/person.vue
@@ -0,0 +1,631 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ userStore.userInfo.nickName }}
+
+
+
+
+
+
+
+ 确认
+
+
+ 取消
+
+
+
+
+
+
+
+ 中国·北京市·朝阳区
+
+
+
+ 北京翻转极光科技有限公司
+
+
+
+ 技术部·前端事业群
+
+
+
+
+
+
+ 发送消息
+
+ 分享主页
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 基本信息
+
+
+
+
+
手机号码:
+
{{ userStore.userInfo.phone || '未设置' }}
+
+ 修改
+
+
+
+
+ 邮箱地址:
+ {{ userStore.userInfo.email || '未设置' }}
+
+ 修改
+
+
+
+
+ 账号密码:
+ 已设置
+
+ 修改
+
+
+
+
+
+
+
+
+ 技能特长
+
+
+
GoLang
+
JavaScript
+
Vue
+
Gorm
+
+
+ 添加技能
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 数据统计
+
+
+
+
+
+
+
+
+ 近期动态
+
+
+
+
+
+
+ {{ activity.title }}
+
+ {{ activity.content }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ time > 0 ? `${time}s` : '获取验证码' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ emailTime > 0 ? `${emailTime}s` : '获取验证码' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/routerHolder.vue b/src/view/routerHolder.vue
new file mode 100644
index 0000000..1b671ab
--- /dev/null
+++ b/src/view/routerHolder.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/src/view/superAdmin/api/api.vue b/src/view/superAdmin/api/api.vue
new file mode 100644
index 0000000..21e971c
--- /dev/null
+++ b/src/view/superAdmin/api/api.vue
@@ -0,0 +1,832 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+
+ 重置
+
+
+
+
+
+
+ 新增
+
+
+ 删除
+
+ 刷新缓存
+ 同步API
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
同步路由
+
+
+ 取 消
+
+
+ 确 定
+
+
+
+
+
+
+ 新增路由
+ 存在于当前路由中,但是不存在于api表
+
+
+
+
+ 自动填充
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
+
+
+
+
+
+
+ 单条新增
+
+
+ 忽略
+
+
+
+
+
+
+ 已删除路由
+ 已经不存在于当前项目的路由中,确定同步后会自动从apis表删除
+
+
+
+
+
+
+
+
+ {{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
+
+
+
+
+
+
+ 忽略路由
+ 忽略路由不参与api同步,常见为不需要进行鉴权行为的路由
+
+
+
+
+
+
+
+
+ {{ scope.row.method }} / {{ methodFilter(scope.row.method) }}
+
+
+
+
+
+
+ 取消忽略
+
+
+
+
+
+
+
+
+
+
{{ dialogTitle }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/authority/authority.vue b/src/view/superAdmin/authority/authority.vue
new file mode 100644
index 0000000..0774141
--- /dev/null
+++ b/src/view/superAdmin/authority/authority.vue
@@ -0,0 +1,422 @@
+
+
+
+
+
+ 新增角色
+
+
+
+
+
+
+ 设置权限
+ 新增子角色
+ 拷贝
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
{{ authorityTitleForm }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/authority/components/apis.vue b/src/view/superAdmin/authority/components/apis.vue
new file mode 100644
index 0000000..ea17645
--- /dev/null
+++ b/src/view/superAdmin/authority/components/apis.vue
@@ -0,0 +1,174 @@
+
+
+
+
+
+ 确 定
+
+
+
+
+
+
+ {{ data.description }}
+
+ {{ data.path }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/authority/components/datas.vue b/src/view/superAdmin/authority/components/datas.vue
new file mode 100644
index 0000000..71e4d5b
--- /dev/null
+++ b/src/view/superAdmin/authority/components/datas.vue
@@ -0,0 +1,145 @@
+
+
+
+
+ 全选
+ 本角色
+ 本角色及子角色
+ 确 定
+
+
+
+ {{ item.authorityName }}
+
+
+
+
+
+
diff --git a/src/view/superAdmin/authority/components/menus.vue b/src/view/superAdmin/authority/components/menus.vue
new file mode 100644
index 0000000..8e2d1c6
--- /dev/null
+++ b/src/view/superAdmin/authority/components/menus.vue
@@ -0,0 +1,233 @@
+
+
+
+
+ 确 定
+
+
+
+
+
+
+ {{ node.label }}
+
+ setDefault(data)"
+ >
+ {{ row.defaultRouter === data.name ? '首页' : '设为首页' }}
+
+
+
+ OpenBtn(data)">
+ 分配按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/dictionary/sysDictionary.vue b/src/view/superAdmin/dictionary/sysDictionary.vue
new file mode 100644
index 0000000..dcb273d
--- /dev/null
+++ b/src/view/superAdmin/dictionary/sysDictionary.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+ 字典列表
+ 新增
+
+
+
+
{{ dictionary.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{
+ type === 'create' ? '添加字典' : '修改字典'
+ }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/dictionary/sysDictionaryDetail.vue b/src/view/superAdmin/dictionary/sysDictionaryDetail.vue
new file mode 100644
index 0000000..a03229f
--- /dev/null
+++ b/src/view/superAdmin/dictionary/sysDictionaryDetail.vue
@@ -0,0 +1,321 @@
+
+
+
+
+ 字典详细内容
+
+ 新增字典项
+
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatBoolean(scope.row.status) }}
+
+
+
+
+
+
+
+
+ 变更
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
{{
+ type === 'create' ? '添加字典项' : '修改字典项'
+ }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/index.vue b/src/view/superAdmin/index.vue
new file mode 100644
index 0000000..4e148d1
--- /dev/null
+++ b/src/view/superAdmin/index.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/menu/components/components-cascader.vue b/src/view/superAdmin/menu/components/components-cascader.vue
new file mode 100644
index 0000000..e7de000
--- /dev/null
+++ b/src/view/superAdmin/menu/components/components-cascader.vue
@@ -0,0 +1,131 @@
+
+
+
+
+ {{ pathIsSelect ? '手动输入' : '快捷选择' }}
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/menu/icon.vue b/src/view/superAdmin/menu/icon.vue
new file mode 100644
index 0000000..d67124e
--- /dev/null
+++ b/src/view/superAdmin/menu/icon.vue
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.key }}
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/menu/menu.vue b/src/view/superAdmin/menu/menu.vue
new file mode 100644
index 0000000..ec4a7e0
--- /dev/null
+++ b/src/view/superAdmin/menu/menu.vue
@@ -0,0 +1,680 @@
+
+
+
+
+
+ 新增根菜单
+
+
+
+
+
+
+
+
+ {{ scope.row.meta.title }}
+
+
+
+
+
+
+
+
+ {{ scope.row.meta.icon }}
+
+
+
+
+
+
+
+ {{ scope.row.hidden ? '隐藏' : '显示' }}
+
+
+
+
+
+
+
+
+ 添加子菜单
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
{{ dialogTitle }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+
+ 如果菜单包含子菜单,请创建router-view二级路由页面或者
+
+ 点我设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 路由Path
+ 添加参数
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 高亮菜单
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是否为基础页面
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增菜单参数
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+ 新增可控按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/operation/sysOperationRecord.vue b/src/view/superAdmin/operation/sysOperationRecord.vue
new file mode 100644
index 0000000..27764c1
--- /dev/null
+++ b/src/view/superAdmin/operation/sysOperationRecord.vue
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+ {{ scope.row.user.userName }}({{ scope.row.user.nickName }})
+
+
+
+
+ {{
+ formatDate(scope.row.CreatedAt)
+ }}
+
+
+
+
+ {{ scope.row.status }}
+
+
+
+
+
+
+
+
+
+
+
+
{{ fmtBody(scope.row.body) }}
+
+
+
+
+
+
+
无
+
+
+
+
+
+
+
+
+
{{ fmtBody(scope.row.resp) }}
+
+
+
+
+
+
无
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/params/sysParams.vue b/src/view/superAdmin/params/sysParams.vue
new file mode 100644
index 0000000..89fe6f9
--- /dev/null
+++ b/src/view/superAdmin/params/sysParams.vue
@@ -0,0 +1,604 @@
+
+
+
+
+
+
+
+
+ 创建日期
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+ 展开
+ 收起
+
+
+
+
+
+ 新增
+ 删除
+
+
+
+
+
+ {{
+ formatDate(scope.row.CreatedAt)
+ }}
+
+
+
+
+
+
+
+
+ 查看详情
+ 变更
+ 删除
+
+
+
+
+
+
+
+
+
{{ type === 'create' ? '添加' : '修改' }}
+
+ 确 定
+ 取 消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
使用说明
+
+ 前端可以通过引入
+ import { getParams } from '@/utils/params'
+ 然后通过
+ await getParams("{{ formData.key }}")
+ 来获取对应的参数。
+
+
+ 后端需要提前
+ import
+ "github.com/flipped-aurora/gin-vue-admin/server/service/system"
+
+
+ 然后调用
+ new(system.SysParamsService).GetSysParam("{{
+ formData.key
+ }}")
+ 来获取对应的 value 值。
+
+
+
+
+
+
+
+ {{ detailFrom.name }}
+
+
+ {{ detailFrom.key }}
+
+
+ {{ detailFrom.value }}
+
+
+ {{ detailFrom.desc }}
+
+
+
+
+
+
+
+
+
diff --git a/src/view/superAdmin/user/user.vue b/src/view/superAdmin/user/user.vue
new file mode 100644
index 0000000..1561ef1
--- /dev/null
+++ b/src/view/superAdmin/user/user.vue
@@ -0,0 +1,524 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+
+ 重置
+
+
+
+
+
+ 新增用户
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ changeAuthority(scope.row, flag, 0)
+ }
+ "
+ @remove-tag="
+ (removeAuth) => {
+ changeAuthority(scope.row, false, removeAuth)
+ }
+ "
+ />
+
+
+
+
+ {
+ switchEnable(scope.row)
+ }
+ "
+ />
+
+
+
+
+
+ 删除
+ 编辑
+ 重置密码
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/system/state.vue b/src/view/system/state.vue
new file mode 100644
index 0000000..e54eeb9
--- /dev/null
+++ b/src/view/system/state.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+ Runtime
+
+
+
+ os:
+ {{ state.os.goos }}
+
+
+ cpu nums:
+ {{ state.os.numCpu }}
+
+
+ compiler:
+ {{ state.os.compiler }}
+
+
+ go version:
+ {{ state.os.goVersion }}
+
+
+ goroutine nums:
+ {{ state.os.numGoroutine }}
+
+
+
+
+
+
+
+ Disk
+
+
+
+
+
+ MountPoint
+ {{ item.mountPoint }}
+
+
+ total (MB)
+ {{ item.totalMb }}
+
+
+ used (MB)
+ {{ item.usedMb }}
+
+
+ total (GB)
+ {{ item.totalGb }}
+
+
+ used (GB)
+ {{ item.usedGb }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CPU
+
+
+
+ physical number of cores:
+ {{ state.cpu.cores }}
+
+
+ core {{ index }}:
+
+
+
+
+
+
+
+
+
+
+ Ram
+
+
+
+
+
+ total (MB)
+ {{ state.ram.totalMb }}
+
+
+ used (MB)
+ {{ state.ram.usedMb }}
+
+
+ total (GB)
+ {{ state.ram.totalMb / 1024 }}
+
+
+ used (GB)
+ {{
+ (state.ram.usedMb / 1024).toFixed(2)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/autoCode/component/fieldDialog.vue b/src/view/systemTools/autoCode/component/fieldDialog.vue
new file mode 100644
index 0000000..8f130e7
--- /dev/null
+++ b/src/view/systemTools/autoCode/component/fieldDialog.vue
@@ -0,0 +1,502 @@
+
+
+
+
+
+
+
+ 自动填充
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.aliasName }}
+ {{
+ item.dbName
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 存储:
+ {{ value }}
+
+
+
+
+ {{ item.isPrimary ? '主 键' : '非主键' }}
+
+ {{ item.columnName }}
+
+ 类型:{{ item.type }}
+ ,字段说明:{{ item.comment }}
+
+
+
+
+
+
+
+ 展示:
+ {{ value }}
+
+
+
+
+ {{ item.isPrimary ? '主 键' : '非主键' }}
+
+ {{ item.columnName }}
+
+ 类型:{{ item.type }}
+ ,字段说明:{{ item.comment }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/autoCode/component/previewCodeDialog.vue b/src/view/systemTools/autoCode/component/previewCodeDialog.vue
new file mode 100644
index 0000000..aa9c030
--- /dev/null
+++ b/src/view/systemTools/autoCode/component/previewCodeDialog.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/autoCode/index.vue b/src/view/systemTools/autoCode/index.vue
new file mode 100644
index 0000000..a1a9cff
--- /dev/null
+++ b/src/view/systemTools/autoCode/index.vue
@@ -0,0 +1,1685 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 【完全免费】前往
插件市场个人中心申请AIPath,填入config.yaml的ai-path属性即可使用。
+
+
+
+
+
+
+ 识图
+
+
+
+
+
+
+
+
+ 【完全免费】前往
插件市场个人中心申请AIPath,填入config.yaml的ai-path属性即可使用。
+
+
+
+
+
+
+ 生成
+
+
+
+
+
+
+
+
从数据库创建
+
+
+
+
+
+
+
+ 业务库
+
+
+
+
+
+
+ {{ item.aliasName }}
+ {{ item.dbName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 使用此表
+
+
+
+
+
+
+
+
+
+
自动化结构
+
+
+
+
+
+
+
+
+
+
+
+
+ 结构简称
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 文件名称
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 业务库
+
+
+
+
+
+
+ {{ item.aliasName }}
+ {{ item.dbName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 专家模式
+
+
+
+
+ {{ isActive ? '收起' : '展开' }}
+
+
+
+
+
+
基础设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
自动化设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
高级设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
树形结构设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 高级编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+ 导出json
+
+
+ 导入json
+
+
+ 清除暂存
+
+
+ 暂存
+
+
+ 生成代码
+
+
+ {{ isAdd ? '查看代码' : '预览代码' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/autoCodeAdmin/index.vue b/src/view/systemTools/autoCodeAdmin/index.vue
new file mode 100644
index 0000000..18bb089
--- /dev/null
+++ b/src/view/systemTools/autoCodeAdmin/index.vue
@@ -0,0 +1,620 @@
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+ {{ formatDate(scope.row.CreatedAt) }}
+
+
+
+
+
+
+
+
+ 已回滚
+
+ 未回滚
+
+
+
+
+
+
+ 增加方法
+
+
+ 增加字段
+
+
+ 回滚
+
+
+ 复用
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
操作栏
+
+
+ 生成
+
+
+ 取消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 当前ai帮写存在不稳定因素,生成代码后请注意手动调整部分内容
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ API路径: [{{ autoFunc.method }}] /{{ autoFunc.abbreviation }}/{{
+ autoFunc.router
+ }}
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/autoPkg/autoPkg.vue b/src/view/systemTools/autoPkg/autoPkg.vue
new file mode 100644
index 0000000..4ef2c5a
--- /dev/null
+++ b/src/view/systemTools/autoPkg/autoPkg.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
创建Package
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/exportTemplate/code.js b/src/view/systemTools/exportTemplate/code.js
new file mode 100644
index 0000000..98823ee
--- /dev/null
+++ b/src/view/systemTools/exportTemplate/code.js
@@ -0,0 +1,32 @@
+export const getCode = (templateID) => {
+ return `
+
+
+
+
+
+
+
+
+
+
+`
+}
diff --git a/src/view/systemTools/exportTemplate/exportTemplate.vue b/src/view/systemTools/exportTemplate/exportTemplate.vue
new file mode 100644
index 0000000..9136556
--- /dev/null
+++ b/src/view/systemTools/exportTemplate/exportTemplate.vue
@@ -0,0 +1,996 @@
+
+
+
+
+
+
+
+
+ 创建日期
+
+
+
+
+
+
+ —
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+ 新增
+
+ 删除
+
+
+
+
+ {{
+ formatDate(scope.row.CreatedAt)
+ }}
+
+
+
+ {{ scope.row.dbName || 'GVA库' }}
+
+
+
+
+
+
+
+
+ 复制
+ 代码
+ 变更
+ 删除
+
+
+
+
+
+
+
+
+
{{ type === 'create' ? '添加' : '修改' }}
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
+
+
+ 业务库
+
+
+
+
+
+
+ {{ item.aliasName }}
+ {{
+ item.dbName
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ formData.joinTemplate.splice(key, 1)"
+ >删除
+
+
+ 添加条件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ formData.conditions.splice(key, 1)"
+ >删除
+
+
+ 添加条件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/formCreate/index.vue b/src/view/systemTools/formCreate/index.vue
new file mode 100644
index 0000000..7e266f9
--- /dev/null
+++ b/src/view/systemTools/formCreate/index.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/src/view/systemTools/index.vue b/src/view/systemTools/index.vue
new file mode 100644
index 0000000..697d431
--- /dev/null
+++ b/src/view/systemTools/index.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/installPlugin/index.vue b/src/view/systemTools/installPlugin/index.vue
new file mode 100644
index 0000000..ce88c5c
--- /dev/null
+++ b/src/view/systemTools/installPlugin/index.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
diff --git a/src/view/systemTools/pubPlug/pubPlug.vue b/src/view/systemTools/pubPlug/pubPlug.vue
new file mode 100644
index 0000000..b16eaf2
--- /dev/null
+++ b/src/view/systemTools/pubPlug/pubPlug.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
diff --git a/src/view/systemTools/system/system.vue b/src/view/systemTools/system/system.vue
new file mode 100644
index 0000000..dfbc913
--- /dev/null
+++ b/src/view/systemTools/system/system.vue
@@ -0,0 +1,1085 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 本地
+ 七牛
+ 腾讯云COS
+ 阿里云OSS
+ 华为云OBS
+ cloudflare R2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 测试邮件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MySQL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PostgreSQL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MsSQL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sqlite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ oracle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 本地配置
+
+
+
+
+
+
+
+
+ 七牛上传配置
+
+
+
+
+
+
+
+
+
+
+ 开启
+
+
+
+
+
+
+
+
+
+
+
+
+ 腾讯云COS上传配置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 阿里云OSS上传配置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 华为云OBS上传配置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cloudflare R2上传配置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 立即更新
+ 重启服务
+
+
+
+
+
+
+
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..35531e0
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,23 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
+ important: true,
+ theme: {
+ extend: {
+ backgroundColor: {
+ main: '#F5F5F5'
+ },
+ textColor: {
+ active: 'var(--el-color-primary)'
+ },
+ boxShadowColor: {
+ active: 'var(--el-color-primary)'
+ },
+ borderColor: {
+ 'table-border': 'var(--el-border-color-lighter)'
+ }
+ }
+ },
+ darkMode: 'class',
+ plugins: []
+}
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..b35c7e9
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,113 @@
+import legacyPlugin from '@vitejs/plugin-legacy'
+import Banner from 'vite-plugin-banner'
+import * as path from 'path'
+import * as dotenv from 'dotenv'
+import * as fs from 'fs'
+import vuePlugin from '@vitejs/plugin-vue'
+import vueDevTools from 'vite-plugin-vue-devtools'
+import VueFilePathPlugin from './vitePlugin/componentName/index.js'
+import { svgBuilder } from 'vite-auto-import-svg'
+import { AddSecret } from './vitePlugin/secret'
+// @see https://cn.vitejs.dev/config/
+export default ({ mode }) => {
+ AddSecret('')
+ const NODE_ENV = mode || 'development'
+ const envFiles = [`.env.${NODE_ENV}`]
+ for (const file of envFiles) {
+ const envConfig = dotenv.parse(fs.readFileSync(file))
+ for (const k in envConfig) {
+ process.env[k] = envConfig[k]
+ }
+ }
+
+ const timestamp = Date.parse(new Date())
+
+ const optimizeDeps = {}
+
+ const alias = {
+ '@': path.resolve(__dirname, './src'),
+ vue$: 'vue/dist/vue.runtime.esm-bundler.js'
+ }
+
+ const esbuild = {}
+
+ const rollupOptions = {
+ output: {
+ entryFileNames: 'assets/087AC4D233B64EB0[name].[hash].js',
+ chunkFileNames: 'assets/087AC4D233B64EB0[name].[hash].js',
+ assetFileNames: 'assets/087AC4D233B64EB0[name].[hash].[ext]'
+ }
+ }
+
+ const config = {
+ base: '/', // 编译后js导入的资源路径
+ root: './', // index.html文件所在位置
+ publicDir: 'public', // 静态资源文件夹
+ resolve: {
+ alias
+ },
+ define: {
+ 'process.env': {}
+ },
+ css: {
+ preprocessorOptions: {
+ scss: {
+ api: 'modern-compiler' // or "modern"
+ }
+ }
+ },
+ server: {
+ // 如果使用docker-compose开发模式,设置为false
+ open: true,
+ port: process.env.VITE_CLI_PORT,
+ proxy: {
+ // 把key的路径代理到target位置
+ // detail: https://cli.vuejs.org/config/#devserver-proxy
+ [process.env.VITE_BASE_API]: {
+ // 需要代理的路径 例如 '/api'
+ target: `${process.env.VITE_BASE_PATH}:${process.env.VITE_SERVER_PORT}/`, // 代理到 目标路径
+ changeOrigin: true,
+ rewrite: (path) =>
+ path.replace(new RegExp('^' + process.env.VITE_BASE_API), '')
+ }
+ },
+ allowedHosts: ['all','lckt.echol.top'],
+ },
+ build: {
+ minify: 'terser', // 是否进行压缩,boolean | 'terser' | 'esbuild',默认使用terser
+ manifest: false, // 是否产出manifest.json
+ sourcemap: false, // 是否产出sourcemap.json
+ outDir: 'dist', // 产出目录
+ terserOptions: {
+ compress: {
+ //生产环境时移除console
+ drop_console: true,
+ drop_debugger: true
+ }
+ },
+ rollupOptions
+ },
+ esbuild,
+ optimizeDeps,
+ plugins: [
+ process.env.VITE_POSITION === 'open' &&
+ vueDevTools({ launchEditor: process.env.VITE_EDITOR }),
+ legacyPlugin({
+ targets: [
+ 'Android > 39',
+ 'Chrome >= 60',
+ 'Safari >= 10.1',
+ 'iOS >= 10.3',
+ 'Firefox >= 54',
+ 'Edge >= 15'
+ ]
+ }),
+ vuePlugin(),
+ svgBuilder('./src/assets/icons/'),
+ svgBuilder('./src/plugin/'),
+ [Banner(`\n Build based on gin-vue-admin \n Time : ${timestamp}`)],
+ VueFilePathPlugin('./src/pathInfo.json')
+ ]
+ }
+ return config
+}
diff --git a/vitePlugin/componentName/index.js b/vitePlugin/componentName/index.js
new file mode 100644
index 0000000..bae9f0f
--- /dev/null
+++ b/vitePlugin/componentName/index.js
@@ -0,0 +1,85 @@
+import fs from 'fs'
+import path from 'path'
+import chokidar from 'chokidar'
+
+const toPascalCase = (str) => {
+ return str.replace(/(^\w|-\w)/g, clearAndUpper)
+}
+
+const clearAndUpper = (text) => {
+ return text.replace(/-/, '').toUpperCase()
+}
+
+// 递归获取目录下所有的 .vue 文件
+const getAllVueFiles = (dir, fileList = []) => {
+ const files = fs.readdirSync(dir)
+ files.forEach((file) => {
+ const filePath = path.join(dir, file)
+ if (fs.statSync(filePath).isDirectory()) {
+ getAllVueFiles(filePath, fileList)
+ } else if (filePath.endsWith('.vue')) {
+ fileList.push(filePath)
+ }
+ })
+ return fileList
+}
+
+// 从 .vue 文件内容中提取组件名称
+const extractComponentName = (fileContent) => {
+ const regex = /defineOptions\(\s*{\s*name:\s*["']([^"']+)["']/
+ const match = fileContent.match(regex)
+ return match ? match[1] : null
+}
+
+// Vite 插件定义
+const vueFilePathPlugin = (outputFilePath) => {
+ let root
+
+ const generatePathNameMap = () => {
+ const vueFiles = [
+ ...getAllVueFiles(path.join(root, 'src/view')),
+ ...getAllVueFiles(path.join(root, 'src/plugin'))
+ ]
+ const pathNameMap = vueFiles.reduce((acc, filePath) => {
+ const content = fs.readFileSync(filePath, 'utf-8')
+ const componentName = extractComponentName(content)
+ let relativePath = '/' + path.relative(root, filePath).replace(/\\/g, '/')
+ acc[relativePath] =
+ componentName || toPascalCase(path.basename(filePath, '.vue'))
+ return acc
+ }, {})
+ const outputContent = JSON.stringify(pathNameMap, null, 2)
+ fs.writeFileSync(outputFilePath, outputContent)
+ }
+
+ const watchDirectoryChanges = () => {
+ const watchDirectories = [
+ path.join(root, 'src/view'),
+ path.join(root, 'src/plugin')
+ ]
+ const watcher = chokidar.watch(watchDirectories, {
+ persistent: true,
+ ignoreInitial: true
+ })
+ watcher.on('all', () => {
+ generatePathNameMap()
+ })
+ }
+
+ return {
+ name: 'vue-file-path-plugin',
+ configResolved(resolvedConfig) {
+ root = resolvedConfig.root
+ },
+ buildStart() {
+ generatePathNameMap()
+ },
+ buildEnd() {
+ if (process.env.NODE_ENV === 'development') {
+ watchDirectoryChanges()
+ }
+ }
+ }
+}
+
+export default vueFilePathPlugin
diff --git a/vitePlugin/secret/index.js b/vitePlugin/secret/index.js
new file mode 100644
index 0000000..93a8464
--- /dev/null
+++ b/vitePlugin/secret/index.js
@@ -0,0 +1,6 @@
+export function AddSecret(secret) {
+ if (!secret) {
+ secret = ''
+ }
+ global['gva-secret'] = secret
+}