This commit is contained in:
zpc 2025-07-29 19:22:24 +08:00
commit 049828db85
279 changed files with 37090 additions and 0 deletions

22
.editorconfig Normal file
View File

@ -0,0 +1,22 @@
# 告诉EditorConfig插件这是根文件不用继续往上查找
root = true
# 匹配全部文件
[*]
# 设置字符集
charset = utf-8
# 缩进风格可选space、tab
indent_style = space
# 缩进的空格数
indent_size = 2
# 结尾换行符可选lf、cr、crlf
end_of_line = lf
# 在文件结尾插入新行
insert_final_newline = true
# 删除一行中的前后空格
trim_trailing_whitespace = true
# 匹配md结尾的文件
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

3
.env Normal file
View File

@ -0,0 +1,3 @@
# 页面标题
VITE_APP_TITLE = 'ZRAdmin.NET'

16
.env.development Normal file
View File

@ -0,0 +1,16 @@
# 开发环境配置
ENV = 'development'
VITE_APP_API_HOST = 'http://localhost:8888'
# 开发环境
VITE_APP_BASE_API = '/dev-api'
# 路由前缀
VITE_APP_ROUTER_PREFIX = '/'
# 默认上传地址
VITE_APP_UPLOAD_URL = '/Common/UploadFile'
#socket API
VITE_APP_SOCKET_API = '/msghub'

18
.env.production Normal file
View File

@ -0,0 +1,18 @@
# 生产环境配置
ENV = 'production'
# 生产环境
VITE_APP_BASE_API = '/prod-api'
# 路由前缀
VITE_APP_ROUTER_PREFIX = '/'
# 默认上传地址
VITE_APP_UPLOAD_URL = '/Common/UploadFile'
#socket API
VITE_APP_SOCKET_API = '/msghub'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

18
.env.staging Normal file
View File

@ -0,0 +1,18 @@
# 测试环境配置
ENV = 'staging'
# 测试环境
VITE_APP_BASE_API = '/stage-api'
# 路由前缀
VITE_APP_ROUTER_PREFIX = '/'
# 默认上传地址
VITE_APP_UPLOAD_URL = '/Common/UploadFile'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
#socket API
VITE_APP_SOCKET_API = '/msghub'

14
.eslintignore Normal file
View File

@ -0,0 +1,14 @@
# 忽略build目录下类型为js的文件的语法检查
build/*.js
# 忽略src/assets目录下文件的语法检查
src/assets
# 忽略public目录下文件的语法检查
public
# 忽略当前目录下为js的文件的语法检查
# *.js
# 忽略当前目录下为vue的文件的语法检查
# *.vue
/node_modules/
/vite/
.eslintrc.js
.prettierrc.js

199
.eslintrc.js Normal file
View File

@ -0,0 +1,199 @@
// ESlint 检查配置
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}

63
.gitattributes vendored Normal file
View File

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log
.vs/*
tests/**/coverage/
tests/e2e/reports
selenium-debug.log
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
package-lock.json
yarn.lock
/deploy.js

12
.jsbeautifyrc Normal file
View File

@ -0,0 +1,12 @@
{
"brace_style": "none,preserve-inline",
"indent_size": 2,
"indent_char": " ",
"jslint_happy": true,
"unformatted": [
""
],
"css": {
"indent_size": 2
}
}

38
.prettierrc.cjs Normal file
View File

@ -0,0 +1,38 @@
module.exports = {
// 超过最大值换行
printWidth: 148,
// 使用 2 个空格缩进
tabWidth: 2,
// 不使用缩进符,而使用空格
useTabs: false,
// 行尾不需要有分号
semi: false,
// 使用单引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: 'as-needed',
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>"默认none
trailingComma: 'none',
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: true,
bracketSameLine: true,
// 箭头函数always只有一个参数的时候也需要括号,'avoid'箭头函数只有一个参数的时候可以忽略括号
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier
requirePragma: false,
// 不需要自动在文件开头插入 @prettier
insertPragma: false,
// 使用默认的折行标准
proseWrap: 'preserve',
// 根据显示样式决定 html 要不要折行
htmlWhitespaceSensitivity: 'css',
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
endOfLine: 'auto'
}

59
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,59 @@
{
"editor.fontSize": 15,
"editor.insertSpaces": false,
"editor.bracketPairColorization.enabled": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
// eslintvue
"eslint.validate": ["javascript", "typescript", "vue"],
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[ts]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[js]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// prettier
"editor.formatOnSave": true,
// eslint --fix
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"eslint.autoFixOnSave": "explicit"
},
"eslint.options": {
"overrideConfig": {
"env": {
"browser": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"ecmaFeatures": {
"jsx": false
}
},
"rules": {
"no-debugger": "off"
}
}
},
"i18n-ally.displayLanguage": "zh-cn",
"i18n-ally.enabledParsers": ["json", "js"],
"i18n-ally.localesPaths": ["src/i18n/lang", "src/i18n/pages/login", "src/i18n/pages/menu"],
"i18n-ally.extract.parsers.html": {
"attributes": ["text", "title", "alt", "placeholder", "label", "aria-label"],
"ignoredTags": ["script", "style"],
"vBind": true,
"inlineText": true
},
"i18n-ally.keystyle": "nested"
}

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 791736813@qq.com zr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

103
README.md Normal file
View File

