Commit 0a530206 authored by 胡占生's avatar 胡占生 🇨🇳

int:项目重新初始化。变更vu3版本

parent 8b9a12af
# 告诉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
# 页面标题 # 页面标题
VUE_APP_TITLE = 若依管理系统 VITE_APP_TITLE = 若依管理系统
# 开发环境配置 # 开发环境配置
ENV = 'development' VITE_APP_ENV = 'development'
# 若依管理系统/开发环境 # 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api' VITE_APP_BASE_API = '/dev-api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 页面标题 # 页面标题
VUE_APP_TITLE = 若依管理系统 VITE_APP_TITLE = 若依管理系统
# 生产环境配置 # 生产环境配置
ENV = 'production' VITE_APP_ENV = 'production'
# 若依管理系统/生产环境 # 若依管理系统/生产环境
VUE_APP_BASE_API = '/prod-api' VITE_APP_BASE_API = '/prod-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
\ No newline at end of file
# 页面标题 # 页面标题
VUE_APP_TITLE = 若依管理系统 VITE_APP_TITLE = 若依管理系统
NODE_ENV = production # 生产环境配置
VITE_APP_ENV = 'staging'
# 测试环境配置 # 若依管理系统/生产环境
ENV = 'staging' VITE_APP_BASE_API = '/stage-api'
# 若依管理系统/测试环境 # 是否在打包时开启压缩,支持 gzip 和 brotli
VUE_APP_BASE_API = '/stage-api' VITE_BUILD_COMPRESS = gzip
\ No newline at end of file
# 忽略build目录下类型为js的文件的语法检查
build/*.js
# 忽略src/assets目录下文件的语法检查
src/assets
# 忽略public目录下文件的语法检查
public
# 忽略当前目录下为js的文件的语法检查
*.js
# 忽略当前目录下为vue的文件的语法检查
*.vue
\ No newline at end of file
// 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']
}
}
The MIT License (MIT)
Copyright (c) 2018 RuoYi
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.
\ No newline at end of file
## 开发 <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.8</h1>
<h4 align="center">基于SpringBoot+Vue3前后端分离的Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.8-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/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) 版本。
* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast) 版本。
* 前端技术栈([Vue2](https://cn.vuejs.org) + [Element](https://github.com/ElemeFE/element) + [Vue CLI](https://cli.vuejs.org/zh)),请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue/tree/master/ruoyi-ui)
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
## 前端运行
```bash ```bash
# 克隆项目 # 克隆项目
git clone https://gitee.com/y_project/RuoYi-Vue git clone https://github.com/yangzongzhuan/RuoYi-Vue3.git
# 进入项目目录 # 进入项目目录
cd ruoyi-ui cd RuoYi-Vue3
# 安装依赖 # 安装依赖
npm install yarn --registry=https://registry.npmmirror.com
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com
# 启动服务 # 启动服务
npm run dev yarn dev
# 构建测试环境 yarn build:stage
# 构建生产环境 yarn build:prod
# 前端访问地址 http://localhost:80
``` ```
浏览器访问 http://localhost:80 ## 内置功能
## 发布 1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
14. 系统接口:根据业务代码自动生成相关的api接口文档。
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器:拖动表单元素生成相应的HTML代码。
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
```bash ## 在线体验
# 构建测试环境
npm run build:stage - admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址:http://vue.ruoyi.vip
文档地址:http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
# 构建生产环境 QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。
npm run build:prod \ No newline at end of file
```
\ No newline at end of file
module.exports = {
presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
'@vue/cli-plugin-babel/preset'
],
'env': {
'development': {
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
'plugins': ['dynamic-import-node']
}
}
}
\ No newline at end of file
...@@ -7,6 +7,6 @@ echo. ...@@ -7,6 +7,6 @@ echo.
cd %~dp0 cd %~dp0
cd .. cd ..
npm run build:prod yarn build:prod
pause pause
\ No newline at end of file
...@@ -7,6 +7,6 @@ echo. ...@@ -7,6 +7,6 @@ echo.
cd %~dp0 cd %~dp0
cd .. cd ..
npm install --registry=https://registry.npmmirror.com yarn --registry=https://registry.npmmirror.com
pause pause
\ No newline at end of file
@echo off @echo off
echo. echo.
echo [信息] 使用 Vue CLI 命令运行 Web 工程。 echo [信息] 使用 Vite 命令运行 Web 工程。
echo. echo.
%~d0 %~d0
cd %~dp0 cd %~dp0
cd .. cd ..
npm run dev yarn dev
pause pause
\ No newline at end of file
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<meta charset="utf-8"> <head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta charset="utf-8">
<meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="renderer" content="webkit">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title><%= webpackConfig.name %></title> <link rel="icon" href="/favicon.ico">
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> <title>若依管理系统</title>
<style> <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html, html,
body, body,
#app { #app {
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
} }
.chromeframe { .chromeframe {
margin: 0.2em 0; margin: 0.2em 0;
background: #ccc; background: #ccc;
...@@ -92,6 +94,7 @@ ...@@ -92,6 +94,7 @@
-ms-transform: rotate(0deg); -ms-transform: rotate(0deg);
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg); -ms-transform: rotate(360deg);
...@@ -105,6 +108,7 @@ ...@@ -105,6 +108,7 @@
-ms-transform: rotate(0deg); -ms-transform: rotate(0deg);
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg); -ms-transform: rotate(360deg);
...@@ -194,15 +198,18 @@ ...@@ -194,15 +198,18 @@
opacity: 0.5; opacity: 0.5;
} }
</style> </style>
</head> </head>
<body>
<div id="app"> <body>
<div id="loader-wrapper"> <div id="app">
<div id="loader"></div> <div id="loader-wrapper">
<div class="loader-section section-left"></div> <div id="loader"></div>
<div class="loader-section section-right"></div> <div class="loader-section section-left"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div> <div class="loader-section section-right"></div>
</div> <div class="load_title">正在加载系统资源,请耐心等待</div>
</div> </div>
</body> </div>
</html> <script type="module" src="/src/main.js"></script>
</body>
</html>
\ No newline at end of file
...@@ -4,87 +4,41 @@ ...@@ -4,87 +4,41 @@
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
"type": "module",
"scripts": { "scripts": {
"dev": "vue-cli-service serve", "dev": "vite",
"build:prod": "vue-cli-service build", "build:prod": "vite build",
"build:stage": "vue-cli-service build --mode staging", "build:stage": "vite build --mode staging",
"preview": "node build/index.js --preview", "preview": "vite preview"
"lint": "eslint --ext .js,.vue src"
}, },
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://gitee.com/y_project/RuoYi-Vue.git" "url": "https://gitee.com/y_project/RuoYi-Vue.git"
}, },
"dependencies": { "dependencies": {
"@riophae/vue-treeselect": "0.4.0", "@element-plus/icons-vue": "2.3.1",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.11.0",
"axios": "0.28.1", "axios": "0.28.1",
"clipboard": "2.0.8", "echarts": "5.5.1",
"core-js": "3.37.1", "element-plus": "2.7.6",
"echarts": "5.4.0",
"element-ui": "2.15.14",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.4.3", "fuse.js": "6.6.2",
"highlight.js": "9.18.5", "js-cookie": "3.0.5",
"js-beautify": "1.13.0", "jsencrypt": "3.3.2",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"quill": "1.3.7", "pinia": "2.1.7",
"screenfull": "5.0.2", "vue": "3.4.31",
"sortablejs": "1.10.2", "vue-cropper": "1.1.1",
"vue": "2.6.12", "vue-router": "4.4.0"
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-meta": "2.4.0",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "4.4.6", "@vitejs/plugin-vue": "5.0.5",
"@vue/cli-plugin-eslint": "4.4.6", "sass": "1.77.5",
"@vue/cli-service": "4.4.6", "unplugin-auto-import": "0.17.6",
"babel-eslint": "10.1.0", "vite": "5.3.2",
"babel-plugin-dynamic-import-node": "2.3.3", "vite-plugin-compression": "0.5.1",
"chalk": "4.1.0", "vite-plugin-svg-icons": "2.0.1",
"compression-webpack-plugin": "6.1.2", "unplugin-vue-setup-extend-plus": "1.0.1"
"connect": "3.6.6", }
"eslint": "7.15.0",
"eslint-plugin-vue": "7.2.0",
"lint-staged": "10.5.3",
"runjs": "4.4.2",
"sass": "1.32.13",
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"vue-template-compiler": "2.6.12"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
} }
User-agent: *
Disallow: /
\ No newline at end of file
<template> <template>
<div id="app"> <router-view />
<router-view />
<theme-picker />
</div>
</template> </template>
<script> <script setup>
import ThemePicker from "@/components/ThemePicker"; import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'
export default { onMounted(() => {
name: "App", nextTick(() => {
components: { ThemePicker }, // 初始化主题样式
metaInfo() { handleThemeStyle(useSettingsStore().theme)
return { })
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title, })
titleTemplate: title => {
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
}
}
}
};
</script> </script>
<style scoped>
#app .theme-picker {
display: none;
}
</style>
...@@ -57,4 +57,4 @@ export function optionselect() { ...@@ -57,4 +57,4 @@ export function optionselect() {
url: '/system/dict/type/optionselect', url: '/system/dict/type/optionselect',
method: 'get' method: 'get'
}) })
} }
\ No newline at end of file
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'
@import './variables.scss'; @import './variables.module.scss';
@mixin colorBtn($color) { @mixin colorBtn($color) {
background: $color; background: $color;
......
...@@ -89,4 +89,8 @@ ...@@ -89,4 +89,8 @@
> .el-submenu__title > .el-submenu__title
.el-submenu__icon-arrow { .el-submenu__icon-arrow {
display: none; display: none;
}
.el-dropdown .el-dropdown-link{
color: var(--el-color-primary) !important;
} }
\ No newline at end of file
/**
* I think element-ui's default theme color is too light for long-term use.
* So I modified the default color and you can modify it to your liking.
**/
/* theme color */
$--color-primary: #1890ff;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
// $--color-info: #1E1E1E;
$--button-font-weight: 400;
// $--color-text-regular: #1f2d3d;
$--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
theme: $--color-primary;
}
@import './variables.scss'; @import './variables.module.scss';
@import './mixin.scss'; @import './mixin.scss';
@import './transition.scss'; @import './transition.scss';
@import './element-ui.scss'; @import './element-ui.scss';
@import './sidebar.scss'; @import './sidebar.scss';
@import './btn.scss'; @import './btn.scss';
@import './ruoyi.scss';
body { body {
height: 100%; height: 100%;
margin: 0;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
......
/** /**
* 通用css样式布局处理 * 通用css样式布局处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
/** 基础通用 **/ /** 基础通用 **/
.pt5 { .pt5 {
padding-top: 5px; padding-top: 5px;
} }
.pr5 { .pr5 {
padding-right: 5px; padding-right: 5px;
} }
.pb5 { .pb5 {
padding-bottom: 5px; padding-bottom: 5px;
} }
.mt5 { .mt5 {
margin-top: 5px; margin-top: 5px;
} }
.mr5 { .mr5 {
margin-right: 5px; margin-right: 5px;
} }
.mb5 { .mb5 {
margin-bottom: 5px; margin-bottom: 5px;
} }
.mb8 { .mb8 {
margin-bottom: 8px; margin-bottom: 8px;
} }
.ml5 { .ml5 {
margin-left: 5px; margin-left: 5px;
} }
.mt10 { .mt10 {
margin-top: 10px; margin-top: 10px;
} }
.mr10 { .mr10 {
margin-right: 10px; margin-right: 10px;
} }
.mb10 { .mb10 {
margin-bottom: 10px; margin-bottom: 10px;
} }
.ml10 { .ml10 {
margin-left: 10px; margin-left: 10px;
} }
.mt20 { .mt20 {
margin-top: 20px; margin-top: 20px;
} }
.mr20 { .mr20 {
margin-right: 20px; margin-right: 20px;
} }
.mb20 { .mb20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.ml20 { .ml20 {
margin-left: 20px; margin-left: 20px;
} }
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
font-family: inherit; font-family: inherit;
font-weight: 500; font-weight: 500;
line-height: 1.1; line-height: 1.1;
color: inherit; color: inherit;
} }
.el-message-box__status + .el-message-box__message{ .el-form .el-form-item__label {
word-break: break-word; font-weight: 700;
} }
.el-dialog:not(.is-fullscreen) { .el-dialog:not(.is-fullscreen) {
margin-top: 6vh !important; margin-top: 6vh !important;
} }
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { .el-dialog.scrollbar .el-dialog__body {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
max-height: 70vh; max-height: 70vh;
padding: 10px 20px 0; padding: 10px 20px 0;
} }
.el-table { .el-table {
.el-table__header-wrapper, .el-table__fixed-header-wrapper { .el-table__header-wrapper, .el-table__fixed-header-wrapper {
th { th {
word-break: break-word; word-break: break-word;
background-color: #f8f8f9; background-color: #f8f8f9 !important;
color: #515a6e; color: #515a6e;
height: 40px; height: 40px !important;
font-size: 13px; font-size: 13px;
} }
} }
.el-table__body-wrapper {
.el-table__body-wrapper { .el-button [class*="el-icon-"] + span {
.el-button [class*="el-icon-"] + span { margin-left: 1px;
margin-left: 1px; }
} }
}
} }
/** 表单布局 **/ /** 表单布局 **/
.form-header { .form-header {
font-size: 15px; font-size:15px;
color: #6379bb; color:#6379bb;
border-bottom: 1px solid #ddd; border-bottom:1px solid #ddd;
margin: 8px 10px 25px 10px; margin:8px 10px 25px 10px;
padding-bottom: 5px padding-bottom:5px
} }
/** 表格布局 **/ /** 表格布局 **/
.pagination-container { .pagination-container {
position: relative; position: relative;
height: 25px; height: 25px;
margin-bottom: 10px; margin-bottom: 10px;
margin-top: 15px; margin-top: 15px;
padding: 10px 20px !important; padding: 10px 20px !important;
}
.el-dialog .pagination-container {
position: static !important;
} }
/* tree border */ /* tree border */
.tree-border { .tree-border {
margin-top: 5px; margin-top: 5px;
border: 1px solid #e5e6e7; border: 1px solid #e5e6e7;
background: #FFFFFF none; background: #FFFFFF none;
border-radius: 4px; border-radius:4px;
width: 100%;
} }
.pagination-container .el-pagination { .pagination-container .el-pagination {
right: 0; right: 0;
position: absolute; position: absolute;
} }
@media (max-width: 768px) { @media ( max-width : 768px) {
.pagination-container .el-pagination > .el-pagination__jump { .pagination-container .el-pagination > .el-pagination__jump {
display: none !important; display: none !important;
} }
...@@ -146,64 +136,65 @@ ...@@ -146,64 +136,65 @@
} }
} }
.el-table .fixed-width .el-button--mini { .el-table .fixed-width .el-button--small {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
width: inherit; width: inherit;
} }
/** 表格更多操作下拉样式 */ /** 表格更多操作下拉样式 */
.el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { .el-table .el-dropdown-link {
cursor: pointer; cursor: pointer;
margin-left: 5px; color: #409EFF;
margin-left: 10px;
} }
.el-table .el-dropdown, .el-icon-arrow-down { .el-table .el-dropdown, .el-icon-arrow-down {
font-size: 12px; font-size: 12px;
} }
.el-tree-node__content > .el-checkbox { .el-tree-node__content > .el-checkbox {
margin-right: 8px; margin-right: 8px;
} }
.list-group-striped > .list-group-item { .list-group-striped > .list-group-item {
border-left: 0; border-left: 0;
border-right: 0; border-right: 0;
border-radius: 0; border-radius: 0;
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
.list-group { .list-group {
padding-left: 0px; padding-left: 0px;
list-style: none; list-style: none;
} }
.list-group-item { .list-group-item {
border-bottom: 1px solid #e7eaec; border-bottom: 1px solid #e7eaec;
border-top: 1px solid #e7eaec; border-top: 1px solid #e7eaec;
margin-bottom: -1px; margin-bottom: -1px;
padding: 11px 0px; padding: 11px 0px;
font-size: 13px; font-size: 13px;
} }
.pull-right { .pull-right {
float: right !important; float: right !important;
} }
.el-card__header { .el-card__header {
padding: 14px 15px 7px; padding: 14px 15px 7px !important;
min-height: 40px; min-height: 40px;
} }
.el-card__body { .el-card__body {
padding: 15px 20px 20px 20px; padding: 15px 20px 20px 20px !important;
} }
.card-box { .card-box {
padding-right: 15px; padding-right: 15px;
padding-left: 15px; padding-left: 15px;
margin-bottom: 10px; margin-bottom: 10px;
} }
/* button color */ /* button color */
...@@ -229,63 +220,62 @@ ...@@ -229,63 +220,62 @@
/* text color */ /* text color */
.text-navy { .text-navy {
color: #1ab394; color: #1ab394;
} }
.text-primary { .text-primary {
color: inherit; color: inherit;
} }
.text-success { .text-success {
color: #1c84c6; color: #1c84c6;
} }
.text-info { .text-info {
color: #23c6c8; color: #23c6c8;
} }
.text-warning { .text-warning {
color: #f8ac59; color: #f8ac59;
} }
.text-danger { .text-danger {
color: #ed5565; color: #ed5565;
} }
.text-muted { .text-muted {
color: #888888; color: #888888;
} }
/* image */ /* image */
.img-circle { .img-circle {
border-radius: 50%; border-radius: 50%;
} }
.img-lg { .img-lg {
width: 120px; width: 120px;
height: 120px; height: 120px;
} }
.avatar-upload-preview { .avatar-upload-preview {
position: relative; position: absolute;
top: 50%; top: 50%;
left: 50%; transform: translate(50%, -50%);
transform: translate(-50%, -50%); width: 200px;
width: 200px; height: 200px;
height: 200px; border-radius: 50%;
border-radius: 50%; box-shadow: 0 0 4px #ccc;
box-shadow: 0 0 4px #ccc; overflow: hidden;
overflow: hidden;
} }
/* 拖拽列样式 */ /* 拖拽列样式 */
.sortable-ghost { .sortable-ghost{
opacity: .8; opacity: .8;
color: #fff !important; color: #fff!important;
background: #42b983 !important; background: #42b983!important;
} }
/* 表格右侧工具栏样式 */
.top-right-btn { .top-right-btn {
position: relative; margin-left: auto;
float: right;
} }
...@@ -70,26 +70,30 @@ ...@@ -70,26 +70,30 @@
width: 100% !important; width: 100% !important;
} }
.el-menu-item, .el-submenu__title { .el-menu-item, .menu-title {
overflow: hidden !important; overflow: hidden !important;
text-overflow: ellipsis !important; text-overflow: ellipsis !important;
white-space: nowrap !important; white-space: nowrap !important;
} }
.el-menu-item .el-menu-tooltip__trigger {
display: inline-block !important;
}
// menu hover // menu hover
.submenu-title-noDropdown, .sub-menu-title-noDropdown,
.el-submenu__title { .el-sub-menu__title {
&:hover { &:hover {
background-color: rgba(0, 0, 0, 0.06) !important; background-color: rgba(0, 0, 0, 0.06) !important;
} }
} }
& .theme-dark .is-active > .el-submenu__title { & .theme-dark .is-active > .el-sub-menu__title {
color: $base-menu-color-active !important; color: $base-menu-color-active !important;
} }
& .nest-menu .el-submenu>.el-submenu__title, & .nest-menu .el-sub-menu>.el-sub-menu__title,
& .el-submenu .el-menu-item { & .el-sub-menu .el-menu-item {
min-width: $base-sidebar-width !important; min-width: $base-sidebar-width !important;
&:hover { &:hover {
...@@ -97,8 +101,8 @@ ...@@ -97,8 +101,8 @@
} }
} }
& .theme-dark .nest-menu .el-submenu>.el-submenu__title, & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
& .theme-dark .el-submenu .el-menu-item { & .theme-dark .el-sub-menu .el-menu-item {
background-color: $base-sub-menu-background !important; background-color: $base-sub-menu-background !important;
&:hover { &:hover {
...@@ -116,7 +120,7 @@ ...@@ -116,7 +120,7 @@
margin-left: 54px; margin-left: 54px;
} }
.submenu-title-noDropdown { .sub-menu-title-noDropdown {
padding: 0 !important; padding: 0 !important;
position: relative; position: relative;
...@@ -129,10 +133,10 @@ ...@@ -129,10 +133,10 @@
} }
} }
.el-submenu { .el-sub-menu {
overflow: hidden; overflow: hidden;
&>.el-submenu__title { &>.el-sub-menu__title {
padding: 0 !important; padding: 0 !important;
.svg-icon { .svg-icon {
...@@ -143,8 +147,8 @@ ...@@ -143,8 +147,8 @@
} }
.el-menu--collapse { .el-menu--collapse {
.el-submenu { .el-sub-menu {
&>.el-submenu__title { &>.el-sub-menu__title {
&>span { &>span {
height: 0; height: 0;
width: 0; width: 0;
...@@ -152,12 +156,19 @@ ...@@ -152,12 +156,19 @@
visibility: hidden; visibility: hidden;
display: inline-block; display: inline-block;
} }
&>i {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
} }
} }
} }
} }
.el-menu--collapse .el-menu .el-submenu { .el-menu--collapse .el-menu .el-sub-menu {
min-width: $base-sidebar-width !important; min-width: $base-sidebar-width !important;
} }
...@@ -198,15 +209,15 @@ ...@@ -198,15 +209,15 @@
} }
} }
.nest-menu .el-submenu>.el-submenu__title, .nest-menu .el-sub-menu>.el-sub-menu__title,
.el-menu-item { .el-menu-item {
&:hover { &:hover {
// you can use $subMenuHover // you can use $sub-menuHover
background-color: rgba(0, 0, 0, 0.06) !important; background-color: rgba(0, 0, 0, 0.06) !important;
} }
} }
// the scroll bar appears when the subMenu is too long // the scroll bar appears when the sub-menu is too long
>.el-menu--popup { >.el-menu--popup {
max-height: 100vh; max-height: 100vh;
overflow-y: auto; overflow-y: auto;
......
// base color // base color
$blue:#324157; $blue: #324157;
$light-blue:#3A71A8; $light-blue: #3A71A8;
$red:#C03639; $red: #C03639;
$pink: #E65D6E; $pink: #E65D6E;
$green: #30B08F; $green: #30B08F;
$tiffany: #4AB7BD; $tiffany: #4AB7BD;
$yellow:#FEC171; $yellow: #FEC171;
$panGreen: #30B08F; $panGreen: #30B08F;
// 默认菜单主题风格 // 默认菜单主题风格
$base-menu-color:#bfcbd9; $base-menu-color: #bfcbd9;
$base-menu-color-active:#f4f4f5; $base-menu-color-active: #f4f4f5;
$base-menu-background:#304156; $base-menu-background: #304156;
$base-logo-title-color: #ffffff; $base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70); $base-menu-light-color: rgba(0, 0, 0, 0.7);
$base-menu-light-background:#ffffff; $base-menu-light-background: #ffffff;
$base-logo-light-title-color: #001529; $base-logo-light-title-color: #001529;
$base-sub-menu-background:#1f2d3d; $base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover:#001528; $base-sub-menu-hover: #001528;
// 自定义暗色菜单风格 // 自定义暗色菜单风格
/** /**
...@@ -36,6 +36,12 @@ $base-sub-menu-background:#000c17; ...@@ -36,6 +36,12 @@ $base-sub-menu-background:#000c17;
$base-sub-menu-hover:#001528; $base-sub-menu-hover:#001528;
*/ */
$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-info: #909399;
$base-sidebar-width: 200px; $base-sidebar-width: 200px;
// the :export directive is the magic sauce for webpack // the :export directive is the magic sauce for webpack
...@@ -50,5 +56,10 @@ $base-sidebar-width: 200px; ...@@ -50,5 +56,10 @@ $base-sidebar-width: 200px;
subMenuHover: $base-sub-menu-hover; subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width; sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color; logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color logoLightTitleColor: $base-logo-light-title-color;
primaryColor: $--color-primary;
successColor: $--color-success;
dangerColor: $--color-danger;
infoColor: $--color-info;
warningColor: $--color-warning;
} }
...@@ -9,57 +9,49 @@ ...@@ -9,57 +9,49 @@
</el-breadcrumb> </el-breadcrumb>
</template> </template>
<script> <script setup>
export default { const route = useRoute();
data() { const router = useRouter();
return { const levelList = ref([])
levelList: null
}
},
watch: {
$route(route) {
// if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) {
return
}
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) { function getBreadcrumb() {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched) // only show routes with meta.title
} let matched = route.matched.filter(item => item.meta && item.meta.title);
const first = matched[0]
// 判断是否为首页
if (!isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
}, }
isDashboard(route) { function isDashboard(route) {
const name = route && route.name const name = route && route.name
if (!name) { if (!name) {
return false return false
} }
return name.trim() === 'Index' return name.trim() === 'Index'
}, }
handleLink(item) { function handleLink(item) {
const { redirect, path } = item const { redirect, path } = item
if (redirect) { if (redirect) {
this.$router.push(redirect) router.push(redirect)
return return
}
this.$router.push(path)
}
} }
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> </script>
<style lang="scss" scoped> <style lang='scss' scoped>
.app-breadcrumb.el-breadcrumb { .app-breadcrumb.el-breadcrumb {
display: inline-block; display: inline-block;
font-size: 14px; font-size: 14px;
...@@ -71,4 +63,4 @@ export default { ...@@ -71,4 +63,4 @@ export default {
cursor: text; cursor: text;
} }
} }
</style> </style>
\ No newline at end of file
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
日,允许的通配符[, - * ? / L W] 日,允许的通配符[, - * ? / L W]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
不指定 不指定
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
周期从 周期从
<el-input-number v-model='cycle01' :min="1" :max="30" /> - <el-input-number v-model='cycle01' :min="1" :max="30" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="31" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每 <el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每
<el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次 <el-input-number v-model='average02' :min="1" :max="31 - average01" /> 日执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="5"> <el-radio v-model='radioValue' :value="5">
每月 每月
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日 <el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="6"> <el-radio v-model='radioValue' :value="6">
本月最后一天 本月最后一天
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="7"> <el-radio v-model='radioValue' :value="7">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option> <el-option v-for="item in 31" :key="item" :label="item" :value="item" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script setup>
<script> const emit = defineEmits(['update'])
export default { const props = defineProps({
data() { cron: {
return { type: Object,
radioValue: 1, default: {
workday: 1, second: "*",
cycle01: 1, min: "*",
cycle02: 2, hour: "*",
average01: 1, day: "*",
average02: 1, month: "*",
checkboxList: [], week: "?",
checkNum: this.$options.propsData.check year: "",
} }
}, },
name: 'crontab-day', check: {
props: ['check', 'cron'], type: Function,
methods: { default: () => {
// 单选按钮值变化时 }
radioChange() { }
('day rachange'); })
if (this.radioValue !== 2 && this.cron.week !== '?') { const radioValue = ref(1)
this.$emit('update', 'week', '?', 'day') const cycle01 = ref(1)
} const cycle02 = ref(2)
const average01 = ref(1)
switch (this.radioValue) { const average02 = ref(1)
case 1: const workday = ref(1)
this.$emit('update', 'day', '*'); const checkboxList = ref([])
break; const checkCopy = ref([1])
case 2: const cycleTotal = computed(() => {
this.$emit('update', 'day', '?'); cycle01.value = props.check(cycle01.value, 1, 30)
break; cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31)
case 3: return cycle01.value + '-' + cycle02.value
this.$emit('update', 'day', this.cycleTotal); })
break; const averageTotal = computed(() => {
case 4: average01.value = props.check(average01.value, 1, 30)
this.$emit('update', 'day', this.averageTotal); average02.value = props.check(average02.value, 1, 31 - average01.value)
break; return average01.value + '/' + average02.value
case 5: })
this.$emit('update', 'day', this.workday + 'W'); const workdayTotal = computed(() => {
break; workday.value = props.check(workday.value, 1, 31)
case 6: return workday.value + 'W'
this.$emit('update', 'day', 'L'); })
break; const checkboxString = computed(() => {
case 7: return checkboxList.value.join(',')
this.$emit('update', 'day', this.checkboxString); })
break; watch(() => props.cron.day, value => changeRadioValue(value))
} watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange())
('day rachange end'); function changeRadioValue(value) {
}, if (value === "*") {
// 周期两个值变化时 radioValue.value = 1
cycleChange() { } else if (value === "?") {
if (this.radioValue == '3') { radioValue.value = 2
this.$emit('update', 'day', this.cycleTotal); } else if (value.indexOf("-") > -1) {
} const indexArr = value.split('-')
}, cycle01.value = Number(indexArr[0])
// 平均两个值变化时 cycle02.value = Number(indexArr[1])
averageChange() { radioValue.value = 3
if (this.radioValue == '4') { } else if (value.indexOf("/") > -1) {
this.$emit('update', 'day', this.averageTotal); const indexArr = value.split('/')
} average01.value = Number(indexArr[0])
}, average02.value = Number(indexArr[1])
// 最近工作日值变化时 radioValue.value = 4
workdayChange() { } else if (value.indexOf("W") > -1) {
if (this.radioValue == '5') { const indexArr = value.split("W")
this.$emit('update', 'day', this.workdayCheck + 'W'); workday.value = Number(indexArr[0])
} radioValue.value = 5
}, } else if (value === "L") {
// checkbox值变化时 radioValue.value = 6
checkboxChange() { } else {
if (this.radioValue == '7') { checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
this.$emit('update', 'day', this.checkboxString); radioValue.value = 7
} }
} }
}, // 单选按钮值变化时
watch: { function onRadioChange() {
'radioValue': 'radioChange', if (radioValue.value === 2 && props.cron.week === '?') {
'cycleTotal': 'cycleChange', emit('update', 'week', '*', 'day')
'averageTotal': 'averageChange', }
'workdayCheck': 'workdayChange', if (radioValue.value !== 2 && props.cron.week !== '?') {
'checkboxString': 'checkboxChange', emit('update', 'week', '?', 'day')
}, }
computed: { switch (radioValue.value) {
// 计算两个周期值 case 1:
cycleTotal: function () { emit('update', 'day', '*', 'day')
const cycle01 = this.checkNum(this.cycle01, 1, 30) break
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31) case 2:
return cycle01 + '-' + cycle02; emit('update', 'day', '?', 'day')
}, break
// 计算平均用到的值 case 3:
averageTotal: function () { emit('update', 'day', cycleTotal.value, 'day')
const average01 = this.checkNum(this.average01, 1, 30) break
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0) case 4:
return average01 + '/' + average02; emit('update', 'day', averageTotal.value, 'day')
}, break
// 计算工作日格式 case 5:
workdayCheck: function () { emit('update', 'day', workdayTotal.value, 'day')
const workday = this.checkNum(this.workday, 1, 31) break
return workday; case 6:
}, emit('update', 'day', 'L', 'day')
// 计算勾选的checkbox值合集 break
checkboxString: function () { case 7:
let str = this.checkboxList.join(); if (checkboxList.value.length === 0) {
return str == '' ? '*' : str; checkboxList.value.push(checkCopy.value[0])
} } else {
} checkCopy.value = checkboxList.value
}
emit('update', 'day', checkboxString.value, 'day')
break
}
} }
</script> </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>
\ No newline at end of file
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
小时,允许的通配符[, - * /] 小时,允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="22" /> - <el-input-number v-model='cycle01' :min="0" :max="22" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="23" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="22" />时开始,每 <el-input-number v-model='average01' :min="0" :max="22" /> 时开始,每
<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次 <el-input-number v-model='average02' :min="1" :max="23 - average01" /> 小时执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script setup>
export default { const emit = defineEmits(['update'])
data() { const props = defineProps({
return { cron: {
radioValue: 1, type: Object,
cycle01: 0, default: {
cycle02: 1, second: "*",
average01: 0, min: "*",
average02: 1, hour: "*",
checkboxList: [], day: "*",
checkNum: this.$options.propsData.check month: "*",
} week: "?",
}, year: "",
name: 'crontab-hour', }
props: ['check', 'cron'], },
methods: { check: {
// 单选按钮值变化时 type: Function,
radioChange() { default: () => {
if (this.cron.min === '*') { }
this.$emit('update', 'min', '0', 'hour'); }
} })
if (this.cron.second === '*') { const radioValue = ref(1)
this.$emit('update', 'second', '0', 'hour'); const cycle01 = ref(0)
} const cycle02 = ref(1)
switch (this.radioValue) { const average01 = ref(0)
case 1: const average02 = ref(1)
this.$emit('update', 'hour', '*') const checkboxList = ref([])
break; const checkCopy = ref([0])
case 2: const cycleTotal = computed(() => {
this.$emit('update', 'hour', this.cycleTotal); cycle01.value = props.check(cycle01.value, 0, 22)
break; cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23)
case 3: return cycle01.value + '-' + cycle02.value
this.$emit('update', 'hour', this.averageTotal); })
break; const averageTotal = computed(() => {
case 4: average01.value = props.check(average01.value, 0, 22)
this.$emit('update', 'hour', this.checkboxString); average02.value = props.check(average02.value, 1, 23 - average01.value)
break; return average01.value + '/' + average02.value
} })
}, const checkboxString = computed(() => {
// 周期两个值变化时 return checkboxList.value.join(',')
cycleChange() { })
if (this.radioValue == '2') { watch(() => props.cron.hour, value => changeRadioValue(value))
this.$emit('update', 'hour', this.cycleTotal); watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
} function changeRadioValue(value) {
}, if (props.cron.min === '*') {
// 平均两个值变化时 emit('update', 'min', '0', 'hour');
averageChange() { }
if (this.radioValue == '3') { if (props.cron.second === '*') {
this.$emit('update', 'hour', this.averageTotal); emit('update', 'second', '0', 'hour');
} }
}, if (value === '*') {
// checkbox值变化时 radioValue.value = 1
checkboxChange() { } else if (value.indexOf('-') > -1) {
if (this.radioValue == '4') { const indexArr = value.split('-')
this.$emit('update', 'hour', this.checkboxString); cycle01.value = Number(indexArr[0])
} cycle02.value = Number(indexArr[1])
} radioValue.value = 2
}, } else if (value.indexOf('/') > -1) {
watch: { const indexArr = value.split('/')
'radioValue': 'radioChange', average01.value = Number(indexArr[0])
'cycleTotal': 'cycleChange', average02.value = Number(indexArr[1])
'averageTotal': 'averageChange', radioValue.value = 3
'checkboxString': 'checkboxChange' } else {
}, checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
computed: { radioValue.value = 4
// 计算两个周期值 }
cycleTotal: function () { }
const cycle01 = this.checkNum(this.cycle01, 0, 22) function onRadioChange() {
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23) switch (radioValue.value) {
return cycle01 + '-' + cycle02; case 1:
}, emit('update', 'hour', '*', 'hour')
// 计算平均用到的值 break
averageTotal: function () { case 2:
const average01 = this.checkNum(this.average01, 0, 22) emit('update', 'hour', cycleTotal.value, 'hour')
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0) break
return average01 + '/' + average02; case 3:
}, emit('update', 'hour', averageTotal.value, 'hour')
// 计算勾选的checkbox值合集 break
checkboxString: function () { case 4:
let str = this.checkboxList.join(); if (checkboxList.value.length === 0) {
return str == '' ? '*' : str; checkboxList.value.push(checkCopy.value[0])
} } else {
} checkCopy.value = checkboxList.value
}
emit('update', 'hour', checkboxString.value, 'hour')
break
}
} }
</script> </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>
\ No newline at end of file
This diff is collapsed.
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
分钟,允许的通配符[, - * /] 分钟,允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> - <el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟 <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> 分钟
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始,每 <el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始, 每
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次 <el-input-number v-model='average02' :min="1" :max="59 - average01" /> 分钟执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model='radioValue' :value="4">
指定
<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-radio>
</el-form-item>
</el-form>
</template> </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>
<script> <style lang="scss" scoped>
export default { .el-input-number--small, .el-select, .el-select--small {
data() { margin: 0 0.2rem;
return { }
radioValue: 1, .el-select, .el-select--small {
cycle01: 1, width: 19.8rem;
cycle02: 2,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-min',
props: ['check', 'cron'],
methods: {
// 单选按钮值变化时
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'min', '*', 'min');
break;
case 2:
this.$emit('update', 'min', this.cycleTotal, 'min');
break;
case 3:
this.$emit('update', 'min', this.averageTotal, 'min');
break;
case 4:
this.$emit('update', 'min', this.checkboxString, 'min');
break;
}
},
// 周期两个值变化时
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'min', this.cycleTotal, 'min');
}
},
// 平均两个值变化时
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'min', this.averageTotal, 'min');
}
},
// checkbox值变化时
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'min', this.checkboxString, 'min');
}
},
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange',
},
computed: {
// 计算两个周期值
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 58)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
return cycle01 + '-' + cycle02;
},
// 计算平均用到的值
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 58)
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
return average01 + '/' + average02;
},
// 计算勾选的checkbox值合集
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
} }
</script> </style>
\ No newline at end of file \ No newline at end of file
<template> <template>
<el-form size='small'> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
月,允许的通配符[, - * /] 月,允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="1" :max="11" /> - <el-input-number v-model='cycle01' :min="1" :max="11" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="12" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每 <el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每
<el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次 <el-input-number v-model='average02' :min="1" :max="12 - average01" /> 月月执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option> <el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script setup>
export default { const emit = defineEmits(['update'])
data() { const props = defineProps({
return { cron: {
radioValue: 1, type: Object,
cycle01: 1, default: {
cycle02: 2, second: "*",
average01: 1, min: "*",
average02: 1, hour: "*",
checkboxList: [], day: "*",
checkNum: this.check month: "*",
} week: "?",
}, year: "",
name: 'crontab-month', }
props: ['check', 'cron'], },
methods: { check: {
// 单选按钮值变化时 type: Function,
radioChange() { default: () => {
switch (this.radioValue) { }
case 1: }
this.$emit('update', 'month', '*'); })
break; const radioValue = ref(1)
case 2: const cycle01 = ref(1)
this.$emit('update', 'month', this.cycleTotal); const cycle02 = ref(2)
break; const average01 = ref(1)
case 3: const average02 = ref(1)
this.$emit('update', 'month', this.averageTotal); const checkboxList = ref([])
break; const checkCopy = ref([1])
case 4: const monthList = ref([
this.$emit('update', 'month', this.checkboxString); {key: 1, value: '一月'},
break; {key: 2, value: '二月'},
} {key: 3, value: '三月'},
}, {key: 4, value: '四月'},
// 周期两个值变化时 {key: 5, value: '五月'},
cycleChange() { {key: 6, value: '六月'},
if (this.radioValue == '2') { {key: 7, value: '七月'},
this.$emit('update', 'month', this.cycleTotal); {key: 8, value: '八月'},
} {key: 9, value: '九月'},
}, {key: 10, value: '十月'},
// 平均两个值变化时 {key: 11, value: '十一月'},
averageChange() { {key: 12, value: '十二月'}
if (this.radioValue == '3') { ])
this.$emit('update', 'month', this.averageTotal); const cycleTotal = computed(() => {
} cycle01.value = props.check(cycle01.value, 1, 11)
}, cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12)
// checkbox值变化时 return cycle01.value + '-' + cycle02.value
checkboxChange() { })
if (this.radioValue == '4') { const averageTotal = computed(() => {
this.$emit('update', 'month', this.checkboxString); average01.value = props.check(average01.value, 1, 11)
} average02.value = props.check(average02.value, 1, 12 - average01.value)
} return average01.value + '/' + average02.value
}, })
watch: { const checkboxString = computed(() => {
'radioValue': 'radioChange', return checkboxList.value.join(',')
'cycleTotal': 'cycleChange', })
'averageTotal': 'averageChange', watch(() => props.cron.month, value => changeRadioValue(value))
'checkboxString': 'checkboxChange' watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
}, function changeRadioValue(value) {
computed: { if (value === '*') {
// 计算两个周期值 radioValue.value = 1
cycleTotal: function () { } else if (value.indexOf('-') > -1) {
const cycle01 = this.checkNum(this.cycle01, 1, 11) const indexArr = value.split('-')
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12) cycle01.value = Number(indexArr[0])
return cycle01 + '-' + cycle02; cycle02.value = Number(indexArr[1])
}, radioValue.value = 2
// 计算平均用到的值 } else if (value.indexOf('/') > -1) {
averageTotal: function () { const indexArr = value.split('/')
const average01 = this.checkNum(this.average01, 1, 11) average01.value = Number(indexArr[0])
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0) average02.value = Number(indexArr[1])
return average01 + '/' + average02; radioValue.value = 3
}, } else {
// 计算勾选的checkbox值合集 checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
checkboxString: function () { radioValue.value = 4
let str = this.checkboxList.join(); }
return str == '' ? '*' : str; }
} 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> </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>
\ No newline at end of file
This diff is collapsed.
<template> <template>
<el-form size="small"> <el-form>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="1"> <el-radio v-model='radioValue' :value="1">
秒,允许的通配符[, - * /] 秒,允许的通配符[, - * /]
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="2"> <el-radio v-model='radioValue' :value="2">
周期从 周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> - <el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" />
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="3"> <el-radio v-model='radioValue' :value="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每 <el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次 <el-input-number v-model='average02' :min="1" :max="59 - average01" /> 秒执行一次
</el-radio> </el-radio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio v-model='radioValue' :label="4"> <el-radio v-model='radioValue' :value="4">
指定 指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> <el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> <el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select> </el-select>
</el-radio> </el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<script> <script setup>
export default { const emit = defineEmits(['update'])
data() { const props = defineProps({
return { cron: {
radioValue: 1, type: Object,
cycle01: 1, default: {
cycle02: 2, second: "*",
average01: 0, min: "*",
average02: 1, hour: "*",
checkboxList: [], day: "*",
checkNum: this.$options.propsData.check month: "*",
} week: "?",
}, year: "",
name: 'crontab-second', }
props: ['check', 'radioParent'], },
methods: { check: {
// 单选按钮值变化时 type: Function,
radioChange() { default: () => {
switch (this.radioValue) { }
case 1: }
this.$emit('update', 'second', '*', 'second'); })
break; const radioValue = ref(1)
case 2: const cycle01 = ref(0)
this.$emit('update', 'second', this.cycleTotal); const cycle02 = ref(1)
break; const average01 = ref(0)
case 3: const average02 = ref(1)
this.$emit('update', 'second', this.averageTotal); const checkboxList = ref([])
break; const checkCopy = ref([0])
case 4: const cycleTotal = computed(() => {
this.$emit('update', 'second', this.checkboxString); cycle01.value = props.check(cycle01.value, 0, 58)
break; cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
} return cycle01.value + '-' + cycle02.value
}, })
// 周期两个值变化时 const averageTotal = computed(() => {
cycleChange() { average01.value = props.check(average01.value, 0, 58)
if (this.radioValue == '2') { average02.value = props.check(average02.value, 1, 59 - average01.value)
this.$emit('update', 'second', this.cycleTotal); return average01.value + '/' + average02.value
} })
}, const checkboxString = computed(() => {
// 平均两个值变化时 return checkboxList.value.join(',')
averageChange() { })
if (this.radioValue == '3') { watch(() => props.cron.second, value => changeRadioValue(value))
this.$emit('update', 'second', this.averageTotal); watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
} function changeRadioValue(value) {
}, if (value === '*') {
// checkbox值变化时 radioValue.value = 1
checkboxChange() { } else if (value.indexOf('-') > -1) {
if (this.radioValue == '4') { const indexArr = value.split('-')
this.$emit('update', 'second', this.checkboxString); cycle01.value = Number(indexArr[0])
} cycle02.value = Number(indexArr[1])
} radioValue.value = 2
}, } else if (value.indexOf('/') > -1) {
watch: { const indexArr = value.split('/')
'radioValue': 'radioChange', average01.value = Number(indexArr[0])
'cycleTotal': 'cycleChange', average02.value = Number(indexArr[1])
'averageTotal': 'averageChange', radioValue.value = 3
'checkboxString': 'checkboxChange', } else {
radioParent() { checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
this.radioValue = this.radioParent radioValue.value = 4
} }
}, }
computed: { // 单选按钮值变化时
// 计算两个周期值 function onRadioChange() {
cycleTotal: function () { switch (radioValue.value) {
const cycle01 = this.checkNum(this.cycle01, 0, 58) case 1:
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59) emit('update', 'second', '*', 'second')
return cycle01 + '-' + cycle02; break
}, case 2:
// 计算平均用到的值 emit('update', 'second', cycleTotal.value, 'second')
averageTotal: function () { break
const average01 = this.checkNum(this.average01, 0, 58) case 3:
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0) emit('update', 'second', averageTotal.value, 'second')
return average01 + '/' + average02; break
}, case 4:
// 计算勾选的checkbox值合集 if (checkboxList.value.length === 0) {
checkboxString: function () { checkboxList.value.push(checkCopy.value[0])
let str = this.checkboxList.join(); } else {
return str == '' ? '*' : str; checkCopy.value = checkboxList.value
} }
} emit('update', 'second', checkboxString.value, 'second')
break
}
} }
</script> </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>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -13,20 +13,17 @@ ...@@ -13,20 +13,17 @@
</div> </div>
</template> </template>
<script> <script setup>
export default { defineProps({
name: 'Hamburger', isActive: {
props: { type: Boolean,
isActive: { default: false
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
} }
})
const emit = defineEmits()
const toggleClick = () => {
emit('toggleClick');
} }
</script> </script>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import * as components from '@element-plus/icons-vue'
export default {
install: (app) => {
for (const key in components) {
const componentConfig = components[key];
app.component(componentConfig.name, componentConfig);
}
},
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment