Author SHA1 Message Date
odboy 44fa37eac3 feat(role): 添加角色菜单权限分配功能
- 后端新增 listRoleMenuByPid 接口用于获取角色菜单权限
- 前端新增 listRoleMenuByPid API 方法调用接口
- 修改角色页面布局,调整菜单授权区域宽度为6列
- 角色页面导入 listRoleMenuByPid 方法替换原有的 listMenuByPid
- 更新树形菜单数据加载方法,使用新的角色菜单权限接口
- 更改前端主题变量从 cyberorange 暗色主题为 cloudsky 亮色主题
2026-01-25 10:16:26 +08:00
odboy df841d64a2 style(theme): 新增主题 2026-01-25 10:10:03 +08:00
odboy 0514bbb8bb move(theme): 移动主题变量文件到主题目录并更新引用 2026-01-25 10:00:12 +08:00
odboy 833a515353 feat(styles): 更换主题样式为云天主题
- 将默认样式主题从 solarflare 替换为 cloudsky
- 新增 cloudsky、mint、oceanbreeze 三个主题样式文件
- 更新基础色彩变量包括蓝色、红色、绿色等配色方案
- 调整侧边栏菜单颜色、导航栏背景及阴影效果
- 优化面包屑导航、汉堡菜单按钮等组件样式变量
- 添加主题变量的 webpack 导出配置支持
2026-01-25 09:49:59 +08:00
odboy 17d812cba9 feat(styles): 更新主题样式变量配置
- 将默认主题从 technology5 替换为 solarflare 主题
- 新增 arcticaurora 主题样式变量文件
- 新增 solarflare 主题样式变量文件,包含全新的配色方案
- 更新导航栏、侧边栏、面包屑等组件的样式变量
- 添加新的颜色配置和渐变效果支持
2026-01-25 09:39:14 +08:00
odboy 34a3a39fea style(styles): 添加顶部导航栏和面包屑样式变量
- 为profession主题添加navbar、hamburger和breadcrumb相关样式变量
- 为technology4主题添加navbar、hamburger和breadcrumb相关样式变量
- 为technology5主题添加navbar、hamburger和breadcrumb相关样式变量
- 更新variables.scss引用从technology3切换到technology5
- 统一顶部导航栏背景渐变、阴影、悬停效果等样式定义
- 标准化面包屑导航文字颜色、链接颜色和悬停效果配置
2026-01-25 09:32:38 +08:00
odboy 77abc7b0e2 style(styles): 添加导航栏面包屑汉堡菜单样式变量并应用
- 在 variables.technology3.scss 中添加 Navbar 顶部导航栏样式变量
- 在 variables.technology3.scss 中添加 Hamburger 汉堡菜单按钮样式变量
- 在 variables.technology3.scss 中添加 Breadcrumb 面包屑导航样式变量
- 在 Breadcrumb 组件中应用新的面包屑样式变量
- 在 Hamburger 组件中应用新的汉堡菜单样式变量
- 在 Navbar 组件中应用新的导航栏样式变量
- 移除 Breadcrumb 组件中对 variables.technology3 的重复导入
2026-01-25 09:29:14 +08:00
odboy 32619cd138 style(Breadcrumb): 更新面包屑组件样式以增强视觉效果
- 导入新的技术变量文件 variables.technology3
- 将面包屑文字颜色统一设置为白色并增加重要性标记
- 为链接状态添加发光阴影效果和悬停滤镜
- 调整分隔符颜色透明度以改善可读性
- 为非重定向项目添加文本阴影效果
- 优化悬停状态的颜色过渡和阴影效果
2026-01-25 09:23:18 +08:00
odboy 89e2eb66ec style(components): 统一导航组件样式主题配置
- 面包屑组件引入变量样式并优化悬停效果
- 汉堡菜单按钮应用主题颜色和过渡动画
- 导航栏背景改为渐变色并调整阴影效果
- 用户头像添加边框和悬停高亮效果
- 下拉箭头图标应用主题颜色并增加交互反馈
- 所有组件统一使用主题变量替换硬编码颜色值
2026-01-25 09:17:16 +08:00
odboy 2b0b81f2a7 feat(style): 添加多种主题样式配置
- 移除原有 variables.scss 文件中的硬编码颜色变量
- 新增 variables.default.scss 提供默认主题样式
- 新增 variables.profession.scss 提供专业稳重主题
- 新增 variables.technology3.scss 提供科技现代主题(深空极客)
- 新增 variables.technology4.scss 提供科技现代主题(赛博蓝光)
- 新增 variables.technology5.scss 提供科技现代主题(钛银脉冲)
- 通过 @import 机制实现主题切换功能
2026-01-24 09:53:05 +08:00
odboy 1618b9fe25 feat(navbar): 移除布局尺寸选择功能 2026-01-24 09:52:34 +08:00
odboy f05aebf193 fix(CuteLink): 更新默认链接地址
- 将默认链接从 GitHub 地址更改为 Gitee 地址
2026-01-24 09:51:43 +08:00
odboy 5660df5762 fix(CuteLink): 更新默认链接地址
- 将默认链接从 GitHub 地址更改为 Gitee 地址
2026-01-24 09:51:29 +08:00
odboy 82fe3a76a0 style(ui): 更新用户界面样式和按钮组件
- 将用户中心的安全设置链接替换为el-button文本按钮
- 调整登录表单高度从370px增加到390px
2026-01-24 09:51:07 +08:00
odboy eb2d0e02a8 refactor(util): 移除废弃类并优化验证工具类
- 删除 TaskTemplateInfoVo 类
- 删除 ServerException 类
- 删除 KitDistributedIdUtil 类
- 删除 SystemQuartzJobVo 类
- 在 KitBigDecimalUtil 中新增格式化金额方法
- 在 KitDateUtil 中新增获取周几方法
- 在 KitCollUtil 中修复空集合验证逻辑
- 移除 KitStringUtil 中的日期相关代码
- 在 KitValidUtil 中新增多种验证方法
- 修改 SystemMenuController 中的菜单保存逻辑
- 优化 SystemQuartzJobController 中的定时任务操作方法
- 为 SystemQuartzJobTb 添加扩展字段 uuid
2026-01-24 09:50:13 +08:00
odboy 9b61ab35b6 feat(framework): 添加Redis序列化白名单配置功能 2026-01-24 09:48:18 +08:00
odboy a4258a3851 refactor(sql): 移除任务模块相关表 2026-01-24 09:46:14 +08:00
odboy 12ad5eb169 refactor(task): 移除任务模块相关常量、控制器和核心实现类 2026-01-24 09:45:06 +08:00
odboy 8f804da741 update cutejava/cutejava-starter/src/main/resources/application-dev.yml.
mybatis-plus批量插入优化

Signed-off-by: Odboy <tianjun@odboy.cn>
2026-01-19 04:05:44 +00:00
odboy 8b9b58c802 update cutejava/cutejava-starter/src/main/resources/application-prod.yml.
myabtis-plus批量插入优化