@ -0,0 +1,103 @@
<h2 align="center"> ZRAdmin.NET后台管理系统</h2>
<p align="center">
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 🍟 概述
- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
- 配套后端代码仓库地址[ZRAdmin.NET](https://gitee.com/izory/ZrAdminNetCore/) 版本。
- 前端采用 Vue3.0、Element UI Plus、vite、compisition api、Pinia 等。
- 支持加载动态权限菜单,多方式轻松权限控制
- 腾讯云秒杀场:[点我进入](https://curl.qcloud.com/4yEoRquq)。
- 腾讯云优惠券:[点我领取](https://curl.qcloud.com/5J4nag8D)。
- 七牛云通用云产品优惠券:[点我进入](https://s.qiniu.com/FzEfay)。
```
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,这样作者才有继续免费下去的动力,谢谢!~
```
## 🍿 在线体验
- 官方文档http://www.izhaorui.cn
- 体验地址http://demo.izhaorui.cn/vue3
- 管理员admin
- 密 码123456
```
由于是个人项目,资金有限,体验服是低配,请大家爱惜,轻戳,不胜感激!!!
```
## 🍁 前端运行
```bash
# 克隆项目
git clone https://gitee.com/izory/ZRAdmin-vue.git
# 进入项目目录
cd ZRAdmin-vue
# 安装依赖
yarn --registry=https://registry.npm.taobao.org --strict-ssl false
yarn --registry=https://registry.npmmirror.com
# 启动服务
yarn dev
# 构建测试环境 yarn build:stage
# 构建生产环境 yarn build:prod
# 前端访问地址 http://localhost:8887
```
## 🍖 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。(支持多语言)
5. 角色管理:角色菜单权限分配。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
8. 登录日志:系统登录日志记录查询包含登录异常。
9. 系统接口:使用 swagger 生成相关 api 接口文档。
10. 参数设置:常用参数配置
11. 发送邮件:可以对多个用户进行发送邮件
12. 任务系统:基于 Quartz.NET可以在线添加、修改、删除、手动执行)任务调度包含执行结果日志。
13. 文章管理:可以写文章记录。
14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、SQL 文件等),支持下载,自定义配置前端展示控件、让开发更快捷高效。
15. 文件管理:可以进行上传文件管理,目前支持上传到本地、阿里云
16. 通知管理:系统通知公告信息发布维护
17. 参数管理:对系统动态配置常用参数。
18. 多语言管理:动态修改多语言翻译
19. 账号注册:可以注册账号登录系统。
20. 多语言管理:支持静态、后端动态配置国际化。目前只支持中、英、繁体(仅支持 vue3)
21. 在线用户:可以查看正在登录使用的用户,可以对其踢出、通知操作
22. db 审计日志:数据库审计功能
23. 三方登录:提供三方登录实现逻辑
24. 导入导出:支持中文表头导入、字典数据转换成文本导出
25. 数据大屏:更直观的展示数据
## 🎉 优势
1. 前台系统不用编写登录、授权、认证模块;只负责编写业务模块即可
2. 后台系统无需任何二次开发,直接发布即可使用
3. 前台与后台系统分离,分别为不同的系统(域名可独立)
4. 全局异常统一处理
5. 自定义的代码生成功能
6. 国际化
## 💐 特别鸣谢
- 👉Ruoyi.vue[Ruoyi](http://www.ruoyi.vip/)
- 👉zb-admin: [zb-admin](https://gitee.com/yuanzbz/vue-admin-perfect)
## 🎀 捐赠
如果这个项目对您有所帮助,请扫下方二维码打赏作者喝杯咖啡。
<img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/pay.jpg"/>
## 源码地址
- [Gitee](https://gitee.com/izory/ZrAdminNetCore/)
- [Github](https://github.com/izhaorui/ZrAdmin.NET/)

12
bat/build.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成dist文件。
echo.
%~d0
cd %~dp0
cd ..
yarn build:prod
pause

12
bat/package.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 安装Web工程生成node_modules文件。
echo.
%~d0
cd %~dp0
cd ..
yarn --registry=https://registry.npm.taobao.org
pause

12
bat/run-web.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 使用 Vite 命令运行 Web 工程。
echo.
%~d0
cd %~dp0
cd ..
yarn dev
pause

46
html/ie.html Normal file

File diff suppressed because one or more lines are too long

139
index.html Normal file
View File

@ -0,0 +1,139 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>ZRAdmin.NET管理系统</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
.first-loading-wrp {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 90vh;
min-height: 90vh;
}
.first-loading-wrp>h1 {
font-size: 30px;
font-weight: bolder;
}
.first-loading-wrp .loading-wrp {
display: flex;
align-items: center;
justify-content: center;
padding: 48px;
}
.dot {
position: relative;
box-sizing: border-box;
display: inline-block;
width: 45px;
height: 45px;
font-size: 64px;
transform: rotate(45deg);
animation: antRotate 1.2s infinite linear;
}
.dot i {
position: absolute;
display: block;
width: 16px;
height: 16px;
background-color: #1890ff;
border-radius: 100%;
opacity: 0.3;
transform: scale(0.75);
transform-origin: 50% 50%;
animation: antSpinMove 1s infinite linear alternate;
}
.dot i:nth-child(1) {
top: 0;
left: 0;
}
.dot i:nth-child(2) {
top: 0;
right: 0;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.dot i:nth-child(3) {
right: 0;
bottom: 0;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.dot i:nth-child(4) {
bottom: 0;
left: 0;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s;
}
@keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@-webkit-keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@keyframes antSpinMove {
to {
opacity: 1;
}
}
@-webkit-keyframes antSpinMove {
to {
opacity: 1;
}
}
</style>
</head>
<body>
<div id="app">
<div class="first-loading-wrp">
<div class="loading-wrp">
<span class="dot dot-spin"> <i></i> <i></i> <i></i> <i></i> </span>
</div>
<h5>正在加载系统资源...</h5>
</div>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

11
jsconfig.json Normal file
View File

@ -0,0 +1,11 @@
/* vscode使 */
{
"compilerOptions": {
"experimentalDecorators": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist", ".vscode"]
}

64
package.json Normal file
View File

@ -0,0 +1,64 @@
{
"name": "zr.admin",
"version": "v20240105",
"description": "ZRAdmin.NET管理系统",
"author": "ZR",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "vite",
"build:prod": "vite build",
"build:stage": "vite build --mode staging",
"preview": "vite preview"
},
"repository": {
"type": "git",
"url": "https://gitee.com/izory/ZrAdminNetCore"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@microsoft/signalr": "^8.0.0",
"@vueuse/core": "^10.7.0",
"@wangeditor/editor": "^5.1.1",
"@wangeditor/editor-for-vue": "^5.1.11",
"axios": "^1.6.2",
"crypto-js": "^4.1.1",
"echarts": "5.2.2",
"element-plus": "^2.9.0",
"file-saver": "2.0.5",
"fuse.js": "6.4.6",
"highlight.js": "^11.5.1",
"js-cookie": "3.0.1",
"jsencrypt": "3.2.1",
"md-editor-v3": "^4.9.0",
"nprogress": "0.2.0",
"pinia": "^2.3.0",
"pinia-plugin-persistedstate": "^3.2.3",
"qrcodejs2-fixes": "^0.0.2",
"qs": "^6.11.0",
"sortablejs": "^1.15.6",
"v-code-diff": "^1.8.0",
"vue": "^3.5.13",
"vue-clipboard3": "^2.0.0",
"vue-countup-v3": "^1.4.0",
"vue-cropper": "1.0.2",
"vue-i18n": "9.2.2",
"vue-router": "^4.5.0",
"vxe-pc-ui": "^4.0.12",
"vxe-table": "^4.9.16",
"xe-utils": "^3.5.32"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"@vue/compiler-sfc": "^3.3.4",
"consola": "^3.2.3",
"sass": "^1.82.0",
"unplugin-auto-import": "^0.17.2",
"vite": "^6.0.2",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-lazy-import": "^1.0.7",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-setup-extend": "^0.4.0"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

62
src/App.vue Normal file
View File

@ -0,0 +1,62 @@
<template>
<el-config-provider :locale="locale" :size="size">
<router-view />
</el-config-provider>
</template>
<script setup>
import useUserStore from './store/modules/user'
import useAppStore from './store/modules/app'
import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn' //
import en from 'element-plus/dist/locale/en' //
import thTw from 'element-plus/dist/locale/zh-tw' //
import defaultSettings from '@/settings'
const { proxy } = getCurrentInstance()
const token = computed(() => {
return useUserStore().userId
})
const lang = computed(() => {
return useAppStore().lang
})
const locale = ref(zhCn)
const size = ref(defaultSettings.defaultSize)
size.value = useAppStore().size
watch(
token,
(val) => {
if (val) {
proxy.signalr.start().then(async (res) => {
if (res) {
await proxy.signalr.SR.invoke('logOut')
}
})
}
},
{
immediate: true,
deep: true
}
)
watch(
lang,
(val) => {
if (val == 'en') {
locale.value = en
} else if (val == 'zh-tw') {
locale.value = thTw
} else {
locale.value = zhCn
}
},
{
immediate: true
}
)
console.log('🎉源码地址: https://gitee.com/izory/ZrAdminNetCore')
console.log('📖官方文档http://www.izhaorui.cn')
console.log('💰打赏作者http://www.izhaorui.cn/doc/support.html')
console.log('📱移动端体验http://www.izhaorui.cn/h5')
</script>

View File

@ -0,0 +1,96 @@
import request from '@/utils/request'
// 查询列表
export function listArticle(query) {
return request({
url: '/Article/list',
method: 'get',
params: query
})
}
// 查询最新列表
export function listNewArticle(query) {
return request({
url: '/Article/newList',
method: 'get',
params: query
})
}
// 查询详细
export function getArticle(Id) {
return request({
url: '/Article/' + Id,
method: 'get'
})
}
// 新增
export function addArticle(data) {
return request({
url: '/Article/add',
method: 'post',
data: data
})
}
// 修改
export function updateArticle(data) {
return request({
url: '/Article/edit',
method: 'put',
data: data
})
}
// 删除文章
export function delArticle(id) {
return request({
url: '/Article/' + id,
method: 'delete'
})
}
// 查询目录
export function listArticleCategory() {
return request({
url: '/Article/CategoryList',
method: 'get'
})
}
// 查询文章目录树
export function listArticleCategoryTree() {
return request({
url: '/Article/CategoryTreeList',
menubar: 'get'
})
}
// 置顶
export function topArticle(data) {
return request({
url: '/Article/top',
method: 'put',
data: data
})
}
// 修改是否公开
export function changeArticlePublic(data) {
return request({
url: '/Article/ChangePublic',
method: 'put',
data: data
})
}
/**
* 审核
* @param type 审核类型 pass ,reject
* @param ids id
*/
export function auditArticle(type, ids, data) {
return request({
url: `article/${type}/${ids}`,
method: 'PUT',
params: data
})
}

View File

@ -0,0 +1,88 @@
import request from '@/utils/request'
/**
* 文章目录分页查询
* @param {查询条件} data
*/
export function listArticleCategory(query) {
return request({
url: 'article/ArticleCategory/list',
method: 'get',
params: query
})
}
/**
* 文章目录tree查询
* @param {查询条件} data
*/
export function treelistArticleCategory(query) {
return request({
url: 'article/ArticleCategory/treelist',
method: 'get',
params: query
})
}
/**
* 新增文章目录
* @param data
*/
export function addArticleCategory(data) {
return request({
url: 'article/ArticleCategory',
method: 'post',
data: data
})
}
/**
* 修改文章目录
* @param data
*/
export function updateArticleCategory(data) {
return request({
url: 'article/ArticleCategory',
method: 'PUT',
data: data
})
}
/**
* 获取文章目录详情
* @param {Id}
*/
export function getArticleCategory(id) {
return request({
url: 'article/ArticleCategory/' + id,
method: 'get'
})
}
/**
* 删除文章目录
* @param {主键} pid
*/
export function delArticleCategory(pid) {
return request({
url: 'article/ArticleCategory/' + pid,
method: 'delete'
})
}
// 导出文章目录
export function exportArticleCategory(query) {
return request({
url: 'article/ArticleCategory/export',
method: 'get',
params: query
})
}
export function changeSort(data) {
return request({
url: 'article/ArticleCategory/ChangeSort',
method: 'get',
params: data
})
}

View File

@ -0,0 +1,62 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 话题分页查询
* @param {查询条件} data
*/
export function listArticleTopic(query) {
return request({
url: 'article/ArticleTopic/list',
method: 'get',
params: query
})
}
/**
* 新增话题
* @param data
*/
export function addArticleTopic(data) {
return request({
url: 'article/ArticleTopic',
method: 'post',
data: data
})
}
/**
* 修改话题
* @param data
*/
export function updateArticleTopic(data) {
return request({
url: 'article/ArticleTopic',
method: 'PUT',
data: data
})
}
/**
* 获取话题详情
* @param {Id}
*/
export function getArticleTopic(id) {
return request({
url: 'article/ArticleTopic/' + id,
method: 'get'
})
}
/**
* 删除话题
* @param {主键} pid
*/
export function delArticleTopic(pid) {
return request({
url: 'article/ArticleTopic/delete/' + pid,
method: 'delete'
})
}
// 导出话题
export async function exportArticleTopic(query) {
await downFile('article/ArticleTopic/export', { ...query })
}

23
src/api/common.js Normal file
View File

@ -0,0 +1,23 @@
import request from '@/utils/request'
export function upload(data) {
return request({
url: '/common/UploadFile',
method: 'POST',
data: data,
headers: { 'Content-Type': 'multipart/form-data' }
})
}
/**
* 发送邮件
* @param {*} data
* @returns
*/
export function sendEmail(data) {
return request({
url: '/common/SendEmail',
method: 'POST',
data: data
})
}

9
src/api/monitor/cache.js Normal file
View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
// 查询缓存详细
export function getCache() {
return request({
url: '/monitor/cache',
method: 'get'
})
}

114
src/api/monitor/job.js Normal file
View File

@ -0,0 +1,114 @@
import request from '@/utils/request'
export function queryTasks(data) {
return request({
url: '/system/tasks/list',
method: 'get',
params: data
})
}
export function getTasks(id) {
return request({
url: '/system/tasks/get?id=' + id,
method: 'get'
})
}
/**
*
* 获取所有任务
* @returns
*/
export function getAllTasks() {
return request({
url: '/system/tasks/getAll',
method: 'get'
})
}
/**
* 创建任务
* @param {*} data
* @returns
*/
export function createTasks(data) {
return request({
url: '/system/tasks/create',
method: 'post',
data
})
}
/**
* 更新任务
* @param {*} data
* @returns
*/
export function updateTasks(data) {
return request({
url: '/system/tasks/update',
method: 'post',
data
})
}
/**
* 删除任务
* @param {*} id
* @returns
*/
export function deleteTasks(id) {
return request({
url: '/system/tasks/delete?id=' + id,
method: 'delete'
})
}
/**
* 启动任务
* @param {*} id
* @returns
*/
export function startTasks(id) {
return request({
url: '/system/tasks/start?id=' + id,
method: 'get'
})
}
/**
* 停止任务
* @param {*} id
* @returns
*/
export function stopTasks(id) {
return request({
url: '/system/tasks/stop?id=' + id,
method: 'get'
})
}
/**
* 运行一次
* @param {*} id
* @returns
*/
export function runTasks(id) {
return request({
url: '/system/tasks/run?id=' + id,
method: 'get'
})
}
/**
* 导出
* @returns
*/
export function exportTasks() {
return request({
url: '/system/tasks/export',
method: 'get'
})
}
export default { queryTasks, getTasks, getAllTasks, createTasks, updateTasks, deleteTasks, startTasks, stopTasks, runTasks, exportTasks }

35
src/api/monitor/jobLog.js Normal file
View File

@ -0,0 +1,35 @@
import request from '@/utils/request'
// 查询调度日志列表
export function listJobLog(query) {
return request({
url: '/monitor/jobLog/list',
method: 'get',
params: query
})
}
// 删除调度日志
export function delJobLog(jobLogId) {
return request({
url: '/monitor/jobLog/' + jobLogId,
method: 'delete'
})
}
// 清空调度日志
export function cleanJobLog() {
return request({
url: '/monitor/jobLog/clean',
method: 'delete'
})
}
// 导出调度日志
export function exportJobLog(query) {
return request({
url: '/monitor/jobLog/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询登录日志列表
export function list(query) {
return request({
url: '/monitor/logininfor/list',
method: 'get',
params: query
})
}
// 查询我的登录日志列表
export function queryMylist(query) {
return request({
url: '/monitor/logininfor/mylist',
method: 'get',
params: query
})
}
// 删除登录日志
export function delLogininfor(infoId) {
return request({
url: '/monitor/logininfor/' + infoId,
method: 'delete'
})
}
// 清空登录日志
export function cleanLogininfor() {
return request({
url: '/monitor/logininfor/clean',
method: 'delete'
})
}
// 导出登录日志
export function exportLogininfor(query) {
return request({
url: '/monitor/logininfor/export',
method: 'get',
params: query
})
}

28
src/api/monitor/online.js Normal file
View File

@ -0,0 +1,28 @@
import request from '@/utils/request'
// 查询在线用户列表
export function listOnline(query) {
return request({
url: '/monitor/online/list',
method: 'get',
params: query
})
}
// 强退用户
export function forceLogout(data) {
return request({
url: '/monitor/online/force',
method: 'delete',
data: data
})
}
// 批量强退用户
export function forceLogoutAll(data) {
return request({
url: '/monitor/online/batchForce',
method: 'delete',
data: data
})
}

View File

@ -0,0 +1,39 @@
import request from '@/utils/request'
import QS from 'qs'
// 查询操作日志列表
export function list(query) {
return request({
url: '/monitor/operlog/list',
method: 'get',
params: query,
paramsSerializer: function (params) {
return QS.stringify(params, { indices: false })
}
})
}
// 删除操作日志
export function delOperlog(operId) {
return request({
url: '/monitor/operlog/' + operId,
method: 'delete'
})
}
// 清空操作日志
export function cleanOperlog() {
return request({
url: '/monitor/operlog/clean',
method: 'delete'
})
}
// 导出操作日志
export function exportOperlog(query) {
return request({
url: '/monitor/operlog/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
// 查询服务器详细
export function getServer() {
return request({
url: '/monitor/server',
method: 'get'
})
}

View File

@ -0,0 +1,29 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 数据差异日志分页查询
* @param {查询条件} data
*/
export function listSqlDiffLog(query) {
return request({
url: 'monitor/SqlDiffLog/list',
method: 'get',
params: query
})
}
/**
* 删除数据差异日志
* @param {主键} pid
*/
export function delSqlDiffLog(pid) {
return request({
url: 'monitor/SqlDiffLog/' + pid,
method: 'delete'
})
}
// 导出数据差异日志
export async function exportSqlDiffLog(query) {
await downFile('monitor/SqlDiffLog/export', { ...query })
}

View File

@ -0,0 +1,51 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 用户在线时长分页查询
* @param {查询条件} data
*/
export function listUserOnlineLog(query) {
return request({
url: 'monitor/UserOnlineLog/list',
method: 'get',
params: query,
})
}
/**
* 新增用户在线时长
* @param data
*/
export function addUserOnlineLog(data) {
return request({
url: 'monitor/UserOnlineLog',
method: 'post',
data: data,
})
}
/**
* 获取用户在线时长详情
* @param {Id}
*/
export function getUserOnlineLog(id) {
return request({
url: 'monitor/UserOnlineLog/' + id,
method: 'get'
})
}
/**
* 删除用户在线时长
* @param {主键} pid
*/
export function delUserOnlineLog(pid) {
return request({
url: 'monitor/UserOnlineLog/delete/' + pid,
method: 'delete'
})
}
// 导出用户在线时长
export async function exportUserOnlineLog(query) {
await downFile('monitor/UserOnlineLog/export', { ...query })
}

View File

@ -0,0 +1,69 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 广告管理分页查询
* @param {查询条件} data
*/
export function listBannerConfig(query) {
return request({
url: 'public/BannerConfig/list',
method: 'get',
params: query,
})
}
/**
* 新增广告管理
* @param data
*/
export function addBannerConfig(data) {
return request({
url: 'public/BannerConfig',
method: 'post',
data: data,
})
}
/**
* 修改广告管理
* @param data
*/
export function updateBannerConfig(data) {
return request({
url: 'public/BannerConfig',
method: 'PUT',
data: data,
})
}
/**
* 获取广告管理详情
* @param {Id}
*/
export function getBannerConfig(id) {
return request({
url: 'public/BannerConfig/' + id,
method: 'get'
})
}
/**
* 删除广告管理
* @param {主键} pid
*/
export function delBannerConfig(pid) {
return request({
url: 'public/BannerConfig/delete/' + pid,
method: 'delete'
})
}
// 导出广告管理
export async function exportBannerConfig(query) {
await downFile('public/BannerConfig/export', { ...query })
}
export function changeSort(data) {
return request({
url: 'public/BannerConfig/ChangeSort',
method: 'get',
params: data
})
}

View File

@ -0,0 +1,100 @@
import request from '@/utils/request'
/**
* 多语言配置分页查询
* @param {查询条件} data
*/
export function listCommonLang(query) {
return request({
url: 'system/CommonLang/list',
method: 'get',
params: query
})
}
/**
* 多语言配置查询
* @param {查询条件} data
*/
export function listLangByLocale(locale) {
return request({
url: 'system/CommonLang/list/' + locale,
method: 'get'
})
}
/**
* 新增多语言配置
* @param data
*/
export function addCommonLang(data) {
return request({
url: 'system/CommonLang',
method: 'post',
data: data
})
}
/**
* 修改多语言配置
* @param data
*/
export function updateCommonLang(data) {
return request({
url: 'system/CommonLang',
method: 'PUT',
data: data
})
}
/**
* 获取多语言配置详情
* @param {Id}
*/
export function getCommonLang(id) {
return request({
url: 'system/CommonLang/' + id,
method: 'get'
})
}
/**
* 获取多语言配置详情
* @param {key}
*/
export function getCommonLangByKey(key) {
return request({
url: 'system/CommonLang/key/' + key,
method: 'get'
})
}
/**
* 删除多语言配置
* @param {主键} pid
*/
export function delCommonLang(pid) {
return request({
url: 'system/CommonLang/' + pid,
method: 'delete'
})
}
/**
* 删除多语言配置
* @param {key} langkey
*/
export function delCommonLangByKey(langkey) {
return request({
url: 'system/CommonLang/ByKey',
method: 'delete',
params: { langkey }
})
}
// 导出多语言配置
export function exportCommonLang(query) {
return request({
url: 'system/CommonLang/export',
method: 'get',
params: query
})
}

69
src/api/system/config.js Normal file
View File

@ -0,0 +1,69 @@
import request from '@/utils/request'
// 查询参数列表
export function listConfig(query) {
return request({
url: '/system/config/list',
method: 'get',
params: query
})
}
// 查询参数详细
export function getConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'get'
})
}
// 根据参数键名查询参数值
export function getConfigKey(configKey) {
return request({
url: '/system/config/configKey/' + configKey,
method: 'get'
})
}
// 新增参数配置
export function addConfig(data) {
return request({
url: '/system/config',
method: 'post',
data: data
})
}
// 修改参数配置
export function updateConfig(data) {
return request({
url: '/system/config',
method: 'put',
data: data
})
}
// 删除参数配置
export function delConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'delete'
})
}
// 刷新参数缓存
export function refreshCache() {
return request({
url: '/system/config/refreshCache',
method: 'delete'
})
}
// 导出参数
// export function exportConfig(query) {
// return request({
// url: '/system/config/export',
// method: 'get',
// params: query
// })
// }

68
src/api/system/dept.js Normal file
View File

@ -0,0 +1,68 @@
import request from '@/utils/request'
// 查询部门列表
export function listDept(query) {
return request({
url: '/system/dept/list',
method: 'get',
params: query
})
}
// 查询部门列表(排除节点)
export function listDeptExcludeChild(deptId) {
return request({
url: '/system/dept/list/exclude/' + deptId,
method: 'get'
})
}
// 查询部门详细
export function getDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'get'
})
}
// 查询部门下拉树结构
export function treeselect() {
return request({
url: '/system/dept/treeselect',
method: 'get'
})
}
// 根据角色ID查询部门树结构
export function roleDeptTreeselect(roleId) {
return request({
url: '/system/dept/roleDeptTreeselect/' + roleId,
method: 'get'
})
}
// 新增部门
export function addDept(data) {
return request({
url: '/system/dept',
method: 'post',
data: data
})
}
// 修改部门
export function updateDept(data) {
return request({
url: '/system/dept',
method: 'put',
data: data
})
}
// 删除部门
export function delDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'delete'
})
}

View File

@ -0,0 +1,89 @@
import request from '@/utils/request'
// 查询字典数据列表
export function listData(query) {
return request({
url: '/system/dict/data/list',
method: 'get',
params: query
})
}
// 查询字典数据详细
export function getData(dictCode) {
return request({
url: '/system/dict/data/info/' + dictCode,
method: 'get'
})
}
// 根据字典类型查询字典数据信息
export function getDicts(dictType) {
if (typeof dictType === 'object') {
var data = dictType.map((x) => {
if (typeof x === 'object') {
return x.dictType
} else {
return x
}
})
return request({
url: '/system/dict/data/dicts',
data: data,
method: 'post'
})
} else {
return request({
url: '/system/dict/data/type/' + dictType,
method: 'get'
})
}
}
// 新增字典数据
export function addData(data) {
return request({
url: '/system/dict/data',
method: 'post',
data: data
})
}
// 修改字典数据
export function updateData(data) {
return request({
url: '/system/dict/data',
method: 'put',
data: data
})
}
// 状态修改
export function changeStatus(dictCode, status) {
const data = {
dictCode,
status
}
return request({
url: '/system/dict/data/changeStatus',
method: 'put',
data: data
})
}
// 删除字典数据
export function delData(dictCode) {
return request({
url: '/system/dict/data/' + dictCode,
method: 'delete'
})
}
// 导出字典数据
export function exportData(query) {
return request({
url: '/system/dict/data/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,69 @@
import request from '@/utils/request'
// 查询字典类型列表
export function listType(query) {
return request({
url: '/system/dict/type/list',
method: 'get',
params: query
})
}
// 查询字典类型详细
export function getType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'get'
})
}
// 新增字典类型
export function addType(data) {
return request({
url: '/system/dict/type/edit',
method: 'post',
data: data
})
}
// 修改字典类型
export function updateType(data) {
return request({
url: '/system/dict/type/edit',
method: 'put',
data: data
})
}
// 删除字典类型
export function delType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'delete'
})
}
// 清理参数缓存
export function clearCache() {
return request({
url: '/system/dict/type/clearCache',
method: 'delete'
})
}
// 导出字典类型
export function exportType(query) {
return request({
url: '/system/dict/type/export',
method: 'get',
params: query
})
}
// 获取字典选择框列表
export function optionselect() {
return request({
url: '/system/dict/type/optionselect',
method: 'get'
})
}

View File

@ -0,0 +1,46 @@
import request from '@/utils/request'
/**
* 邮件发送记录分页查询
* @param {查询条件} data
*/
export function listEmailLog(query) {
return request({
url: 'system/EmailLog/list',
method: 'get',
params: query,
})
}
/**
* 新增邮件发送记录
* @param data
*/
export function sendEmail(data) {
return request({
url: 'system/EmailLog/sendEmail',
method: 'post',
data: data,
})
}
/**
* 获取邮件发送记录详情
* @param {Id}
*/
export function getEmailLog(id) {
return request({
url: 'system/EmailLog/' + id,
method: 'get'
})
}
/**
* 删除邮件发送记录
* @param {主键} pid
*/
export function delEmailLog(pid) {
return request({
url: 'system/EmailLog/' + pid,
method: 'delete'
})
}

View File

@ -0,0 +1,57 @@
import request from '@/utils/request'
/**
* 邮件模板分页查询
* @param {查询条件} data
*/
export function listEmailTpl(query) {
return request({
url: 'system/EmailTpl/list',
method: 'get',
params: query,
})
}
/**
* 新增邮件模板
* @param data
*/
export function addEmailTpl(data) {
return request({
url: 'system/EmailTpl',
method: 'post',
data: data,
})
}
/**
* 修改邮件模板
* @param data
*/
export function updateEmailTpl(data) {
return request({
url: 'system/EmailTpl',
method: 'PUT',
data: data,
})
}
/**
* 获取邮件模板详情
* @param {Id}
*/
export function getEmailTpl(id) {
return request({
url: 'system/EmailTpl/' + id,
method: 'get'
})
}
/**
* 删除邮件模板
* @param {主键} pid
*/
export function delEmailTpl(pid) {
return request({
url: 'system/EmailTpl/' + pid,
method: 'delete'
})
}

118
src/api/system/login.js Normal file
View File

@ -0,0 +1,118 @@
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid, clientId) {
const data = {
username,
password,
code,
uuid,
clientId
}
return request({
url: '/login',
method: 'POST',
data: data,
headers: {
userName: username
}
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
}
// 退出方法
export function logout() {
return request({
url: '/LogOut',
method: 'POST'
})
}
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
method: 'get'
})
}
/**
* 注册
* @returns
*/
export function register(data) {
return request({
url: '/register',
method: 'post',
data: data
})
}
/**
* 三方授权回调
* @param {*} data
* @param {*} params
* @returns
*/
export function oauthCallback(data, params) {
return request({
url: '/auth/callback',
method: 'post',
data: data,
params: params
})
}
/**
* 生成二维码
* @param {*} data
* @returns
*/
export function generateQrcode(data) {
return request({
url: '/GenerateQrcode',
method: 'GET',
params: data
})
}
/**
* 刷新二维码
* @param {*} data
* @returns
*/
export function verifyScan(data) {
return request({
url: '/VerifyScan',
method: 'post',
data: data
})
}
/**
* 发送短信验证码
* @param {*} data
* @returns
*/
export function checkMobile(data) {
return request({
method: 'post',
data: data,
url: '/checkMobile'
})
}
// 登录方法
export function phoneLogin(data) {
return request({
url: '/phoneLogin',
method: 'POST',
data: data
})
}

