diff --git a/README.md b/README.md index aa6570e..a25b88e 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,33 @@ Kinit 是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 - 🧑‍🤝‍🧑前端采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) 、[Vue3](https://cn.vuejs.org/guide/introduction.html)、[Element Plus](https://element-plus.gitee.io/zh-CN/guide/design.html)、[TypeScript](https://www.tslang.cn/),等主流技术开发。 -- 👭后端采用 Python 语言高性能 [FastAPI](https://fastapi.tiangolo.com/zh/) 框架以及强大的 Mysql 数据库。 +- 👭后端采用 Python 语言以及现代、快速(高性能) [FastAPI](https://fastapi.tiangolo.com/zh/) 框架。 - 👫权限认证使用[(哈希)密码和 JWT Bearer 令牌的 OAuth2](https://fastapi.tiangolo.com/zh/tutorial/security/oauth2-jwt/),支持多终端认证系统。 - 👬支持加载动态权限菜单,多方式轻松权限控制。 -- 💏特别鸣谢:[django-vue-admin](https://gitee.com/liqianglog/django-vue-admin) 、 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin)。 - 开箱即用的中后台解决方案,可以用来作为新项目的启动模版,也可用于学习参考。并且时刻关注着最新技术动向,尽可能的第一时间更新。 +## 💏特别鸣谢 + +[ELADMIN](https://eladmin.vip/demo):项目基于 Spring Boot 2.1.0 、 Jpa、 Spring Security、redis、Vue的前后端分离的后台管理系统。 + +[django-vue-admin](https://gitee.com/liqianglog/django-vue-admin):基于RBAC模型的权限控制的一整套基础开发平台,前后端分离,后端采用 django+django-rest-framework,前端采用 vue+ElementUI。 + +[vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin):一套基于vue3、element-plus、typescript4、vite3的后台集成方案 + +[Ant Design Pro](https://preview.pro.ant.design/dashboard/analysis):开箱即用的中台前端/设计解决方案 + +[Gin-Vue-Admin](https://demo.gin-vue-admin.com):基于vite+vue3+gin搭建的开发基础平台(支持TS,JS混用),集成jwt鉴权,权限管理,动态路由,显隐可控组件,分页封装,多点登录拦截,资源权限,上传下载,代码生成器,表单生成器等开发必备功能。 + +[Vben Admin (vvbin.cn)](https://vvbin.cn/next):Vue Vben Admin 是一个免费开源的中后台模版。使用了最新的`vue3`,`vite2`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,也可用于学习参考。 + +[中华人民共和国行政区划 (github.com)](https://github.com/modood/Administrative-divisions-of-China):省级(省份)、 地级(城市)、 县级(区县)、 乡级(乡镇街道)、 村级(村委会居委会) ,中国省市区镇村二级三级四级五级联动地址数据。 + +[Vue Admin Plus](https://vue-admin-beautiful.com/admin-plus/#/index):vue-admin-better是github开源admin中最优秀的集成框架之一,它是国内首个基于vue3.0的开源admin项目,同时支持电脑,手机,平板,默认分支使用vue3.x+antdv开发,master分支使用的是vue2.x+element开发。 + +[小诺开源技术 (xiaonuo.vip)](https://www.xiaonuo.vip/):国内首个国密前后端分离快速开发平台 + +[my-web:](https://gitee.com/newgateway/my-web):MyWeb 是一个企业级中后台前端/设计解决方案的的项目工程模板,它可以帮助你快速搭建企业级中后台产品原型 + ## 在线体验 👩‍👧‍👦演示地址:http://kinit.ktianc.top/ @@ -49,11 +70,7 @@ github地址:https://github.com/vvandk/kinit 👩‍👦‍👦 - [x] 📚字典管理:对系统中经常使用的一些较为固定的数据进行维护。 -- [ ] 📁附件管理:对平台上所有文件、图片等进行统一管理。 - -- [ ] 🗓️登录日志:用户登录日志记录和查询。 - -- [ ] 🗓️操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +- [ ] 📁附件管理:对平台上所有文件、图片等进行统一管理,对接阿里云OSS。 - [x] 🔒登录认证:目前支持用户使用手机号+密码方式登录。 @@ -61,6 +78,32 @@ github地址:https://github.com/vvandk/kinit 👩‍👦‍👦 说明:用户在第一次登录时,必须修改当前用户密码。 +- [x] 系统配置:对本系统环境信息进行动态配置 + + 网站标题,LOGO,描述,ICO,备案号,底部内容,百度统计代码,等等 + +- [ ] 数据分析:根据用户的登录用户地址分析出哪个地区的人最多 + +- [x] 🗓️登录日志:用户登录日志记录和查询。 + +- [x] 🗓️操作日志:系统用户每次操作功能时的详细记录。 + +- [ ] **🗓️异常日志:获取并展示接口异常日志** + +- [x] 🧾接口文档:提供自动生成的交互式 API 文档,与 ReDoc 文档 + +- [x] 导入导出:灵活支持数据导入导出功能 + +- [x] 手机验证码登录功能’ + +## TODO + +- [ ] 考虑支持多机部署方案,如果接口使用多机,那么用户是否支持统一认证 +- [ ] **自动化编排服务:使用docker-compose部署项目** +- [ ] **数据库备份:自动备份数据库** +- [ ] **接入数据大屏** +- [ ] **可视化低代码表单:接入低代码表单,https://vform666.com/vform3.html?from=element_plus** + ## 前序准备 - [FastAPI](https://fastapi.tiangolo.com/zh/) - 熟悉后台接口 Web 框架 @@ -73,6 +116,18 @@ github地址:https://github.com/vvandk/kinit 👩‍👦‍👦 - [Element-Plus](https://gitee.com/link?target=https%3A%2F%2Felement-plus.org%2F) - element-plus 基本使用 - [Mock.js](https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fnuysoft%2FMock) - mockjs 基本语法 +### 依赖包 + +#### 前端 + +- [vue3-json-viewer](https://gitee.com/isfive/vue3-json-viewer):简单易用的json内容展示组件,适配vue3和vite。 +- [vue3-slide-verify](https://github.com/monoplasty/vue3-slide-verify):滑块验证码插件 vue3 + typescript +- [SortableJS/vue.draggable.next](https://github.com/SortableJS/vue.draggable.next):Vue 组件 (Vue.js 3.0) 允许拖放和与视图模型数组同步。 + +#### 后端 + +- [iP查询接口文档](https://user.ip138.com/ip/doc):IP查询第三方服务,有1000次的免费次数 + ## 安装和使用 获取代码 diff --git a/images/1.png b/images/1.png index ed824a5..f098268 100644 Binary files a/images/1.png and b/images/1.png differ diff --git a/images/2.png b/images/2.png index d06955b..a3beeb3 100644 Binary files a/images/2.png and b/images/2.png differ diff --git a/images/3.png b/images/3.png index e6fd10c..253f5a0 100644 Binary files a/images/3.png and b/images/3.png differ diff --git a/images/4.png b/images/4.png index 0e7eb9b..321ead8 100644 Binary files a/images/4.png and b/images/4.png differ diff --git a/images/5.png b/images/5.png index 91a681e..7f7bffe 100644 Binary files a/images/5.png and b/images/5.png differ diff --git a/kinit-admin/.env.base b/kinit-admin/.env.base deleted file mode 100644 index 71f37f1..0000000 --- a/kinit-admin/.env.base +++ /dev/null @@ -1,11 +0,0 @@ -# 环境 -NODE_ENV=development - -# 接口前缀 -VITE_API_BASEPATH=base - -# 打包路径 -VITE_BASE_PATH=/ - -# 标题 -VITE_APP_TITLE=Kinit diff --git a/kinit-admin/.env.dev b/kinit-admin/.env.dev index e6876bf..3e2b7d0 100644 --- a/kinit-admin/.env.dev +++ b/kinit-admin/.env.dev @@ -1,11 +1,8 @@ # 环境 -NODE_ENV=production +NODE_ENV=development -# 接口前缀 -VITE_API_BASEPATH=dev - -# 打包路径 -VITE_BASE_PATH=/dist-dev/ +# 访问基础路径 +VITE_BASE_PATH=/ # 是否删除debugger VITE_DROP_DEBUGGER=false @@ -16,8 +13,8 @@ VITE_DROP_CONSOLE=false # 是否sourcemap VITE_SOURCEMAP=true -# 输出路径 +# 打包输出路径 VITE_OUT_DIR=dist-dev # 标题 -VITE_APP_TITLE=Kinit +VITE_APP_TITLE=后台系统-开发 diff --git a/kinit-admin/.env.gitee b/kinit-admin/.env.gitee deleted file mode 100644 index 0b509d8..0000000 --- a/kinit-admin/.env.gitee +++ /dev/null @@ -1,23 +0,0 @@ -# 环境 -NODE_ENV=production - -# 接口前缀 -VITE_API_BASEPATH=pro - -# 打包路径 -VITE_BASE_PATH=/kinit/ - -# 是否删除debugger -VITE_DROP_DEBUGGER=true - -# 是否删除console.log -VITE_DROP_CONSOLE=true - -# 是否sourcemap -VITE_SOURCEMAP=false - -# 输出路径 -VITE_OUT_DIR=dist-pro - -# 标题 -VITE_APP_TITLE=Kinit diff --git a/kinit-admin/.env.pro b/kinit-admin/.env.pro index 8b687fe..d8206ac 100644 --- a/kinit-admin/.env.pro +++ b/kinit-admin/.env.pro @@ -1,10 +1,7 @@ # 环境 NODE_ENV=production -# 接口前缀 -VITE_API_BASEPATH=pro - -# 打包路径 +# 访问基础路径 VITE_BASE_PATH=/ # 是否删除debugger @@ -16,8 +13,8 @@ VITE_DROP_CONSOLE=true # 是否sourcemap VITE_SOURCEMAP=false -# 输出路径 +# 打包输出路径 VITE_OUT_DIR=dist-pro # 标题 -VITE_APP_TITLE=Kinit +VITE_APP_TITLE=后台系统 diff --git a/kinit-admin/.env.test b/kinit-admin/.env.test deleted file mode 100644 index 47fc83d..0000000 --- a/kinit-admin/.env.test +++ /dev/null @@ -1,23 +0,0 @@ -# 环境 -NODE_ENV=production - -# 接口前缀 -VITE_API_BASEPATH=test - -# 打包路径 -VITE_BASE_PATH=/dist-test/ - -# 是否删除debugger -VITE_DROP_DEBUGGER=false - -# 是否删除console.log -VITE_DROP_CONSOLE=false - -# 是否sourcemap -VITE_SOURCEMAP=true - -# 输出路径 -VITE_OUT_DIR=dist-test - -# 标题 -VITE_APP_TITLE=Kinit diff --git a/kinit-admin/CHANGELOG.md b/kinit-admin/CHANGELOG.md index e41e0c3..bd72fa1 100644 --- a/kinit-admin/CHANGELOG.md +++ b/kinit-admin/CHANGELOG.md @@ -2,6 +2,86 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.8.3](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.8.2...v1.8.3) (2022-10-28) + + +### Performance Improvements + +* 优化描述组件 ([73ecc98](https://github.com/kailong321200875/vue-element-plus-admin/commit/73ecc98671d430013920246d98ce9ab1752e56eb)) + +## [1.8.2](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.8.1...v1.8.2) (2022-10-18) + + +### Bug Fixes + +* Correct spelling of words(aciton →action) ([eb405b2](https://github.com/kailong321200875/vue-element-plus-admin/commit/eb405b2a9041ca0ad4455db79bf617ec910dc485)) +* Correct spelling of words(tigger →trigger) ([c2ca2d7](https://github.com/kailong321200875/vue-element-plus-admin/commit/c2ca2d736c92e02380923a6741450844acb41a38)) + +## [1.8.1](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.8.0...v1.8.1) (2022-10-11) + + +### Bug Fixes + +* 修复cutMenu收起时 ([993af6b](https://github.com/kailong321200875/vue-element-plus-admin/commit/993af6bb6576249e66e0c0ea592ebf851f65ab8c)) + + +### Styling + +* cutMenu层级样式 ([32d2408](https://github.com/kailong321200875/vue-element-plus-admin/commit/32d2408588c487cff2cf73e3cc132e5105ff4459)) + +## [1.8.0](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.7.1...v1.8.0) (2022-10-10) + + +### Features + +* types优化 ([3351155](https://github.com/kailong321200875/vue-element-plus-admin/commit/33511553cd9055b036b2d7491f9c2eda123f8b22)) + + +### Styling + +* 优化第四种布局 ([122fa62](https://github.com/kailong321200875/vue-element-plus-admin/commit/122fa62d859413d16175e0d97c7bf13f232dbb3a)) + +## [1.7.1](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.7.0...v1.7.1) (2022-10-10) + + +### Bug Fixes + +* 修正types提示错误 ([ef3e006](https://github.com/kailong321200875/vue-element-plus-admin/commit/ef3e006859dcd8b93ffb7cffcaeae24cbb330f2a)) + +## [1.7.0](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.6.6...v1.7.0) (2022-10-09) + + +### Features + +* type抽离 ([8b4fa1a](https://github.com/kailong321200875/vue-element-plus-admin/commit/8b4fa1aa21aa2c1379288315ccd64a6f3375be51)) + +## [1.6.6](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.6.5...v1.6.6) (2022-10-09) + + +### Bug Fixes + +* table search params ([a62929a](https://github.com/kailong321200875/vue-element-plus-admin/commit/a62929a8dac21028d3dd1cddf98189492c33b093)) + +## [1.6.5](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.6.4...v1.6.5) (2022-10-08) + + +### Bug Fixes + +* The attribute of option does not work ([d946920](https://github.com/kailong321200875/vue-element-plus-admin/commit/d946920e61ed81beacf9f1f8be7ee1f50505f64d)) + + +### Performance Improvements + +* perf store ([d416178](https://github.com/kailong321200875/vue-element-plus-admin/commit/d416178d69ca6100be4b635922b1a22d27629f08)) +* token test ([b320e65](https://github.com/kailong321200875/vue-element-plus-admin/commit/b320e658d1a559a6eaebdf374d63649c223c2ecd)) + +## [1.6.4](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.6.3...v1.6.4) (2022-09-21) + + +### Bug Fixes + +* fix bug ([da39f3b](https://github.com/kailong321200875/vue-element-plus-admin/commit/da39f3bc904ca2d80f432a31709725f9a57deb19)) + ## [1.6.3](https://github.com/kailong321200875/vue-element-plus-admin/compare/v1.6.2...v1.6.3) (2022-08-20) diff --git a/kinit-admin/README.md b/kinit-admin/README.md index f7a0340..8ea862b 100644 --- a/kinit-admin/README.md +++ b/kinit-admin/README.md @@ -56,6 +56,12 @@ git clone https://github.com/kailong321200875/vue-element-plus-admin.git - 安装依赖 ```bash +临时修改 +pnpm --registry https://registry.npm.taobao.org install any-touch + +持久使用 +pnpm config set registry https://registry.npm.taobao.org + cd vue-element-plus-admin pnpm install diff --git a/kinit-admin/index.html b/kinit-admin/index.html index 507d616..0dd08ca 100644 --- a/kinit-admin/index.html +++ b/kinit-admin/index.html @@ -1,8 +1,8 @@ - + - + <%= title %> @@ -126,10 +126,11 @@
-
+ +
diff --git a/kinit-admin/mock/workplace/index.ts b/kinit-admin/mock/workplace/index.ts deleted file mode 100644 index 22d0ecc..0000000 --- a/kinit-admin/mock/workplace/index.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { config } from '@/config/axios/config' -import { MockMethod } from 'vite-plugin-mock' - -const { result_code } = config - -const timeout = 1000 - -export default [ - // 获取统计 - { - url: '/api/workplace/total', - method: 'get', - timeout, - response: () => { - return { - code: result_code, - data: { - project: 40, - access: 2340, - todo: 10 - } - } - } - }, - // 获取项目 - { - url: '/api/workplace/project', - method: 'get', - timeout, - response: () => { - return { - code: result_code, - data: [ - { - name: 'Github', - icon: 'akar-icons:github-fill', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - }, - { - name: 'Vue', - icon: 'logos:vue', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - }, - { - name: 'Angular', - icon: 'logos:angular-icon', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - }, - { - name: 'React', - icon: 'logos:react', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - }, - { - name: 'Webpack', - icon: 'logos:webpack', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - }, - { - name: 'Vite', - icon: 'vscode-icons:file-type-vite', - message: 'workplace.introduction', - personal: 'kinit', - time: new Date() - } - ] - } - } - }, - // 获取动态 - { - url: '/api/workplace/dynamic', - method: 'get', - timeout, - response: () => { - return { - code: result_code, - data: [ - { - keys: ['workplace.push', 'Github'], - time: new Date() - }, - { - keys: ['workplace.push', 'Github'], - time: new Date() - } - ] - } - } - }, - // 获取团队信息 - { - url: '/api/workplace/team', - method: 'get', - timeout, - response: () => { - return { - code: result_code, - data: [ - { - name: 'Github', - icon: 'akar-icons:github-fill' - }, - { - name: 'Vue', - icon: 'logos:vue' - }, - { - name: 'Angular', - icon: 'logos:angular-icon' - }, - { - name: 'React', - icon: 'logos:react' - }, - { - name: 'Webpack', - icon: 'logos:webpack' - }, - { - name: 'Vite', - icon: 'vscode-icons:file-type-vite' - } - ] - } - } - } -] as MockMethod[] diff --git a/kinit-admin/package.json b/kinit-admin/package.json index 1ccd1a4..4c354f2 100644 --- a/kinit-admin/package.json +++ b/kinit-admin/package.json @@ -1,20 +1,17 @@ { "name": "vue-element-plus-admin", - "version": "1.6.3", + "version": "1.8.4", "description": "一套基于vue3、element-plus、typesScript、vite3的后台集成方案。", "author": "Archer <502431556@qq.com>", "private": false, "scripts": { "i": "pnpm install", - "dev": "vite --mode base", + "dev": "vite --mode dev", "ts:check": "vue-tsc --noEmit", "build:pro": "vite build --mode pro", - "build:gitee": "vite build --mode gitee", "build:dev": "npm run ts:check && vite build --mode dev", - "build:test": "npm run ts:check && vite build --mode test", "serve:pro": "vite preview --mode pro", "serve:dev": "vite preview --mode dev", - "serve:test": "vite preview --mode test", "npm:check": "npx npm-check-updates", "clean": "npx rimraf node_modules", "clean:cache": "npx rimraf node_modules/.cache", @@ -23,84 +20,88 @@ "lint:style": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js", "prepare": "husky install", - "p": "plop" + "p": "plop", + "analysis": "windicss-analysis" }, "dependencies": { - "@iconify/iconify": "^2.2.1", - "@vueuse/core": "^9.1.1", - "@wangeditor/editor": "^5.1.14", + "@iconify/iconify": "^3.0.0", + "@vueuse/core": "^9.4.0", + "@wangeditor/editor": "^5.1.22", "@wangeditor/editor-for-vue": "^5.1.10", - "@zxcvbn-ts/core": "^2.0.4", + "@zxcvbn-ts/core": "^2.1.0", "animate.css": "^4.1.1", - "axios": "^0.27.2", - "echarts": "^5.3.3", + "axios": "^1.1.3", + "clipboard": "^2.0.11", + "echarts": "^5.4.0", "echarts-wordcloud": "^2.0.0", - "element-plus": "2.2.15", + "element-plus": "2.2.21", "intro.js": "^6.0.0", "lodash-es": "^4.17.21", "mitt": "^3.0.0", "mockjs": "^1.1.0", "nprogress": "^0.2.0", - "pinia": "^2.0.21", + "pinia": "^2.0.23", "pinia-plugin-persist": "^1.0.0", "qrcode": "^1.5.1", "qs": "^6.11.0", "url": "^0.11.0", - "vue": "3.2.37", + "vue": "3.2.41", "vue-i18n": "9.2.2", - "vue-router": "^4.1.5", + "vue-router": "^4.1.6", "vue-types": "^4.2.1", + "vue3-json-viewer": "^2.2.2", + "vuedraggable": "4.1.0", "web-storage-cache": "^1.1.1" }, "devDependencies": { - "@commitlint/cli": "^17.1.2", - "@commitlint/config-conventional": "^17.1.0", - "@iconify/json": "^2.1.100", - "@intlify/vite-plugin-vue-i18n": "^6.0.1", + "@commitlint/cli": "^17.2.0", + "@commitlint/config-conventional": "^17.2.0", + "@iconify/json": "^2.1.134", + "@intlify/vite-plugin-vue-i18n": "^6.0.3", "@purge-icons/generated": "^0.9.0", "@types/intro.js": "^5.1.0", "@types/lodash-es": "^4.17.6", - "@types/node": "^18.7.13", + "@types/node": "^18.11.9", "@types/nprogress": "^0.2.0", "@types/qrcode": "^1.5.0", "@types/qs": "^6.9.7", - "@typescript-eslint/eslint-plugin": "^5.35.1", - "@typescript-eslint/parser": "^5.35.1", - "@vitejs/plugin-vue": "^3.0.3", - "@vitejs/plugin-vue-jsx": "^2.0.0", - "autoprefixer": "^10.4.8", - "eslint": "^8.23.0", + "@typescript-eslint/eslint-plugin": "^5.42.0", + "@typescript-eslint/parser": "^5.42.0", + "@vitejs/plugin-vue": "^3.2.0", + "@vitejs/plugin-vue-jsx": "^2.1.0", + "autoprefixer": "^10.4.13", + "eslint": "^8.27.0", "eslint-config-prettier": "^8.5.0", - "eslint-define-config": "^1.6.0", + "eslint-define-config": "^1.11.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-vue": "^9.4.0", + "eslint-plugin-vue": "^9.7.0", "husky": "^8.0.1", "less": "^4.1.3", "lint-staged": "^13.0.3", "plop": "^3.1.1", - "postcss": "^8.4.16", + "postcss": "^8.4.18", "postcss-html": "^1.5.0", "postcss-less": "^6.0.0", "prettier": "^2.7.1", "rimraf": "^3.0.2", - "rollup": "^2.78.1", - "stylelint": "^14.11.0", + "rollup": "^3.2.5", + "stylelint": "^14.14.1", "stylelint-config-html": "^1.1.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-recommended": "^9.0.0", - "stylelint-config-standard": "^28.0.0", + "stylelint-config-standard": "^29.0.0", "stylelint-order": "^5.0.0", - "typescript": "4.8.2", - "unplugin-vue-macros": "^0.11.0", - "vite": "3.0.9", + "typescript": "4.8.4", + "unplugin-vue-macros": "^0.16.0", + "vite": "3.2.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-html": "^3.2.0", "vite-plugin-mock": "^2.9.6", - "vite-plugin-purge-icons": "^0.9.0", + "vite-plugin-purge-icons": "^0.9.1", "vite-plugin-style-import": "2.0.0", "vite-plugin-svg-icons": "^2.0.1", - "vite-plugin-windicss": "^1.8.7", - "vue-tsc": "^0.40.4", + "vite-plugin-windicss": "^1.8.8", + "vue-tsc": "^1.0.9", "windicss": "^3.5.6", "windicss-analysis": "^0.3.5" }, diff --git a/kinit-admin/src/App.vue b/kinit-admin/src/App.vue index 08d6b99..feb301d 100644 --- a/kinit-admin/src/App.vue +++ b/kinit-admin/src/App.vue @@ -5,6 +5,7 @@ import { ConfigGlobal } from '@/components/ConfigGlobal' import { isDark } from '@/utils/is' import { useDesign } from '@/hooks/web/useDesign' import { useCache } from '@/hooks/web/useCache' +import { getSystemSettingsClassifysApi } from '@/api/vadmin/system/settings' const { getPrefixCls } = useDesign() @@ -12,6 +13,36 @@ const prefixCls = getPrefixCls('app') const appStore = useAppStore() +// 手动添加mate标签 +const addMeta = (name: string, content: string) => { + const meta = document.createElement('meta') + meta.content = content + meta.name = name + document.getElementsByTagName('head')[0].appendChild(meta) +} + +// 获取并设置系统配置 +const setSystemConfig = async () => { + const res = await getSystemSettingsClassifysApi({ classify: 'web' }) + if (res) { + appStore.setTitle(res.data.web_basic.web_title || import.meta.env.VITE_APP_TITLE) + appStore.setLogoImage(res.data.web_basic.web_logo || '/static/system/logo.png') + appStore.setFooterContent(res.data.web_basic.web_copyright || 'Copyright ©2022-present K') + appStore.setIcpNumber(res.data.web_basic.web_icp_number || '') + addMeta( + 'description', + res.data.web_basic.web_desc || + 'Kinit 是一套开箱即用的中后台解决方案,可以作为新项目的启动模版。' + ) + // 接入百度统计 + if (res.data.web_baidu.web_baidu) { + eval(res.data.web_baidu.web_baidu) + } + } +} + +setSystemConfig() + const currentSize = computed(() => appStore.getCurrentSize) const greyMode = computed(() => appStore.getGreyMode) @@ -60,4 +91,14 @@ body { .@{prefix-cls}-grey-mode { filter: grayscale(100%); } + +ol { + display: block; + list-style-type: decimal; + margin-block-start: 1em; + margin-block-end: 1em; + margin-inline-start: 0px; + margin-inline-end: 0px; + padding-inline-start: 40px; +} diff --git a/kinit-admin/src/api/dashboard/analysis/index.ts b/kinit-admin/src/api/dashboard/analysis/index.ts new file mode 100644 index 0000000..5240286 --- /dev/null +++ b/kinit-admin/src/api/dashboard/analysis/index.ts @@ -0,0 +1,23 @@ +import request from '@/config/axios' +import type { + AnalysisBannersTypes, + UserAccessSource, + WeeklyUserActivity, + MonthlySales +} from './types' + +export const getBannersApi = (): Promise> => { + return request.get({ url: '/vadmin/analysis/banners/' }) +} + +export const getUserAccessSourceApi = (): Promise> => { + return request.get({ url: '/vadmin/analysis/user/access/source/' }) +} + +export const getWeeklyUserActivityApi = (): Promise> => { + return request.get({ url: '/vadmin/analysis/weekly/user/activity/' }) +} + +export const getMonthlySalesApi = (): Promise> => { + return request.get({ url: '/vadmin/analysis/monthly/sales/' }) +} diff --git a/kinit-admin/src/api/dashboard/analysis/types.ts b/kinit-admin/src/api/dashboard/analysis/types.ts new file mode 100644 index 0000000..9f0c1ed --- /dev/null +++ b/kinit-admin/src/api/dashboard/analysis/types.ts @@ -0,0 +1,20 @@ +export type AnalysisBannersTypes = { + id: number + image: string +} + +export type UserAccessSource = { + value: number + name: string +} + +export type WeeklyUserActivity = { + value: number + name: string +} + +export type MonthlySales = { + name: string + estimate: number + actual: number +} diff --git a/kinit-admin/src/api/dashboard/workplace/index.ts b/kinit-admin/src/api/dashboard/workplace/index.ts index 0880640..a25c948 100644 --- a/kinit-admin/src/api/dashboard/workplace/index.ts +++ b/kinit-admin/src/api/dashboard/workplace/index.ts @@ -1,22 +1,26 @@ import request from '@/config/axios' -import type { WorkplaceTotal, Project, Dynamic, Team, RadarData } from './types' +import type { WorkplaceTotal, Project, Dynamic, Team, RadarData, Shortcuts } from './types' export const getCountApi = (): Promise> => { - return request.get({ url: '/workplace/total' }) + return request.get({ url: '/vadmin/workplace/total/' }) } export const getProjectApi = (): Promise> => { - return request.get({ url: '/workplace/project' }) + return request.get({ url: '/vadmin/workplace/project/' }) } export const getDynamicApi = (): Promise> => { - return request.get({ url: '/workplace/dynamic' }) + return request.get({ url: '/vadmin/workplace/dynamic/' }) } export const getTeamApi = (): Promise> => { - return request.get({ url: '/workplace/team' }) + return request.get({ url: '/vadmin/workplace/team/' }) } export const getRadarApi = (): Promise> => { - return request.get({ url: '/workplace/radar' }) + return request.get({ url: '/vadmin/workplace/radar/' }) +} + +export const getShortcutsApi = (): Promise> => { + return request.get({ url: '/vadmin/workplace/shortcuts/' }) } diff --git a/kinit-admin/src/api/dashboard/workplace/types.ts b/kinit-admin/src/api/dashboard/workplace/types.ts index da23e74..713b4c6 100644 --- a/kinit-admin/src/api/dashboard/workplace/types.ts +++ b/kinit-admin/src/api/dashboard/workplace/types.ts @@ -9,6 +9,7 @@ export type Project = { icon: string message: string personal: string + link: string time: Date | number | string } @@ -28,3 +29,8 @@ export type RadarData = { max: number name: string } + +export type Shortcuts = { + name: string + link: string +} diff --git a/kinit-admin/src/api/login/index.ts b/kinit-admin/src/api/login/index.ts index 7b5fef5..b51a94a 100644 --- a/kinit-admin/src/api/login/index.ts +++ b/kinit-admin/src/api/login/index.ts @@ -8,3 +8,7 @@ export const loginApi = (data: UserLoginType): Promise => { export const getRoleMenusApi = (): Promise> => { return request.get({ url: '/auth/getMenuList/' }) } + +export const postSMSCodeApi = (params: any): Promise => { + return request.post({ url: '/vadmin/system/sms/send/', params }) +} diff --git a/kinit-admin/src/api/login/types.ts b/kinit-admin/src/api/login/types.ts index ddacc9c..233928c 100644 --- a/kinit-admin/src/api/login/types.ts +++ b/kinit-admin/src/api/login/types.ts @@ -1,6 +1,7 @@ export type UserLoginType = { telephone: string password: string + method: string } export type UserType = { diff --git a/kinit-admin/src/api/vadmin/auth/user.ts b/kinit-admin/src/api/vadmin/auth/user.ts index 87a04b4..18519da 100644 --- a/kinit-admin/src/api/vadmin/auth/user.ts +++ b/kinit-admin/src/api/vadmin/auth/user.ts @@ -31,3 +31,26 @@ export const postCurrentUserUpdateInfo = (data: any): Promise => { export const getCurrentUserInfo = (): Promise => { return request.get({ url: `/vadmin/auth/user/current/info/` }) } + +export const postExportUserQueryListApi = (params: any, data: any): Promise => { + return request.post({ url: `/vadmin/auth/user/export/query/list/to/excel/`, params, data }) +} + +export const getImportTemplateApi = (): Promise => { + return request.get({ url: `/vadmin/auth/user/download/import/template/` }) +} + +export const postImportUserApi = (data: any): Promise => { + return request.post({ + url: `/vadmin/auth/import/users/`, + headers: { + 'Content-Type': 'multipart/form-data' + }, + timeout: 5 * 60 * 1000, + data + }) +} + +export const postUsersInitPasswordSendSMSApi = (data: any): Promise => { + return request.post({ url: `/vadmin/auth/users/init/password/send/sms/`, data }) +} diff --git a/kinit-admin/src/api/vadmin/system/record/login.ts b/kinit-admin/src/api/vadmin/system/record/login.ts new file mode 100644 index 0000000..924a5b8 --- /dev/null +++ b/kinit-admin/src/api/vadmin/system/record/login.ts @@ -0,0 +1,5 @@ +import request from '@/config/axios' + +export const getRecordLoginListApi = (params: any): Promise => { + return request.get({ url: '/vadmin/record/logins/', params }) +} diff --git a/kinit-admin/src/api/vadmin/system/record/operation.ts b/kinit-admin/src/api/vadmin/system/record/operation.ts new file mode 100644 index 0000000..0d4dfaa --- /dev/null +++ b/kinit-admin/src/api/vadmin/system/record/operation.ts @@ -0,0 +1,5 @@ +import request from '@/config/axios' + +export const getRecordOperationListApi = (params: any): Promise => { + return request.get({ url: '/vadmin/record/operations/', params }) +} diff --git a/kinit-admin/src/api/vadmin/system/settings.ts b/kinit-admin/src/api/vadmin/system/settings.ts new file mode 100644 index 0000000..8156e50 --- /dev/null +++ b/kinit-admin/src/api/vadmin/system/settings.ts @@ -0,0 +1,17 @@ +import request from '@/config/axios' + +export const getSystemSettingsTabsApi = (params: any): Promise => { + return request.get({ url: '/vadmin/system/settings/tabs/', params }) +} + +export const getSystemSettingsApi = (params: any): Promise => { + return request.get({ url: '/vadmin/system/settings/tabs/values/', params }) +} + +export const putSystemSettingsApi = (data: any): Promise => { + return request.put({ url: '/vadmin/system/settings/tabs/values/', data }) +} + +export const getSystemSettingsClassifysApi = (params: any): Promise => { + return request.get({ url: '/vadmin/system/settings/classifys/', params }) +} diff --git a/kinit-admin/src/components/ConfigGlobal/src/ConfigGlobal.vue b/kinit-admin/src/components/ConfigGlobal/src/ConfigGlobal.vue index 985d5df..da6f8c7 100644 --- a/kinit-admin/src/components/ConfigGlobal/src/ConfigGlobal.vue +++ b/kinit-admin/src/components/ConfigGlobal/src/ConfigGlobal.vue @@ -7,13 +7,14 @@ import { useWindowSize } from '@vueuse/core' import { useAppStore } from '@/store/modules/app' import { setCssVar } from '@/utils' import { useDesign } from '@/hooks/web/useDesign' +import { ElementPlusSize } from '@/types/elementPlus' const { variables } = useDesign() const appStore = useAppStore() const props = defineProps({ - size: propTypes.oneOf(['default', 'small', 'large']).def('default') + size: propTypes.oneOf(['default', 'small', 'large']).def('default') }) provide('configGlobal', props) diff --git a/kinit-admin/src/components/ContextMenu/src/ContextMenu.vue b/kinit-admin/src/components/ContextMenu/src/ContextMenu.vue index 5007121..5e77307 100644 --- a/kinit-admin/src/components/ContextMenu/src/ContextMenu.vue +++ b/kinit-admin/src/components/ContextMenu/src/ContextMenu.vue @@ -4,7 +4,7 @@ import { PropType, ref } from 'vue' import { useI18n } from '@/hooks/web/useI18n' import { useDesign } from '@/hooks/web/useDesign' import type { RouteLocationNormalizedLoaded } from 'vue-router' - +import { contextMenuSchema } from '../../../types/contextMenu' const { getPrefixCls } = useDesign() const prefixCls = getPrefixCls('context-menu') diff --git a/kinit-admin/src/components/Descriptions/src/Descriptions.vue b/kinit-admin/src/components/Descriptions/src/Descriptions.vue index c59d74a..7fa023a 100644 --- a/kinit-admin/src/components/Descriptions/src/Descriptions.vue +++ b/kinit-admin/src/components/Descriptions/src/Descriptions.vue @@ -2,8 +2,9 @@ import { ElCollapseTransition, ElDescriptions, ElDescriptionsItem, ElTooltip } from 'element-plus' import { useDesign } from '@/hooks/web/useDesign' import { propTypes } from '@/utils/propTypes' -import { ref, unref, PropType, computed, useAttrs } from 'vue' +import { ref, unref, PropType, computed, useAttrs, useSlots } from 'vue' import { useAppStore } from '@/store/modules/app' +import { DescriptionsSchema } from '@/types/descriptions' const appStore = useAppStore() @@ -11,6 +12,8 @@ const mobile = computed(() => appStore.getMobile) const attrs = useAttrs() +const slots = useSlots() + const props = defineProps({ title: propTypes.string.def(''), message: propTypes.string.def(''), @@ -95,6 +98,9 @@ const toggleClick = () => { :direction="mobile ? 'vertical' : 'horizontal'" v-bind="getBindValue" > + { diff --git a/kinit-admin/src/components/SizeDropdown/src/SizeDropdown.vue b/kinit-admin/src/components/SizeDropdown/src/SizeDropdown.vue index 773ad62..cb8d9f8 100644 --- a/kinit-admin/src/components/SizeDropdown/src/SizeDropdown.vue +++ b/kinit-admin/src/components/SizeDropdown/src/SizeDropdown.vue @@ -5,6 +5,7 @@ import { useAppStore } from '@/store/modules/app' import { useI18n } from '@/hooks/web/useI18n' import { propTypes } from '@/utils/propTypes' import { useDesign } from '@/hooks/web/useDesign' +import { ElementPlusSize } from '@/types/elementPlus' const { getPrefixCls } = useDesign() @@ -20,7 +21,7 @@ const appStore = useAppStore() const sizeMap = computed(() => appStore.sizeMap) -const setCurrentSize = (size: ElememtPlusSize) => { +const setCurrentSize = (size: ElementPlusSize) => { appStore.setCurrentSize(size) } diff --git a/kinit-admin/src/components/TabMenu/src/TabMenu.vue b/kinit-admin/src/components/TabMenu/src/TabMenu.vue index 061421b..1ec61ca 100644 --- a/kinit-admin/src/components/TabMenu/src/TabMenu.vue +++ b/kinit-admin/src/components/TabMenu/src/TabMenu.vue @@ -1,7 +1,7 @@ + + diff --git a/kinit-admin/src/components/UserInfo/src/UserInfo.vue b/kinit-admin/src/components/UserInfo/src/UserInfo.vue index d665306..d92c296 100644 --- a/kinit-admin/src/components/UserInfo/src/UserInfo.vue +++ b/kinit-admin/src/components/UserInfo/src/UserInfo.vue @@ -1,5 +1,5 @@ + + + + diff --git a/kinit-admin/src/views/Dashboard/Workplace.vue b/kinit-admin/src/views/Dashboard/Workplace.vue index c72fa77..6475d03 100644 --- a/kinit-admin/src/views/Dashboard/Workplace.vue +++ b/kinit-admin/src/views/Dashboard/Workplace.vue @@ -6,8 +6,20 @@ import { ref, reactive } from 'vue' import { CountTo } from '@/components/CountTo' import { formatTime } from '@/utils' import { Highlight } from '@/components/Highlight' -import { getCountApi, getProjectApi, getDynamicApi, getTeamApi } from '@/api/dashboard/workplace' -import type { WorkplaceTotal, Project, Dynamic, Team } from '@/api/dashboard/workplace/types' +import { + getCountApi, + getProjectApi, + getDynamicApi, + getTeamApi, + getShortcutsApi +} from '@/api/dashboard/workplace' +import type { + WorkplaceTotal, + Project, + Dynamic, + Team, + Shortcuts +} from '@/api/dashboard/workplace/types' import { useCache } from '@/hooks/web/useCache' import { useAppStoreWithOut } from '@/store/modules/app' @@ -15,6 +27,10 @@ const { wsCache } = useCache() const loading = ref(true) +const toLink = (link: string) => { + window.open(link) +} + // 获取统计数 let totalSate = reactive({ project: 0, @@ -39,6 +55,18 @@ const getProject = async () => { } } +let shortcuts = reactive([]) + +// 获取快捷操作 +const getShortcuts = async () => { + const res = await getShortcutsApi().catch(() => {}) + if (res) { + shortcuts = Object.assign(shortcuts, res.data) + } +} + +getShortcuts() + // 获取动态 let dynamics = reactive([]) @@ -154,14 +182,16 @@ const user = wsCache.get(appStore.getUserInfo) :xs="24" > -
- - {{ item.name }} -
-
{{ t(item.message) }}
-
- {{ item.personal }} - {{ formatTime(item.time, 'yyyy-MM-dd') }} +
+
+ + {{ item.name }} +
+
{{ t(item.message) }}
+
+ {{ item.personal }} + {{ formatTime(item.time, 'yyyy-MM-dd') }} +
@@ -206,9 +236,18 @@ const user = wsCache.get(appStore.getUserInfo) {{ t('workplace.shortcutOperation') }} - - - {{ t('workplace.operation') }} + + + {{ item.name }} diff --git a/kinit-admin/src/views/Dashboard/components/Charts.vue b/kinit-admin/src/views/Dashboard/components/Charts.vue new file mode 100644 index 0000000..129056f --- /dev/null +++ b/kinit-admin/src/views/Dashboard/components/Charts.vue @@ -0,0 +1,125 @@ + + + diff --git a/kinit-admin/src/views/Dashboard/components/echarts-data.ts b/kinit-admin/src/views/Dashboard/components/echarts-data.ts new file mode 100644 index 0000000..dead29c --- /dev/null +++ b/kinit-admin/src/views/Dashboard/components/echarts-data.ts @@ -0,0 +1,310 @@ +import { EChartsOption } from 'echarts' +import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud' +import { useI18n } from '@/hooks/web/useI18n' + +const { t } = useI18n() + +export const lineOptions: EChartsOption = { + title: { + text: t('analysis.monthlySales'), + left: 'center' + }, + xAxis: { + data: [ + t('analysis.january'), + t('analysis.february'), + t('analysis.march'), + t('analysis.april'), + t('analysis.may'), + t('analysis.june'), + t('analysis.july'), + t('analysis.august'), + t('analysis.september'), + t('analysis.october'), + t('analysis.november'), + t('analysis.december') + ], + boundaryGap: false, + axisTick: { + show: false + } + }, + grid: { + left: 20, + right: 20, + bottom: 20, + top: 80, + containLabel: true + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross' + }, + padding: [5, 10] + }, + yAxis: { + axisTick: { + show: false + } + }, + legend: { + data: [t('analysis.estimate'), t('analysis.actual')], + top: 50 + }, + series: [ + { + name: t('analysis.estimate'), + smooth: true, + type: 'line', + data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123], + animationDuration: 2800, + animationEasing: 'cubicInOut' + }, + { + name: t('analysis.actual'), + smooth: true, + type: 'line', + itemStyle: {}, + data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123], + animationDuration: 2800, + animationEasing: 'quadraticOut' + } + ] +} + +export const pieOptions: EChartsOption = { + title: { + text: t('analysis.userAccessSource'), + left: 'center' + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c} ({d}%)' + }, + legend: { + orient: 'vertical', + left: 'left', + data: [ + t('analysis.directAccess'), + t('analysis.mailMarketing'), + t('analysis.allianceAdvertising'), + t('analysis.videoAdvertising'), + t('analysis.searchEngines') + ] + }, + series: [ + { + name: t('analysis.userAccessSource'), + type: 'pie', + radius: '55%', + center: ['50%', '60%'], + data: [ + { value: 335, name: t('analysis.directAccess') }, + { value: 310, name: t('analysis.mailMarketing') }, + { value: 234, name: t('analysis.allianceAdvertising') }, + { value: 135, name: t('analysis.videoAdvertising') }, + { value: 1548, name: t('analysis.searchEngines') } + ] + } + ] +} + +export const barOptions: EChartsOption = { + title: { + text: t('analysis.weeklyUserActivity'), + left: 'center' + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + grid: { + left: 50, + right: 20, + bottom: 20 + }, + xAxis: { + type: 'category', + data: [ + t('analysis.monday'), + t('analysis.tuesday'), + t('analysis.wednesday'), + t('analysis.thursday'), + t('analysis.friday'), + t('analysis.saturday'), + t('analysis.sunday') + ], + axisTick: { + alignWithLabel: true + } + }, + yAxis: { + type: 'value' + }, + series: [ + { + name: t('analysis.activeQuantity'), + data: [13253, 34235, 26321, 12340, 24643, 1322, 1324], + type: 'bar' + } + ] +} + +export const radarOption: EChartsOption = { + legend: { + data: [t('workplace.personal'), t('workplace.team')] + }, + radar: { + // shape: 'circle', + indicator: [ + { name: t('workplace.quote'), max: 65 }, + { name: t('workplace.contribution'), max: 160 }, + { name: t('workplace.hot'), max: 300 }, + { name: t('workplace.yield'), max: 130 }, + { name: t('workplace.follow'), max: 100 } + ] + }, + series: [ + { + name: `xxx${t('workplace.index')}`, + type: 'radar', + data: [ + { + value: [42, 30, 20, 35, 80], + name: t('workplace.personal') + }, + { + value: [50, 140, 290, 100, 90], + name: t('workplace.team') + } + ] + } + ] +} + +export const wordOptions: EChartsWordOption = { + series: [ + { + type: 'wordCloud', + gridSize: 2, + sizeRange: [12, 50], + rotationRange: [-90, 90], + shape: 'pentagon', + width: 600, + height: 400, + drawOutOfBound: true, + textStyle: { + color: function () { + return ( + 'rgb(' + + [ + Math.round(Math.random() * 160), + Math.round(Math.random() * 160), + Math.round(Math.random() * 160) + ].join(',') + + ')' + ) + } + }, + emphasis: { + textStyle: { + shadowBlur: 10, + shadowColor: '#333' + } + }, + data: [ + { + name: 'Sam S Club', + value: 10000, + textStyle: { + color: 'black' + }, + emphasis: { + textStyle: { + color: 'red' + } + } + }, + { + name: 'Macys', + value: 6181 + }, + { + name: 'Amy Schumer', + value: 4386 + }, + { + name: 'Jurassic World', + value: 4055 + }, + { + name: 'Charter Communications', + value: 2467 + }, + { + name: 'Chick Fil A', + value: 2244 + }, + { + name: 'Planet Fitness', + value: 1898 + }, + { + name: 'Pitch Perfect', + value: 1484 + }, + { + name: 'Express', + value: 1112 + }, + { + name: 'Home', + value: 965 + }, + { + name: 'Johnny Depp', + value: 847 + }, + { + name: 'Lena Dunham', + value: 582 + }, + { + name: 'Lewis Hamilton', + value: 555 + }, + { + name: 'KXAN', + value: 550 + }, + { + name: 'Mary Ellen Mark', + value: 462 + }, + { + name: 'Farrah Abraham', + value: 366 + }, + { + name: 'Rita Ora', + value: 360 + }, + { + name: 'Serena Williams', + value: 282 + }, + { + name: 'NCAA baseball tournament', + value: 273 + }, + { + name: 'Point Break', + value: 265 + } + ] + } + ] +} diff --git a/kinit-admin/src/views/Dashboard/echarts-data.ts b/kinit-admin/src/views/Dashboard/echarts-data.ts new file mode 100644 index 0000000..dead29c --- /dev/null +++ b/kinit-admin/src/views/Dashboard/echarts-data.ts @@ -0,0 +1,310 @@ +import { EChartsOption } from 'echarts' +import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud' +import { useI18n } from '@/hooks/web/useI18n' + +const { t } = useI18n() + +export const lineOptions: EChartsOption = { + title: { + text: t('analysis.monthlySales'), + left: 'center' + }, + xAxis: { + data: [ + t('analysis.january'), + t('analysis.february'), + t('analysis.march'), + t('analysis.april'), + t('analysis.may'), + t('analysis.june'), + t('analysis.july'), + t('analysis.august'), + t('analysis.september'), + t('analysis.october'), + t('analysis.november'), + t('analysis.december') + ], + boundaryGap: false, + axisTick: { + show: false + } + }, + grid: { + left: 20, + right: 20, + bottom: 20, + top: 80, + containLabel: true + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross' + }, + padding: [5, 10] + }, + yAxis: { + axisTick: { + show: false + } + }, + legend: { + data: [t('analysis.estimate'), t('analysis.actual')], + top: 50 + }, + series: [ + { + name: t('analysis.estimate'), + smooth: true, + type: 'line', + data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123], + animationDuration: 2800, + animationEasing: 'cubicInOut' + }, + { + name: t('analysis.actual'), + smooth: true, + type: 'line', + itemStyle: {}, + data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123], + animationDuration: 2800, + animationEasing: 'quadraticOut' + } + ] +} + +export const pieOptions: EChartsOption = { + title: { + text: t('analysis.userAccessSource'), + left: 'center' + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c} ({d}%)' + }, + legend: { + orient: 'vertical', + left: 'left', + data: [ + t('analysis.directAccess'), + t('analysis.mailMarketing'), + t('analysis.allianceAdvertising'), + t('analysis.videoAdvertising'), + t('analysis.searchEngines') + ] + }, + series: [ + { + name: t('analysis.userAccessSource'), + type: 'pie', + radius: '55%', + center: ['50%', '60%'], + data: [ + { value: 335, name: t('analysis.directAccess') }, + { value: 310, name: t('analysis.mailMarketing') }, + { value: 234, name: t('analysis.allianceAdvertising') }, + { value: 135, name: t('analysis.videoAdvertising') }, + { value: 1548, name: t('analysis.searchEngines') } + ] + } + ] +} + +export const barOptions: EChartsOption = { + title: { + text: t('analysis.weeklyUserActivity'), + left: 'center' + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + grid: { + left: 50, + right: 20, + bottom: 20 + }, + xAxis: { + type: 'category', + data: [ + t('analysis.monday'), + t('analysis.tuesday'), + t('analysis.wednesday'), + t('analysis.thursday'), + t('analysis.friday'), + t('analysis.saturday'), + t('analysis.sunday') + ], + axisTick: { + alignWithLabel: true + } + }, + yAxis: { + type: 'value' + }, + series: [ + { + name: t('analysis.activeQuantity'), + data: [13253, 34235, 26321, 12340, 24643, 1322, 1324], + type: 'bar' + } + ] +} + +export const radarOption: EChartsOption = { + legend: { + data: [t('workplace.personal'), t('workplace.team')] + }, + radar: { + // shape: 'circle', + indicator: [ + { name: t('workplace.quote'), max: 65 }, + { name: t('workplace.contribution'), max: 160 }, + { name: t('workplace.hot'), max: 300 }, + { name: t('workplace.yield'), max: 130 }, + { name: t('workplace.follow'), max: 100 } + ] + }, + series: [ + { + name: `xxx${t('workplace.index')}`, + type: 'radar', + data: [ + { + value: [42, 30, 20, 35, 80], + name: t('workplace.personal') + }, + { + value: [50, 140, 290, 100, 90], + name: t('workplace.team') + } + ] + } + ] +} + +export const wordOptions: EChartsWordOption = { + series: [ + { + type: 'wordCloud', + gridSize: 2, + sizeRange: [12, 50], + rotationRange: [-90, 90], + shape: 'pentagon', + width: 600, + height: 400, + drawOutOfBound: true, + textStyle: { + color: function () { + return ( + 'rgb(' + + [ + Math.round(Math.random() * 160), + Math.round(Math.random() * 160), + Math.round(Math.random() * 160) + ].join(',') + + ')' + ) + } + }, + emphasis: { + textStyle: { + shadowBlur: 10, + shadowColor: '#333' + } + }, + data: [ + { + name: 'Sam S Club', + value: 10000, + textStyle: { + color: 'black' + }, + emphasis: { + textStyle: { + color: 'red' + } + } + }, + { + name: 'Macys', + value: 6181 + }, + { + name: 'Amy Schumer', + value: 4386 + }, + { + name: 'Jurassic World', + value: 4055 + }, + { + name: 'Charter Communications', + value: 2467 + }, + { + name: 'Chick Fil A', + value: 2244 + }, + { + name: 'Planet Fitness', + value: 1898 + }, + { + name: 'Pitch Perfect', + value: 1484 + }, + { + name: 'Express', + value: 1112 + }, + { + name: 'Home', + value: 965 + }, + { + name: 'Johnny Depp', + value: 847 + }, + { + name: 'Lena Dunham', + value: 582 + }, + { + name: 'Lewis Hamilton', + value: 555 + }, + { + name: 'KXAN', + value: 550 + }, + { + name: 'Mary Ellen Mark', + value: 462 + }, + { + name: 'Farrah Abraham', + value: 366 + }, + { + name: 'Rita Ora', + value: 360 + }, + { + name: 'Serena Williams', + value: 282 + }, + { + name: 'NCAA baseball tournament', + value: 273 + }, + { + name: 'Point Break', + value: 265 + } + ] + } + ] +} diff --git a/kinit-admin/src/views/Home/components/InfoWrite.vue b/kinit-admin/src/views/Home/components/InfoWrite.vue index e8b42d1..a2aacb3 100644 --- a/kinit-admin/src/views/Home/components/InfoWrite.vue +++ b/kinit-admin/src/views/Home/components/InfoWrite.vue @@ -81,6 +81,9 @@ const loading = ref(false) // 提交 const save = async () => { + if (authStore.getUser.id === 1) { + return ElMessage.warning('编辑账号为演示账号,无权限操作!') + } const formRef = unref(elFormRef) await formRef?.validate(async (isValid) => { if (isValid) { diff --git a/kinit-admin/src/views/Home/components/PasswordWrite.vue b/kinit-admin/src/views/Home/components/PasswordWrite.vue index c1b721e..039069f 100644 --- a/kinit-admin/src/views/Home/components/PasswordWrite.vue +++ b/kinit-admin/src/views/Home/components/PasswordWrite.vue @@ -75,6 +75,9 @@ const loading = ref(false) // 提交 const save = async () => { + if (authStore.getUser.id === 1) { + return ElMessage.warning('编辑账号为演示账号,无权限操作!') + } const formRef = unref(elFormRef) await formRef?.validate(async (isValid) => { if (isValid) { diff --git a/kinit-admin/src/views/Login/Login.vue b/kinit-admin/src/views/Login/Login.vue index 615d12c..7379ab4 100644 --- a/kinit-admin/src/views/Login/Login.vue +++ b/kinit-admin/src/views/Login/Login.vue @@ -1,11 +1,13 @@