Signed-off-by: Odboy <tianjun@odboy.cn>
2026-01-19 04:05:18 +00:00
odboy 1c10dc2ce2 !6 chore(version): 更新项目版本号从1.5.0到1.5.2
Merge pull request !6 from Odboy/dev
2026-01-17 02:19:51 +00:00
odboy 65699dcab4 chore(version): 更新项目版本号从1.5.0到1.5.2 2026-01-17 10:19:14 +08:00
odboy 8a38e532e2 !4 fix(test): 修复测试类中对象实例化错误
Merge pull request !4 from Odboy/dev
2026-01-17 02:10:58 +00:00
odboy df43cd2333 fix(test): 修复测试类中对象实例化错误
- 添加了 SystemDeptTb 类的导入声明
- 将 SystemDeptVo 对象替换为 SystemDeptTb 对象
- 确保测试代码使用正确的数据对象类型
2026-01-17 10:09:50 +08:00
odboy 65e94a204c !3 feat(system): 新增系统组件服务重构部门和用户选择功能
Merge pull request !3 from Odboy/dev
2026-01-17 02:04:58 +00:00
odboy da255fa7e0 feat(system): 新增系统组件服务重构部门和用户选择功能
- 新增 CuteDeptTreeVo 模型类用于部门树形结构
- 重命名并迁移 SystemProductLineTreeVo 到 CuteProductLineSelectProVo
- 重命名并迁移 SystemProductLineVo 到 CuteProductLineSelectVo
- 新增 CuteUserSelectVo 模型类用于用户选择组件
- 新增 CuteBaseService 提供基础部门查询服务
- 新增 CuteDeptTreeService 处理部门树形数据逻辑
- 新增 CuteFileUploadService 管理文件上传功能
- 新增 CuteProductLineSelectProService 和 CuteProductLineSelectService
- 新增 CuteUserSelectService 提供用户选择数据源
- 新增多个 API 控制器包括 CuteDeptTreeApi、CuteFileUploadApi 等
- 更新缓存键常量 USER_INFO 替代 ONLINE_USER
- 移除旧的 SystemComponentController 和相关方法
- 调整 SystemUserInfoDAO 使用新的缓存键名
- 修改 SystemUserVo 中的部门字段类型为 SystemDeptTb
2026-01-17 10:01:42 +08:00
odboy d413ea4469 refactor(system): 优化部门服务中的数据对象使用
- 将 SystemUserVo 中的 dept 字段类型从 SystemDeptVo 改为 SystemDeptTb
- 在 SystemDeptService 中统一使用 SystemDeptTb 对象替代 SystemDeptVo
- 删除了 getDeptVoById 方法并替换为直接使用 getDeptById
- 重构了部门树构建逻辑,优化了部门数据的查询和映射
- 修改了部门删除、查询、验证等相关方法的数据类型处理
- 添加了获取所有部门映射的私有方法以提高查询效率
2026-01-17 09:53:36 +08:00
odboy 4eaa383717 feat(dept): 新增部门树形组件功能
- 创建 CuteDeptTreeVo 模型类用于部门树形结构数据传输
- 实现 CuteDeptTreeService 服务类处理部门树形数据查询逻辑
- 开发 CuteDeptTreeApi 接口提供部门树形数据查询功能
- 将 SystemDeptService 中的 filterRootDeptList 和 queryDeptByArgs 方法改为 public 以便外部调用
- 前端创建 cute-dept-tree API 接口文件封装请求方法
- 更新 CuteDeptTree 组件使用新的部门树形接口并调整数据处理逻辑
- 修改组件 props 类型从 Number/String 改为 String 类型
2026-01-17 09:34:42 +08:00
odboy d113ebfa2f fix(select): 统一选择组件值类型为字符串
- 将 CuteProductLineSelect 组件的 value 类型从 [Number, String] 修改为 String
- 为 CuteProductLineSelectProVo 添加 value 和 label 字段注释说明
- 将 CuteProductLineSelectVo 的 value 字段类型从 Long 修改为 String
- 为 CuteUserSelectVo 添加 deptId、email、phone 字段注释说明
- 在 CuteProductLineSelectService 中将部门 ID 转换为字符串赋值给 value
2026-01-17 09:11:28 +08:00
odboy f2898da525 feat(user): 添加根据用户名列表查询用户基础数据功能
- 在CuteUserSelectService中新增listMetadataByUsernames方法
- 为CuteUserSelectApi添加listMetadataByUsernames接口
- 在前端cute-user-select.js中新增listMetadataByUsernames请求方法
- 修改CuteSingleUserSelect组件支持初始化时根据用户名加载用户信息
- 修改CuteUserSelect组件移除dataSource属性并支持初始化加载
- 更新CuteBusinessDemo演示页面用户字段默认值为空数组
2026-01-17 09:01:10 +08:00
odboy 462abff607 refactor(system): 重构系统组件服务结构
- 将产品线选择组件相关VO类从dal层移动到application层并重命名
- 新增CuteUserSelectVo、CuteBaseService、CuteFileUploadService等服务类
- 创建CuteProductLineSelectProService和CuteProductLineSelectService业务服务
- 新增CuteUserSelectService用户选择服务及对应的API接口
- 修改文件上传API使用新的服务类并添加权限控制
- 更新产品线选择API使用新服务类并移除旧的实现方法
- 删除系统用户服务中的旧用户元数据查询方法
- 更新前端用户选择组件调用新的API接口
- 移除旧的用户元数据选项查询API调用
2026-01-17 06:38:38 +08:00
odboy 89803b3908 feat(api): 添加文件上传组件专用接口支持本地和OSS上传
- 在api store中新增fileUploadApplicationApi和ossUploadApplicationApi两个专用接口地址
- 从getters中移除已废弃的deployUploadApi和databaseUploadApi
- 将上传组件改为使用新的专用接口,并通过mode参数区分本地和OSS上传
- 更新组件文档注释将上传方式从server改为local
- 创建CuteFileUploadApi控制器提供uploadLocal和uploadOSS接口
- 在SystemLocalStorageService中实现uploadLocal方法处理本地文件上传逻辑
- 更新演示页面默认使用本地上传模式
2026-01-17 05:59:42 +08:00
odboy df6dc89b96 feat(component): 添加产品线选择组件并重构系统组件API
- 新增 CuteProductLineSelect 组件API接口
- 重命名 SystemComponentController 为 CuteProductLineSelectProApi
- 迁移部门选择数据源接口到新API路径
- 更新前端组件导入路径和API调用方式
- 修改 CuteDeptTree 组件分页大小限制
- 为文件上传组件添加上传方式配置选项
- 调整字典详情和定时任务模块的API导入路径
2026-01-17 05:28:24 +08:00
odboy 5989b8bc78 !1 refactor(system): 重构系统模块的缓存键和数据对象配置
Merge pull request !1 from Odboy/dev
2026-01-16 11:44:05 +00:00
odboy d41333c766 refactor(system): 重构系统模块的缓存键和数据对象配置 2026-01-16 19:43:27 +08:00
odboy 83c4e28527 feat(user): 优化用户数据对象和查询服务 2026-01-16 19:40:20 +08:00
odboy 1053669077 refactor(websocket): 更新WebSocket消息处理并重构缓存键配置 2026-01-16 19:32:21 +08:00
odboy 96647a055b feat(menu): 添加菜单查询中是否包含按钮类型的参数控制 2026-01-16 19:09:33 +08:00
odboy 02bff29f94 refactor(system): 重构系统服务模块代码结构和功能实现 2026-01-16 18:53:36 +08:00
287 changed files with 6374 additions and 8003 deletions
-1
View File
@@ -118,4 +118,3 @@
- cutejava-framework:系统基础框架。提供核心功能,如:权限、数据权限、异常处理、缓存、工具类、接口限流、接口防重、接口幂等。 - cutejava-framework:系统基础框架。提供核心功能,如:权限、数据权限、异常处理、缓存、工具类、接口限流、接口防重、接口幂等。
- cutejava-module-system:系统功能模块。提供用户、角色、菜单、部门、岗位、字典、定时任务、邮件、Minio存储、服务监控等功能 - cutejava-module-system:系统功能模块。提供用户、角色、菜单、部门、岗位、字典、定时任务、邮件、Minio存储、服务监控等功能
- cutejava-module-task:串行任务模块,已实现流水线功能。参考阿里云云效,提供流水线功能,可配置流水线任务,并支持任务依赖、任务参数、任务参数校验、任务参数回填。
-4
View File
@@ -45,7 +45,3 @@ npm run build:prod
2、加速node-sass安装 2、加速node-sass安装
https://www.ydyno.com/archives/1219.html https://www.ydyno.com/archives/1219.html
#### 特别鸣谢
- 感谢 [elunez](https://github.com/elunez/eladmin-mp) 大佬提供的基础框架
@@ -0,0 +1,12 @@
import request from '@/utils/request'
export function listMetadata(query) {
return request({
url: 'api/component/CuteDeptTree/listMetadata',
method: 'post',
data: query
})
}
export default { listMetadata }
@@ -0,0 +1,8 @@
import request from '@/utils/request'
export function listMetadata() {
return request({
url: 'api/component/CuteProductLineSelectPro/listMetadata',
method: 'post'
})
}
@@ -0,0 +1,8 @@
import request from '@/utils/request'
export function listMetadata() {
return request({
url: 'api/component/CuteProductLineSelect/listMetadata',
method: 'post'
})
}
@@ -0,0 +1,22 @@
import request from '@/utils/request'
export function listMetadata(query) {
return request({
url: 'api/component/CuteUserSelect/listMetadata',
method: 'post',
data: {
blurry: query
}
})
}
export function listMetadataByUsernames(usernameList = []) {
return request({
url: 'api/component/CuteUserSelect/listMetadataByUsernames',
method: 'post',
data: usernameList
})
}
export default { listMetadata, listMetadataByUsernames }
@@ -1,15 +0,0 @@
import request from '@/utils/request'
export function listDeptSelectDataSource() {
return request({
url: 'api/component/listDeptSelectDataSource',
method: 'post'
})
}
export function listDeptSelectProDataSource() {
return request({
url: 'api/component/listDeptSelectProDataSource',
method: 'post'
})
}
@@ -1,44 +1,44 @@
import request from '@/utils/request' import request from '@/utils/request'
/** /**
* 默认入口:add、del、edit、get * 默认入口:add、del、edit、get
*/ */
export function get(dictName) { export function get(dictName) {
const params = { const params = {
page: 1, page: 1,
size: 9999999, size: 9999999,
args: { args: {
dictName: dictName dictName: dictName
} }
} }
return request({ return request({
url: 'api/dictDetail/searchDictDetail', url: 'api/dictDetail/searchDictDetail',
method: 'post', method: 'post',
data: params data: params
}) })
} }
export function add(data) { export function add(data) {
return request({ return request({
url: 'api/dictDetail/saveDictDetail', url: 'api/dictDetail/saveDictDetail',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function del(id) { export function del(id) {
return request({ return request({
url: 'api/dictDetail/deleteDictDetailById', url: 'api/dictDetail/deleteDictDetailById',
method: 'post', method: 'post',
data: { id: id } data: { id: id }
}) })
} }
export function edit(data) { export function edit(data) {
return request({ return request({
url: 'api/dictDetail/updateDictDetailById', url: 'api/dictDetail/updateDictDetailById',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export default { add, edit, del } export default { add, edit, del }
@@ -1,29 +1,29 @@
import request from '@/utils/request' import request from '@/utils/request'
/** /**
* 默认入口:add、del、edit、get * 默认入口:add、del、edit、get
*/ */
export function add(data) { export function add(data) {
return request({ return request({
url: 'api/localStorage/uploadFile', url: 'api/localStorage/uploadFile',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function del(ids) { export function del(ids) {
return request({ return request({
url: 'api/localStorage/deleteFileByIds', url: 'api/localStorage/deleteFileByIds',
method: 'post', method: 'post',
data: ids data: ids
}) })
} }
export function edit(data) { export function edit(data) {
return request({ return request({
url: 'api/localStorage/updateLocalStorageById', url: 'api/localStorage/updateLocalStorageById',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export default { add, edit, del } export default { add, edit, del }
+7
View File
@@ -34,6 +34,13 @@ export function listMenuByPid(pid) {
}) })
} }
export function listRoleMenuByPid(pid) {
return request({
url: 'api/menu/listRoleMenuByPid?pid=' + pid,
method: 'post'
})
}
export function searchMenu(params) { export function searchMenu(params) {
return request({ return request({
url: 'api/menu/searchMenu', url: 'api/menu/searchMenu',
@@ -1,21 +1,21 @@
import request from '@/utils/request' import request from '@/utils/request'
/** /**
* 默认入口:add、del、edit、get * 默认入口:add、del、edit、get
*/ */
export function add(data) { export function add(data) {
return request({ return request({
url: 'api/ossStorage/uploadFile', url: 'api/ossStorage/uploadFile',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function del(ids) { export function del(ids) {
return request({ return request({
url: 'api/ossStorage/deleteFileByIds', url: 'api/ossStorage/deleteFileByIds',
method: 'post', method: 'post',
data: ids data: ids
}) })
} }
export default { add, del } export default { add, del }
@@ -1,43 +1,43 @@
import request from '@/utils/request' import request from '@/utils/request'
/** /**
* 默认入口:add、del、edit、get * 默认入口:add、del、edit、get
*/ */
export function add(data) { export function add(data) {
return request({ return request({
url: 'api/quartzJob/createQuartzJob', url: 'api/quartzJob/createQuartzJob',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function del(ids) { export function del(ids) {
return request({ return request({
url: 'api/quartzJob/deleteJobByIds', url: 'api/quartzJob/deleteJobByIds',
method: 'post', method: 'post',
data: ids data: ids
}) })
} }
export function edit(data) { export function edit(data) {
return request({ return request({
url: 'api/quartzJob/updateQuartzJobResumeCron', url: 'api/quartzJob/updateQuartzJobResumeCron',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function switchQuartzJobStatus(id) { export function switchQuartzJobStatus(id) {
return request({ return request({
url: 'api/quartzJob/switchQuartzJobStatus/' + id, url: 'api/quartzJob/switchQuartzJobStatus/' + id,
method: 'post' method: 'post'
}) })
} }
export function startQuartzJob(id) { export function startQuartzJob(id) {
return request({ return request({
url: 'api/quartzJob/startQuartzJob/' + id, url: 'api/quartzJob/startQuartzJob/' + id,
method: 'post' method: 'post'
}) })
} }
export default { add, edit, del, switchQuartzJobStatus, startQuartzJob } export default { add, edit, del, switchQuartzJobStatus, startQuartzJob }
+1 -16
View File
@@ -68,20 +68,5 @@ export function updateUserEmailByUsername(form) {
}) })
} }
export function queryUserMetadataOptions(query) { export default { add, edit, del, resetUserPasswordByIds }
const params = {
page: 1,
size: 50,
args: {
blurry: query
}
}
return request({
url: 'api/user/queryUserMetadataOptions',
method: 'post',
data: params
})
}
export default { add, edit, del, resetUserPasswordByIds, queryUserMetadataOptions }
@@ -0,0 +1,100 @@
// 科技现代:极光幻境(梦幻唯美)
// base color
$blue: #6C5CE7;
$light-blue: #A29BFE;
$red: #FF7675;
$pink: #FD79A8;
$green: #00B894;
$tiffany: #81ECEC;
$yellow: #FFEAA7;
$panGreen: #00B894;
// sidebar
$menuText: #B2BEC3;
$menuActiveText: #A29BFE;
$subMenuActiveText: #FFFFFF;
$menuBg: #0F0F1F;
$menuHover: #1A1A35;
$subMenuBg: #14142A;
$subMenuHover: #2C2C5A;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从深靛蓝过渡到深紫蓝色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #0A0A18;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(162, 155, 254, 0.18);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(162, 155, 254, 0.25);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(162, 155, 254, 0.1);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(162, 155, 254, 0.32);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(162, 155, 254, 0.3);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(162, 155, 254, 0.42);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px rgba(162, 155, 254, 0.45);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #F0F1F8;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #F0F1F8;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(162, 155, 254, 0.18);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(162, 155, 254, 0.4);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(129, 236, 236, 0.55);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #F7F8FC;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 赛博橙(热情奔放)
// base color
$blue: #FF5722;
$light-blue: #FF7043;
$red: #FF1744;
$pink: #FF4081;
$green: #00E676;
$tiffany: #69F0AE;
$yellow: #FFD600;
$panGreen: #00E676;
// sidebar
$menuText: #FFCCBC;
$menuActiveText: #FF6D00;
$subMenuActiveText: #FFFFFF;
$menuBg: #261411;
$menuHover: #3D1F1A;
$subMenuBg: #1E0D0B;
$subMenuHover: #502620;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色
$navbarBgStart: $menuBg;
$navbarBgEnd: #1A0E0C;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(255, 109, 0, 0.25);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(255, 109, 0, 0.35);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(255, 109, 0, 0.12);
// 右侧菜单项文字颜色
$navbarRightMenuColor: #FFD0BC;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(255, 109, 0, 0.4);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(255, 109, 0, 0.4);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(255, 109, 0, 0.5);
// 下拉箭头颜色
$navbarCaretColor: #FFCCBC;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: #FFCCBC;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 8px rgba(255, 109, 0, 0.5);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #FFFFFF;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #FFFFFF;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(255, 109, 0, 0.18);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 8px rgba(255, 109, 0, 0.5);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(255, 64, 129, 0.6);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #FFFFFF;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 默认风格
// base color
$blue: #324157;
$light-blue: #3A71A8;
$red: #C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow: #FEC171;
$panGreen: #30B08F;
// sidebar 默认
$menuText: #bfcbd9;
$menuActiveText: #409EFF;
$subMenuActiveText: #f4f4f5; // https://github.com/ElemeFE/element/issues/12951
$menuBg: #304156;
$menuHover: #263445;
$subMenuBg: #1f2d3d;
$subMenuHover: #001528;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从侧边栏颜色过渡到深蓝色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #263445;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(0, 21, 41, 0.15);
$navbarShadowY: 1px;
$navbarShadowBlur: 4px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(0, 21, 41, 0.2);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(0, 0, 0, 0.025);
// 右侧菜单项文字颜色
$navbarRightMenuColor: #5a5e66;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: transparent;
// 头像边框颜色
$navbarAvatarBorderColor: transparent;
$navbarAvatarHoverBorderColor: transparent;
$navbarAvatarHoverGlow: transparent;
// 下拉箭头颜色
$navbarCaretColor: #5a5e66;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: transparent;
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #97a8be;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #97a8be;
// Breadcrumb 发光效果
$breadcrumbTextGlow: transparent;
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: transparent;
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: #97a8be;
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #97a8be;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,101 @@
// 专业稳重(一般)
// base color
$blue: #3A71A8;
$light-blue: #5A9BDB;
$red: #D5657A;
$pink: #E696A5;
$green: #4AB7BD;
$tiffany: #6BCFD5;
$yellow: #FFD166;
$panGreen: #4AB7BD;
// sidebar
$menuText: #C0C9D5;
$menuActiveText: #FFFFFF;
$subMenuActiveText: #409EFF;
$menuBg: #234781;
$menuHover: #1D3A6B;
$subMenuBg: #152B4F;
$subMenuHover: #2D5BA6;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从侧边栏颜色过渡到深蓝色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #1A3055;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(58, 113, 168, 0.2);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(90, 155, 219, 0.3);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(90, 155, 219, 0.15);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(90, 155, 219, 0.3);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(90, 155, 219, 0.3);
$navbarAvatarHoverBorderColor: $light-blue;
$navbarAvatarHoverGlow: rgba(90, 155, 219, 0.4);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px rgba(90, 155, 219, 0.3);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #F0F4F8;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #F0F4F8;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(90, 155, 219, 0.2);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $light-blue;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(90, 155, 219, 0.3);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(90, 155, 219, 0.4);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #F5F8FC;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 科技现代:太阳耀斑(热烈活力)
// base color
$blue: #FF6B35;
$light-blue: #FF8C42;
$red: #E84C5B;
$pink: #FF7B9C;
$green: #FFC857;
$tiffany: #FF9F45;
$yellow: #FFD93D;
$panGreen: #FFC857;
// sidebar
$menuText: #D4A574;
$menuActiveText: #FF8C42;
$subMenuActiveText: #FFFFFF;
$menuBg: #1A1512;
$menuHover: #2A221D;
$subMenuBg: #221E1A;
$subMenuHover: #3D332C;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从深棕色过渡到炭黑色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #15100D;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(255, 140, 66, 0.2);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(255, 140, 66, 0.25);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(255, 140, 66, 0.1);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(255, 140, 66, 0.3);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(255, 140, 66, 0.3);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(255, 140, 66, 0.45);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px rgba(255, 140, 66, 0.4);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #FDF6EC;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #FDF6EC;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(255, 140, 66, 0.15);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(255, 140, 66, 0.35);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(255, 159, 69, 0.5);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #FFF9F0;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,101 @@
// 科技现代:深空极客(好看)
// base color
$blue: #4A90E2;
$light-blue: #66CCFF;
$red: #FF6B6B;
$pink: #FF9E9E;
$green: #66FFCC;
$tiffany: #81D8D0;
$yellow: #FFD93D;
$panGreen: #66FFCC;
// sidebar
$menuText: #A0AABF;
$menuActiveText: #66FFCC;
$subMenuActiveText: #FFFFFF;
$menuBg: #0F1520;
$menuHover: #1C2430;
$subMenuBg: #1A2332;
$subMenuHover: #2A3B5C;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从侧边栏颜色过渡到深蓝色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #162035;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(74, 144, 226, 0.15);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(74, 144, 226, 0.2);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(74, 144, 226, 0.1);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(102, 255, 204, 0.3);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(102, 255, 204, 0.3);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(102, 255, 204, 0.4);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px $menuActiveText;
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #FFFFFF;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #FFFFFF;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(102, 255, 204, 0.3);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(102, 255, 204, 0.4);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(102, 255, 204, 0.5);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #FFFFFF;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,101 @@
// 科技现代:赛博蓝光(好看)
// base color
$blue: #4FC3F7;
$light-blue: #81D4FA;
$red: #FF8A80;
$pink: #FFB3B8;
$green: #80DEEA;
$tiffany: #81D4FA;
$yellow: #FFD54F;
$panGreen: #80DEEA;
// sidebar
$menuText: #B0B8D0;
$menuActiveText: #4FC3F7;
$subMenuActiveText: #FFFFFF;
$menuBg: #0A0E17;
$menuHover: #151A2A;
$subMenuBg: #12182D;
$subMenuHover: #1E3A8A;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从侧边栏颜色过渡到深蓝紫色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #0D1422;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(79, 195, 247, 0.15);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(79, 195, 247, 0.2);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(79, 195, 247, 0.1);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(79, 195, 247, 0.3);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(79, 195, 247, 0.3);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(79, 195, 247, 0.4);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px $menuActiveText;
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #FFFFFF;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #FFFFFF;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(79, 195, 247, 0.2);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(79, 195, 247, 0.4);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(79, 195, 247, 0.5);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #FFFFFF;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,101 @@
// 科技现代:钛银脉冲(好看)
// base color
$blue: #393E7C;
$light-blue: #4A50A0;
$red: #E84C5B;
$pink: #FF7B9C;
$green: #4AB7BD;
$tiffany: #64D2FF;
$yellow: #FFD166;
$panGreen: #4AB7BD;
// sidebar
$menuText: #CCCCCC;
$menuActiveText: #00E5FF;
$subMenuActiveText: #FFFFFF;
$menuBg: #1A1A2E;
$menuHover: #222244;
$subMenuBg: #252545;
$subMenuHover: #393E7C;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从侧边栏颜色过渡到深紫色)
$navbarBgStart: $menuBg;
$navbarBgEnd: #141426;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(0, 229, 255, 0.15);
$navbarShadowY: 2px;
$navbarShadowBlur: 8px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(0, 229, 255, 0.2);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: rgba(0, 229, 255, 0.1);
// 右侧菜单项文字颜色
$navbarRightMenuColor: $menuText;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(0, 229, 255, 0.3);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(0, 229, 255, 0.3);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(0, 229, 255, 0.4);
// 下拉箭头颜色
$navbarCaretColor: $menuText;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: $menuText;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 6px $menuActiveText;
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #FFFFFF;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #FFFFFF;
// Breadcrumb 发光效果
$breadcrumbTextGlow: rgba(0, 229, 255, 0.2);
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: 0 0 6px rgba(0, 229, 255, 0.4);
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(0, 229, 255, 0.5);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #FFFFFF;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 清新明亮:天空云朵(清新舒适)
// base color
$blue: #5BA3F0;
$light-blue: #7BC4FF;
$red: #FF6B8A;
$pink: #FF8FA8;
$green: #6BCB77;
$tiffany: #7FD1AE;
$yellow: #FFD93D;
$panGreen: #6BCB77;
// sidebar
$menuText: #2A3A4A;
$menuActiveText: #2B7BD9;
$subMenuActiveText: #2B7BD9;
$menuBg: #FFFFFF;
$menuHover: #F0F5FF;
$subMenuBg: #F8FAFC;
$subMenuHover: #E1E8F5;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从白色过渡到浅蓝)
$navbarBgStart: #FFFFFF;
$navbarBgEnd: #F5F9FF;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(91, 163, 240, 0.15);
$navbarShadowY: 1px;
$navbarShadowBlur: 4px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(91, 163, 240, 0.2);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: #F0F5FF;
// 右侧菜单项文字颜色
$navbarRightMenuColor: #5A6C7D;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(91, 163, 240, 0.2);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(91, 163, 240, 0.25);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(91, 163, 240, 0.3);
// 下拉箭头颜色
$navbarCaretColor: #5A6C7D;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: #5A6C7D;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 4px rgba(91, 163, 240, 0.3);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #3A4A5A;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #3A4A5A;
// Breadcrumb 发光效果
$breadcrumbTextGlow: transparent;
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: transparent;
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(91, 163, 240, 0.4);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #2A3A4A;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 清新明亮:薄荷清新(清爽自然)
// base color
$blue: #5F9EA0;
$light-blue: #7DD3C0;
$red: #FF7F7F;
$pink: #FFA8A8;
$green: #95E1D3;
$tiffany: #B8F2E6;
$yellow: #FFEAA7;
$panGreen: #95E1D3;
// sidebar
$menuText: #3A4A5A;
$menuActiveText: #5F9EA0;
$subMenuActiveText: #5F9EA0;
$menuBg: #FAFEFC;
$menuHover: #F0FAF7;
$subMenuBg: #FCFDFB;
$subMenuHover: #E5F5F0;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从白色过渡到淡薄荷色)
$navbarBgStart: #FFFFFF;
$navbarBgEnd: #F5FFFA;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(95, 158, 160, 0.12);
$navbarShadowY: 1px;
$navbarShadowBlur: 4px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(95, 158, 160, 0.15);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: #F0FAF7;
// 右侧菜单项文字颜色
$navbarRightMenuColor: #5A6B7A;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(95, 158, 160, 0.2);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(95, 158, 160, 0.25);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(95, 158, 160, 0.3);
// 下拉箭头颜色
$navbarCaretColor: #5A6B7A;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: #5A6B7A;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 4px rgba(95, 158, 160, 0.3);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #3A4A5A;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #3A4A5A;
// Breadcrumb 发光效果
$breadcrumbTextGlow: transparent;
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: transparent;
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(90, 107, 122, 0.4);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #2A3A4A;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -0,0 +1,100 @@
// 清新明亮:海风浅蓝(宁静舒适)
// base color
$blue: #4A90E2;
$light-blue: #6BB3FF;
$red: #FF7F7F;
$pink: #FFA3A3;
$green: #7DD3C0;
$tiffany: #9CE6DC;
$yellow: #FFEAA7;
$panGreen: #7DD3C0;
// sidebar
$menuText: #3A4A5A;
$menuActiveText: #4A90E2;
$subMenuActiveText: #4A90E2;
$menuBg: #F5FAFF;
$menuHover: #EBF4FF;
$subMenuBg: #F8FCFF;
$subMenuHover: #D9EBFF;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// ===== Navbar 顶部导航栏样式变量 =====
// Navbar 背景渐变色(从白色过渡到浅蓝色)
$navbarBgStart: #FFFFFF;
$navbarBgEnd: #F5FAFF;
// Navbar 阴影颜色和透明度
$navbarShadowColor: rgba(74, 144, 226, 0.12);
$navbarShadowY: 1px;
$navbarShadowBlur: 4px;
$navbarShadowSpread: 0px;
// Navbar 底部边框颜色和透明度
$navbarBorderColor: rgba(74, 144, 226, 0.15);
$navbarBorderWidth: 1px;
// Navbar 悬停背景色(hamburger 和右侧菜单项)
$navbarHoverBg: #EBF4FF;
// 右侧菜单项文字颜色
$navbarRightMenuColor: #5A6C7D;
// 右侧菜单项悬停效果颜色
$navbarRightMenuHoverColor: $menuActiveText;
$navbarRightMenuHoverGlow: rgba(74, 144, 226, 0.2);
// 头像边框颜色
$navbarAvatarBorderColor: rgba(74, 144, 226, 0.25);
$navbarAvatarHoverBorderColor: $menuActiveText;
$navbarAvatarHoverGlow: rgba(74, 144, 226, 0.3);
// 下拉箭头颜色
$navbarCaretColor: #5A6C7D;
// ===== Hamburger 汉堡菜单按钮样式变量 =====
// Hamburger 默认颜色
$hamburgerColor: #5A6C7D;
// Hamburger 激活状态颜色
$hamburgerActiveColor: $menuActiveText;
// Hamburger 发光效果
$hamburgerGlow: 0 0 4px rgba(74, 144, 226, 0.3);
// ===== Breadcrumb 面包屑导航样式变量 =====
// Breadcrumb 文字颜色
$breadcrumbTextColor: #3A4A5A;
// Breadcrumb 链接颜色(可点击项)
$breadcrumbLinkColor: #3A4A5A;
// Breadcrumb 发光效果
$breadcrumbTextGlow: transparent;
// Breadcrumb 悬停颜色
$breadcrumbHoverColor: $menuActiveText;
// Breadcrumb 悬停发光效果
$breadcrumbHoverGlow: transparent;
// Breadcrumb 分隔符颜色
$breadcrumbSeparatorColor: rgba(90, 108, 125, 0.4);
// Breadcrumb 当前页面文字颜色(不可点击项)
$breadcrumbNoRedirectColor: #2A3A4A;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between/js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -1,36 +1 @@
// base color @import 'themes/light/variables.cloudsky';
$blue:#324157;
$light-blue:#3A71A8;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
// sidebar
$menuText:#bfcbd9;
$menuActiveText:#409EFF;
$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
$menuBg:#304156;
$menuHover:#263445;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
// 左侧菜单栏宽度
$sideBarWidth: 250px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}
@@ -70,15 +70,57 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "~@/assets/styles/variables";
.app-breadcrumb.el-breadcrumb { .app-breadcrumb.el-breadcrumb {
display: inline-block; display: inline-block;
font-size: 14px; font-size: 14px;
line-height: 50px; line-height: 50px;
margin-left: 8px; margin-left: 8px;
::v-deep .el-breadcrumb__item {
.el-breadcrumb__inner {
color: $breadcrumbTextColor !important;
font-weight: 500;
transition: all 0.3s ease;
&.is-link {
color: $breadcrumbLinkColor !important;
text-shadow: 0 0 4px $breadcrumbTextGlow;
&:hover {
color: $breadcrumbHoverColor !important;
filter: drop-shadow($breadcrumbHoverGlow);
}
}
&:hover {
color: $breadcrumbHoverColor !important;
filter: drop-shadow($breadcrumbHoverGlow);
}
}
.el-breadcrumb__separator {
color: $breadcrumbSeparatorColor;
}
}
a {
color: $breadcrumbLinkColor !important;
font-weight: 500;
text-shadow: 0 0 4px $breadcrumbTextGlow;
&:hover {
color: $breadcrumbHoverColor !important;
filter: drop-shadow($breadcrumbHoverGlow);
}
}
.no-redirect { .no-redirect {
color: #97a8be; color: $breadcrumbNoRedirectColor !important;
cursor: text; cursor: text;
font-weight: 500;
text-shadow: 0 0 4px $breadcrumbTextGlow;
} }
} }
</style> </style>
+1 -1
View File
@@ -1,5 +1,5 @@
import Vue from 'vue' import Vue from 'vue'
import { get as getDictDetail } from '@/api/system/dictDetail' import { get as getDictDetail } from '@/api/system/dict-detail'
export default class Dict { export default class Dict {
constructor(dict) { constructor(dict) {
@@ -1,6 +1,6 @@
<template> <template>
<a <a
href="https://github.com/odboy-tianjun/cutejava" href="https://gitee.com/odboy-tianjun/cutejava"
target="_blank" target="_blank"
class="github-corner" class="github-corner"
aria-label="View source on Github" aria-label="View source on Github"
@@ -32,15 +32,25 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
@import "~@/assets/styles/variables";
.hamburger { .hamburger {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
width: 20px; width: 20px;
height: 20px; height: 20px;
fill: $hamburgerColor;
transition: all 0.3s ease;
} }
.hamburger.is-active { .hamburger.is-active {
transform: rotate(180deg); transform: rotate(180deg);
fill: $hamburgerActiveColor;
filter: drop-shadow($hamburgerGlow);
}
.hamburger:hover {
fill: $hamburgerActiveColor;
} }
</style> </style>
+34 -13
View File
@@ -12,10 +12,9 @@
<screenfull id="screenfull" class="right-menu-item hover-effect" /> <screenfull id="screenfull" class="right-menu-item hover-effect" />
</el-tooltip> </el-tooltip>
<el-tooltip content="布局设置" effect="dark" placement="bottom"> <!--<el-tooltip content="布局设置" effect="dark" placement="bottom">-->
<size-select id="size-select" class="right-menu-item hover-effect" /> <!-- <size-select id="size-select" class="right-menu-item hover-effect" />-->
</el-tooltip> <!--</el-tooltip>-->
</template> </template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
@@ -50,7 +49,7 @@ import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb' import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger' import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull' import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect' // import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch' import Search from '@/components/HeaderSearch'
import Avatar from '@/assets/images/avatar.png' import Avatar from '@/assets/images/avatar.png'
@@ -59,7 +58,7 @@ export default {
Breadcrumb, Breadcrumb,
Hamburger, Hamburger,
Screenfull, Screenfull,
SizeSelect, // SizeSelect,
Search Search
}, },
data() { data() {
@@ -110,23 +109,30 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "~@/assets/styles/variables";
.navbar { .navbar {
height: 50px; height: 50px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background: #fff; background: linear-gradient(90deg, $navbarBgStart 0%, $navbarBgEnd 100%);
box-shadow: 0 1px 4px rgba(0,21,41,.08); box-shadow: 0 $navbarShadowY $navbarShadowBlur $navbarShadowSpread $navbarShadowColor;
border-bottom: $navbarBorderWidth solid $navbarBorderColor;
.hamburger-container { .hamburger-container {
line-height: 46px; line-height: 46px;
height: 100%; height: 100%;
float: left; float: left;
cursor: pointer; cursor: pointer;
transition: background .3s; transition: all 0.3s ease;
-webkit-tap-highlight-color:transparent; -webkit-tap-highlight-color:transparent;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: $navbarHoverBg;
.hamburger {
color: $menuActiveText;
filter: drop-shadow($hamburgerGlow);
}
} }
} }
@@ -153,15 +159,17 @@ export default {
padding: 0 8px; padding: 0 8px;
height: 100%; height: 100%;
font-size: 18px; font-size: 18px;
color: #5a5e66; color: $menuText;
vertical-align: text-bottom; vertical-align: text-bottom;
&.hover-effect { &.hover-effect {
cursor: pointer; cursor: pointer;
transition: background .3s; transition: all 0.3s ease;
&:hover { &:hover {
background: rgba(0, 0, 0, .025) background: $navbarHoverBg;
color: $navbarRightMenuHoverColor;
filter: drop-shadow(0 0 8px $navbarRightMenuHoverGlow);
} }
} }
} }
@@ -178,6 +186,13 @@ export default {
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 10px; border-radius: 10px;
border: 2px solid $navbarAvatarBorderColor;
transition: all 0.3s ease;
&:hover {
border-color: $navbarAvatarHoverBorderColor;
box-shadow: 0 0 15px $navbarAvatarHoverGlow;
}
} }
.el-icon-caret-bottom { .el-icon-caret-bottom {
@@ -186,6 +201,12 @@ export default {
right: -20px; right: -20px;
top: 25px; top: 25px;
font-size: 12px; font-size: 12px;
color: $navbarCaretColor;
transition: all 0.3s ease;
&:hover {
color: $menuActiveText;
}
} }
} }
} }
+4 -3
View File
@@ -3,8 +3,6 @@
* @type {any} * @type {any}
*/ */
const getters = { const getters = {
deployUploadApi: state => state.api.deployUploadApi,
databaseUploadApi: state => state.api.databaseUploadApi,
size: state => state.app.size, size: state => state.app.size,
sidebar: state => state.app.sidebar, sidebar: state => state.app.sidebar,
device: state => state.app.device, device: state => state.app.device,
@@ -24,6 +22,9 @@ const getters = {
swaggerApi: state => state.api.swaggerApi, swaggerApi: state => state.api.swaggerApi,
websocketApi: state => state.api.websocketApi, websocketApi: state => state.api.websocketApi,
sidebarRouters: state => state.permission.sidebarRouters, sidebarRouters: state => state.permission.sidebarRouters,
statusConst: state => state.pipeline.statusConst statusConst: state => state.pipeline.statusConst,
// 上传组件专用
fileUploadApplicationApi: state => state.api.fileUploadApplicationApi,
ossUploadApplicationApi: state => state.api.ossUploadApplicationApi
} }
export default getters export default getters
+3
View File
@@ -16,6 +16,9 @@ const api = {
fileUploadApi: baseUrl + '/api/localStorage/uploadFile', fileUploadApi: baseUrl + '/api/localStorage/uploadFile',
// oss上传 // oss上传
ossUploadApi: baseUrl + '/api/ossStorage/uploadFile', ossUploadApi: baseUrl + '/api/ossStorage/uploadFile',
// 上传组件专用
fileUploadApplicationApi: baseUrl + '/api/component/CuteFileUpload/uploadLocal',
ossUploadApplicationApi: baseUrl + '/api/component/CuteFileUpload/uploadOSS',
// baseUrl, // baseUrl,
baseApi: baseUrl baseApi: baseUrl
} }
@@ -30,13 +30,13 @@
<script> <script>
import { searchDept } from '@/api/system/dept' import CuteDeptTreeApi from '@/api/application/cute-dept-tree'
export default { export default {
name: 'CuteDeptTree', name: 'CuteDeptTree',
props: { props: {
value: { value: {
type: [Number, String], type: String,
required: false, required: false,
default: null default: null
} }
@@ -61,15 +61,11 @@ export default {
params['pid'] = node.data.id params['pid'] = node.data.id
} }
setTimeout(() => { setTimeout(() => {
searchDept({ CuteDeptTreeApi.listMetadata(params).then(res => {
page: 1,
size: 9999999,
args: params
}).then(res => {
if (resolve) { if (resolve) {
resolve(res.content) resolve(res)
} else { } else {
this.deptData = res.content this.deptData = res
} }
}) })
}, 100) }, 100)
@@ -14,7 +14,7 @@
:headers="headers" :headers="headers"
:on-success="handleSuccess" :on-success="handleSuccess"
:on-error="handleError" :on-error="handleError"
:action="ossUploadApi" :action="mode === 'oss' ? ossUploadApplicationApi: fileUploadApplicationApi"
> >
<i class="el-icon-upload" /> <i class="el-icon-upload" />
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
@@ -34,6 +34,14 @@ export default {
type: Object, type: Object,
required: true, required: true,
default: null default: null
},
/**
* 上传方式:local、oss
*/
mode: {
type: String,
required: true,
default: 'oss'
} }
}, },
data() { data() {
@@ -44,7 +52,8 @@ export default {
computed: { computed: {
...mapGetters([ ...mapGetters([
'baseApi', 'baseApi',
'ossUploadApi' 'fileUploadApplicationApi',
'ossUploadApplicationApi'
]) ])
}, },
methods: { methods: {
@@ -13,7 +13,7 @@
:headers="headers" :headers="headers"
:on-success="handleSuccess" :on-success="handleSuccess"
:on-error="handleError" :on-error="handleError"
:action="ossUploadApi" :action="mode === 'oss' ? ossUploadApplicationApi: fileUploadApplicationApi"
> >
<el-button size="small" type="primary">点击上传</el-button> <el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传不超过100MB的文件</div> <div slot="tip" class="el-upload__tip">只能上传不超过100MB的文件</div>
@@ -32,6 +32,14 @@ export default {
type: Object, type: Object,
required: true, required: true,
default: null default: null
},
/**
* 上传方式:local、oss
*/
mode: {
type: String,
required: true,
default: 'oss'
} }
}, },
data() { data() {
@@ -42,7 +50,8 @@ export default {
computed: { computed: {
...mapGetters([ ...mapGetters([
'baseApi', 'baseApi',
'ossUploadApi' 'fileUploadApplicationApi',
'ossUploadApplicationApi'
]) ])
}, },
methods: { methods: {
@@ -25,14 +25,14 @@
<script> <script>
import { listDeptSelectDataSource } from '@/api/system/component' import { listMetadata } from '@/api/application/cute-product-line-select'
import CsMessage from '@/utils/elementui/CsMessage' import CsMessage from '@/utils/elementui/CsMessage'
export default { export default {
name: 'CuteProductLineSelect', name: 'CuteProductLineSelect',
props: { props: {
value: { value: {
type: [Number, String], type: String,
default: null default: null
}, },
disabled: { disabled: {
@@ -56,7 +56,7 @@ export default {
}, },
methods: { methods: {
fetchDeptData() { fetchDeptData() {
listDeptSelectDataSource().then(data => { listMetadata().then(data => {
this.deptOptions = data this.deptOptions = data
}).catch(error => { }).catch(error => {
console.error('获取部门数据失败:', error) console.error('获取部门数据失败:', error)
@@ -17,7 +17,7 @@
<script> <script>
import { listDeptSelectProDataSource } from '@/api/system/component' import { listMetadata } from '@/api/application/cute-product-line-select-pro'
import CsMessage from '@/utils/elementui/CsMessage' import CsMessage from '@/utils/elementui/CsMessage'
export default { export default {
@@ -62,7 +62,7 @@ export default {
}) })
}, },
fetchDeptData() { fetchDeptData() {
listDeptSelectProDataSource().then(data => { listMetadata().then(data => {
this.deptOptions = this.cleanEmptyChildren(data) this.deptOptions = this.cleanEmptyChildren(data)
// console.error('deptOptions', this.deptOptions) // console.error('deptOptions', this.deptOptions)
}).catch(error => { }).catch(error => {
@@ -28,7 +28,7 @@
<script> <script>
import UserService from '@/api/system/user' import CuteUserSelectApi from '@/api/application/cute-user-select'
export default { export default {
name: 'CuteSingleUserSelect', name: 'CuteSingleUserSelect',
@@ -41,7 +41,7 @@ export default {
}, },
data() { data() {
return { return {
user: this.value, user: [],
loading: false, loading: false,
options: [] options: []
} }
@@ -51,21 +51,28 @@ export default {
this.user = newVal this.user = newVal
} }
}, },
async mounted() {
const that = this
if (that.value && that.value.length > 0) {
that.options = await CuteUserSelectApi.listMetadataByUsernames(that.value)
that.users = that.value
}
},
methods: { methods: {
remoteMethod(query) { remoteMethod(query) {
if (query !== '') { if (query !== '') {
this.loading = true this.loading = true
setTimeout(() => { setTimeout(() => {
this.loading = false this.loading = false
this.queryUserMetadataOptions(query) this.listMetadata(query)
}, 200) }, 200)
} else { } else {
this.options = [] this.options = []
} }
}, },
queryUserMetadataOptions(query, options) { listMetadata(query, options) {
const that = this const that = this
UserService.queryUserMetadataOptions(query).then(res => { CuteUserSelectApi.listMetadata(query).then(res => {
that.options = res that.options = res
}) })
}, },
@@ -28,7 +28,7 @@
<script> <script>
import UserService from '@/api/system/user' import CuteUserSelectApi from '@/api/application/cute-user-select'
export default { export default {
name: 'CuteUserSelect', name: 'CuteUserSelect',
@@ -37,16 +37,11 @@ export default {
type: Array, type: Array,
required: false, required: false,
default: null default: null
},
dataSource: {
type: Array,
required: false,
default: null
} }
}, },
data() { data() {
return { return {
users: this.value, users: [],
loading: false, loading: false,
options: [] options: []
} }
@@ -56,9 +51,11 @@ export default {
this.users = newVal this.users = newVal
} }
}, },
mounted() { async mounted() {
if (this.dataSource && this.dataSource.length > 0) { const that = this
this.options = this.dataSource if (that.value && that.value.length > 0) {
that.options = await CuteUserSelectApi.listMetadataByUsernames(that.value)
that.users = that.value
} }
}, },
methods: { methods: {
@@ -67,15 +64,15 @@ export default {
this.loading = true this.loading = true
setTimeout(() => { setTimeout(() => {
this.loading = false this.loading = false
this.queryUserMetadataOptions(query) this.listMetadata(query)
}, 200) }, 200)
} else { } else {
this.options = [] this.options = []
} }
}, },
queryUserMetadataOptions(query, options) { listMetadata(query, options) {
const that = this const that = this
UserService.queryUserMetadataOptions(query).then(res => { CuteUserSelectApi.listMetadata(query).then(res => {
that.options = res that.options = res
}) })
}, },
@@ -26,7 +26,7 @@ export default {
href: { href: {
type: String, type: String,
required: true, required: true,
default: 'https://github.com/odboy-tianjun' default: 'https://gitee.com/odboy-tianjun'
} }
} }
} }
@@ -65,7 +65,7 @@ export default {
data() { data() {
return { return {
form: { form: {
user: null, user: [],
dept: null, dept: null,
productLine: null, productLine: null,
productLinePro: null productLinePro: null
@@ -11,7 +11,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="文件上传" prop="fileUrl"> <el-form-item label="文件上传" prop="fileUrl">
<cute-file-drag-upload v-model="form" /> <cute-file-drag-upload v-model="form" mode="local" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button> <el-button type="primary" @click="submitForm('form')">提 交</el-button>
@@ -11,7 +11,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="文件上传" prop="fileUrl"> <el-form-item label="文件上传" prop="fileUrl">
<cute-file-upload v-model="form" /> <cute-file-upload v-model="form" mode="local" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button> <el-button type="primary" @click="submitForm('form')">提 交</el-button>
+1 -1
View File
@@ -220,7 +220,7 @@ export default {
.login-form-box { .login-form-box {
width: 360px; width: 360px;
height: 370px; height: 390px;
background-color: #FFFFFF; background-color: #FFFFFF;
} }
@@ -72,7 +72,7 @@
</template> </template>
<script> <script>
import crudDictDetail from '@/api/system/dictDetail' import crudDictDetail from '@/api/system/dict-detail'
import CRUD, { form, header, presenter } from '@crud/crud' import CRUD, { form, header, presenter } from '@crud/crud'
import pagination from '@crud/Pagination' import pagination from '@crud/Pagination'
import udOperation from '@crud/UD.operation' import udOperation from '@crud/UD.operation'
@@ -167,7 +167,7 @@
</template> </template>
<script> <script>
import crudJob from '@/api/system/quartzJob' import crudJob from '@/api/system/quartz-job'
import Log from './log' import Log from './log'
import CRUD, { crud, form, header, presenter } from '@crud/crud' import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
@@ -68,7 +68,7 @@
</el-dialog> </el-dialog>
<el-row :gutter="15"> <el-row :gutter="15">
<!--角色管理--> <!--角色管理-->
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px"> <el-col span="18" style="margin-bottom: 10px">
<el-card class="box-card" shadow="never"> <el-card class="box-card" shadow="never">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span class="role-span">角色列表</span> <span class="role-span">角色列表</span>
@@ -113,7 +113,7 @@
</el-card> </el-card>
</el-col> </el-col>
<!-- 菜单授权 --> <!-- 菜单授权 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7"> <el-col span="6">
<el-card class="box-card" shadow="never"> <el-card class="box-card" shadow="never">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top"> <el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
@@ -153,7 +153,7 @@
<script> <script>
import crudRoles from '@/api/system/role' import crudRoles from '@/api/system/role'
import { searchDept, searchDeptTree } from '@/api/system/dept' import { searchDept, searchDeptTree } from '@/api/system/dept'
import { listChildMenuSetByMenuId, listMenuByPid } from '@/api/system/menu' import { listChildMenuSetByMenuId, listRoleMenuByPid } from '@/api/system/menu'
import CRUD, { crud, form, header, presenter } from '@crud/crud' import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation' import crudOperation from '@crud/CRUD.operation'
@@ -197,7 +197,7 @@ export default {
methods: { methods: {
getMenuDatas(node, resolve) { getMenuDatas(node, resolve) {
setTimeout(() => { setTimeout(() => {
listMenuByPid(node.data.id ? node.data.id : 0).then(res => { listRoleMenuByPid(node.data.id ? node.data.id : 0).then(res => {
resolve(res) resolve(res)
}) })
}, 100) }, 100)
@@ -125,7 +125,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import crudFile from '@/api/system/localStorage' import crudFile from '@/api/system/local-storage'
import CRUD, { crud, form, header, presenter } from '@crud/crud' import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation' import crudOperation from '@crud/CRUD.operation'
@@ -94,7 +94,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import crudFile from '@/api/system/ossStorage' import crudFile from '@/api/system/oss-storage'
import CRUD, { crud, form, header, presenter } from '@crud/crud' import CRUD, { crud, form, header, presenter } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation' import crudOperation from '@crud/CRUD.operation'
@@ -55,8 +55,8 @@
<svg-icon icon-class="anq" /> <svg-icon icon-class="anq" />
安全设置 安全设置
<div class="user-right"> <div class="user-right">
<a @click="$refs.pass.dialog = true">修改密码</a> <el-button type="text" style="padding: 0" @click="$refs.pass.dialog = true">修改密码</el-button>
<a @click="$refs.email.dialog = true">修改邮箱</a> <el-button type="text" style="padding: 0" @click="$refs.email.dialog = true">修改邮箱</el-button>
</div> </div>
</li> </li>
</ul> </ul>
@@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>cutejava</artifactId> <artifactId>cutejava</artifactId>
<groupId>cn.odboy</groupId> <groupId>cn.odboy</groupId>
<version>1.5.0</version> <version>1.5.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>cutejava-framework</artifactId> <artifactId>cutejava-framework</artifactId>
@@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.exception; package cn.odboy.framework.exception;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import lombok.Getter; import lombok.Getter;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
/** /**
* 统一异常处理 * 统一异常处理
@@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.exception; package cn.odboy.framework.exception;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import lombok.Getter; import lombok.Getter;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
@Getter @Getter
public class ServerException extends RuntimeException { public class ServerException extends RuntimeException {
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.exception.handler; package cn.odboy.framework.exception.handler;
import lombok.Data; import lombok.Data;
@@ -42,5 +41,3 @@ public final class ApiError {
return apiError; return apiError;
} }
} }
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.exception.handler; package cn.odboy.framework.exception.handler;
import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.exceptions.ExceptionUtil;
@@ -77,8 +76,8 @@ public class GlobalExceptionHandler {
log.error(ExceptionUtil.stacktraceToString(e)); log.error(ExceptionUtil.stacktraceToString(e));
ObjectError objectError = e.getBindingResult().getAllErrors().get(0); ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
String message = objectError.getDefaultMessage(); String message = objectError.getDefaultMessage();
if (objectError instanceof FieldError fieldError) { if (objectError instanceof FieldError) {
message = fieldError.getField() + ": " + message; message = ((FieldError) objectError).getField() + ": " + message;
} }
return buildResponseEntity(ApiError.error(message)); return buildResponseEntity(ApiError.error(message));
} }
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties; package cn.odboy.framework.properties;
import cn.odboy.framework.properties.model.CaptchaModel; import cn.odboy.framework.properties.model.CaptchaModel;
import cn.odboy.framework.properties.model.ContentRsaEncodeSettingModel; import cn.odboy.framework.properties.model.ContentRsaEncodeSettingModel;
import cn.odboy.framework.properties.model.JwtAuthSettingModel; import cn.odboy.framework.properties.model.JwtAuthSettingModel;
import cn.odboy.framework.properties.model.StorageOSSModel; import cn.odboy.framework.properties.model.StorageOSSModel;
import cn.odboy.framework.properties.model.SwaggerApiDocSettingModel;
import cn.odboy.framework.properties.model.ThreadPoolSettingModel; import cn.odboy.framework.properties.model.ThreadPoolSettingModel;
import cn.odboy.framework.properties.model.UserLoginSettingModel; import cn.odboy.framework.properties.model.UserLoginSettingModel;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
/** /**
* 应用配置 * 应用配置
@@ -40,9 +41,12 @@ public class AppProperties {
private ContentRsaEncodeSettingModel rsa; private ContentRsaEncodeSettingModel rsa;
private JwtAuthSettingModel jwt; private JwtAuthSettingModel jwt;
private UserLoginSettingModel login; private UserLoginSettingModel login;
private SwaggerApiDocSettingModel swagger;
private ThreadPoolSettingModel asyncTaskPool; private ThreadPoolSettingModel asyncTaskPool;
private CaptchaModel captcha; private CaptchaModel captcha;
private StorageOSSModel oss; private StorageOSSModel oss;
/**
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题
*/
private List<String> serialWhiteList;
} }
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -31,17 +30,14 @@ public class JwtAuthSettingModel extends KitObject {
* 必须使用最少88位的Base64对该令牌进行编码 * 必须使用最少88位的Base64对该令牌进行编码
*/ */
private String base64Secret; private String base64Secret;
/** /**
* 令牌过期时间 此处单位/毫秒 * 令牌过期时间 此处单位/毫秒
*/ */
private Long tokenValidityInSeconds; private Long tokenValidityInSeconds;
/** /**
* token 续期检查 * token 续期检查
*/ */
private Long detect; private Long detect;
/** /**
* 续期时间 * 续期时间
*/ */
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import lombok.Getter; import lombok.Getter;
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.system.dal.model.response; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
/**
* @author odboy
* @date 2025-04-13
*/
@Getter @Getter
@Setter @Setter
public class SystemProductLineTreeVo extends KitObject { public class SwaggerApiDocSettingModel extends KitObject {
private String value; private Boolean enabled;
private String label;
private List<SystemProductLineTreeVo> children;
} }
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@@ -26,9 +25,9 @@ import com.wf.captcha.ChineseGifCaptcha;
import com.wf.captcha.GifCaptcha; import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha; import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import java.awt.Font;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.awt.*;
/** /**
* 验证码配置 * 验证码配置
@@ -40,32 +39,26 @@ import lombok.Setter;
public class UserLoginCaptchaSettingModel extends KitObject { public class UserLoginCaptchaSettingModel extends KitObject {
private CaptchaCodeEnum codeType; private CaptchaCodeEnum codeType;
/** /**
* 验证码有效期 分钟 * 验证码有效期 分钟
*/ */
private Long expiration = 5L; private Long expiration = 5L;
/** /**
* 验证码内容长度 * 验证码内容长度
*/ */
private int length = 4; private int length = 4;
/** /**
* 验证码宽度 * 验证码宽度
*/ */
private int width = 111; private int width = 111;
/** /**
* 验证码高度 * 验证码高度
*/ */
private int height = 36; private int height = 36;
/** /**
* 验证码字体 * 验证码字体
*/ */
private String fontName; private String fontName;
/** /**
* 字体大小 * 字体大小
*/ */
@@ -79,29 +72,30 @@ public class UserLoginCaptchaSettingModel extends KitObject {
public Captcha getCaptcha() { public Captcha getCaptcha() {
Captcha captcha; Captcha captcha;
switch (codeType) { switch (codeType) {
case ARITHMETIC -> { case ARITHMETIC:
// 算术类型 https://gitee.com/whvse/EasyCaptcha // 算术类型 https://gitee.com/whvse/EasyCaptcha
captcha = new FixedArithmeticCaptcha(width, height); captcha = new FixedArithmeticCaptcha(width, height);
// 几位数运算, 默认是两位 // 几位数运算, 默认是两位
captcha.setLen(length); captcha.setLen(length);
} break;
case CHINESE -> { case CHINESE:
captcha = new ChineseCaptcha(width, height); captcha = new ChineseCaptcha(width, height);
captcha.setLen(length); captcha.setLen(length);
} break;
case CHINESE_GIF -> { case CHINESE_GIF:
captcha = new ChineseGifCaptcha(width, height); captcha = new ChineseGifCaptcha(width, height);
captcha.setLen(length); captcha.setLen(length);
} break;
case GIF -> { case GIF:
captcha = new GifCaptcha(width, height); captcha = new GifCaptcha(width, height);
captcha.setLen(length); captcha.setLen(length);
} break;
case SPEC -> { case SPEC:
captcha = new SpecCaptcha(width, height); captcha = new SpecCaptcha(width, height);
captcha.setLen(length); captcha.setLen(length);
} break;
default -> throw new BadRequestException("验证码配置信息错误!正确配置查看 LoginCodeEnum "); default:
throw new BadRequestException("验证码配置信息错误!正确配置查看 LoginCodeEnum ");
} }
if (StrUtil.isNotBlank(fontName)) { if (StrUtil.isNotBlank(fontName)) {
captcha.setFont(new Font(fontName, Font.PLAIN, fontSize)); captcha.setFont(new Font(fontName, Font.PLAIN, fontSize));
@@ -120,15 +114,12 @@ public class UserLoginCaptchaSettingModel extends KitObject {
// 生成随机数字和运算符 // 生成随机数字和运算符
int n1 = num(1, 10), n2 = num(1, 10); int n1 = num(1, 10), n2 = num(1, 10);
int opt = num(3); int opt = num(3);
// 计算结果 // 计算结果
int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt]; int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt];
// 转换为字符运算符 // 转换为字符运算符
char optChar = "+-x".charAt(opt); char optChar = "+-x".charAt(opt);
this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2)); this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2));
this.chars = String.valueOf(res); this.chars = String.valueOf(res);
return chars.toCharArray(); return chars.toCharArray();
} }
} }
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.properties.model; package cn.odboy.framework.properties.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
@@ -20,15 +20,6 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnection;
@@ -40,6 +31,15 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Component @Component
public class KitRedisHelper { public class KitRedisHelper {
@@ -280,7 +280,8 @@ public class KitRedisHelper {
if (value == null) { if (value == null) {
return null; return null;
} }
if (value instanceof List<?> list) { if (value instanceof List<?>) {
List<?> list = (List<?>) value;
// 检查每个元素是否为指定类型 // 检查每个元素是否为指定类型
if (list.stream().allMatch(clazz::isInstance)) { if (list.stream().allMatch(clazz::isInstance)) {
return list.stream().map(clazz::cast).collect(Collectors.toList()); return list.stream().map(clazz::cast).collect(Collectors.toList());
@@ -13,22 +13,20 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.framework.redis; package cn.odboy.framework.redis;
import cn.odboy.framework.properties.AppProperties;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONFactory; import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.JSONWriter;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.MurmurHash3; import org.apache.commons.codec.digest.MurmurHash3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.KeyGenerator;
@@ -43,19 +41,19 @@ import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException; import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Slf4j @Slf4j
@Configuration @Configuration
@EnableCaching @EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class) @AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfiguration { public class RedisConfiguration extends CachingConfigurerSupport {
/** @Autowired
* 自动识别json对象白名单配置(仅允许解析的包名, 范围越小越安全)<br/> 未配置可能导致, 登录失败, 反复登录等问题 private AppProperties properties;
*/
private static final String[] WHITELIST_STR =
{"org.springframework", "cn.odboy.system.dal.dataobject", "cn.odboy.system.dal.model",
"cn.odboy.task.dal.dataobject", "cn.odboy.task.dal.model",};
/** /**
* 设置 redis 数据默认过期时间,默认2小时 设置@cacheable 序列化方式 * 设置 redis 数据默认过期时间,默认2小时 设置@cacheable 序列化方式
@@ -64,8 +62,7 @@ public class RedisConfiguration {
public RedisCacheConfiguration redisCacheConfiguration() { public RedisCacheConfiguration redisCacheConfiguration() {
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
configuration = configuration.serializeValuesWith( configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer))
RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer))
.entryTtl(Duration.ofHours(2)); .entryTtl(Duration.ofHours(2));
return configuration; return configuration;
} }
@@ -79,8 +76,9 @@ public class RedisConfiguration {
template.setValueSerializer(fastJsonRedisSerializer); template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer); template.setHashValueSerializer(fastJsonRedisSerializer);
// 设置fastJson的序列化白名单 // 设置fastJson的序列化白名单
for (String pack : WHITELIST_STR) { for (String pack : properties.getSerialWhiteList()) {
JSONFactory.getDefaultObjectReaderProvider().addAutoTypeAccept(pack); JSONFactory.getDefaultObjectReaderProvider().addAutoTypeAccept(pack);
log.warn("设置fastJson的序列化白名单:{}", pack);
} }
// key的序列化采用StringRedisSerializer // key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer()); template.setKeySerializer(new StringRedisSerializer());
@@ -104,8 +102,8 @@ public class RedisConfiguration {
/** /**
* 自定义缓存key生成策略 * 自定义缓存key生成策略
*/ */
@Bean @Bean
@Override
public KeyGenerator keyGenerator() { public KeyGenerator keyGenerator() {
return (target, method, params) -> { return (target, method, params) -> {
Map<String, Object> container = new HashMap<>(8); Map<String, Object> container = new HashMap<>(8);
@@ -137,7 +135,7 @@ public class RedisConfiguration {
} }
@Override @Override
public void handleCachePutError(@NonNull RuntimeException exception, @NonNull Cache cache, @NonNull Object key, @NonNull Object value) { public void handleCachePutError(@NonNull RuntimeException exception, @NonNull Cache cache, @NonNull Object key, Object value) {
// 处理缓存写入错误 // 处理缓存写入错误
log.error("Cache Put Error: {}", exception.getMessage()); log.error("Cache Put Error: {}", exception.getMessage());
} }
@@ -17,6 +17,14 @@ package cn.odboy.util;
import cn.odboy.annotation.AnonymousAccess; import cn.odboy.annotation.AnonymousAccess;
import cn.odboy.constant.RequestMethodEnum; import cn.odboy.constant.RequestMethodEnum;
import lombok.experimental.UtilityClass;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -24,13 +32,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import lombok.experimental.UtilityClass;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
/** /**
* 匿名标记工具 * 匿名标记工具
@@ -45,10 +46,9 @@ public class KitAnonTagUtil {
* @return / * @return /
*/ */
public static Map<String, Set<String>> getAnonymousUrl(final ApplicationContext applicationContext) { public static Map<String, Set<String>> getAnonymousUrl(final ApplicationContext applicationContext) {
RequestMappingHandlerMapping requestMappingHandlerMapping = RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
(RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
Map<String, java.util.Set<String>> anonymousUrls = new HashMap<>(8); Map<String, Set<String>> anonymousUrls = new HashMap<>(8);
// 获取匿名标记 // 获取匿名标记
Set<String> get = new HashSet<>(); Set<String> get = new HashSet<>();
Set<String> post = new HashSet<>(); Set<String> post = new HashSet<>();
@@ -60,30 +60,28 @@ public class KitAnonTagUtil {
HandlerMethod handlerMethod = infoEntry.getValue(); HandlerMethod handlerMethod = infoEntry.getValue();
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
if (null != anonymousAccess && infoEntry.getKey() != null) { if (null != anonymousAccess && infoEntry.getKey() != null) {
List<RequestMethod> requestMethods = List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
RequestMethodEnum request = RequestMethodEnum.find( PathPatternsRequestCondition patternsCondition = infoEntry.getKey().getPathPatternsCondition();
requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
PatternsRequestCondition patternsCondition = infoEntry.getKey().getPatternsCondition();
if (patternsCondition != null) { if (patternsCondition != null) {
switch (Objects.requireNonNull(request)) { switch (Objects.requireNonNull(request)) {
case GET: case GET:
get.addAll(patternsCondition.getPatterns()); get.addAll(patternsCondition.getPatternValues());
break; break;
case POST: case POST:
post.addAll(patternsCondition.getPatterns()); post.addAll(patternsCondition.getPatternValues());
break; break;
case PUT: case PUT:
put.addAll(patternsCondition.getPatterns()); put.addAll(patternsCondition.getPatternValues());
break; break;
case PATCH: case PATCH:
patch.addAll(patternsCondition.getPatterns()); patch.addAll(patternsCondition.getPatternValues());
break; break;
case DELETE: case DELETE:
delete.addAll(patternsCondition.getPatterns()); delete.addAll(patternsCondition.getPatternValues());
break; break;
default: default:
all.addAll(patternsCondition.getPatterns()); all.addAll(patternsCondition.getPatternValues());
break; break;
} }
} }
@@ -17,8 +17,8 @@ package cn.odboy.util;
import cn.hutool.core.codec.Base64Encoder; import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import java.nio.charset.StandardCharsets;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import java.nio.charset.StandardCharsets;
/** /**
* 加密令牌生成工具 * 加密令牌生成工具
@@ -17,10 +17,10 @@ package cn.odboy.util;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.bean.copier.CopyOptions;
import lombok.experimental.UtilityClass;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import lombok.experimental.UtilityClass;
/** /**
* Bean拷贝相关 * Bean拷贝相关
@@ -15,9 +15,10 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import lombok.experimental.UtilityClass;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import lombok.experimental.UtilityClass; import java.text.NumberFormat;
/** /**
* 计算类 * 计算类
@@ -133,6 +134,23 @@ public final class KitBigDecimalUtil {
return yuan.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).longValue(); return yuan.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).longValue();
} }
/**
* 格式化为 xxx,xxx,xxx 格式
*
* @param obj 金额
* @return /
*/
public static String formatGroupingAmount(Object obj) {
if (obj == null) {
return "0";
}
BigDecimal bigDecimal = toBigDecimal(obj);
NumberFormat nf = NumberFormat.getInstance();
// 启用千位分隔符
nf.setGroupingUsed(true);
return nf.format(bigDecimal.setScale(0, RoundingMode.HALF_UP));
}
public static void main(String[] args) { public static void main(String[] args) {
BigDecimal num1 = new BigDecimal("10.123"); BigDecimal num1 = new BigDecimal("10.123");
BigDecimal num2 = new BigDecimal("2.456"); BigDecimal num2 = new BigDecimal("2.456");
@@ -17,11 +17,11 @@ package cn.odboy.util;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil; import cn.hutool.http.useragent.UserAgentUtil;
import java.net.InetAddress;
import java.net.UnknownHostException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/** /**
* 浏览器 相关 * 浏览器 相关
@@ -15,10 +15,10 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import lombok.experimental.UtilityClass;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import lombok.experimental.UtilityClass;
/** /**
* 类 相关 * 类 相关
@@ -15,8 +15,8 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import java.io.Closeable;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import java.io.Closeable;
/** /**
* 用于关闭各种连接, 缺啥补啥 * 用于关闭各种连接, 缺啥补啥
@@ -15,10 +15,9 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import cn.hutool.core.collection.CollUtil;
import cn.odboy.base.KitSelectOptionVo; import cn.odboy.base.KitSelectOptionVo;
import cn.odboy.framework.exception.BadRequestException;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import lombok.experimental.UtilityClass;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@@ -31,7 +30,6 @@ import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
/** /**
* 集合工具 * 集合工具
@@ -194,7 +192,7 @@ public final class KitCollUtil extends cn.hutool.core.collection.CollUtil {
* @return / * @return /
*/ */
public static BigDecimal streamBigDecimalAvg(List<BigDecimal> data) { public static BigDecimal streamBigDecimalAvg(List<BigDecimal> data) {
KitValidUtil.notEmpty(data, "data"); KitValidUtil.isEmpty(data, "data");
return data.stream().filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add) return data.stream().filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(BigDecimal.valueOf(data.size()), 6, RoundingMode.FLOOR); .divide(BigDecimal.valueOf(data.size()), 6, RoundingMode.FLOOR);
} }
@@ -17,8 +17,9 @@ package cn.odboy.util;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import java.util.Date;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import java.util.Calendar;
import java.util.Date;
/** /**
* 时间相关工具 * 时间相关工具
@@ -129,4 +130,22 @@ public class KitDateUtil {
} }
return result.toString(); return result.toString();
} }
/**
* 获得当天是周几
*/
public static String getWeekDay() {
String[] weekDays = {"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0) {
w = 0;
}
return weekDays[w];
}
public static void main(String[] args) {
System.err.println(getWeekDay());
}
} }
@@ -15,13 +15,13 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import java.nio.charset.StandardCharsets; import lombok.experimental.UtilityClass;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import lombok.experimental.UtilityClass; import java.nio.charset.StandardCharsets;
/** /**
* DES加密 * DES加密
@@ -15,11 +15,6 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import static cn.odboy.constant.SystemConst.SYMBOL_ADD;
import static cn.odboy.constant.SystemConst.SYMBOL_AT;
import static cn.odboy.constant.SystemConst.SYMBOL_EQUAL;
import static cn.odboy.constant.SystemConst.SYMBOL_SUBTRACT;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
@@ -29,6 +24,11 @@ import cn.hutool.poi.excel.ExcelUtil;
import cn.odboy.constant.FileTypeEnum; import cn.odboy.constant.FileTypeEnum;
import cn.odboy.constant.SystemConst; import cn.odboy.constant.SystemConst;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.ServletOutputStream; import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -46,11 +46,10 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.experimental.UtilityClass; import static cn.odboy.constant.SystemConst.SYMBOL_ADD;
import lombok.extern.slf4j.Slf4j; import static cn.odboy.constant.SystemConst.SYMBOL_AT;
import org.apache.poi.util.IOUtils; import static cn.odboy.constant.SystemConst.SYMBOL_EQUAL;
import org.apache.poi.xssf.streaming.SXSSFSheet; import static cn.odboy.constant.SystemConst.SYMBOL_SUBTRACT;
import org.springframework.web.multipart.MultipartFile;
/** /**
* File工具类, 扩展 hutool 工具包 * File工具类, 扩展 hutool 工具包
@@ -16,12 +16,12 @@
package cn.odboy.util; package cn.odboy.util;
import cn.odboy.framework.context.KitSpringBeanHolder; import cn.odboy.framework.context.KitSpringBeanHolder;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher; import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo; import net.dreamlu.mica.ip2region.core.IpInfo;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
/** /**
* IP地址 相关 * IP地址 相关
@@ -17,9 +17,9 @@ package cn.odboy.util;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference; import com.alibaba.fastjson2.TypeReference;
import lombok.experimental.UtilityClass;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.experimental.UtilityClass;
/** /**
* Json工具 * Json工具
@@ -17,11 +17,11 @@ package cn.odboy.util;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.odboy.base.KitBaseUserTimeTb; import cn.odboy.base.KitBaseUserTimeTb;
import lombok.experimental.UtilityClass;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
/** /**
* List 工具 * List 工具
@@ -40,7 +40,7 @@ public final class KitListUtil {
*/ */
public static <T, K> List<T> distinctByArgs(List<T> items, Function<? super T, ? extends K> classifier) { public static <T, K> List<T> distinctByArgs(List<T> items, Function<? super T, ? extends K> classifier) {
return items.stream().collect(Collectors.groupingBy(classifier)).values().stream() return items.stream().collect(Collectors.groupingBy(classifier)).values().stream()
.map(List::getFirst).collect(Collectors.toList()); .map(monitorItem -> monitorItem.iterator().next()).collect(Collectors.toList());
} }
/** /**
@@ -17,9 +17,9 @@ package cn.odboy.util;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.experimental.UtilityClass;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import lombok.experimental.UtilityClass;
/** /**
* 分页工具 * 分页工具
@@ -15,13 +15,13 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
/** /**
* 返回值处理 工具 * 返回值处理 工具
@@ -15,6 +15,9 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import lombok.experimental.UtilityClass;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.KeyPair; import java.security.KeyPair;
@@ -26,9 +29,6 @@ import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import lombok.experimental.UtilityClass;
import org.apache.commons.codec.binary.Base64;
/** /**
* Rsa 工具类, 公钥私钥生成, 加解密 * Rsa 工具类, 公钥私钥生成, 加解密
@@ -15,8 +15,6 @@
*/ */
package cn.odboy.util; package cn.odboy.util;
import java.util.Calendar;
import java.util.Date;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -97,19 +95,4 @@ public final class KitStringUtil {
} }
return sb.toString(); return sb.toString();
} }
/**
* 获得当天是周几
*/
public static String getWeekDay() {
// String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0) {
w = 0;
}
return weekDays[w];
}
} }
@@ -0,0 +1,17 @@
package cn.odboy.util;
import cn.hutool.core.thread.ThreadUtil;
public class KitThreadUtil {
/**
* 可中断的睡眠
*/
public static void interruptSleep(int i) throws InterruptedException {
Thread.sleep(i);
}
public static void safeSleep(int i) {
ThreadUtil.safeSleep(i);
}
}
@@ -18,16 +18,16 @@ package cn.odboy.util;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import java.util.List; import lombok.experimental.UtilityClass;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation; import jakarta.validation.Validation;
import jakarta.validation.Validator; import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory; import jakarta.validation.ValidatorFactory;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.groups.Default; import jakarta.validation.groups.Default;
import lombok.experimental.UtilityClass; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* Bean验证工具 * Bean验证工具
@@ -46,6 +46,12 @@ public final class KitValidUtil {
} }
} }
/**
* 验证实体是否通过校验 <br/> 实体内通过 javax.validation.constraints 中的表达式限制参数 <br/>
*
* @param object /
* @param <T> /
*/
public static <T> void validate(T object) { public static <T> void validate(T object) {
Set<ConstraintViolation<T>> violations = VALIDATOR.validate(object, Default.class); Set<ConstraintViolation<T>> violations = VALIDATOR.validate(object, Default.class);
if (!violations.isEmpty()) { if (!violations.isEmpty()) {
@@ -54,39 +60,125 @@ public final class KitValidUtil {
} }
} }
public static void notNull(Object value) { /**
* 参数为null,抛异常
*
* @param value 参数值
*/
public static void isNull(Object value) {
if (value == null) { if (value == null) {
throw new BadRequestException("参数必填"); throw new BadRequestException("参数必填");
} }
} }
public static void isNull(Object value) { /**
if (value != null) { * 参数为空,抛异常
throw new BadRequestException("参数非必填"); *
} * @param value 参数值
} * @param name 参数名称
* @param code 参数编码
public static void notNull(Object value, @NotNull String name, @NotNull String code) { */
public static void isNull(Object value, @NotNull String name, @NotNull String code) {
if (value == null) { if (value == null) {
throw new BadRequestException(String.format("参数 %s(%s) 必填", name, code)); throw new BadRequestException(String.format("参数 %s(%s) 必填", name, code));
} }
} }
public static void isBlank(CharSequence value, @NotNull String name, @NotNull String code) { /**
if (StrUtil.isNotBlank(value)) { * 参数为空,抛异常
throw new BadRequestException(String.format("参数 %s(%s) 非必填", name, code)); *
* @param value 参数值
* @param message 异常信息
*/
public static void isNull(Object value, @NotNull String message) {
if (value == null) {
throw new BadRequestException(message);
} }
} }
public static void notBlank(CharSequence value, @NotNull String name, @NotNull String code) { /**
* 参数为空,抛异常
*
* @param value 参数值
* @param code 参数编码
*/
public static void isNullF(Object value, @NotNull String code) {
if (value == null) {
throw new BadRequestException(String.format("参数 %s 必填", code));
}
}
/**
* 参数为空字符串,抛异常
*
* @param value 参数值
* @param name 参数名称
* @param code 参数编码
*/
public static void isBlank(CharSequence value, @NotNull String name, @NotNull String code) {
if (StrUtil.isBlank(value)) { if (StrUtil.isBlank(value)) {
throw new BadRequestException(String.format("参数 %s(%s) 必填", name, code)); throw new BadRequestException(String.format("参数 %s(%s) 必填", name, code));
} }
} }
public static void notEmpty(List<?> data, @NotNull String code) { /**
* 集合为空,抛异常
*
* @param data 集合值
* @param code 参数编码
*/
public static void isEmpty(List<?> data, @NotNull String code) {
if (CollUtil.isEmpty(data)) { if (CollUtil.isEmpty(data)) {
throw new BadRequestException(String.format("参数 %s 必填", code)); throw new BadRequestException(String.format("参数 %s 必填", code));
} }
} }
/**
* 集合为空,抛异常
*
* @param data 集合值
* @param name 参数名称
* @param code 参数编码
*/
public static void isEmpty(List<?> data, @NotNull String name, @NotNull String code) {
if (CollUtil.isEmpty(data)) {
throw new BadRequestException(String.format("参数 %s(%s) 必填", name, code));
}
}
/**
* 表达式为true,抛异常
*
* @param condition 表达式
* @param message 异常信息
*/
public static void isTrue(boolean condition, String message) {
if (condition) {
throw new BadRequestException(message);
}
}
/**
* 表达式为false,抛异常
*
* @param condition 表达式
* @param message 异常信息
*/
public static void isFalse(boolean condition, String message) {
if (!condition) {
throw new BadRequestException(message);
}
}
/**
* 参数为空字符串,抛异常
*
* @param value 参数值
* @param message 异常信息
*/
public static void isBlank(String value, String message) {
if (StrUtil.isBlank(value)) {
throw new BadRequestException(message);
}
}
} }
@@ -3,12 +3,12 @@ package cn.odboy.util.xlsx;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.idev.excel.EasyExcel; import cn.idev.excel.EasyExcel;
import jakarta.servlet.http.HttpServletResponse;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
/** /**
* EasyExcel 导出增强工具类 (支持普通/分页模式) * EasyExcel 导出增强工具类 (支持普通/分页模式)
@@ -6,14 +6,14 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.idev.excel.FastExcel; import cn.idev.excel.FastExcel;
import cn.odboy.framework.exception.BadRequestException; import cn.odboy.framework.exception.BadRequestException;
import lombok.experimental.UtilityClass;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import lombok.experimental.UtilityClass;
/** /**
* xlsx文件导出工具 * xlsx文件导出工具
@@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>cutejava</artifactId> <artifactId>cutejava</artifactId>
<groupId>cn.odboy</groupId> <groupId>cn.odboy</groupId>
<version>1.5.0</version> <version>1.5.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>cutejava-module-system</artifactId> <artifactId>cutejava-module-system</artifactId>
@@ -13,7 +13,7 @@
<dependency> <dependency>
<groupId>cn.odboy</groupId> <groupId>cn.odboy</groupId>
<artifactId>cutejava-framework</artifactId> <artifactId>cutejava-framework</artifactId>
<version>1.5.0</version> <version>1.5.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.minio/minio --> <!-- https://mvnrepository.com/artifact/io.minio/minio -->
<dependency> <dependency>
@@ -0,0 +1,46 @@
/*
* Copyright 2021-2026 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.system.application;
import cn.odboy.system.application.model.CuteDeptTreeVo;
import cn.odboy.system.application.service.CuteDeptTreeService;
import cn.odboy.system.dal.model.request.SystemQueryDeptArgs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Api(tags = "系统组件:CuteDeptTree")
@RequestMapping("/api/component/CuteDeptTree")
public class CuteDeptTreeApi {
@Autowired
private CuteDeptTreeService cuteDeptTreeService;
@ApiOperation("查询部门")
@PostMapping(value = "/listMetadata")
public ResponseEntity<List<CuteDeptTreeVo>> listMetadata(@Validated @RequestBody SystemQueryDeptArgs args) throws Exception {
List<CuteDeptTreeVo> depts = cuteDeptTreeService.listMetadata(args);
return ResponseEntity.ok(depts);
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2021-2026 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.system.application;
import cn.odboy.system.application.service.CuteFileUploadService;
import cn.odboy.system.framework.operalog.OperationLog;
import cn.odboy.system.service.SystemOssStorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@Api(tags = "系统组件:CuteFileUpload")
@RequestMapping("/api/component/CuteFileUpload")
public class CuteFileUploadApi {
@Autowired
private CuteFileUploadService cuteFileUploadService;
@Autowired
private SystemOssStorageService systemOssStorageService;
@OperationLog
@ApiOperation("上传文件到服务器本地")
@PostMapping(value = "/uploadLocal")
@PreAuthorize("@el.check()")
public ResponseEntity<String> uploadLocal(@RequestParam("file") MultipartFile file) {
String fileUrl = cuteFileUploadService.uploadLocal(file);
return ResponseEntity.ok(fileUrl);
}
@OperationLog
@ApiOperation("上传文件到OSS")
@PostMapping(value = "/uploadOSS")
@PreAuthorize("@el.check()")
public ResponseEntity<String> uploadOSS(@RequestParam("file") MultipartFile file) {
String fileUrl = systemOssStorageService.uploadFile(file);
return ResponseEntity.ok(fileUrl);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2021-2026 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.system.application;
import cn.odboy.system.application.service.CuteProductLineSelectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Api(tags = "系统组件:CuteProductLineSelect")
@RequestMapping("/api/component/CuteProductLineSelect")
public class CuteProductLineSelectApi {
@Autowired
private CuteProductLineSelectService cuteProductLineSelectService;
@ApiOperation("查询部门下拉选择数据源")
@PostMapping(value = "/listMetadata")
@PreAuthorize("@el.check()")
public ResponseEntity<?> listMetadata() {
return ResponseEntity.ok(cuteProductLineSelectService.listMetadata());
}
}
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.system.controller; package cn.odboy.system.application;
import cn.odboy.system.service.SystemDeptService; import cn.odboy.system.application.service.CuteProductLineSelectProService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -26,24 +26,17 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@Api(tags = "系统:组件数据源") @Api(tags = "系统组件:CuteProductLineSelectPro")
@RequestMapping("/api/component") @RequestMapping("/api/component/CuteProductLineSelectPro")
public class SystemComponentController { public class CuteProductLineSelectProApi {
@Autowired @Autowired
private SystemDeptService systemDeptService; private CuteProductLineSelectProService cuteProductLineSelectProService;
@ApiOperation("查询部门下拉选择数据源")
@PostMapping(value = "/listDeptSelectDataSource")
@PreAuthorize("@el.check()")
public ResponseEntity<?> listDeptSelectDataSource() {
return ResponseEntity.ok(systemDeptService.listDeptSelectDataSource());
}
@ApiOperation("查询部门下拉选择Pro数据源") @ApiOperation("查询部门下拉选择Pro数据源")
@PostMapping(value = "/listDeptSelectProDataSource") @PostMapping(value = "/listMetadata")
@PreAuthorize("@el.check()") @PreAuthorize("@el.check()")
public ResponseEntity<?> listDeptSelectProDataSource() { public ResponseEntity<?> listMetadata() {
return ResponseEntity.ok(systemDeptService.listDeptSelectProDataSource()); return ResponseEntity.ok(cuteProductLineSelectProService.listMetadata());
} }
} }
@@ -0,0 +1,56 @@
/*
* Copyright 2021-2026 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.system.application;
import cn.odboy.system.application.model.CuteUserSelectVo;
import cn.odboy.system.application.service.CuteUserSelectService;
import cn.odboy.system.dal.model.request.SystemQueryUserArgs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Api(tags = "系统组件:CuteUserSelect")
@RequestMapping("/api/component/CuteUserSelect")
public class CuteUserSelectApi {
@Autowired
private CuteUserSelectService cuteUserSelectService;
@ApiOperation("查询用户基础数据")
@PostMapping(value = "/listMetadata")
@PreAuthorize("@el.check()")
public ResponseEntity<List<CuteUserSelectVo>> listMetadata(@Validated @RequestBody SystemQueryUserArgs args) {
List<CuteUserSelectVo> collect = cuteUserSelectService.listMetadata(args);
return ResponseEntity.ok(collect);
}
@ApiOperation("根据用户名称集合查询用户基础数据")
@PostMapping(value = "/listMetadataByUsernames")
@PreAuthorize("@el.check()")
public ResponseEntity<List<CuteUserSelectVo>> listMetadataByUsernames(@RequestBody List<String> usernameList) {
List<CuteUserSelectVo> collect = cuteUserSelectService.listMetadataByUsernames(usernameList);
return ResponseEntity.ok(collect);
}
}
@@ -13,52 +13,51 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.task.dal.model; package cn.odboy.system.application.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import java.util.Date;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
/**
* 任务节点数据
*
* @author odboy
*/
@Getter @Getter
@Setter @Setter
public class TaskInstanceNodeVo extends KitObject { public class CuteDeptTreeVo extends KitObject {
/** /**
* 业务编码 * 部门ID
*/ */
protected String code; private String id;
/** /**
* 业务名称 * 部门名称
*/ */
protected String name; private String name;
/** /**
* 开始时间 * 上级部门ID
*/ */
protected Date startTime; private String pid;
/** /**
* 完成时间 * 子节点数目
*/ */
protected Date finishTime; private Integer subCount = 0;
/** /**
* 耗时多久 * 是否有子节点
*/ */
protected String durationDesc; public Boolean getHasChildren() {
return subCount > 0;
}
/** /**
* 进行中描述 * 是否为叶子
*/ */
protected String runningDesc; public Boolean getLeaf() {
return subCount <= 0;
}
/** /**
* 节点状态编码 * 标签名称
*/ */
protected String status; public String getLabel() {
/** return name;
* 节点状态描述 }
*/
protected String statusDesc;
} }
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.system.dal.model.response; package cn.odboy.system.application.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import lombok.Getter; import lombok.Getter;
@@ -22,9 +22,14 @@ import java.util.List;
@Getter @Getter
@Setter @Setter
public class SystemProductLineTreeVo extends KitObject { public class CuteProductLineSelectProVo extends KitObject {
/**
* 部门ID(select的value)
*/
private String value; private String value;
/**
* 产品线,如"研发部/华南分部/devops组"
*/
private String label; private String label;
private List<SystemProductLineTreeVo> children; private List<CuteProductLineSelectProVo> children;
} }
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.system.dal.model.response; package cn.odboy.system.application.model;
import cn.odboy.base.KitObject; import cn.odboy.base.KitObject;
import lombok.Getter; import lombok.Getter;
@@ -21,12 +21,12 @@ import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class SystemProductLineVo extends KitObject { public class CuteProductLineSelectVo extends KitObject {
/** /**
* 部门ID(select的value) * 部门ID(select的value)
*/ */
private Long value; private String value;
/** /**
* 产品线,如"研发部/华南分部/devops组" * 产品线,如"研发部/华南分部/devops组"
*/ */
@@ -0,0 +1,46 @@
/*
* Copyright 2021-2026 Odboy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.odboy.system.application.model;
import cn.odboy.base.KitObject;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CuteUserSelectVo extends KitObject {
/**
* username
*/
private String value;
/**
* nickname
*/
private String label;
/**
* 部门ID
*/
private String deptId;
/**
* 邮箱
*/
private String email;
/**
* 手机号
*/
private String phone;
}
@@ -13,29 +13,27 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package cn.odboy.task.service; package cn.odboy.system.application.service;
import cn.odboy.task.dal.model.TaskTemplateInfoVo; import cn.odboy.system.dal.dataobject.SystemDeptTb;
import cn.odboy.task.dal.mysql.TaskTemplateInfoMapper; import cn.odboy.system.dal.mysql.SystemDeptMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List;
/** public class CuteBaseService {
* <p>
* 任务模板
* </p>
*
* @author codegen
* @since 2025-09-28
*/
@Service
public class TaskTemplateInfoService {
@Autowired @Autowired
private TaskTemplateInfoMapper taskTemplateInfoMapper; private SystemDeptMapper systemDeptMapper;
public TaskTemplateInfoVo getTemplateInfoByECL(String envAlias, String contextName, String language, /**
String changeType) { * 查询启用的所有部门集合
return taskTemplateInfoMapper.selectTemplateInfoByECL(envAlias, contextName, language, changeType); *
* @return /
*/
public List<SystemDeptTb> listEnabledDept() {
LambdaQueryWrapper<SystemDeptTb> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SystemDeptTb::getEnabled, 1);
return systemDeptMapper.selectList(wrapper);
} }
} }

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