92
src/api/system/menu.js Normal file
View File

@ -0,0 +1,92 @@
import request from '@/utils/request'
// 查询菜单列表
export function listMenu(query) {
return request({
url: '/system/menu/treelist',
method: 'get',
params: query
})
}
// 查询菜单列表
export function listMenuById(menuId) {
return request({
url: '/system/menu/list/' + menuId,
method: 'get'
})
}
// 查询菜单详细
export function getMenu(menuId) {
return request({
url: '/system/menu/' + menuId,
method: 'get'
})
}
// 查询菜单下拉树结构
export function treeselect() {
return request({
url: '/system/Menu/treeSelect',
method: 'get'
})
}
// 根据角色ID查询菜单下拉树结构
export function roleMenuTreeselect(roleId) {
return request({
url: '/system/menu/roleMenuTreeselect/' + roleId,
method: 'get'
})
}
// 新增菜单
export const addMenu = (data) => {
return request({
url: '/system/menu/add',
method: 'put',
data: data
})
}
// 修改菜单
export function updateMenu(data) {
return request({
url: '/system/Menu/edit',
method: 'post',
data: data
})
}
// 删除菜单
export function delMenu(menuId) {
return request({
url: '/system/Menu/' + menuId,
method: 'delete'
})
}
// 删除菜单
export function delAllMenu(menuId) {
return request({
url: '/system/Menu/deleteAll/' + menuId,
method: 'delete'
})
}
//排序
export function changeMenuSort(data) {
return request({
url: '/system/Menu/ChangeSort',
method: 'GET',
params: data
})
}
// 获取路由
export const getRouters = (query) => {
return request({
url: '/getRouters',
method: 'get',
params: query
})
}

61
src/api/system/notice.js Normal file
View File

@ -0,0 +1,61 @@
import request from '@/utils/request'
// 导航栏查询公告列表
export function queryNotice(query) {
return request({
url: '/system/notice/queryNotice',
method: 'get',
params: query
})
}
// 查询公告列表
export function listNotice(query) {
return request({
url: '/system/notice/list',
method: 'get',
params: query
})
}
// 查询公告详细
export function getNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'get'
})
}
// 新增公告
export function addNotice(data) {
return request({
url: '/system/notice',
method: 'post',
data: data
})
}
// 修改公告
export function updateNotice(data) {
return request({
url: '/system/notice',
method: 'put',
data: data
})
}
// 删除公告
export function delNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'delete'
})
}
// 发送通知公告
export function sendNotice(noticeId) {
return request({
url: '/system/notice/send/' + noticeId,
method: 'PUT'
})
}

54
src/api/system/post.js Normal file
View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
// 查询岗位列表
export function listPost(query) {
return request({
url: '/system/post/list',
method: 'get',
params: query
})
}
// 查询岗位详细
export function getPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'get'
})
}
// 新增岗位
export function addPost(data) {
return request({
url: '/system/post',
method: 'post',
data: data
})
}
// 修改岗位
export function updatePost(data) {
return request({
url: '/system/post',
method: 'put',
data: data
})
}
// 删除岗位
export function delPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'delete'
})
}
// 导出岗位
export async function exportPost(query) {
// return request({
// url: '/system/post/export',
// method: 'get',
// params: query
// })
await downFile('/system/post/export', query)
}

80
src/api/system/role.js Normal file
View File

@ -0,0 +1,80 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
// 查询角色列表
export function listRole(query) {
return request({
url: '/system/role/list',
method: 'get',
params: query
})
}
// 查询角色详细
export function getRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'get'
})
}
// 新增角色
export const addRole = (data) => {
return request({
url: '/system/role/edit',
method: 'post',
data: data
})
}
// 修改角色
export function updateRole(data) {
return request({
url: '/system/role/edit',
method: 'put',
data: data
})
}
// 角色数据权限
export function dataScope(data) {
return request({
url: '/system/role/dataScope',
method: 'put',
data: data
})
}
// 角色状态修改
export function changeRoleStatus(roleId, status) {
const data = {
roleId,
status
}
return request({
url: '/system/role/changeStatus',
method: 'put',
data: data
})
}
// 删除角色
export function delRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'delete'
})
}
// 导出角色
export function exportRole(query) {
return request({
url: '/system/role/export',
method: 'get',
params: query
})
}
// 导出角色菜单
export async function exportRoleMenu(query) {
await downFile('/system/role/exportRoleMenu', { ...query })
}

View File

@ -0,0 +1,40 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 短信验证码记录分页查询
* @param {查询条件} data
*/
export function listSmscodeLog(query) {
return request({
url: 'system/SmscodeLog/list',
method: 'get',
params: query
})
}
/**
* 获取短信验证码记录详情
* @param {Id}
*/
export function getSmscodeLog(id) {
return request({
url: 'system/SmscodeLog/' + id,
method: 'get'
})
}
/**
* 删除短信验证码记录
* @param {主键} pid
*/
export function delSmscodeLog(pid) {
return request({
url: 'system/SmscodeLog/' + pid,
method: 'delete'
})
}
// 导出短信验证码记录
export async function exportSmscodeLog(query) {
await downFile('system/SmscodeLog/export', { ...query })
}

View File

@ -0,0 +1,82 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 用户系统消息分页查询
* @param {查询条件} data
*/
export function listSysUserMsg(query) {
return request({
url: 'SysUserMsg/list',
method: 'get',
params: query
})
}
/**
* 用户系统消息分页查询
* @param {查询条件} data
*/
export function listMySysUserMsg(query) {
return request({
url: 'SysUserMsg/mylist',
method: 'get',
params: query
})
}
/**
* 新增用户系统消息
* @param data
*/
export function addSysUserMsg(data) {
return request({
url: 'SysUserMsg',
method: 'post',
data: data
})
}
/**
* 获取用户系统消息详情
* @param {Id}
*/
export function getSysUserMsg(id) {
return request({
url: 'SysUserMsg/' + id,
method: 'get'
})
}
/**
* 删除用户系统消息
* @param {主键} pid
*/
export function delSysUserMsg(pid) {
return request({
url: 'SysUserMsg/delete/' + pid,
method: 'delete'
})
}
// 清空用户系统消息
export function clearSysUserMsg() {
return request({
url: 'SysUserMsg/clean',
method: 'delete'
})
}
// 导出用户系统消息
export async function exportSysUserMsg(query) {
await downFile('SysUserMsg/export', { ...query })
}
/**
* 已读用户系统消息
* @param data
*/
export function readSysUserMsg(msgId, msgType) {
return request({
url: 'SysUserMsg/read/' + msgId + '/' + msgType,
method: 'post',
params: { msgType }
})
}

View File

@ -0,0 +1,70 @@
import request from '@/utils/request'
/**
* 三方账号绑定分页查询
* @param {查询条件} data
*/
export function listThirdAccount(query) {
return request({
url: 'system/ThirdAccount/list',
method: 'get',
params: query,
})
}
/**
* 新增三方账号绑定
* @param data
*/
export function addThirdAccount(data) {
return request({
url: 'system/ThirdAccount',
method: 'post',
data: data,
})
}
/**
* 修改三方账号绑定
* @param data
*/
export function updateThirdAccount(data) {
return request({
url: 'system/ThirdAccount',
method: 'PUT',
data: data,
})
}
/**
* 获取三方账号绑定详情
* @param {Id}
*/
export function getThirdAccount(id) {
return request({
url: 'system/ThirdAccount/' + id,
method: 'get'
})
}
/**
* 删除三方账号绑定
* @param {主键} pid
*/
export function delThirdAccount(pid) {
return request({
url: 'system/ThirdAccount/' + pid,
method: 'delete'
})
}
// 导出三方账号绑定
export function exportThirdAccount(query) {
return request({
url: 'system/ThirdAccount/export',
method: 'get',
params: query
})
}

131
src/api/system/user.js Normal file
View File

@ -0,0 +1,131 @@
import request from '@/utils/request'
import { praseStrZero } from '@/utils/ruoyi'
import { downFile } from '@/utils/request'
// 查询用户列表
export function listUser(query) {
return request({
url: '/system/user/list',
method: 'get',
params: query
})
}
// 查询用户详细
export function getUser(userId) {
return request({
url: '/system/user/' + praseStrZero(userId),
method: 'get'
})
}
// 新增用户
export function addUser(data) {
return request({
url: '/system/user/add',
method: 'post',
data: data
})
}
// 修改用户
export function updateUser(data) {
return request({
url: '/system/user/edit',
method: 'put',
data: data
})
}
// 删除用户
export function delUser(userId) {
return request({
url: '/system/user/' + userId,
method: 'delete'
})
}
// 导出用户
export async function exportUser(query) {
// return request({
// url: '/system/User/export',
// method: 'get',
// params: query
// })
await downFile('/system/user/export', { ...query })
}
// 用户密码重置
export function resetUserPwd(userId, password) {
const data = {
userId,
password
}
return request({
url: '/system/user/resetPwd',
method: 'put',
data: data
})
}
// 用户状态修改
export function changeUserStatus(userId, status) {
const data = {
userId,
status
}
return request({
url: '/system/user/changeStatus',
method: 'put',
data: data
})
}
// 查询用户个人信息
export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
}
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
}
// 用户头像上传
export function uploadAvatar(data) {
return request({
url: '/system/user/profile/avatar',
method: 'post',
data: data,
headers: { 'Content-Type': 'multipart/form-data' }
})
}
// 下载用户导入模板
export function importTemplate() {
return request({
url: '/system/user/importTemplate',
method: 'get',
responseType: 'blob' //1.首先设置responseType对象格式为 blob:
})
}

View File

@ -0,0 +1,37 @@
import request from '@/utils/request'
// 查询角色用户
export function getRoleUsers(query) {
return request({
url: '/system/userRole/list',
method: 'get',
params: query,
})
}
// 添加角色用户
export function createRoleUsers(data) {
return request({
url: '/system/userRole/create',
method: 'post',
data
})
}
// 删除角色用户
export function deleteRoleUsers(data) {
return request({
url: '/system/userRole/delete',
method: 'post',
data
})
}
// 查询角色未添加用户列表
export function getExcludeUsers(query) {
return request({
url: '/system/userRole/getExcludeUsers',
method: 'get',
params: query,
})
}
// export default { getRoleUsers, getExcludeUsers }

68
src/api/tool/file.js Normal file
View File

@ -0,0 +1,68 @@
import request from '@/utils/request'
/**
* 文件存储分页查询
* @param {查询条件} data
*/
export function listSysfile(query) {
return request({
url: 'tool/file/list',
method: 'get',
params: query
})
}
/**
* 新增文件存储
* @param data
*/
export function addSysfile(data) {
return request({
url: 'tool/file',
method: 'post',
data: data
})
}
/**
* 修改文件存储
* @param data
*/
export function updateSysfile(data) {
return request({
url: 'tool/file',
method: 'PUT',
data: data
})
}
/**
* 获取文件存储详情
* @param {Id}
*/
export function getSysfile(id) {
return request({
url: 'tool/file/' + id,
method: 'get'
})
}
/**
* 删除文件存储
* @param {主键} pid
*/
export function delSysfile(pid) {
return request({
url: 'tool/file/' + pid,
method: 'delete'
})
}
// 导出文件存储
export function exportSysfile(query) {
return request({
url: 'tool/file/export',
method: 'get',
params: query
})
}

103
src/api/tool/gen.js Normal file
View File

@ -0,0 +1,103 @@
import request from '@/utils/request'
/**
* 获取数据库
*/
export function codeGetDBList() {
return request({
url: 'tool/gen/getDbList',
method: 'get'
})
}
/**
* 获取数据库表
*/
export function listDbTable(data) {
return request({
url: 'tool/gen/getTableList',
method: 'get',
params: data
})
}
/**
* 生成代码
*/
export async function codeGenerator(data) {
return await request({
url: 'tool/gen/genCode',
method: 'POST',
data: data
})
}
/**
* 获取表格列信息
* @param {*} data
* @returns
*/
export function queryColumnInfo(tableId) {
return request({
url: 'tool/gen/Column/' + tableId,
method: 'GET'
})
}
// 查询生成表数据
export function listTable(params) {
return request({
url: 'tool/gen/list',
method: 'get',
params: params
})
}
// 查询表详细信息
export function getGenTable(tableId) {
return request({
url: '/tool/gen/' + tableId,
method: 'get'
})
}
// 导入表
export function importTable(data) {
return request({
url: '/tool/gen/importTable',
method: 'post',
data: data
})
}
// 删除表数据
export function delTable(tableId) {
return request({
url: '/tool/gen/' + tableId,
method: 'delete'
})
}
// 修改代码生成表信息
export function updateGenTable(data) {
return request({
url: '/tool/gen/',
method: 'put',
data: data
})
}
// 预览生成代码
export function previewTable(tableId, data) {
return request({
url: '/tool/gen/preview/' + tableId,
method: 'post',
params: data
})
}
// 同步数据库
export function synchDb(tableId, data) {
return request({
url: '/tool/gen/synchDb/' + tableId,
method: 'get',
params: data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,399 @@
@font-face {
font-family: "iconfont"; /* Project id 4017520 */
src: url('iconfont.woff2?t=1695878634619') format('woff2'),
url('iconfont.woff?t=1695878634619') format('woff'),
url('iconfont.ttf?t=1695878634619') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-exit-fullscreen:before {
content: "\e66d";
}
.icon-validCode:before {
content: "\e621";
}
.icon-index:before {
content: "\e61f";
}
.icon-tree-table:before {
content: "\e637";
}
.icon-unlock:before {
content: "\e654";
}
.icon-zujian:before {
content: "\e655";
}
.icon-theme:before {
content: "\e659";
}
.icon-swagger:before {
content: "\e65c";
}
.icon-star:before {
content: "\e661";
}
.icon-time:before {
content: "\e662";
}
.icon-upload:before {
content: "\e663";
}
.icon-weixin:before {
content: "\e664";
}
.icon-system:before {
content: "\e667";
}
.icon-web:before {
content: "\e668";
}
.icon-tree:before {
content: "\e669";
}
.icon-user:before {
content: "\e66a";
}
.icon-tool:before {
content: "\e66b";
}
.icon-zip:before {
content: "\e66c";
}
.icon-link:before {
content: "\e636";
}
.icon-list:before {
content: "\e638";
}
.icon-international:before {
content: "\e639";
}
.icon-language:before {
content: "\e63a";
}
.icon-ipvisits:before {
content: "\e63c";
}
.icon-money:before {
content: "\e63d";
}
.icon-message:before {
content: "\e63e";
}
.icon-login:before {
content: "\e63f";
}
.icon-lock:before {
content: "\e640";
}
.icon-menu:before {
content: "\e641";
}
.icon-log:before {
content: "\e643";
}
.icon-logininfor:before {
content: "\e644";
}
.icon-mnt:before {
content: "\e645";
}
.icon-password:before {
content: "\e646";
}
.icon-peoples:before {
content: "\e647";
}
.icon-post:before {
content: "\e648";
}
.icon-permission:before {
content: "\e649";
}
.icon-phone:before {
content: "\e64a";
}
.icon-people:before {
content: "\e64b";
}
.icon-online:before {
content: "\e64d";
}
.icon-pdf:before {
content: "\e64f";
}
.icon-redis:before {
content: "\e650";
}
.icon-size:before {
content: "\e651";
}
.icon-search:before {
content: "\e652";
}
.icon-server:before {
content: "\e653";
}
.icon-select:before {
content: "\e656";
}
.icon-question:before {
content: "\e657";
}
.icon-rate:before {
content: "\e658";
}
.icon-monitor:before {
content: "\e65a";
}
.icon-source:before {
content: "\e65b";
}
.icon-role:before {
content: "\e65d";
}
.icon-shopping:before {
content: "\e65e";
}
.icon-skill:before {
content: "\e65f";
}
.icon-number:before {
content: "\e660";
}
.icon-a-404:before {
content: "\e622";
}
.icon-email:before {
content: "\e623";
}
.icon-example:before {
content: "\e624";
}
.icon-error:before {
content: "\e625";
}
.icon-excel:before {
content: "\e626";
}
.icon-education:before {
content: "\e627";
}
.icon-eye-open:before {
content: "\e628";
}
.icon-eye:before {
content: "\e629";
}
.icon-github:before {
content: "\e62b";
}
.icon-guide:before {
content: "\e62c";
}
.icon-gonggao:before {
content: "\e62d";
}
.icon-icon1:before {
content: "\e62e";
}
.icon-fullscreen:before {
content: "\e62f";
}
.icon-icon:before {
content: "\e630";
}
.icon-image:before {
content: "\e631";
}
.icon-form:before {
content: "\e632";
}
.icon-job:before {
content: "\e635";
}
.icon-cascader:before {
content: "\e603";
}
.icon-alipay:before {
content: "\e604";
}
.icon-anq:before {
content: "\e605";
}
.icon-backup:before {
content: "\e606";
}
.icon-bug:before {
content: "\e607";
}
.icon-button:before {
content: "\e609";
}
.icon-chain:before {
content: "\e60b";
}
.icon-chart:before {
content: "\e60c";
}
.icon-checkbox:before {
content: "\e60d";
}
.icon-clipboard:before {
content: "\e60e";
}
.icon-codeConsole:before {
content: "\e60f";
}
.icon-code:before {
content: "\e610";
}
.icon-color:before {
content: "\e611";
}
.icon-database:before {
content: "\e612";
}
.icon-component:before {
content: "\e613";
}
.icon-dashboard:before {
content: "\e614";
}
.icon-date:before {
content: "\e615";
}
.icon-deploy:before {
content: "\e616";
}
.icon-develop:before {
content: "\e617";
}
.icon-dept:before {
content: "\e619";
}
.icon-dictionary:before {
content: "\e61a";
}
.icon-documentation:before {
content: "\e61b";
}
.icon-doc:before {
content: "\e61c";
}
.icon-download:before {
content: "\e61d";
}
.icon-dict:before {
content: "\e61e";
}
.icon-edit:before {
content: "\e620";
}
.icon-app:before {
content: "\e602";
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,681 @@
{
"id": "4017520",
"name": "admin",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "37140510",
"name": "exit-fullscreen",
"font_class": "exit-fullscreen",
"unicode": "e66d",
"unicode_decimal": 58989
},
{
"icon_id": "37139279",
"name": "validCode",
"font_class": "validCode",
"unicode": "e621",
"unicode_decimal": 58913
},
{
"icon_id": "35896169",
"name": "index",
"font_class": "index",
"unicode": "e61f",
"unicode_decimal": 58911
},
{
"icon_id": "35076965",
"name": "tree-table",
"font_class": "tree-table",
"unicode": "e637",
"unicode_decimal": 58935
},
{
"icon_id": "35076967",
"name": "unlock",
"font_class": "unlock",
"unicode": "e654",
"unicode_decimal": 58964
},
{
"icon_id": "35076968",
"name": "zujian",
"font_class": "zujian",
"unicode": "e655",
"unicode_decimal": 58965
},
{
"icon_id": "35076969",
"name": "theme",
"font_class": "theme",
"unicode": "e659",
"unicode_decimal": 58969
},
{
"icon_id": "35076970",
"name": "swagger",
"font_class": "swagger",
"unicode": "e65c",
"unicode_decimal": 58972
},
{
"icon_id": "35076971",
"name": "star",
"font_class": "star",
"unicode": "e661",
"unicode_decimal": 58977
},
{
"icon_id": "35076972",
"name": "time",
"font_class": "time",
"unicode": "e662",
"unicode_decimal": 58978
},
{
"icon_id": "35076973",
"name": "upload",
"font_class": "upload",
"unicode": "e663",
"unicode_decimal": 58979
},
{
"icon_id": "35076974",
"name": "weixin",
"font_class": "weixin",
"unicode": "e664",
"unicode_decimal": 58980
},
{
"icon_id": "35076977",
"name": "system",
"font_class": "system",
"unicode": "e667",
"unicode_decimal": 58983
},
{
"icon_id": "35076979",
"name": "web",
"font_class": "web",
"unicode": "e668",
"unicode_decimal": 58984
},
{
"icon_id": "35076980",
"name": "tree",
"font_class": "tree",
"unicode": "e669",
"unicode_decimal": 58985
},
{
"icon_id": "35076981",
"name": "user",
"font_class": "user",
"unicode": "e66a",
"unicode_decimal": 58986
},
{
"icon_id": "35076982",
"name": "tool",
"font_class": "tool",
"unicode": "e66b",
"unicode_decimal": 58987
},
{
"icon_id": "35076986",
"name": "zip",
"font_class": "zip",
"unicode": "e66c",
"unicode_decimal": 58988
},
{
"icon_id": "35076492",
"name": "link",
"font_class": "link",
"unicode": "e636",
"unicode_decimal": 58934
},
{
"icon_id": "35076494",
"name": "list",
"font_class": "list",
"unicode": "e638",
"unicode_decimal": 58936
},
{
"icon_id": "35076495",
"name": "international",
"font_class": "international",
"unicode": "e639",
"unicode_decimal": 58937
},
{
"icon_id": "35076496",
"name": "language",
"font_class": "language",
"unicode": "e63a",
"unicode_decimal": 58938
},
{
"icon_id": "35076498",
"name": "ipvisits",
"font_class": "ipvisits",
"unicode": "e63c",
"unicode_decimal": 58940
},
{
"icon_id": "35076499",
"name": "money",
"font_class": "money",
"unicode": "e63d",
"unicode_decimal": 58941
},
{
"icon_id": "35076500",
"name": "message",
"font_class": "message",
"unicode": "e63e",
"unicode_decimal": 58942
},
{
"icon_id": "35076501",
"name": "login",
"font_class": "login",
"unicode": "e63f",
"unicode_decimal": 58943
},
{
"icon_id": "35076502",
"name": "lock",
"font_class": "lock",
"unicode": "e640",
"unicode_decimal": 58944
},
{
"icon_id": "35076503",
"name": "menu",
"font_class": "menu",
"unicode": "e641",
"unicode_decimal": 58945
},
{
"icon_id": "35076505",
"name": "log",
"font_class": "log",
"unicode": "e643",
"unicode_decimal": 58947
},
{
"icon_id": "35076506",
"name": "logininfor",
"font_class": "logininfor",
"unicode": "e644",
"unicode_decimal": 58948
},
{
"icon_id": "35076507",
"name": "mnt",
"font_class": "mnt",
"unicode": "e645",
"unicode_decimal": 58949
},
{
"icon_id": "35076509",
"name": "password",
"font_class": "password",
"unicode": "e646",
"unicode_decimal": 58950
},
{
"icon_id": "35076510",
"name": "peoples",
"font_class": "peoples",
"unicode": "e647",
"unicode_decimal": 58951
},
{
"icon_id": "35076511",
"name": "post",
"font_class": "post",
"unicode": "e648",
"unicode_decimal": 58952
},
{
"icon_id": "35076512",
"name": "permission",
"font_class": "permission",
"unicode": "e649",
"unicode_decimal": 58953
},
{
"icon_id": "35076513",
"name": "phone",
"font_class": "phone",
"unicode": "e64a",
"unicode_decimal": 58954
},
{
"icon_id": "35076514",
"name": "people",
"font_class": "people",
"unicode": "e64b",
"unicode_decimal": 58955
},
{
"icon_id": "35076516",
"name": "online",
"font_class": "online",
"unicode": "e64d",
"unicode_decimal": 58957
},
{
"icon_id": "35076518",
"name": "pdf",
"font_class": "pdf",
"unicode": "e64f",
"unicode_decimal": 58959
},
{
"icon_id": "35076519",
"name": "redis",
"font_class": "redis",
"unicode": "e650",
"unicode_decimal": 58960
},
{
"icon_id": "35076520",
"name": "size",
"font_class": "size",
"unicode": "e651",
"unicode_decimal": 58961
},
{
"icon_id": "35076521",
"name": "search",
"font_class": "search",
"unicode": "e652",
"unicode_decimal": 58962
},
{
"icon_id": "35076522",
"name": "server",
"font_class": "server",
"unicode": "e653",
"unicode_decimal": 58963
},
{
"icon_id": "35076525",
"name": "select",
"font_class": "select",
"unicode": "e656",
"unicode_decimal": 58966
},
{
"icon_id": "35076526",
"name": "question",
"font_class": "question",
"unicode": "e657",
"unicode_decimal": 58967
},
{
"icon_id": "35076527",
"name": "rate",
"font_class": "rate",
"unicode": "e658",
"unicode_decimal": 58968
},
{
"icon_id": "35076529",
"name": "monitor",
"font_class": "monitor",
"unicode": "e65a",
"unicode_decimal": 58970
},
{
"icon_id": "35076530",
"name": "source",
"font_class": "source",
"unicode": "e65b",
"unicode_decimal": 58971
},
{
"icon_id": "35076532",
"name": "role",
"font_class": "role",
"unicode": "e65d",
"unicode_decimal": 58973
},
{
"icon_id": "35076533",
"name": "shopping",
"font_class": "shopping",
"unicode": "e65e",
"unicode_decimal": 58974
},
{
"icon_id": "35076534",
"name": "skill",
"font_class": "skill",
"unicode": "e65f",
"unicode_decimal": 58975
},
{
"icon_id": "35076535",
"name": "number",
"font_class": "number",
"unicode": "e660",
"unicode_decimal": 58976
},
{
"icon_id": "35076366",
"name": "404",
"font_class": "a-404",
"unicode": "e622",
"unicode_decimal": 58914
},
{
"icon_id": "35076470",
"name": "email",
"font_class": "email",
"unicode": "e623",
"unicode_decimal": 58915
},
{
"icon_id": "35076471",
"name": "example",
"font_class": "example",
"unicode": "e624",
"unicode_decimal": 58916
},
{
"icon_id": "35076472",
"name": "error",
"font_class": "error",
"unicode": "e625",
"unicode_decimal": 58917
},
{
"icon_id": "35076473",
"name": "excel",
"font_class": "excel",
"unicode": "e626",
"unicode_decimal": 58918
},
{
"icon_id": "35076474",
"name": "education",
"font_class": "education",
"unicode": "e627",
"unicode_decimal": 58919
},
{
"icon_id": "35076475",
"name": "eye-open",
"font_class": "eye-open",
"unicode": "e628",
"unicode_decimal": 58920
},
{
"icon_id": "35076476",
"name": "eye",
"font_class": "eye",
"unicode": "e629",
"unicode_decimal": 58921
},
{
"icon_id": "35076480",
"name": "github",
"font_class": "github",
"unicode": "e62b",
"unicode_decimal": 58923
},
{
"icon_id": "35076481",
"name": "guide",
"font_class": "guide",
"unicode": "e62c",
"unicode_decimal": 58924
},
{
"icon_id": "35076482",
"name": "gonggao",
"font_class": "gonggao",
"unicode": "e62d",
"unicode_decimal": 58925
},
{
"icon_id": "35076483",
"name": "icon1",
"font_class": "icon1",
"unicode": "e62e",
"unicode_decimal": 58926
},
{
"icon_id": "35076484",
"name": "fullscreen",
"font_class": "fullscreen",
"unicode": "e62f",
"unicode_decimal": 58927
},
{
"icon_id": "35076485",
"name": "icon",
"font_class": "icon",
"unicode": "e630",
"unicode_decimal": 58928
},
{
"icon_id": "35076486",
"name": "image",
"font_class": "image",
"unicode": "e631",
"unicode_decimal": 58929
},
{
"icon_id": "35076487",
"name": "form",
"font_class": "form",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "35076491",
"name": "job",
"font_class": "job",
"unicode": "e635",
"unicode_decimal": 58933
},
{
"icon_id": "35076284",
"name": "cascader",
"font_class": "cascader",
"unicode": "e603",
"unicode_decimal": 58883
},
{
"icon_id": "35076315",
"name": "alipay",
"font_class": "alipay",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "35076316",
"name": "anq",
"font_class": "anq",
"unicode": "e605",
"unicode_decimal": 58885
},
{
"icon_id": "35076317",
"name": "backup",
"font_class": "backup",
"unicode": "e606",
"unicode_decimal": 58886
},
{
"icon_id": "35076318",
"name": "bug",
"font_class": "bug",
"unicode": "e607",
"unicode_decimal": 58887
},
{
"icon_id": "35076321",
"name": "button",
"font_class": "button",
"unicode": "e609",
"unicode_decimal": 58889
},
{
"icon_id": "35076323",
"name": "chain",
"font_class": "chain",
"unicode": "e60b",
"unicode_decimal": 58891
},
{
"icon_id": "35076324",
"name": "chart",
"font_class": "chart",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "35076325",
"name": "checkbox",
"font_class": "checkbox",
"unicode": "e60d",
"unicode_decimal": 58893
},
{
"icon_id": "35076326",
"name": "clipboard",
"font_class": "clipboard",
"unicode": "e60e",
"unicode_decimal": 58894
},
{
"icon_id": "35076327",
"name": "codeConsole",
"font_class": "codeConsole",
"unicode": "e60f",
"unicode_decimal": 58895
},
{
"icon_id": "35076328",
"name": "code",
"font_class": "code",
"unicode": "e610",
"unicode_decimal": 58896
},
{
"icon_id": "35076329",
"name": "color",
"font_class": "color",
"unicode": "e611",
"unicode_decimal": 58897
},
{
"icon_id": "35076330",
"name": "database",
"font_class": "database",
"unicode": "e612",
"unicode_decimal": 58898
},
{
"icon_id": "35076331",
"name": "component",
"font_class": "component",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "35076332",
"name": "dashboard",
"font_class": "dashboard",
"unicode": "e614",
"unicode_decimal": 58900
},
{
"icon_id": "35076333",
"name": "date",
"font_class": "date",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "35076334",
"name": "deploy",
"font_class": "deploy",
"unicode": "e616",
"unicode_decimal": 58902
},
{
"icon_id": "35076335",
"name": "develop",
"font_class": "develop",
"unicode": "e617",
"unicode_decimal": 58903
},
{
"icon_id": "35076337",
"name": "dept",
"font_class": "dept",
"unicode": "e619",
"unicode_decimal": 58905
},
{
"icon_id": "35076340",
"name": "dictionary",
"font_class": "dictionary",
"unicode": "e61a",
"unicode_decimal": 58906
},
{
"icon_id": "35076341",
"name": "documentation",
"font_class": "documentation",
"unicode": "e61b",
"unicode_decimal": 58907
},
{
"icon_id": "35076342",
"name": "doc",
"font_class": "doc",
"unicode": "e61c",
"unicode_decimal": 58908
},
{
"icon_id": "35076343",
"name": "download",
"font_class": "download",
"unicode": "e61d",
"unicode_decimal": 58909
},
{
"icon_id": "35076344",
"name": "dict",
"font_class": "dict",
"unicode": "e61e",
"unicode_decimal": 58910
},
{
"icon_id": "35076351",
"name": "edit",
"font_class": "edit",
"unicode": "e620",
"unicode_decimal": 58912
},
{
"icon_id": "35075963",
"name": "app",
"font_class": "app",
"unicode": "e602",
"unicode_decimal": 58882
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg>

After

Width:  |  Height:  |  Size: 954 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700531242903" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4238" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.5859375" height="200"><path d="M984.064 461.824q20.48-12.288 31.232-9.728t10.752 16.896l0 318.464q0 36.864-8.704 58.88t-23.552 32.768-34.816 13.824-43.52 3.072l-45.056 0q-33.792 0-81.408-0.512t-105.984-0.512l-119.808 0-120.832 0-110.592 0-90.112 0-57.344 0q-36.864 0-60.416-9.728t-36.864-25.088-18.432-35.328-5.12-41.472l0-304.128q0-20.48 10.24-26.112t25.6 4.608q4.096 3.072 18.432 12.288t33.28 20.992 40.448 25.088 39.936 24.576 31.744 19.968 17.408 10.752q13.312 8.192 12.288 17.92t-6.144 17.92q-4.096 8.192-12.288 25.6t-17.408 36.352-17.408 35.84-12.288 24.064q-5.12 8.192-3.584 13.824t5.632 8.704 10.24 1.536 11.264-7.68q3.072-3.072 15.872-17.92t28.16-32.256 29.184-32.256 17.92-18.944q5.12-5.12 15.872-11.776t22.016-1.536q6.144 4.096 20.992 13.824t32.768 20.992 35.84 23.04 30.208 18.944q12.288 8.192 26.112 10.24t26.112 1.024 22.528-4.608 15.36-6.656q6.144-3.072 23.552-13.312t37.888-23.04 38.4-24.064 25.088-15.36q11.264-6.144 19.456-3.584t17.408 10.752q4.096 3.072 16.384 18.432t27.136 33.28 27.648 34.304 17.92 22.528q6.144 7.168 12.8 7.68t11.264-3.072 6.144-10.24-3.584-14.848q-2.048-4.096-8.192-19.968t-13.824-35.328-15.872-37.888-12.288-26.624q-8.192-15.36-8.704-24.576t10.752-16.384q3.072-2.048 25.6-16.384t50.176-32.256 53.76-33.792 35.328-22.016zM544.768 637.952q-5.12 1.024-17.408-5.12t-27.648-15.36q-54.272-29.696-108.544-61.44-47.104-26.624-100.864-57.856t-99.84-57.856l0-184.32 2.048 0 0-1.024q0-26.624 10.24-49.664t27.648-40.448 40.448-27.648 49.664-10.24l448.512 0q26.624 0 50.176 10.24t40.96 27.648 27.648 40.448 10.24 49.664l0 1.024 2.048 0 0 184.32q-47.104 26.624-100.864 57.856t-100.864 57.856q-55.296 31.744-108.544 62.464-9.216 5.12-24.064 12.288t-20.992 7.168zM385.024 319.488l320.512 0 0-64.512-320.512 0 0 64.512zM385.024 447.488l320.512 0 0-64.512-320.512 0 0 64.512z" p-id="4239"></path></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700531099119" class="icon" viewBox="0 0 1044 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4078" xmlns:xlink="http://www.w3.org/1999/xlink" width="203.90625" height="200"><path d="M16.384 157.696q-11.264-8.192-14.336-13.312t-3.072-14.336l0-9.216q0-26.624 13.312-41.984t46.08-15.36l843.776 1.024q33.792 0 47.104 14.336t13.312 39.936l1.024 11.264q0 9.216-2.048 12.8t-16.384 14.848l-418.816 251.904q-10.24 4.096-25.088 11.264t-19.968 8.192q-6.144 0-18.432-5.632t-27.648-14.848zM646.144 572.416q-21.504 0-34.816 9.216t-20.992 23.552-10.24 32.256-2.56 34.304l0 71.68 0 12.288q0 6.144 1.024 11.264l-141.312 0q-72.704 0-136.192-0.512t-111.616-0.512l-70.656 0q-36.864 0-60.416-9.728t-36.864-25.088-18.432-35.328-5.12-41.472l0-378.88q0-21.504 10.24-27.136t25.6 5.632q5.12 3.072 18.432 11.776t31.744 19.968 38.4 24.064 37.888 24.064 30.72 19.456 16.896 10.24q14.336 9.216 16.384 23.04t-3.072 24.064q-4.096 10.24-12.288 26.624t-17.408 33.28-17.92 32.256-11.776 23.552q-5.12 14.336 2.048 19.456t22.528-4.096q3.072-2.048 16.896-15.872t29.184-30.72 29.184-31.744 18.944-17.92q9.216-8.192 24.064-11.776t26.112 2.56q7.168 4.096 19.456 12.288t27.136 17.92 30.208 19.968l27.648 18.432q12.288 8.192 26.112 10.24t26.624 1.024 23.04-4.608 15.36-6.656 19.456-11.776 31.232-18.944 31.744-19.456 22.016-13.312l129.024-79.872q2.048-1.024 12.8-8.192t26.624-17.408 34.816-22.528 35.84-23.04 31.232-19.968 20.48-13.312q19.456-12.288 30.208-9.728t10.752 16.896l0 266.24q-28.672-23.552-55.808-44.032t-49.664-34.816q-22.528-15.36-39.424-10.752t-27.648 19.968-16.384 35.84-5.632 36.864q0 11.264-0.512 18.432t-0.512 12.288q-1.024 5.12-1.024 8.192l-15.36 0-104.448 0zM1028.096 679.936q13.312 10.24 13.824 28.672t-10.752 26.624q-15.36 12.288-35.84 29.184t-42.496 34.304-43.008 34.816-38.4 30.72q-21.504 17.408-30.208 18.432t-8.704-26.624l0-46.08q0-17.408-8.704-28.672t-23.04-11.264l-118.784 0q-14.336 0-28.16-10.24t-13.824-26.624l0-52.224q0-28.672 9.216-34.816t32.768-6.144l20.48 0q9.216 0 20.992 0.512t28.16 0.512l43.008 0q20.48 0 29.184-7.168t8.704-25.6l0-45.056q0-18.432 6.144-23.552t22.528 8.192q16.384 12.288 37.888 29.696t44.544 35.328 45.056 35.84 39.424 31.232z" p-id="4079"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682510872430" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1825" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M512 1024C229.222 1024 0 794.778 0 512S229.222 0 512 0s512 229.222 512 512-229.222 512-512 512z m259.149-568.883h-290.74a25.293 25.293 0 0 0-25.292 25.293l-0.026 63.206c0 13.952 11.315 25.293 25.267 25.293h177.024c13.978 0 25.293 11.315 25.293 25.267v12.646a75.853 75.853 0 0 1-75.853 75.853h-240.23a25.293 25.293 0 0 1-25.267-25.293V417.203a75.853 75.853 0 0 1 75.827-75.853h353.946a25.293 25.293 0 0 0 25.267-25.292l0.077-63.207a25.293 25.293 0 0 0-25.268-25.293H417.152a189.62 189.62 0 0 0-189.62 189.645V771.15c0 13.977 11.316 25.293 25.294 25.293h372.94a170.65 170.65 0 0 0 170.65-170.65V480.384a25.293 25.293 0 0 0-25.293-25.267z" fill="#C71D23" p-id="1826"></path></svg>

After

Width:  |  Height:  |  Size: 1010 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1711767593370" class="icon" viewBox="0 0 1052 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4273" xmlns:xlink="http://www.w3.org/1999/xlink" width="131.5" height="128"><path d="M281.977144 775.178668H0v-526.357336h281.977144z m-206.783239-75.193905h131.589334v-375.969526H75.193905z" fill="#1262B3" p-id="4274"></path><path d="M733.140576 1024l-526.357337-263.178668V263.178668L733.140576 0zM281.977144 714.342099l375.969526 187.984763V121.673138l-375.969526 187.984763z" fill="#1262B3" p-id="4275"></path><path d="M902.326862 474.403047h150.387811v75.193906H902.326862zM798.610969 167.23007l130.238193-75.193905 37.596953 65.120272-130.238194 75.193905zM800.960778 857.400854l37.596953-65.120272 130.239368 75.193905-37.596952 65.120272z" fill="#FF584D" p-id="4276"></path></svg>

After

Width:  |  Height:  |  Size: 938 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1692263225130" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4039" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M245.76 286.72h552.96c124.928 0 225.28 100.352 225.28 225.28s-100.352 225.28-225.28 225.28H0V532.48c0-135.168 110.592-245.76 245.76-245.76z m133.12 348.16V401.408H348.16v178.176l-112.64-178.176H204.8V634.88h30.72v-178.176L348.16 634.88h30.72z m182.272-108.544v-24.576h-96.256v-75.776h110.592v-24.576h-141.312V634.88h143.36v-24.576h-112.64v-83.968h96.256z m100.352 28.672l-34.816-151.552h-34.816l55.296 233.472H675.84l47.104-161.792 4.096-20.48 4.096 20.48 47.104 161.792h28.672l57.344-233.472h-34.816l-32.768 151.552-4.096 30.72-6.144-30.72-40.96-151.552h-30.72l-40.96 151.552-6.144 30.72-6.144-30.72z" fill="#EE502F" p-id="4040"></path></svg>

After

Width:  |  Height:  |  Size: 976 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691394989170" class="icon" viewBox="0 0 1170 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8595" xmlns:xlink="http://www.w3.org/1999/xlink" width="228.515625" height="200"><path d="M585.142857 365.714286m-36.571428 0a36.571429 36.571429 0 1 0 73.142857 0 36.571429 36.571429 0 1 0-73.142857 0Z" fill="#54C3F1" p-id="8596"></path><path d="M731.428571 365.714286m-36.571428 0a36.571429 36.571429 0 1 0 73.142857 0 36.571429 36.571429 0 1 0-73.142857 0Z" fill="#54C3F1" p-id="8597"></path><path d="M438.857143 365.714286m-36.571429 0a36.571429 36.571429 0 1 0 73.142857 0 36.571429 36.571429 0 1 0-73.142857 0Z" fill="#54C3F1" p-id="8598"></path><path d="M1060.571429 877.714286H109.714286a109.714286 109.714286 0 0 1-109.714286-109.714286V109.714286a109.714286 109.714286 0 0 1 109.714286-109.714286h950.857143a109.714286 109.714286 0 0 1 109.714285 109.714286v658.285714a109.714286 109.714286 0 0 1-109.714285 109.714286zM109.714286 73.142857a36.571429 36.571429 0 0 0-36.571429 36.571429v658.285714a36.571429 36.571429 0 0 0 36.571429 36.571429h950.857143a36.571429 36.571429 0 0 0 36.571428-36.571429V109.714286a36.571429 36.571429 0 0 0-36.571428-36.571429z" fill="#54C3F1" p-id="8599"></path><path d="M36.571429 658.285714h1097.142857v73.142857H36.571429zM402.285714 841.142857h73.142857v146.285714h-73.142857zM694.857143 841.142857h73.142857v146.285714h-73.142857z" fill="#54C3F1" p-id="8600"></path><path d="M292.571429 950.857143h585.142857v73.142857H292.571429z" fill="#54C3F1" p-id="8601"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691394871411" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2379" width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M480 544H368v-64h112V368h64v288h-64V544z m368 304V592h64v320H592v-64h256zM656 656v144h-64V592h208v64H656zM176 176v192h192V176H176z m-64-64h320v320H112V112z m544 64v192h192V176H656z m-64-64h320v320H592V112zM112 480h160v64H112v-64z m640 0h160v64H752v-64zM544 112v160h-64V112h64z m0 640v160h-64V752h64z m-368-96v192h192V656H176z m-64-64h320v320H112V592z m112-368h96v96h-96v-96z m0 480h96v96h-96v-96z m480-480h96v96h-96v-96z" fill="#5090F1" p-id="2380"></path></svg>

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
src/assets/logo/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,99 @@
@use './variables.module.scss';
@mixin colorBtn($color) {
background: $color;
&:hover {
color: $color;
&:before,
&:after {
background: $color;
}
}
}
.blue-btn {
@include colorBtn(variables.$blue);
}
.light-blue-btn {
@include colorBtn(variables.$light-blue);
}
.red-btn {
@include colorBtn(variables.$red);
}
.pink-btn {
@include colorBtn(variables.$pink);
}
.green-btn {
@include colorBtn(variables.$green);
}
.tiffany-btn {
@include colorBtn(variables.$tiffany);
}
.yellow-btn {
@include colorBtn(variables.$yellow);
}
.pan-btn {
font-size: 14px;
color: #fff;
padding: 14px 36px;
border-radius: 8px;
border: none;
outline: none;
transition: 600ms ease all;
position: relative;
display: inline-block;
&:hover {
background: #fff;
&:before,
&:after {
width: 100%;
transition: 600ms ease all;
}
}
&:before,
&:after {
content: '';
position: absolute;
top: 0;
right: 0;
height: 2px;
width: 0;
transition: 400ms ease all;
}
&::after {
right: inherit;
top: inherit;
left: 0;
bottom: 0;
}
}
.custom-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
color: #fff;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: 0;
margin: 0;
padding: 10px 15px;
font-size: 14px;
border-radius: 4px;
}

View File

@ -0,0 +1,175 @@
// cover some element-ui styles
.el-upload__input {
display: none;
}
.cell {
.el-tag {
margin-right: 0px;
}
}
// table 里面操作按钮样式覆盖
.el-table__cell .cell {
.el-button.is-text {
padding: 8px 5px;
}
}
.status-col {
.cell {
padding: 0 10px;
text-align: center;
.el-tag {
margin-right: 0px;
}
}
}
// fix 2.2.0 版本label标签不居中
// .el-form-item--small .el-form-item__label {
// line-height: 32px !important;
// }
// element ui 移动端组件适配
.el-icon {
vertical-align: middle;
}
.el-header {
--el-header-padding: 0 0px !important;
// --el-header-height: 50px !important;
}
// el 2.2.0 text button
.el-button.is-text {
color: var(--el-color-primary) !important;
}
@media screen and (max-width: 500px) {
.el-message {
min-width: 300px !important;
}
}
@media screen and (max-width: 500px) {
.el-message-box {
width: 300px !important;
}
.el-pagination__jump {
display: none !important;
}
.el-pagination__sizes {
display: none !important;
}
}
// dialog
@media screen and (max-width: 700px) {
.el-dialog {
--el-dialog-width: 100% !important;
// --el-dialog-margin-top: 0 !important;
}
// .el-dialog:not(.is-fullscreen) {
// margin-top: 0 !important;
// }
.el-drawer {
width: 85% !important;
}
}
/** 表格更多操作下拉样式 */
.el-table .el-dropdown-link {
cursor: pointer;
color: #409eff;
margin-left: 5px;
}
.el-table .el-dropdown,
.el-icon-arrow-down {
font-size: 12px;
}
//适配完毕
// 隐藏picture-card 上传按钮
.hide .el-upload--picture-card {
display: none;
}
// 禁止菜单选中
.el-sub-menu .el-sub-menu__title span,
.el-menu .el-menu-item {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
// fix 侧边栏二级导航缩小图标消失问题
// .el-sub-menu__title {
// padding-right: unset !important;
// }
// fix 顶部导航更多样式问题
// .el-menu--horizontal .el-sub-menu .el-sub-menu__icon-arrow {
// right: calc(0px - var(--el-menu-base-level-padding)) !important;
// }
// 弹出搜索框
.header-search-select {
.el-select-dropdown__item {
height: unset !important;
line-height: unset !important;
margin-bottom: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
// el-table 表头样式
.el-table-header-cell {
text-align: center !important;
}
.el-dialog__headerbtn {
width: 47px !important;
}
// el-tree
.tree-item-flex {
&.is-expanded .el-tree-node__children {
display: flex !important;
flex-direction: column;
flex-direction: row;
flex-wrap: wrap;
}
}
// 修复饿了么 el-select没有宽度
.el-select {
--el-select-width: 200px !important;
}
// 按钮样式调整
.el-button {
margin-left: unset !important;
margin-right: 12px;
}
.el-button:last-child {
margin-right: 0;
}
// 解决top布局一级菜单高度不整齐
.topbar-menu .el-menu-item {
height: unset;
line-height: unset;
}
// 顶部导航宽度
.nav3 {
.el-sub-menu__title {
--el-menu-base-level-padding: 5px;
}
}

View File

@ -0,0 +1,283 @@
@use './variables.module.scss';
@use './mixin.scss';
@use './transition.scss';
@use './element-ui.scss';
@use './sidebar.scss';
@use './btn.scss';
@use './waves.scss';
html,
body,
#app {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
background-color: var(--base-bg-main);
// overflow: hidden;
position: relative;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.no-padding {
padding: 0 !important;
}
.padding-content {
padding: 4px 0;
}
a:focus,
a:active {
outline: none;
}
a,
a:focus,
a:hover {
cursor: pointer;
color: inherit;
text-decoration: none;
}
div:focus {
outline: none;
}
.fr {
float: right;
}
.fl {
float: left;
}
.pr-5 {
padding-right: 5px;
}
.pl-5 {
padding-left: 5px;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
.inlineBlock {
display: block;
}
.clearfix {
&:after {
visibility: hidden;
display: block;
font-size: 0;
content: ' ';
clear: both;
height: 0;
}
}
.text-center {
text-align: center;
}
.link-type,
.link-type:focus {
color: var(--el-color-primary);
cursor: pointer;
&:hover {
// color: rgb(32, 160, 255);
opacity: 0.3;
}
}
/** 基础通用 **/
.pt5 {
padding-top: 5px;
}
.pr5 {
padding-right: 5px;
}
.pb5 {
padding-bottom: 5px;
}
.pb20 {
padding-bottom: 20px;
}
.mt5 {
margin-top: 5px;
}
.mr5 {
margin-right: 5px;
}
.mb5 {
margin-bottom: 5px;
}
.mb8 {
margin-bottom: 8px;
}
.ml5 {
margin-left: 5px;
}
.mt10 {
margin-top: 10px;
}
.mr10 {
margin-right: 10px;
}
.mb10 {
margin-bottom: 10px;
}
.ml10 {
margin-left: 10px;
}
.mt20 {
margin-top: 20px;
}
.mr20 {
margin-right: 20px;
}
.mb20 {
margin-bottom: 20px;
}
.ml20 {
margin-left: 20px;
}
.ml {
margin-left: auto;
}
.mr {
margin-right: auto;
}
.mt {
margin-top: auto;
}
.mb {
margin-bottom: auto;
}
.w20 {
width: 20%;
}
.w100 {
width: 100%;
}
.pull-right {
float: right !important;
}
/* text color */
.text-navy {
color: #1ab394;
}
.text-pink {
color: pink;
}
.text-primary {
color: inherit;
}
.text-success {
color: #1c84c6;
}
.text-info {
color: #23c6c8;
}
.text-warning {
color: #f8ac59;
}
.text-danger {
color: #ff0000;
}
.text-muted {
color: #888888;
}
.text-orange {
color: #ff7d00;
}
.text-hotpink {
color: hotpink;
}
.text-green {
color: green;
}
.text-greenyellow {
color: greenyellow;
}
.text-purple {
color: #ff00ff;
}
/* image */
.img-circle {
border-radius: 50%;
}
.card-box {
padding-right: 15px;
padding-left: 15px;
margin-bottom: 10px;
}
.icon {
width: 100px;
}
.table-td-thumb {
width: 56px;
}
.flex-center {
flex-direction: column;
overflow: hidden;
}
.hljs {
display: flex;
flex-wrap: wrap;
width: 100%;
border-radius: 5px;
}

View File

@ -0,0 +1,111 @@
.login-wrap {
background: radial-gradient(220% 105% at top center, #1b2947 10%, #4b76a7 40%, #81acae 65%, #f7f7b6);
background-attachment: fixed;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
// background-image: url('@/assets/images/login-bg.jpg');
background-size: cover;
flex-direction: column;
.login {
margin: 0 auto;
background: #ffffff;
border-radius: 6px;
width: var(--base-login-width);
position: relative;
// height: 420px;
}
}
.title {
margin: 10px auto 15px auto;
text-align: center;
// color: #fff;
}
.login-form {
padding: 5px 25px 5px 25px;
position: relative;
height: 230px;
.input-icon {
height: 30px;
width: 14px;
margin-left: 0px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 40px;
float: right;
img {
width: 100%;
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 40px;
padding-left: 12px;
}
.langSet {
position: absolute;
left: 20px;
top: 10px;
}
.scan-wrap {
position: absolute;
right: 0;
top: 0;
width: 50px;
height: 50px;
cursor: pointer;
transition: all ease 0.3s;
overflow: hidden;
.icon {
width: 48px;
height: 50px;
display: inline-block;
font-size: 48px;
position: absolute;
right: 1px;
top: 0px;
}
.scan-delta {
position: absolute;
width: 35px;
height: 70px;
z-index: 2;
top: 2px;
right: 21px;
background: var(--el-color-white);
transform: rotate(-45deg);
}
}

View File

@ -0,0 +1,66 @@
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}
@mixin pct($pct) {
width: #{$pct};
position: relative;
margin: 0 auto;
}
@mixin triangle($width, $height, $color, $direction) {
$width: $width/2;
$color-border-style: $height solid $color;
$transparent-border-style: $width solid transparent;
height: 0;
width: 0;
@if $direction==up {
border-bottom: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==right {
border-left: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
@else if $direction==down {
border-top: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==left {
border-right: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
}

View File

@ -0,0 +1,85 @@
.el-menu-item,
.el-sub-menu {
.svg-icon + span {
margin-left: 5px;
}
}
#app {
.sidebar {
position: relative;
overflow-y: hidden;
z-index: 1001;
transition: width 0.28s ease;
background-color: var(--base-menu-background);
height: 100%;
display: flex;
flex-direction: column;
-webkit-box-shadow: 2px 0 14px rgb(0 21 41 / 10%);
box-shadow: 2px 0 14px rgb(0 21 41 / 10%);
.el-scrollbar__bar.is-vertical {
right: 0px;
}
// 去掉el-menu边框
.el-menu {
border: none;
}
// [class^='el-icon'] {
// width: 1em;
// height: 1em;
// font-size: unset;
// }
}
// 展开sidebar状态设置svg-icon边距
.openSidebar {
.sidebar {
transform: translate(0);
}
}
// 隐藏侧边栏样式
.hideSidebar {
.el-aside {
--el-aside-width: 60px;
}
// 隐藏箭头
.el-sub-menu {
overflow: hidden;
& > .el-sub-menu__title {
.el-sub-menu__icon-arrow {
display: none;
}
}
}
// 折叠状态下
.el-menu--collapse {
.menu-icon {
margin-right: 0;
}
}
}
// mobile responsive
.mobile {
.main-container {
margin-left: 0px;
}
.sidebar {
transition: transform 0.28s;
position: fixed;
// background: var(--base-menu-background, #fff);
}
&.hideSidebar {
.sidebar {
pointer-events: none;
transform: translate3d(-220px, 0, 0);
transition-duration: 0.3s;
}
}
}
}

View File

@ -0,0 +1,48 @@
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}

View File

@ -0,0 +1,92 @@
// base color
$blue: #324157;
$light-blue: #3a71a8;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// 默认菜单主题风格
:root {
--base-text-color-rgba: rgba(0, 0, 0, 0.85);
--base-menu-background: #fff;
--base-sidebar-width: 220px;
// 左侧菜单宽度
--el-aside-width: 220px;
//底部高度
--base-footer-height: 30px;
--base-tags-height: 34px;
--base-header-height: 50px;
//登录框宽度
--base-login-width: 360px;
// 侧边栏图标大小
--el-menu-icon-width: 14px;
--el-menu-horizontal-height: 50px;
--vxe-table-column-padding-default: 7px 0 !important;
}
/***侧边栏深色配置***/
[data-theme='theme-black'] {
--base-menu-background: #324157;
--base-logo-title-color: #ffffff;
--base-topBar-background: #324157;
--base-topBar-color: #fff;
// el-ement ui 设置
// --el-fill-color-blank: #304156;
--el-text-color-primary: #e5eaf3;
--base-color-white: #ffffff;
--el-menu-text-color: var(--el-text-color-primary);
}
// 黑色主题
html.dark {
/* custom dark bg color */
// --el-bg-color: #141414;
--base-color-white: #ffffff;
--base-text-color-rgba: #ffffff;
--base-menu-background: #000;
--base-topBar-background: #000;
// vxe-table黑色样式
--vxe-font-color: #98989e;
--vxe-primary-color: #2c7ecf;
--vxe-icon-background-color: #98989e;
--vxe-table-font-color: #98989e;
--vxe-table-resizable-color: #95969a;
--vxe-table-header-background-color: #28282a;
--vxe-table-body-background-color: #151518;
--vxe-table-background-color: #4a5663;
--vxe-table-border-width: 1px;
--vxe-table-border-color: #37373a;
.current-row {
color: #e65d6e;
}
.header-search {
.el-select {
background-color: #000;
}
}
// wangEditor
--w-e-textarea-bg-color: #111;
--w-e-textarea-color: #fff;
--w-e-toolbar-color: #fff;
--w-e-toolbar-bg-color: #111;
--w-e-toolbar-active-color: #ccc;
--w-e-toolbar-active-bg-color: #111;
/* ...其他... */
}
html.cafe {
filter: sepia(0.9) hue-rotate(315deg) brightness(0.9);
}
html.contrast {
filter: contrast(2);
}

View File

@ -0,0 +1,101 @@
/* Waves v0.6.0
* http://fian.my.id/Waves
*
* Copyright 2014 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
*/
.waves-effect {
position: relative;
cursor: pointer;
display: inline-block;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
vertical-align: middle;
z-index: 1;
will-change: opacity, transform;
transition: all 0.3s ease-out;
}
.waves-effect .waves-ripple {
position: absolute;
border-radius: 50%;
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
opacity: 0;
background: rgba(0, 0, 0, 0.2);
transition: all 0.7s ease-out;
transition-property: opacity, -webkit-transform;
transition-property: transform, opacity;
transition-property: transform, opacity, -webkit-transform;
-webkit-transform: scale(0);
transform: scale(0);
pointer-events: none;
}
.waves-effect.waves-light .waves-ripple {
background-color: rgba(255, 255, 255, 0.45);
}
.waves-effect.waves-red .waves-ripple {
background-color: rgba(244, 67, 54, 0.7);
}
.waves-effect.waves-yellow .waves-ripple {
background-color: rgba(255, 235, 59, 0.7);
}
.waves-effect.waves-orange .waves-ripple {
background-color: rgba(255, 152, 0, 0.7);
}
.waves-effect.waves-purple .waves-ripple {
background-color: rgba(156, 39, 176, 0.7);
}
.waves-effect.waves-green .waves-ripple {
background-color: rgba(76, 175, 80, 0.7);
}
.waves-effect.waves-teal .waves-ripple {
background-color: rgba(0, 150, 136, 0.7);
}
.waves-effect input[type='button'],
.waves-effect input[type='reset'],
.waves-effect input[type='submit'] {
border: 0;
font-style: normal;
font-size: inherit;
text-transform: inherit;
background: none;
}
.waves-notransition {
transition: none !important;
}
.waves-circle {
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%);
}
.waves-input-wrapper {
border-radius: 0.2em;
vertical-align: bottom;
}
.waves-input-wrapper .waves-button-input {
position: relative;
top: 0;
left: 0;
z-index: 1;
}
.waves-circle {
text-align: center;
width: 2.5em;
height: 2.5em;
line-height: 2.5em;
border-radius: 50%;
-webkit-mask-image: none;
}
.waves-block {
display: block;
}
a.waves-effect .waves-ripple {
z-index: -1;
}

87
src/auto-import.d.ts vendored Normal file
View File

@ -0,0 +1,87 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const createPinia: typeof import('pinia')['createPinia']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const effectScope: typeof import('vue')['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useLink: typeof import('vue-router')['useLink']
const useModel: typeof import('vue')['useModel']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}

19
src/components.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
import SvgIcon from '@/components/SvgIcon/index.vue'
import UploadImage from '@/components/ImageUpload.vue'
import UploadFile from '@/components/FileUpload'
import ImagePreview from '@/components/ImagePreview'
import DictTag from '@/components/DictTag'
import Dialog from '@/components/Dialog'
import MyTable from '@/components/MyTable'
declare module '@vue/runtime-core' {
export interface GlobalComponents {
SvgIcon: typeof SvgIcon,
UploadImage: typeof UploadImage,
DictTag: typeof DictTag,
ImagePreview: typeof ImagePreview,
UploadFile: typeof UploadFile,
ZrDialog: typeof Dialog,
MyTable: typeof MyTable
}
}

View File

@ -0,0 +1,98 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script setup>
import usePermissionStore from '@/store/modules/permission'
const route = useRoute()
const router = useRouter()
const permissionStore = usePermissionStore()
const levelList = ref([])
function getBreadcrumb() {
// only show routes with meta.title
let matched = []
const pathNum = findPathNum(route.path)
// multi-level menu
if (pathNum > 2) {
const reg = /\/\w+/gi
const pathList = route.path.match(reg).map((item, index) => {
if (index !== 0) item = item.slice(1)
return item
})
getMatched(pathList, permissionStore.sidebarRouters, matched)
} else {
matched = route.matched.filter((item) => item.meta && item.meta.title)
}
//
if (!isDashboard(matched[0])) {
matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
}
levelList.value = matched.filter((item) => item.meta && item.meta.title && item.meta.breadcrumb !== false)
}
function findPathNum(str, char = '/') {
let index = str.indexOf(char)
let num = 0
while (index !== -1) {
num++
index = str.indexOf(char, index + 1)
}
return num
}
function getMatched(pathList, routeList, matched) {
let data = routeList.find((item) => item.path == pathList[0])
if (data) {
matched.push(data)
if (data.children && pathList.length) {
pathList.shift()
getMatched(pathList, data.children, matched)
}
}
}
function isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim() === 'Index'
}
function handleLink(item) {
const { redirect, path } = item
if (redirect) {
router.push(redirect)
return
}
router.push(path)
}
watchEffect(() => {
// if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) {
return
}
getBreadcrumb()
})
getBreadcrumb()
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@ -0,0 +1,170 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * ? / L W] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2"> 不指定 </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从
<el-input-number v-model="cycle01" :min="1" :max="30" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="31" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="1" :max="30" /> 号开始
<el-input-number v-model="average02" :min="1" :max="31 - average01" /> 日执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
每月
<el-input-number v-model="workday" :min="1" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="6"> 本月最后一天 </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="7"> 指定 </el-radio>
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 31" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const props = defineProps({
cron: {
type: Object,
default: {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
},
check: {
type: Function,
default: () => {}
}
})
const radioValue = ref(1)
const cycle01 = ref(1)
const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const workday = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 1, 30)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31)
return cycle01.value + '-' + cycle02.value
})
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 1, 30)
average02.value = props.check(average02.value, 1, 31 - average01.value)
return average01.value + '/' + average02.value
})
const workdayTotal = computed(() => {
workday.value = props.check(workday.value, 1, 31)
return workday.value + 'W'
})
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(
() => props.cron.day,
(value) => changeRadioValue(value)
)
watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value === '?') {
radioValue.value = 2
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 3
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 4
} else if (value.indexOf('W') > -1) {
const indexArr = value.split('W')
workday.value = Number(indexArr[0])
radioValue.value = 5
} else if (value === 'L') {
radioValue.value = 6
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))]
radioValue.value = 7
}
}
//
function onRadioChange() {
if (radioValue.value === 2 && props.cron.week === '?') {
emit('update', 'week', '*', 'day')
}
if (radioValue.value !== 2 && props.cron.week !== '?') {
emit('update', 'week', '?', 'day')
}
switch (radioValue.value) {
case 1:
emit('update', 'day', '*', 'day')
break
case 2:
emit('update', 'day', '?', 'day')
break
case 3:
emit('update', 'day', cycleTotal.value, 'day')
break
case 4:
emit('update', 'day', averageTotal.value, 'day')
break
case 5:
emit('update', 'day', workdayTotal.value, 'day')
break
case 6:
emit('update', 'day', 'L', 'day')
break
case 7:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'day', checkboxString.value, 'day')
break
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -0,0 +1,127 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 小时允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="22" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="23" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="22" /> 时开始
<el-input-number v-model="average02" :min="1" :max="23 - average01" /> 小时执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4"> 指定 </el-radio>
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const props = defineProps({
cron: {
type: Object,
default: {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
},
check: {
type: Function,
default: () => {}
}
})
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 0, 22)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23)
return cycle01.value + '-' + cycle02.value
})
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 0, 22)
average02.value = props.check(average02.value, 1, 23 - average01.value)
return average01.value + '/' + average02.value
})
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(
() => props.cron.hour,
(value) => changeRadioValue(value)
)
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))]
radioValue.value = 4
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'hour', '*', 'hour')
break
case 2:
emit('update', 'hour', cycleTotal.value, 'hour')
break
case 3:
emit('update', 'hour', averageTotal.value, 'hour')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'hour', checkboxString.value, 'hour')
break
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -0,0 +1,284 @@
<template>
<div>
<el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronsecond" />
</el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmin" />
</el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronhour" />
</el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronday" />
</el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMonth @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmonth" />
</el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronweek" />
</el-tab-pane>
<el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronyear" />
</el-tab-pane>
</el-tabs>
<div class="popup-main">
<div class="popup-result">
<p class="title">时间表达式</p>
<table>
<thead>
<tr>
<th v-for="item of tabTitles" :key="item">{{ item }}</th>
<th>Cron 表达式</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span v-if="crontabValueObj.second.length < 10">{{ crontabValueObj.second }}</span>
<el-tooltip v-else :content="crontabValueObj.second" placement="top">
<span>{{ crontabValueObj.second }}</span>
</el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.min.length < 10">{{ crontabValueObj.min }}</span>
<el-tooltip v-else :content="crontabValueObj.min" placement="top">
<span>{{ crontabValueObj.min }}</span>
</el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.hour.length < 10">{{ crontabValueObj.hour }}</span>
<el-tooltip v-else :content="crontabValueObj.hour" placement="top"
><span>{{ crontabValueObj.hour }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.day.length < 10">{{ crontabValueObj.day }}</span>
<el-tooltip v-else :content="crontabValueObj.day" placement="top"
><span>{{ crontabValueObj.day }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.month.length < 10">{{ crontabValueObj.month }}</span>
<el-tooltip v-else :content="crontabValueObj.month" placement="top"
><span>{{ crontabValueObj.month }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.week.length < 10">{{ crontabValueObj.week }}</span>
<el-tooltip v-else :content="crontabValueObj.week" placement="top"
><span>{{ crontabValueObj.week }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.year.length < 10">{{ crontabValueObj.year }}</span>
<el-tooltip v-else :content="crontabValueObj.year" placement="top"
><span>{{ crontabValueObj.year }}</span></el-tooltip
>
</td>
<td class="result">
<span v-if="crontabValueString.length < 90">{{ crontabValueString }}</span>
<el-tooltip v-else :content="crontabValueString" placement="top"
><span>{{ crontabValueString }}</span></el-tooltip
>
</td>
</tr>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="pop_btn">
<el-button type="primary" @click="submitFill">确定</el-button>
<el-button type="warning" @click="clearCron">重置</el-button>
<el-button @click="hidePopup">取消</el-button>
</div>
</div>
</div>
</template>
<script setup>
import CrontabSecond from './second.vue'
import CrontabMin from './min.vue'
import CrontabHour from './hour.vue'
import CrontabDay from './day.vue'
import CrontabMonth from './month.vue'
import CrontabWeek from './week.vue'
import CrontabYear from './year.vue'
import CrontabResult from './result.vue'
const { proxy } = getCurrentInstance()
const emit = defineEmits(['hide', 'fill'])
const props = defineProps({
hideComponent: {
type: Array,
default: () => []
},
expression: {
type: String,
default: ''
}
})
const tabTitles = ref(['秒', '分钟', '小时', '日', '月', '周', '年'])
const tabActive = ref(0)
const hideComponent = ref([])
const expression = ref('')
const crontabValueObj = ref({
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
})
const crontabValueString = computed(() => {
const obj = crontabValueObj.value
return obj.second + ' ' + obj.min + ' ' + obj.hour + ' ' + obj.day + ' ' + obj.month + ' ' + obj.week + (obj.year === '' ? '' : ' ' + obj.year)
})
watch(expression, () => resolveExp())
function shouldHide(key) {
return !(hideComponent.value && hideComponent.value.includes(key))
}
function resolveExp() {
//
if (expression.value) {
const arr = expression.value.split(/\s+/)
if (arr.length >= 6) {
//6
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : ''
}
crontabValueObj.value = {
...obj
}
}
} else {
//
clearCron()
}
}
// tab
function tabCheck(index) {
tabActive.value = index
}
//
function updateCrontabValue(name, value, from) {
crontabValueObj.value[name] = value
}
// -props
function checkNumber(value, minLimit, maxLimit) {
//
value = Math.floor(value)
if (value < minLimit) {
value = minLimit
} else if (value > maxLimit) {
value = maxLimit
}
return value
}
//
function hidePopup() {
emit('hide')
}
//
function submitFill() {
emit('fill', crontabValueString.value)
hidePopup()
}
function clearCron() {
//
crontabValueObj.value = {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
}
onMounted(() => {
expression.value = props.expression
hideComponent.value = props.hideComponent
})
</script>
<style lang="scss" scoped>
.pop_btn {
text-align: center;
margin-top: 20px;
}
.popup-main {
position: relative;
margin: 10px auto;
//background: #fff;
border-radius: 5px;
font-size: 12px;
overflow: hidden;
}
.popup-title {
overflow: hidden;
line-height: 34px;
padding-top: 6px;
background: #f2f2f2;
}
.popup-result {
box-sizing: border-box;
line-height: 24px;
margin: 25px auto;
padding: 15px 10px 10px;
border: 1px solid #ccc;
position: relative;
}
.popup-result .title {
position: absolute;
top: -28px;
left: 50%;
width: 140px;
font-size: 14px;
margin-left: -70px;
text-align: center;
line-height: 30px;
background: #fff;
}
.popup-result table {
text-align: center;
width: 100%;
margin: 0 auto;
}
.popup-result table td:not(.result) {
width: 3.5rem;
min-width: 3.5rem;
max-width: 3.5rem;
}
.popup-result table span {
display: block;
width: 100%;
font-family: arial;
line-height: 30px;
height: 30px;
white-space: nowrap;
overflow: hidden;
border: 1px solid #e8e8e8;
}
.popup-result-scroll {
font-size: 12px;
line-height: 24px;
height: 10em;
overflow-y: auto;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 分钟允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="58" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="59" /> 分钟
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="58" /> 分钟开始
<el-input-number v-model="average02" :min="1" :max="59 - average01" /> 分钟执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4"> 指定 </el-radio>
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const props = defineProps({
cron: {
type: Object,
default: {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
},
check: {
type: Function,
default: () => {}
}
})
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 0, 58)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
return cycle01.value + '-' + cycle02.value
})
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 0, 58)
average02.value = props.check(average02.value, 1, 59 - average01.value)
return average01.value + '/' + average02.value
})
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(
() => props.cron.min,
(value) => changeRadioValue(value)
)
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))]
radioValue.value = 4
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'min', '*', 'min')
break
case 2:
emit('update', 'min', cycleTotal.value, 'min')
break
case 3:
emit('update', 'min', averageTotal.value, 'min')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'min', checkboxString.value, 'min')
break
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select,
.el-select--small {
width: 19.8rem;
}
</style>

View File

@ -0,0 +1,144 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="1" :max="11" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="12" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="1" :max="11" /> 月开始
<el-input-number v-model="average02" :min="1" :max="maxMonth" /> 月执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4"> 指定 </el-radio>
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8" style="width: 80%">
<el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const props = defineProps({
cron: {
type: Object,
default: {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
},
check: {
type: Function,
default: () => {}
}
})
const radioValue = ref(1)
const cycle01 = ref(1)
const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
const monthList = ref([
{ key: 1, value: '一月' },
{ key: 2, value: '二月' },
{ key: 3, value: '三月' },
{ key: 4, value: '四月' },
{ key: 5, value: '五月' },
{ key: 6, value: '六月' },
{ key: 7, value: '七月' },
{ key: 8, value: '八月' },
{ key: 9, value: '九月' },
{ key: 10, value: '十月' },
{ key: 11, value: '十一月' },
{ key: 12, value: '十二月' }
])
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 1, 11)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12)
return cycle01.value + '-' + cycle02.value
})
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 1, 11)
average02.value = props.check(average02.value, 1, 12 - average01.value)
return average01.value + '/' + average02.value
})
const maxMonth = computed(() => {
return 12 - average01.value
})
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(
() => props.cron.month,
(value) => changeRadioValue(value)
)
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))]
radioValue.value = 4
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'month', '*', 'month')
break
case 2:
emit('update', 'month', cycleTotal.value, 'month')
break
case 3:
emit('update', 'month', averageTotal.value, 'month')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'month', checkboxString.value, 'month')
break
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -0,0 +1,560 @@
<template>
<div class="popup-result">
<p class="title">最近5次运行时间</p>
<ul class="popup-result-scroll">
<template v-if="isShow">
<li v-for="item in resultList" :key="item">{{ item }}</li>
</template>
<li v-else>计算结果中...</li>
</ul>
</div>
</template>
<script setup>
const props = defineProps({
ex: {
type: String,
default: ''
}
})
const dayRule = ref('')
const dayRuleSup = ref('')
const dateArr = ref([])
const resultList = ref([])
const isShow = ref(false)
watch(
() => props.ex,
() => expressionChange()
)
//
function expressionChange() {
// -
isShow.value = false
// [0123456]
let ruleArr = props.ex.split(' ')
//
let nums = 0
//
let resultArr = []
// []
let nTime = new Date()
let nYear = nTime.getFullYear()
let nMonth = nTime.getMonth() + 1
let nDay = nTime.getDate()
let nHour = nTime.getHours()
let nMin = nTime.getMinutes()
let nSecond = nTime.getSeconds()
// 100
getSecondArr(ruleArr[0])
getMinArr(ruleArr[1])
getHourArr(ruleArr[2])
getDayArr(ruleArr[3])
getMonthArr(ruleArr[4])
getWeekArr(ruleArr[5])
getYearArr(ruleArr[6], nYear)
// -便使
let sDate = dateArr.value[0]
let mDate = dateArr.value[1]
let hDate = dateArr.value[2]
let DDate = dateArr.value[3]
let MDate = dateArr.value[4]
let YDate = dateArr.value[5]
//
let sIdx = getIndex(sDate, nSecond)
let mIdx = getIndex(mDate, nMin)
let hIdx = getIndex(hDate, nHour)
let DIdx = getIndex(DDate, nDay)
let MIdx = getIndex(MDate, nMonth)
let YIdx = getIndex(YDate, nYear)
// ()
const resetSecond = function () {
sIdx = 0
nSecond = sDate[sIdx]
}
const resetMin = function () {
mIdx = 0
nMin = mDate[mIdx]
resetSecond()
}
const resetHour = function () {
hIdx = 0
nHour = hDate[hIdx]
resetMin()
}
const resetDay = function () {
DIdx = 0
nDay = DDate[DIdx]
resetHour()
}
const resetMonth = function () {
MIdx = 0
nMonth = MDate[MIdx]
resetDay()
}
//
if (nYear !== YDate[YIdx]) {
resetMonth()
}
//
if (nMonth !== MDate[MIdx]) {
resetDay()
}
//
if (nDay !== DDate[DIdx]) {
resetHour()
}
//
if (nHour !== hDate[hIdx]) {
resetMin()
}
//
if (nMin !== mDate[mIdx]) {
resetSecond()
}
//
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
let YY = YDate[Yi]
//
if (nMonth > MDate[MDate.length - 1]) {
resetMonth()
continue
}
//
goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
// 便
let MM = MDate[Mi]
MM = MM < 10 ? '0' + MM : MM
//
if (nDay > DDate[DDate.length - 1]) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue
}
//
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
// 便
let DD = DDate[Di]
let thisDD = DD < 10 ? '0' + DD : DD
//
if (nHour > hDate[hDate.length - 1]) {
resetHour()
if (Di === DDate.length - 1) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue goMonth
}
continue
}
//
if (
checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true &&
dayRule.value !== 'workDay' &&
dayRule.value !== 'lastWeek' &&
dayRule.value !== 'lastDay'
) {
resetDay()
continue goMonth
}
//
if (dayRule.value === 'lastDay') {
//
if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--
thisDD = DD < 10 ? '0' + DD : DD
}
}
} else if (dayRule.value === 'workDay') {
// 230
if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--
thisDD = DD < 10 ? '0' + DD : DD
}
}
// X
let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
//
if (thisWeek === 1) {
//
DD++
thisDD = DD < 10 ? '0' + DD : DD
//
if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD -= 3
}
} else if (thisWeek === 7) {
// 61
if (dayRuleSup.value !== 1) {
DD--
} else {
DD += 2
}
}
} else if (dayRule.value === 'weekDay') {
//
//
let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
// dayRuleSup
if (dayRuleSup.value.indexOf(thisWeek) < 0) {
//
if (Di === DDate.length - 1) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue goMonth
}
continue
}
} else if (dayRule.value === 'assWeek') {
//
// 1
let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
if (dayRuleSup.value[1] >= thisWeek) {
DD = (dayRuleSup.value[0] - 1) * 7 + dayRuleSup.value[1] - thisWeek + 1
} else {
DD = dayRuleSup.value[0] * 7 + dayRuleSup.value[1] - thisWeek + 1
}
} else if (dayRule.value === 'lastWeek') {
//
// 230
if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
DD--
thisDD = DD < 10 ? '0' + DD : DD
}
}
//
let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
//
if (dayRuleSup.value < thisWeek) {
DD -= thisWeek - dayRuleSup.value
} else if (dayRuleSup.value > thisWeek) {
DD -= 7 - (dayRuleSup.value - thisWeek)
}
}
// 1005
DD = DD < 10 ? '0' + DD : DD
//
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
//
if (nMin > mDate[mDate.length - 1]) {
resetMin()
if (hi === hDate.length - 1) {
resetHour()
if (Di === DDate.length - 1) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue goMonth
}
continue goDay
}
continue
}
// ""
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi]
//
if (nSecond > sDate[sDate.length - 1]) {
resetSecond()
if (mi === mDate.length - 1) {
resetMin()
if (hi === hDate.length - 1) {
resetHour()
if (Di === DDate.length - 1) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue goMonth
}
continue goDay
}
continue goHour
}
continue
}
// ""
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si]
//
if (MM !== '00' && DD !== '00') {
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
nums++
}
// 退
if (nums === 5) break goYear
//
if (si === sDate.length - 1) {
resetSecond()
if (mi === mDate.length - 1) {
resetMin()
if (hi === hDate.length - 1) {
resetHour()
if (Di === DDate.length - 1) {
resetDay()
if (Mi === MDate.length - 1) {
resetMonth()
continue goYear
}
continue goMonth
}
continue goDay
}
continue goHour
}
continue goMin
}
} //goSecond
} //goMin
} //goHour
} //goDay
} //goMonth
}
// 100
if (resultArr.length === 0) {
resultList.value = ['没有达到条件的结果!']
} else {
resultList.value = resultArr
if (resultArr.length !== 5) {
resultList.value.push('最近100年内只有上面' + resultArr.length + '条结果!')
}
}
// -
isShow.value = true
}
//
function getIndex(arr, value) {
if (value <= arr[0] || value > arr[arr.length - 1]) {
return 0
} else {
for (let i = 0; i < arr.length - 1; i++) {
if (value > arr[i] && value <= arr[i + 1]) {
return i + 1
}
}
}
}
// ""
function getYearArr(rule, year) {
dateArr.value[5] = getOrderArr(year, year + 100)
if (rule !== undefined) {
if (rule.indexOf('-') >= 0) {
dateArr.value[5] = getCycleArr(rule, year + 100, false)
} else if (rule.indexOf('/') >= 0) {
dateArr.value[5] = getAverageArr(rule, year + 100)
} else if (rule !== '*') {
dateArr.value[5] = getAssignArr(rule)
}
}
}
// ""
function getMonthArr(rule) {
dateArr.value[4] = getOrderArr(1, 12)
if (rule.indexOf('-') >= 0) {
dateArr.value[4] = getCycleArr(rule, 12, false)
} else if (rule.indexOf('/') >= 0) {
dateArr.value[4] = getAverageArr(rule, 12)
} else if (rule !== '*') {
dateArr.value[4] = getAssignArr(rule)
}
}
// ""-
function getWeekArr(rule) {
//
if (dayRule.value === '' && dayRuleSup.value === '') {
if (rule.indexOf('-') >= 0) {
dayRule.value = 'weekDay'
dayRuleSup.value = getCycleArr(rule, 7, false)
} else if (rule.indexOf('#') >= 0) {
dayRule.value = 'assWeek'
let matchRule = rule.match(/[0-9]{1}/g)
dayRuleSup.value = [Number(matchRule[1]), Number(matchRule[0])]
dateArr.value[3] = [1]
if (dayRuleSup.value[1] === 7) {
dayRuleSup.value[1] = 0
}
} else if (rule.indexOf('L') >= 0) {
dayRule.value = 'lastWeek'
dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0])
dateArr.value[3] = [31]
if (dayRuleSup.value === 7) {
dayRuleSup.value = 0
}
} else if (rule !== '*' && rule !== '?') {
dayRule.value = 'weekDay'
dayRuleSup.value = getAssignArr(rule)
}
}
}
// ""-
function getDayArr(rule) {
dateArr.value[3] = getOrderArr(1, 31)
dayRule.value = ''
dayRuleSup.value = ''
if (rule.indexOf('-') >= 0) {
dateArr.value[3] = getCycleArr(rule, 31, false)
dayRuleSup.value = 'null'
} else if (rule.indexOf('/') >= 0) {
dateArr.value[3] = getAverageArr(rule, 31)
dayRuleSup.value = 'null'
} else if (rule.indexOf('W') >= 0) {
dayRule.value = 'workDay'
dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0])
dateArr.value[3] = [dayRuleSup.value]
} else if (rule.indexOf('L') >= 0) {
dayRule.value = 'lastDay'
dayRuleSup.value = 'null'
dateArr.value[3] = [31]
} else if (rule !== '*' && rule !== '?') {
dateArr.value[3] = getAssignArr(rule)
dayRuleSup.value = 'null'
} else if (rule === '*') {
dayRuleSup.value = 'null'
}
}
// ""
function getHourArr(rule) {
dateArr.value[2] = getOrderArr(0, 23)
if (rule.indexOf('-') >= 0) {
dateArr.value[2] = getCycleArr(rule, 24, true)
} else if (rule.indexOf('/') >= 0) {
dateArr.value[2] = getAverageArr(rule, 23)
} else if (rule !== '*') {
dateArr.value[2] = getAssignArr(rule)
}
}
// ""
function getMinArr(rule) {
dateArr.value[1] = getOrderArr(0, 59)
if (rule.indexOf('-') >= 0) {
dateArr.value[1] = getCycleArr(rule, 60, true)
} else if (rule.indexOf('/') >= 0) {
dateArr.value[1] = getAverageArr(rule, 59)
} else if (rule !== '*') {
dateArr.value[1] = getAssignArr(rule)
}
}
// ""
function getSecondArr(rule) {
dateArr.value[0] = getOrderArr(0, 59)
if (rule.indexOf('-') >= 0) {
dateArr.value[0] = getCycleArr(rule, 60, true)
} else if (rule.indexOf('/') >= 0) {
dateArr.value[0] = getAverageArr(rule, 59)
} else if (rule !== '*') {
dateArr.value[0] = getAssignArr(rule)
}
}
// min-max
function getOrderArr(min, max) {
let arr = []
for (let i = min; i <= max; i++) {
arr.push(i)
}
return arr
}
//
function getAssignArr(rule) {
let arr = []
let assiginArr = rule.split(',')
for (let i = 0; i < assiginArr.length; i++) {
arr[i] = Number(assiginArr[i])
}
arr.sort(compare)
return arr
}
//
function getAverageArr(rule, limit) {
let arr = []
let agArr = rule.split('/')
let min = Number(agArr[0])
let step = Number(agArr[1])
while (min <= limit) {
arr.push(min)
min += step
}
return arr
}
//
function getCycleArr(rule, limit, status) {
// status--01
let arr = []
let cycleArr = rule.split('-')
let min = Number(cycleArr[0])
let max = Number(cycleArr[1])
if (min > max) {
max += limit
}
for (let i = min; i <= max; i++) {
let add = 0
if (status === false && i % limit === 0) {
add = limit
}
arr.push(Math.round((i % limit) + add))
}
arr.sort(compare)
return arr
}
// Array.sort
function compare(value1, value2) {
if (value2 - value1 > 0) {
return -1
} else {
return 1
}
}
// 2017-9-19 18:04:33
function formatDate(value, type) {
//
let time = typeof value == 'number' ? new Date(value) : value
let Y = time.getFullYear()
let M = time.getMonth() + 1
let D = time.getDate()
let h = time.getHours()
let m = time.getMinutes()
let s = time.getSeconds()
let week = time.getDay()
// type
if (type === undefined) {
return (
Y +
'-' +
(M < 10 ? '0' + M : M) +
'-' +
(D < 10 ? '0' + D : D) +
' ' +
(h < 10 ? '0' + h : h) +
':' +
(m < 10 ? '0' + m : m) +
':' +
(s < 10 ? '0' + s : s)
)
} else if (type === 'week') {
// quartz 1
return week + 1
}
}
//
function checkDate(value) {
let time = new Date(value)
let format = formatDate(time)
return value === format
}
onMounted(() => {
expressionChange()
})
</script>

Some files were not shown because too many files have changed in this diff Show More