lxm final

This commit is contained in:
李旭明 committed 2025-08-23 10:22:24 +08:00
commit e46971e383
2419 files changed
+296967 -243218

No files matched your search

+40
View File
@@ -909,3 +909,43 @@ const pendingDeleteAttachmentIds = ref<string[]>([]); // 编辑时标
- **✅ 必须** 在新页面开发时引用本规范并注明 *附件管理统一规范* 版本
> **版本**: 2025-01-27 附件管理统一规范 v1.0
---
## 5. 构建问题解决方案
### 5.1 JavaScript heap out of memory 解决方案(2025-01-27)
#### 问题描述
在执行 `npm run build:prod` 时出现内存溢出错误:
```
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
```
#### 根本原因
- 项目使用大量图标插件(unplugin-icons、svg-icons、element-plus图标等)
- 构建时需要加载大量图标文件到内存处理
- Node.js默认堆内存限制(~1.4GB)不足
#### 标准解决方案
修改 `package.json` 中的构建脚本,增加Node.js堆内存限制:
```json
{
"scripts": {
"build:prod": "node --max-old-space-size=8192 node_modules/vite/bin/vite.js build --mode production",
"build:dev": "node --max-old-space-size=8192 node_modules/vite/bin/vite.js build --mode development"
}
}
```
#### 参数说明
- `--max-old-space-size=8192`:设置堆内存限制为8GB
- 可根据项目规模和机器内存调整数值(4096=4GB, 8192=8GB)
#### 适用场景
- 大型前端项目构建
- 使用大量图标组件的项目
- 需要处理大量静态资源的项目
> **版本**: 2025-01-27 构建问题解决方案 v1.0
File diff suppressed because it is too large. Load diff
+334
View File
@@ -0,0 +1,334 @@
# Cursor Rules - 项目开发规范总览
## 🎯 项目概述
**项目名称**: 校园管理系统 (hzdyjs_xg)
**技术架构**: 前后端分离 + 移动端
**工作目录**: `/Users/wuzilong/work/00code/hzdyjs_xg`
### 项目结构
- **前端工程**: `web/` (Vue 3 + TypeScript + Element Plus)
- **后端工程**: `backend/` (Spring Boot 3.4.6 + MyBatis-Plus)
- **移动端工程**: `mobile/` (Vue 2.6.14 + uni-app + uview-ui 2.0.38 - 智慧校园移动端)
- **文档管理**: `docs/` (完整的项目文档体系)
---
## 📚 规范文件引用
**重要说明**: 本项目的开发规范已按技术栈模块化拆分,请根据开发场景参考对应规范:
### 🔗 专门规范文件
```
.cursor/
├── cursorrules-docs.md # 📋 文档管理规范
├── cursorrules-frontend.md # 🎨 前端开发规范 (Vue 3)
├── cursorrules-backend.md # ⚙️ 后端开发规范 (Spring Boot)
├── cursorrules-mobile.md # 📱 移动端开发规范 (Vue 2 + uni-app + uview-ui)
├── cursorrules-workflow.md # 🔄 工作流开发规范 (Warm-Flow)
└── cursorrules-api-test.md # 🧪 API测试规范
```
### 📖 规范文件详情
#### 📋 文档管理规范 (.cursor/cursorrules-docs.md)
- 文档目录组织(中文化架构)
- **🚨 强制性文档同步更新规则**
- 变更记录管理规范(按日期和用户分文件)
- 业务模块文档管理(为AI提供完整上下文)
- **📊 API文档拆分管理规范** (2025-07-01新增,文件夹重组):
- **📁 文件夹结构**: 所有API文档统一存放在 `docs/开发文档/API/` 文件夹下
- **📝 文件组织**: 按业务模块拆分:基础规范、认证登录、物业报修、满意度调查
- **🔤 命名规范**: 中文文件命名,便于快速识别和查找
- **🔗 模块化管理**: 独立维护,减少冲突,交叉引用基础规范
- **📚 主入口**: API文档总览.md 作为统一导航入口
- **📋 模板支持**: API文档模板.md 用于新API文档生成
- **🔄 自动生成规则**: 新增API模块时,优先在API文件夹下创建对应文档
- 测试文档管理规范
#### 🎨 前端开发规范 (.cursor/cursorrules-frontend.md)
- Vue 3.5.13 + TypeScript 5.8.3 技术栈
- Art Design Pro UI 设计规范
- 轮廓式按钮设计系统
- 组件开发标准和页面模板
- API接口定义和状态管理
- 项目架构和性能优化
#### ⚙️ 后端开发规范 (.cursor/cursorrules-backend.md)
- Spring Boot 3.4.6 技术栈
- **🔴 数据库规范(强制性)** - 雪花ID、逻辑删除、多租户
- **🔴 API接口规范(强制性)** - 统一响应格式、Token认证
- **🔐 菜单界面和接口权限配置规范**
- 标准代码模板 (Controller/Service/Mapper)
#### 📱 移动端开发规范 (.cursor/cursorrules-mobile.md)
- **Vue 2.6.14 + uni-app + uview-ui 2.0.38 技术栈(智慧校园移动端)**
- **基于Vue 2的稳定架构(兼容性优先)**
- **uview-ui 2.0.38 成熟UI组件库(Vue 2版本)**
- **现代CSS变量设计系统和响应式布局适配**
- **完整的用户体验优化(动画、手势识别、无障碍访问)**
- **智能缓存策略和网络请求优化**
- **多端发布支持(H5、微信小程序、App、鸿蒙)**
- **iconfont图标系统(支持uview-ui的u-icon组件)**
#### 🔄 工作流开发规范 (.cursor/cursorrules-workflow.md)
- **Warm-Flow工作流框架** - 基于dromara社区开源的轻量级工作流引擎
- **🔴 强制性VO类规范(避免MyBatis映射错误)** - 所有工作流业务VO类必须包含四个基础字段
- **工作流状态管理** - 7种标准业务状态(draft、waiting、complete等)
- **标准工作流模式** - 普通流程、排他网关、并行网关、会签等6种模式
- **前端工作流组件** - approvalButton、submitVerify、approvalRecord标准组件使用
- **工作流权限配置** - @ConditionalOnEnable条件开启和Sa-Token权限控制
- **请假工作流示例** - 完整的工作流开发实践模板
#### 🧪 API测试规范 (.cursor/cursorrules-api-test.md)
- **✅ AES+RSA双重加密登录方法(已完全解决)**
- API测试最佳实践和通用测试方法
- 自动化测试脚本和性能测试
- 测试记录模板
---
## 🚨 核心开发原则(必须遵循)
### 1. 📝 强制性文档同步更新
**⚠️ 超级重要**: 每次代码调整都必须立即同步更新相应文档!
#### 必须更新的文档
- **API变更** → 按业务模块更新对应的API文档(2025-07-01重新组织到API文件夹):
- 基础规范变更 → `docs/开发文档/API/API文档基础规范.md`
- 认证登录变更 → `docs/开发文档/API/用户认证登录API.md`
- 物业报修变更 → `docs/开发文档/API/物业报修管理API.md`
- 满意度调查变更 → `docs/开发文档/API/后勤满意度调查API.md`
- API文档总览 → `docs/开发文档/API/API文档总览.md`
- **数据库变更** → `docs/设计文档/database/`
- **业务逻辑变更** → `docs/业务模块/[模块名称]/`
- **配置变更** → `docs/中间件配置/` 或 `docs/部署文档/`
- **📱 移动端变更** → 移动端工程相关文档必须同步更新:
- **移动端API新增/变更** → 相应的API文档必须补充移动端实现章节
- **移动端页面开发** → `docs/开发文档/` 移动端相关文档
- **移动端功能变更** → `docs/业务模块/[模块名称]/` 移动端部分
- **移动端技术规范变更** → `.cursor/cursorrules-mobile.md`
#### 变更记录规范
- **文件格式**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
- **排序要求**: 按时间倒序排列,最新记录在最上面
- **时间填写**: 必须填写真实的当前时间(YYYY-MM-DD HH:mm:ss)
### 2. 🔴 数据库开发强制要求
- **标准基础字段**: 所有业务表必须包含统一的基础字段
- **雪花ID主键**: 统一使用 `bigint(20)` 作为主键
- **逻辑删除**: 禁止物理删除,使用 `deleted` 字段
- **多租户支持**: 必须包含 `tenant_id` 字段
- **参考规范**: `docs/设计文档/database/mysql-database-standard.md`
### 3. 🔴 API接口开发强制要求
- **统一响应格式**: 分页用TableDataInfo,非分页用R类型
- **Token认证**: Bearer格式,包含clientid、referer等必需Header
- **权限注解**: 每个接口必须有@SaCheckPermission注解
- **参数验证**: 使用Bean Validation进行参数校验
### 4. 🎯 技术要求
- **Node.js**: 20.15.x+, npm 10.7.x+
- **Java**: JDK 17/21
- **前端访问**: http://localhost (默认80端口)
- **后端服务**: http://localhost:8080
- **移动端**: Vue 2.6.14 + uni-app + uview-ui 2.0.38(智慧校园移动端)
---
## 🔄 Cursor AI 工作流程
### 📋 开发工作流程
```
1. **确定开发场景** → 自动应用对应技术栈规范
2. **编写/修改代码** → 遵循相应的编码规范
3. **立即更新文档** → 同步更新API文档和相关文档
4. **记录变更日志** → 在当日变更文件中记录
5. **验证和测试** → 确保功能正常和文档准确
```
### 🤖 Cursor AI 规范应用
- **前端开发**: 自动参考 `cursorrules-frontend.md`
- **后端开发**: 自动参考 `cursorrules-backend.md`
- **移动端开发**: 自动参考 `cursorrules-mobile.md`
- **工作流开发**: 自动参考 `cursorrules-workflow.md`
- **文档更新**: 自动参考 `cursorrules-docs.md`
- **API测试**: 自动参考 `cursorrules-api-test.md`
### 👍 点赞后知识总结机制
**⚠️ 重要提醒:当用户对Cursor回答点赞时,请主动询问是否需要进行总结归档**
#### 点赞触发规则
- **触发条件**: 用户对Cursor的回答点赞(👍)
- **自动提醒**: "检测到您对本次回答满意,是否需要将相关经验总结归档到项目规范中?"
- **总结目标**: 将成功的解决方案、最佳实践、经验教训整理到规范文档中
#### 总结内容建议
1. **技术解决方案**: 将有效的技术方案整理到对应的cursorrules文档
2. **开发流程优化**: 将改进的工作流程补充到开发规范中
3. **最佳实践**: 将成功经验添加到最佳实践文档
4. **问题解决方案**: 将常见问题和解决方案整理到知识库
5. **规范完善**: 根据实际应用效果完善和优化现有规范
#### 总结文档位置
- **技术规范**: 对应的`.cursor/cursorrules-*.md`文件
- **最佳实践**: `docs/开发文档/API开发最佳实践总结.md`
- **项目知识库**: `docs/知识库/`目录
- **变更记录**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
#### 总结流程
```
用户点赞 → Cursor主动询问 → 确认总结 → 分析价值点 → 整理到规范 → 更新相关文档
```
#### 价值目标
- 📚 **知识积累**: 将零散的经验系统化整理
- 🔄 **规范优化**: 基于实际应用持续改进规范
- 📖 **团队共享**: 将个人经验转化为团队资产
- 🚀 **效率提升**: 为后续类似问题提供标准解决方案
### 💡 API开发最佳实践
**⚠️ 基于场地预约管理系统开发实践制定的标准流程**
#### 完整开发流程(6个阶段)
1. **需求分析和文档创建** → 业务需求+技术架构文档
2. **数据库设计和初始化** → 表结构+字典+权限+示例数据
3. **后端模块开发** → 完整ruoyi模块(16个API接口)
4. **API文档编写** → 400+行详细API文档
5. **自动化测试脚本** → 450+行Python测试脚本
6. **变更记录和验证** → 完整的变更日志
#### 16个标准API接口模式
- **基础管理接口(6个)**: list、详情、新增、修改、删除、可用选项
- **业务功能接口(4个)**: 我的数据、待处理、规则检查、审批
- **辅助功能接口(6个)**: 导出、导入、统计、批量、启用、禁用
#### 🔴 VO类基础字段统一规范(新增 2025-07-01)
**⚠️ 超级重要:所有VO类必须包含统一的基础字段!**
**背景问题**:
- MyBatis-Plus自动查询:不包含继承字段
- 自定义SQL查询:明确包含字段,VO类必须有对应属性
- 导致运行时字段缺失错误:`Could not set property 'createBy'`
**统一解决方案**:
```java
// 所有VO类必须包含的四个基础字段
private Long createBy; // 创建者
private Date createTime; // 创建时间(含JSON格式化)
private Long updateBy; // 更新者
private Date updateTime; // 更新时间(含JSON格式化)
```
**强制要求**:
- ✅ 新增VO类必须包含四个基础字段
- ✅ 修复现有VO类时必须补全缺失字段
- ✅ 时间字段使用`@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")`
- ✅ 详细规范见:`.cursor/cursorrules-backend.md` → "VO类基础字段规范"
#### 质量保证标准
- ✅ **完整交付物**: 2个需求文档+3个SQL脚本+18个代码文件+1个API文档+1个测试脚本
- ✅ **开发时长**: 约3.5天完成完整API模块
- ✅ **文档同步**: 代码完成立即更新相关文档
- ✅ **测试覆盖**: 强制AES+RSA加密登录+完整功能测试
- ✅ **VO类规范**: 所有VO类包含统一基础字段,避免MyBatis映射错误
#### 参考文档
- **完整实践总结**: `docs/开发文档/API开发最佳实践总结.md`
- **成功案例**: `docs/开发文档/API/场地预约管理API.md`
- **测试脚本模板**: `test/场地预约API测试脚本.py`
- **VO类规范**: `.cursor/cursorrules-backend.md` → "VO类基础字段规范(强制性)"
---
## 🎯 快速开始
### 💡 开发提示
1. **查看具体规范**: 打开对应的 `.cursor/cursorrules-*.md` 文件
2. **遵循强制要求**: 特别注意标记为🔴和🚨的强制性规范
3. **使用标准模板**: 参考各规范文件中的代码模板
4. **及时更新文档**: 代码完成后立即更新相关文档
### 📚 重要文档位置
- **项目启动指南**: `工程本地启动指导.md`
- **API文档拆分架构** (按业务模块拆分,2025-07-01优化并重新组织到API文件夹):
- 📚 **API文档总览**: `docs/开发文档/API/API文档总览.md` (主入口导航)
- 📋 **基础规范**: `docs/开发文档/API/API文档基础规范.md` (通用规范)
- 🔐 **认证登录**: `docs/开发文档/API/用户认证登录API.md` (登录、用户信息)
- 🛠️ **物业报修**: `docs/开发文档/API/物业报修管理API.md` (报修工单管理)
- 📊 **满意度调查**: `docs/开发文档/API/后勤满意度调查API.md` (问卷答题)
- 📝 **API文档模板**: `docs/开发文档/API/API文档模板.md` (新API文档生成模板)
- **数据库设计**: `docs/设计文档/database/`
- **业务模块文档**: `docs/业务模块/`
- **测试脚本**: `test/` 目录
---
## 📞 规范说明
### 🔧 规范更新
- **规范文件更新**: 直接编辑对应的专门文件
- **跨模块变更**: 需要在相关文件中保持一致
- **重大变更**: 需要同步更新本主配置文件
### 📋 使用原则
1. **技术栈导向**: 根据当前开发的技术栈参考对应规范
2. **强制性要求**: 必须严格遵循标记为强制性的规范
3. **文档同步**: 代码变更必须同步更新文档
4. **质量保证**: 确保代码和文档的一致性
---
**🎯 目标**: 通过模块化规范管理和强制性文档同步,为Cursor AI提供准确的开发上下文,确保高质量的代码生成和完善的项目文档!
**📝 维护**: 拆分完成于 2025-07-01,所有原有内容完整保留
**📁 文件**: 5个专门规范文件 + 1个主配置文件
**🔄 加载**: Cursor自动识别和应用相关规范
# 原型文件存放规范(2025-07-01 新增)
- 所有后续生成的原型文件(如HTML原型、交互原型等),必须统一存放在 docs/原型文件/ 目录下的相应子目录中。
- 子目录应按端(如 web、移动端、小程序等)或业务模块分类,确保结构清晰、便于查找和维护。
- 禁止将原型文件存放在源码目录(如 web/src、mobile/src 等)或其他非文档目录。
- 迁移或生成原型文件时,需同步更新目录结构说明文档(如 docs/原型文件/README.md )。
# 移动端技术栈规范(2025-01-27 更新)
## 🚨 重要变更说明
**变更时间**: 2025-01-27
**变更内容**: 移动端技术栈从 Vue 3 + uview-plus 调整为 Vue 2 + uview-ui
**变更原因**: 基于项目实际技术配置和稳定性考虑
### 📱 移动端技术栈调整
#### 调整前(错误)
- Vue 3.4.21 + uview-plus 3.4.45
- 现代化架构但与实际项目不符
#### 调整后(正确)
- **Vue 2.6.14 + uview-ui 2.0.38**
- **基于uni-app的稳定架构**
- **与实际项目配置完全一致**
### 🔄 相关文档更新
- ✅ **主规范文件**: `.cursor/cursorrules.md` - 移动端技术栈描述已更新
- ✅ **移动端规范**: `.cursor/cursorrules-mobile.md` - 完整重写为Vue 2技术栈
- 📝 **变更记录**: 本次调整将记录在变更管理文档中
### 📋 开发者注意事项
1. **图标使用**: 支持 iconfont 图标系统 + uview-ui 的 u-icon 组件
2. **组件引用**: 使用 `<u-xxx>` 格式引用 uview-ui 组件
3. **页面配置**: easycom 自动注册:`"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"`
4. **样式导入**: `@import 'uview-ui/index.scss'`
### 🎯 技术选型原则
- **稳定性优先**: Vue 2 生态成熟稳定
- **兼容性考虑**: uview-ui 2.x 对 uni-app 兼容性更好
- **团队熟悉度**: 基于实际项目经验
- **维护成本**: 降低技术栈复杂度
+1 -2
View File
@@ -1,3 +1,2 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
temp/
test/
+9 -18
View File
@@ -9,7 +9,7 @@
### 项目结构
- **前端工程**: `web/` (Vue 3 + TypeScript + Element Plus)
- **后端工程**: `backend/` (Spring Boot 3.4.6 + MyBatis-Plus)
- **移动端工程**: `mobile/` (Vue 3.4.21 + uniapp + uview-plus 3.4.45 - 现代化智慧校园)
- **移动端工程**: `mobile/` (Vue 2.6.14 + uni-app 2.x + uview-ui 2.0.38 - 智慧校园移动应用)
- **文档管理**: `docs/` (完整的项目文档体系)
---
@@ -34,7 +34,6 @@
#### 📋 文档管理规范 (.cursor/cursorrules-docs.md)
- 文档目录组织(中文化架构)
- **🚨 强制性文档同步更新规则**
- 变更记录管理规范(按日期和用户分文件)
- 业务模块文档管理(为AI提供完整上下文)
- **📊 API文档拆分管理规范** (2025-07-01新增,文件夹重组):
- **📁 文件夹结构**: 所有API文档统一存放在 `docs/开发文档/API/` 文件夹下
@@ -62,8 +61,8 @@
- 标准代码模板 (Controller/Service/Mapper)
#### 📱 移动端开发规范 (.cursor/cursorrules-mobile.md)
- Vue 3.4.21 + uni-app + uview-plus 3.4.45 技术栈(现代化智慧校园)
- 纯净的Vue 3项目架构(无状态管理库,采用原生API)
- Vue 2.6.14 + uni-app 2.x + uview-ui 2.0.38 技术栈(智慧校园移动应用)
- 基于Vue 2的响应式项目架构(包含Vuex状态管理)
- 现代CSS变量设计系统和响应式布局适配
- 完整的用户体验优化(动画、手势识别、无障碍访问)
- 智能缓存策略和网络请求优化
@@ -107,11 +106,6 @@
- **移动端功能变更** → `docs/业务模块/[模块名称]/` 移动端部分
- **移动端技术规范变更** → `.cursor/cursorrules-mobile.md`
#### 变更记录规范
- **文件格式**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
- **排序要求**: 按时间倒序排列,最新记录在最上面
- **时间填写**: 必须填写真实的当前时间(YYYY-MM-DD HH:mm:ss)
### 2. 🔴 数据库开发强制要求
- **标准基础字段**: 所有业务表必须包含统一的基础字段
- **雪花ID主键**: 统一使用 `bigint(20)` 作为主键
@@ -130,7 +124,7 @@
- **Java**: JDK 17/21
- **前端访问**: http://localhost (默认80端口)
- **后端服务**: http://localhost:8080
- **移动端**: Vue 3.4.21 + uni-app + uview-plus 3.4.45(现代化智慧校园)
- **移动端**: Vue 2.6.14 + uni-app 2.x + uview-ui 2.0.38(智慧校园移动应用,端口8081)
---
@@ -141,8 +135,7 @@
1. **确定开发场景** → 自动应用对应技术栈规范
2. **编写/修改代码** → 遵循相应的编码规范
3. **立即更新文档** → 同步更新API文档和相关文档
4. **记录变更日志** → 在当日变更文件中记录
5. **验证和测试** → 确保功能正常和文档准确
4. **验证和测试** → 确保功能正常和文档准确
```
### 🤖 Cursor AI 规范应用
@@ -173,7 +166,6 @@
- **技术规范**: 对应的`.cursor/cursorrules-*.md`文件
- **最佳实践**: `docs/开发文档/API开发最佳实践总结.md`
- **项目知识库**: `docs/知识库/`目录
- **变更记录**: `docs/变更管理/code-adjust-record-YYYY-MM-DD-{username}.md`
#### 总结流程
```
@@ -190,13 +182,12 @@
**⚠️ 基于场地预约管理系统开发实践制定的标准流程**
#### 完整开发流程(6个阶段)
#### 完整开发流程(5个阶段)
1. **需求分析和文档创建** → 业务需求+技术架构文档
2. **数据库设计和初始化** → 表结构+字典+权限+示例数据
3. **后端模块开发** → 完整ruoyi模块(16个API接口)
4. **API文档编写** → 400+行详细API文档
5. **自动化测试脚本** → 450+行Python测试脚本
6. **变更记录和验证** → 完整的变更日志
#### 16个标准API接口模式
- **基础管理接口(6个)**: list、详情、新增、修改、删除、可用选项
@@ -292,12 +283,12 @@ private Date updateTime; // 更新时间(含JSON格式化)
- 禁止将原型文件存放在源码目录(如 web/src、mobile/src 等)或其他非文档目录。
- 迁移或生成原型文件时,需同步更新目录结构说明文档(如 docs/原型文件/README.md )。
# uview-plus 图标组件规范(2025-07-01 新增)
- 移动端UI开发中,图标组件统一使用 <u-icon />(uview-plus 3.x 官方标准),禁止使用 <up-icon /> 或 <uv-icon />。
# uview-ui 图标组件规范(2025-01-03 更新)
- 移动端UI开发中,图标组件统一使用 <u-icon />(uview-ui 2.x 官方标准),同时支持iconfont自定义图标。
- 推荐通过 easycom 自动全局注册,无需手动 import。
- 标准用法示例:
```vue
<u-icon name="account" size="22" color="#b0b8c9" />
<u-icon name="lock-open" size="22" color="#b0b8c9" />
```
- 图标名称请参考 uview-plus 官方文档:https://v3.uviewui.com/components/icon.html
- 图标名称请参考 uview-ui 官方文档:https://www.uviewui.com/components/icon.html
+18
View File
@@ -162,6 +162,7 @@ coverage/
*.p12
*.keystore/xgxt/
excel/
backend/script/sql/add-related-type-field.sql
backend/script/sql/execute-fix-stgl-member.sql
backend/script/sql/fix-stgl-activity-remark-field.sql
@@ -306,3 +307,20 @@ docs/变更管理/code-adjust-record-2025-01-08-cursor.md
docs/变更管理/code-adjust-record-2025-01-08-cursor.md
docs/变更管理/code-adjust-record-2025-01-14-cursor.md
docs/设计文档/database/社团管理/社团管理建表脚本.sql
# 吴自龙注释
test/*
script/*
stgl-api-test.js
update/*
本地临时文件目录/*
docs/变更管理/
学生考核模块的提示词.md
学生考核模块的上下文信息临时存储.md
学生违纪记录界面-移动端.md
学生考核申请界面-移动端.md
移动端附件组件规范.md
移动端违纪记录模块开发规范.md
.playwright-mcp/
-117
View File
@@ -1,117 +0,0 @@
Application Version: 5.4.0
Spring Boot Version: 3.4.6
__________ _____.___.__ ____ ____ __________.__
\______ \__ __ ____\__ | |__| \ \ / /_ __ ____ \______ \ | __ __ ______
| _/ | \/ _ \/ | | | ______ \ Y / | \_/ __ \ ______ | ___/ | | | \/ ___/
| | \ | ( <_> )____ | | /_____/ \ /| | /\ ___/ /_____/ | | | |_| | /\___ \
|____|_ /____/ \____// ______|__| \___/ |____/ \___ > |____| |____/____//____ >
\/ \/ \/ \/
2025-07-26 13:02:51 [background-preinit] INFO  o.h.validator.internal.util.Version
 - HV000001: Hibernate Validator 8.0.2.Final
2025-07-26 13:02:51 [restartedMain] INFO  org.dromara.DromaraApplication
 - Starting DromaraApplication using Java 17.0.9 with PID 89083 (/Users/wuzhen/Documents/myworkspace/myproject/hzdyjspro/all-project/backend/ruoyi-admin/target/classes started by wuzhen in /Users/wuzhen/Documents/myworkspace/myproject/hzdyjspro/all-project/backend/ruoyi-admin)
2025-07-26 13:02:51 [restartedMain] INFO  org.dromara.DromaraApplication
 - The following 1 profile is active: "dev"
2025-07-26 13:02:55 [restartedMain] DEBUG o.apache.ibatis.logging.LogFactory
 - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
2025-07-26 13:02:57 [restartedMain] INFO  io.undertow.servlet
 - Initializing Spring embedded WebApplicationContext
2025-07-26 13:02:58 [restartedMain] INFO  c.b.d.d.DynamicRoutingDataSource
 - dynamic-datasource detect P6SPY plugin and enabled it
2025-07-26 13:02:58 [restartedMain] INFO  com.zaxxer.hikari.HikariDataSource
 - master - Starting...
2025-07-26 13:02:58 [restartedMain] INFO  com.zaxxer.hikari.pool.HikariPool
 - master - Added connection com.mysql.cj.jdbc.ConnectionImpl@47691398
2025-07-26 13:02:58 [restartedMain] INFO  com.zaxxer.hikari.HikariDataSource
 - master - Start completed.
2025-07-26 13:02:58 [restartedMain] INFO  c.b.d.d.DynamicRoutingDataSource
 - dynamic-datasource - add a datasource named [master] success
2025-07-26 13:02:58 [restartedMain] INFO  c.b.d.d.DynamicRoutingDataSource
 - dynamic-datasource initial loaded [1] datasource,primary datasource named [master]
2025-07-26 13:03:00 [restartedMain] WARN  c.b.m.c.injector.DefaultSqlInjector
 - class org.dromara.xg.domain.XgSysDept ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2025-07-26 13:03:01 [restartedMain] ERROR c.b.m.core.MybatisConfiguration
 - mapper[org.dromara.zsjy.mapper.ZsjyEnrollmentProcessMapper.countByPaymentStatus] is ignored, because it exists, maybe from xml file
2025-07-26 13:03:01 [restartedMain] ERROR c.b.m.core.MybatisConfiguration
 - mapper[org.dromara.zsjy.mapper.ZsjyEnrollmentProcessMapper.countByAdmissionStatus] is ignored, because it exists, maybe from xml file
2025-07-26 13:03:01 [restartedMain] ERROR c.b.m.core.MybatisConfiguration
 - mapper[org.dromara.zsjy.mapper.ZsjyEnrollmentProcessMapper.selectByEnrollmentId] is ignored, because it exists, maybe from xml file
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.5.12
2025-07-26 13:03:02 [restartedMain] INFO  o.d.common.redis.config.RedisConfig
 - 初始化 redis 配置
2025-07-26 13:03:02 [restartedMain] INFO  org.redisson.Version
 - Redisson 3.45.1
2025-07-26 13:03:02 [redisson-netty-1-6] INFO  o.r.connection.ConnectionsHolder
 - 1 connections initialized for 47.99.164.66/47.99.164.66:16379
2025-07-26 13:03:03 [redisson-netty-1-3] INFO  o.r.connection.ConnectionsHolder
 - 8 connections initialized for 47.99.164.66/47.99.164.66:16379
2025-07-26 13:03:06 [restartedMain] INFO  c.a.s.c.j.c.e.b.AbstractScriptExecutor$SnailFileUtils
 - [FileUtils] [workspace] use user.home as workspace: /Users/wuzhen/snailJob/worker
2025-07-26 13:03:06 [restartedMain] INFO  c.a.s.c.j.c.e.b.AbstractScriptExecutor$SnailFileUtils
 - [FileUtils] [workspace] use user.home as workspace: /Users/wuzhen/snailJob/worker
2025-07-26 13:03:06 [restartedMain] INFO  c.a.s.c.j.c.e.b.AbstractScriptExecutor$SnailFileUtils
 - [FileUtils] [workspace] use user.home as workspace: /Users/wuzhen/snailJob/worker
2025-07-26 13:03:07 [restartedMain] INFO  o.d.common.json.config.JacksonConfig
 - 初始化 jackson 配置
____ ____ ___ ____ _ _ ____ _ _
[__ |__| __ | | | |_/ |___ |\ |
___] | | | |__| | \_ |___ | \|
https://sa-token.cc (v1.42.0)
2025-07-26 13:03:08 [restartedMain] INFO  c.b.m.e.s.MybatisPlusApplicationContextAware
 - Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@1d95e68a
▄ ▄ ▄▄▄▄▄▄ ▄
█ █ █ ▄▄▄ ▄ ▄▄ ▄▄▄▄▄ █ █ ▄▄▄ ▄ ▄
▀ █▀█ █ ▀ █ █▀ ▀ █ █ █ ▄▄▄▄▄ █▄▄▄▄▄ █ █▀ ▀█ ▀▄ ▄ ▄▀
██ ██▀ ▄▀▀▀█ █ █ █ █ █ █ █ █ █▄█▄█
█ █ ▀▄▄▀█ █ █ █ █ █ █▄▄ ▀█▄█▀ █ █
 :: Warm-Flow :: (v1.7.3)
2025-07-26 13:03:24 [restartedMain] INFO  o.d.w.p.modes.sb.config.BeanConfig
 - 【warm-flow】,加载完成
2025-07-26 13:03:26 [restartedMain] WARN  o.s.b.d.a.OptionalLiveReloadServer
 - Unable to start LiveReload server
2025-07-26 13:03:27 [restartedMain] INFO  io.undertow
 - starting server: Undertow - 2.3.18.Final
2025-07-26 13:03:27 [restartedMain] INFO  org.xnio
 - XNIO version 3.8.16.Final
2025-07-26 13:03:28 [restartedMain] INFO  org.xnio.nio
 - XNIO NIO Implementation Version 3.8.16.Final
2025-07-26 13:03:28 [restartedMain] INFO  org.jboss.threads
 - JBoss Threads version 3.5.0.Final
2025-07-26 13:03:28 [restartedMain] INFO  io.undertow
 - stopping server: Undertow - 2.3.18.Final
2025-07-26 13:03:28 [restartedMain] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext
 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
2025-07-26 13:03:28 [restartedMain] INFO  o.d.c.core.config.ThreadPoolConfig
 - ====关闭后台任务任务线程池====
2025-07-26 13:03:28 [restartedMain] INFO  c.b.d.d.DynamicRoutingDataSource
 - dynamic-datasource start closing ....
2025-07-26 13:03:28 [restartedMain] INFO  com.zaxxer.hikari.HikariDataSource
 - master - Shutdown initiated...
2025-07-26 13:03:28 [restartedMain] INFO  com.zaxxer.hikari.HikariDataSource
 - master - Shutdown completed.
2025-07-26 13:03:28 [restartedMain] INFO  c.b.d.d.d.DefaultDataSourceDestroyer
 - dynamic-datasource close the datasource named [master] success,
2025-07-26 13:03:28 [restartedMain] INFO  c.b.d.d.DynamicRoutingDataSource
 - dynamic-datasource all closed success,bye
2025-07-26 13:03:28 [restartedMain] ERROR o.s.b.d.LoggingFailureAnalysisReporter
 -
***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+12 -4
View File
@@ -383,11 +383,11 @@
<version>${revision}</version>
</dependency>
<!-- 学工管理信息系统模块 -->
<dependency>
<!-- <dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-xg-xx</artifactId>
<version>${revision}</version>
</dependency>
</dependency> -->
<!-- 招生就业管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
@@ -407,12 +407,20 @@
<version>${revision}</version>
</dependency>
<!-- 社团管理模块 -->
<!-- 招生就业管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-zsjy</artifactId>
<version>${revision}</version>
</dependency>
<!-- 社团管理模块 -->
<!-- <dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-stgl</artifactId>
<version>${revision}</version>
</dependency>
</dependency> -->
</dependencies>
</dependencyManagement>
+25 -4
View File
@@ -112,12 +112,13 @@
<groupId>org.dromara</groupId>
<artifactId>ruoyi-xg</artifactId>
</dependency>
<!-- 学工管理-学生信息管理模块 -->
<dependency>
<!-- <dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-xg-xx</artifactId>
<version>${revision}</version>
</dependency>
</dependency> -->
<!-- 招生就业管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
@@ -135,12 +136,32 @@
<version>${revision}</version>
</dependency>
<!-- 社团管理模块 -->
<!-- 学生考核管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-xskh</artifactId>
<version>${revision}</version>
</dependency>
<!-- 奖惩补贴管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-jcbt</artifactId>
<version>${revision}</version>
</dependency>
<!-- 班主任考核管理模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-bzrkh</artifactId>
<version>${revision}</version>
</dependency>
<!-- 社团管理模块 -->
<!-- <dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-stgl</artifactId>
<version>${revision}</version>
</dependency>
</dependency> -->
<dependency>
<groupId>de.codecentric</groupId>
@@ -3,6 +3,7 @@ package org.dromara;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 启动程序
@@ -10,6 +11,7 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt
* @author Lion Li
*/
@EnableAsync
@SpringBootApplication
public class DromaraApplication {
@@ -0,0 +1,63 @@
package org.dromara.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 异步任务配置
* 用于支持审批流程等异步事件处理,提升系统响应性能
*
* @author Cursor
* @date 2025-08-01
*/
@Slf4j
@Configuration
@EnableAsync
public class AsyncConfig {
/**
* 审批流程异步任务执行器
*/
// 吴自龙注释了,跟震哥确定为不需要的代码
// @Bean("approvalTaskExecutor")
// public TaskExecutor approvalTaskExecutor() {
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// // 核心线程数
// executor.setCorePoolSize(5);
// // 最大线程数
// executor.setMaxPoolSize(10);
// // 队列容量
// executor.setQueueCapacity(50);
// // 线程名前缀
// executor.setThreadNamePrefix("approval-async-");
// // 线程空闲存活时间(秒)
// executor.setKeepAliveSeconds(60);
// // 拒绝策略:调用线程执行
// executor.setRejectedExecutionHandler(new
// ThreadPoolExecutor.CallerRunsPolicy());
// // 等待任务完成后再关闭线程池
// executor.setWaitForTasksToCompleteOnShutdown(true);
// // 等待时间(秒)
// executor.setAwaitTerminationSeconds(30);
// // 初始化
// executor.initialize();
// log.info("✅ 审批流程异步任务执行器初始化完成");
// return executor;
// }
}
@@ -79,7 +79,7 @@ public class AuthController {
* @param body 登录信息
* @return 结果
*/
@ApiEncrypt(response = true)
@ApiEncrypt(response = true) // 临时移除加密,待完善加密实现后恢复
@PostMapping("/login")
public R<LoginVo> login(@RequestBody String body) {
LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
@@ -72,7 +72,8 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# 增加锁等待超时参数,减少锁冲突
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&innodb_lock_wait_timeout=120&autocommit=true
username: root
password: hn02le.34lkdLKD
# # 从库数据源
@@ -102,20 +103,22 @@ spring:
# username: SA
# password: root
hikari:
# 最大连接池数量
# 最大连接池数量(增加以减少连接竞争)
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
# 最小空闲线程数量(减少空闲连接数)
minIdle: 5
# 配置获取连接等待超时的时间(减少等待时间)
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 多久检查一次连接的活性
keepaliveTime: 30000
# 空闲连接存活最大时间,默认10分钟(减少空闲超时)
idleTimeout: 300000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟(减少生命周期)
maxLifetime: 900000
# 多久检查一次连接的活性(增加间隔,减少检测频率)
keepaliveTime: 60000
# 连接测试查询(验证连接有效性)
# connectionTestQuery: SELECT 11
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring.data:
@@ -125,11 +128,11 @@ spring.data:
# 端口,默认为6379
port: 16379
# 数据库索引
database: 0
database: 8
# redis 密码必须配置
password: Hzdyjs@123456
# 连接超时时间
timeout: 10s
timeout: 30s
# 是否开启ssl
ssl.enabled: false
@@ -152,7 +155,11 @@ redisson:
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
timeout: 10000
# 命令失败重试次数
retryAttempts: 3
# 命令重试发送时间间隔,单位:毫秒
retryInterval: 1500
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
@@ -333,4 +340,41 @@ system:
# - 对于内存充足的环境,可以适当增加 max-cache-size-bytes
# - 对于频繁访问的小文件,可以增加 max-cache-size
# - 对于大文件较多的环境,可以调整 max-single-file-size
# - 对于访问频率较低的环境,可以适当减少 expire-time-ms
# - 对于访问频率较低的环境,可以适当减少 expire-time-ms
--- # SQL日志配置(用于调试班级名额查询问题)
logging:
level:
# 开启 MyBatis SQL 日志
org.dromara.jcbt.mapper: DEBUG
org.dromara.jcbt.service: DEBUG
# 开启 MyBatis-Plus SQL 日志
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor: DEBUG
# 开启 HikariCP 连接池日志(可选)
com.zaxxer.hikari: DEBUG
# 开启 P6Spy SQL 日志(更详细的SQL执行日志)
p6spy: INFO
pattern:
# 控制台日志格式,增加线程名和方法名
console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"
# MyBatis 配置
mybatis-plus:
configuration:
# 开启 SQL 日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 开启驼峰命名转换
map-underscore-to-camel-case: true
# 开启缓存
cache-enabled: true
# 开启懒加载
lazy-loading-enabled: true
# 开启积极懒加载
aggressive-lazy-loading: false
--- # 高德地图配置
amap:
# 高德地图API密钥(请替换为您的实际密钥)
key: 920750e421cd6357ddf60ee1e929e0dd
# 高德地图API基础URL
url: https://restapi.amap.com
@@ -5,7 +5,7 @@ spring.servlet.multipart.location: /ruoyi/server/temp
spring.boot.admin.client:
# 增加客户端开关
enabled: true
url: http://localhost:9090/admin
url: http://47.121.125.41:9090/admin
instance:
service-host-type: IP
metadata:
@@ -22,7 +22,7 @@ snail-job:
# SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config`表
token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT"
server:
host: 127.0.0.1
host: 47.121.125.41
port: 17888
# 命名空间UUID 详见 script/sql/ry_job.sql `sj_namespace`表`unique_id`字段
namespace: ${spring.profiles.active}
@@ -54,7 +54,7 @@ spring:
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: 'hn02le.34lkdLKD'
password: hn02le.34lkdLKD
# # 从库数据源
# slave:
# lazy: true
@@ -83,7 +83,7 @@ spring:
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20
maxPoolSize: 30
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
@@ -101,13 +101,13 @@ spring:
spring.data:
redis:
# 地址
host: localhost
host: 47.99.164.66
# 端口,默认为6379
port: 6379
port: 16379
# 数据库索引
database: 0
database: 3
# redis 密码必须配置
password: ruoyi123
password: Hzdyjs@123456
# 连接超时时间
timeout: 10s
# 是否开启ssl
@@ -312,4 +312,42 @@ system:
# - 对于内存充足的环境,可以适当增加 max-cache-size-bytes
# - 对于频繁访问的小文件,可以增加 max-cache-size
# - 对于大文件较多的环境,可以调整 max-single-file-size
# - 对于访问频率较低的环境,可以适当减少 expire-time-ms
# - 对于访问频率较低的环境,可以适当减少 expire-time-ms
--- # SQL日志配置(用于调试班级名额查询问题)
logging:
level:
# 开启 MyBatis SQL 日志
org.dromara.jcbt.mapper: DEBUG
org.dromara.jcbt.service: DEBUG
# 开启 MyBatis-Plus SQL 日志
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor: DEBUG
# 开启 HikariCP 连接池日志(可选)
com.zaxxer.hikari: DEBUG
# 开启 P6Spy SQL 日志(更详细的SQL执行日志)
p6spy: INFO
pattern:
# 控制台日志格式,增加线程名和方法名
console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"
# MyBatis 配置
mybatis-plus:
configuration:
# 开启 SQL 日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 开启驼峰命名转换
map-underscore-to-camel-case: true
# 开启缓存
cache-enabled: true
# 开启懒加载
lazy-loading-enabled: true
# 开启积极懒加载
aggressive-lazy-loading: false
--- # 高德地图配置
amap:
# 高德地图API密钥(请替换为您的实际密钥)
key: 920750e421cd6357ddf60ee1e929e0dd
# 高德地图API基础URL
url: https://restapi.amap.com
@@ -41,6 +41,10 @@ logging:
org.springframework: warn
org.mybatis.spring.mapper: error
org.apache.fury: warn
# 关闭SQL日志调试,减少SELECT 1心跳检测日志
# org.dromara.cw.mapper.CwApprovalRecordMapper: info
# org.dromara.cw.service.impl.CwApprovalRecordServiceImpl: info
# org.dromara.cw.listener.ApprovalProcessEventListener: info
config: classpath:logback-plus.xml
# 用户配置
@@ -88,6 +92,10 @@ spring:
deserialization:
# 允许对象忽略json中不存在的属性
fail_on_unknown_properties: false
# thymeleaf模板配置 weizhong
thymeleaf:
# 是否检查模板位置
check-template-location: false
# Sa-Token配置
sa-token:
@@ -120,6 +128,10 @@ security:
- /v3/api-docs/**
- /webjars/**
- /warm-flow-ui/config
# 招聘门户公开接口 weizhong
- /rs/job/public/**
- /rs/job/view/**
- /rs/application/submit
- /system/dict/data/type/*
# 多租户配置
@@ -151,6 +163,9 @@ mybatis-plus:
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: org.dromara.**.domain
# 启用SQL日志输出,用于调试数据库插入问题
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
dbConfig:
# 主键类型
@@ -175,7 +190,7 @@ mybatis-encryptor:
# api接口加密
api-decrypt:
# 是否开启全局接口加密
enabled: true
enabled: true # 恢复为true,保持其他接口的安全性
# AES 加密头标识
headerFlag: encrypt-key
# 响应加密公钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="log.path" value="./logs"/>
<property name="console.log.pattern"
value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<property name="console.log.pattern" value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>
<!-- 控制台输出 -->
@@ -113,24 +112,24 @@
</appender>
<!-- 整合 skywalking 控制台输出 tid -->
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!-- 整合 skywalking 推送采集日志 -->
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!--系统操作日志-->
<root level="info">
@@ -138,10 +137,10 @@
<appender-ref ref="async_info" />
<appender-ref ref="async_error" />
<appender-ref ref="file_console" />
<!-- <appender-ref ref="sky_log"/>-->
<!-- <appender-ref ref="sky_log"/>-->
</root>
<!-- 设置MyBatis的日志级别为DEBUG,以便打印SQL语句 -->
<!-- 设置MyBatis的日志级别为INFO,减少SELECT 1心跳检测日志 -->
<logger name="org.dromara.xg.mapper" level="DEBUG">
<appender-ref ref="file_sql" />
</logger>
@@ -102,10 +102,16 @@ public class ExcelDownHandler implements SheetWriteHandler {
String converterExp = format.readConverterExp();
if (StringUtils.isNotBlank(dictType)) {
// 如果传递了字典名,则依据字典建立下拉
Collection<String> values = Optional.ofNullable(dictService.getAllDictByDictType(dictType))
.orElseThrow(() -> new ServiceException(String.format("字典 %s 不存在", dictType)))
.values();
options = new ArrayList<>(values);
try {
Map<String, String> dictMap = dictService.getAllDictByDictType(dictType);
if (CollUtil.isNotEmpty(dictMap)) {
options = new ArrayList<>(dictMap.values());
} else {
log.warn("ExcelDownHandler: 字典 {} 数据为空,跳过下拉渲染", dictType);
}
} catch (Exception ex) {
log.warn("ExcelDownHandler: 字典 {} 不存在或加载失败,跳过下拉渲染. cause={}", dictType, ex.getMessage());
}
} else if (StringUtils.isNotBlank(converterExp)) {
// 如果指定了确切的值,则直接解析确切的值
List<String> strList = StringUtils.splitList(converterExp, format.separator());
@@ -119,6 +119,12 @@ public class PageQuery implements Serializable {
return (pageNum - 1) * pageSize;
}
/**
* 无参构造器
*/
public PageQuery() {
}
public PageQuery(Integer pageSize, Integer pageNum) {
this.pageSize = pageSize;
this.pageNum = pageNum;
@@ -38,7 +38,7 @@ spring.boot.admin.client:
# 增加客户端开关
enabled: true
# 设置 Spring Boot Admin Server 地址
url: http://localhost:9090/admin
url: http://127.0.0.1:9090/admin
instance:
service-host-type: IP
metadata:
@@ -2,9 +2,9 @@ spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
url: jdbc:mysql://47.99.164.66:3306/hzdyjs_xg?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
password: hn02le.34lkdLKD
hikari:
connection-timeout: 30000
validation-timeout: 5000
@@ -30,7 +30,7 @@ snail-job:
spring.boot.admin.client:
# 增加客户端开关
enabled: true
url: http://localhost:9090/admin
url: http://47.121.125.41:9090/admin
instance:
service-host-type: IP
metadata:
+5 -2
View File
@@ -15,14 +15,17 @@
<module>ruoyi-demo</module>
<module>ruoyi-workflow</module>
<module>ruoyi-xg</module>
<module>ruoyi-xg-xx</module>
<!-- <module>ruoyi-xg-xx</module> -->
<module>ruoyi-zsjy</module>
<module>ruoyi-hq</module>
<module>ruoyi-aqbw</module>
<module>ruoyi-cw</module>
<module>ruoyi-rs</module>
<module>ruoyi-xljk</module>
<module>ruoyi-stgl</module>
<module>ruoyi-jcbt</module>
<module>ruoyi-bzrkh</module>
<module>ruoyi-xskh</module>
<!-- <module>ruoyi-stgl</module> -->
</modules>
<artifactId>ruoyi-modules</artifactId>
+109
View File
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi-modules</artifactId>
<groupId>org.dromara</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-bzrkh</artifactId>
<description>
班主任考核管理模块
</description>
<dependencies>
<!-- 通用工具 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-web</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-excel</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-ratelimiter</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mail</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-job</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
<!-- demo模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-demo</artifactId>
</dependency>
<!-- 工作流模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-workflow</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,168 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
import org.dromara.bzrkh.domain.vo.EvaluationLevelStatsVo;
import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
import org.dromara.bzrkh.domain.bo.BatchApprovalBo;
import org.dromara.bzrkh.service.IAssessmentApprovalService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.excel.utils.ExcelUtil;
import jakarta.servlet.http.HttpServletResponse;
/**
* 班主任考核审核Controller
*
* @author ruoyi
* @date 2025-01-28
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentApproval")
public class AssessmentApprovalController extends BaseController {
private final IAssessmentApprovalService assessmentApprovalService;
/**
* 查询班主任考核审核列表
*/
@SaCheckPermission("bzrkh:assessmentApproval:list")
@GetMapping("/list")
public TableDataInfo<AssessmentApprovalVo> list(AssessmentApprovalQueryBo bo, PageQuery pageQuery) {
return assessmentApprovalService.queryPageList(bo, pageQuery);
}
/**
* 获取考核审核详情
*/
@SaCheckPermission("bzrkh:assessmentApproval:query")
@GetMapping("/detail")
public R<AssessmentApprovalDetailVo> getApprovalDetail(
@RequestParam @NotNull(message = "计划ID不能为空") Long planId,
@RequestParam @NotNull(message = "班级ID不能为空") Long classId,
@RequestParam @NotNull(message = "被评价用户ID不能为空") Long evaluatedUserId) {
AssessmentApprovalDetailVo detail = assessmentApprovalService.getApprovalDetail(planId, classId, evaluatedUserId);
return R.ok(detail);
}
/**
* 提交考核审核
*/
@SaCheckPermission("bzrkh:assessmentApproval:approve")
@Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
@PostMapping("/submit")
public R<Void> submitApproval(@RequestBody @Validated AssessmentApprovalSubmitBo bo) {
Long approverUserId = LoginHelper.getUserId();
boolean result = assessmentApprovalService.submitApproval(bo, approverUserId);
return toAjax(result);
}
/**
* 批量审核通过
*/
@SaCheckPermission("bzrkh:assessmentApproval:approve")
@Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
@PostMapping("/batchApprove")
public R<Void> batchApprove(@RequestBody BatchApprovalBo bo) {
Long approverUserId = LoginHelper.getUserId();
boolean result = assessmentApprovalService.batchApprove(bo.getIds(), approverUserId);
return toAjax(result);
}
/**
* 批量审核拒绝
*/
@SaCheckPermission("bzrkh:assessmentApproval:reject")
@Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
@PostMapping("/batchReject")
public R<Void> batchReject(@Validated @RequestBody BatchApprovalBo bo) {
boolean result = assessmentApprovalService.batchReject(bo.getIds(), bo.getRejectReason(), LoginHelper.getUserId());
return result ? R.ok() : R.fail("批量审核拒绝失败");
}
/**
* 删除异常的审批记录(管理员专用)
* 用于清理审批列表中显示但实际已被删除的异常数据
*/
@SaCheckPermission("bzrkh:assessmentApproval:delete")
@Log(title = "班主任考核审核", businessType = BusinessType.DELETE)
@DeleteMapping("/deleteAbnormalRecord")
public R<Void> deleteAbnormalRecord(@RequestParam Long planId, @RequestParam Long evaluatedUserId) {
boolean result = assessmentApprovalService.deleteAbnormalRecord(planId, evaluatedUserId);
return result ? R.ok() : R.fail("删除异常记录失败");
}
/**
* 获取考核方案下拉选项
*/
@SaCheckPermission("bzrkh:assessmentApproval:list")
@GetMapping("/schemeOptions")
public R<List<SchemeOptionVo>> getSchemeOptions() {
List<SchemeOptionVo> options = assessmentApprovalService.getSchemeOptions();
return R.ok(options);
}
/**
* 导出班主任考核审核数据
*/
@SaCheckPermission("bzrkh:assessmentApproval:export")
@Log(title = "班主任考核审核", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(AssessmentApprovalQueryBo bo, HttpServletResponse response) {
List<AssessmentApprovalVo> list = assessmentApprovalService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核审核数据", AssessmentApprovalVo.class, response);
}
/**
* 获取评价等级统计数据
*/
@SaCheckPermission("bzrkh:assessmentApproval:query")
@GetMapping("/evaluationStats")
public R<EvaluationLevelStatsVo> getEvaluationLevelStats(@RequestParam @NotNull(message = "计划ID不能为空") Long planId) {
EvaluationLevelStatsVo stats = assessmentApprovalService.getEvaluationLevelStats(planId);
return R.ok(stats);
}
/**
* 批量拒绝请求对象
*/
public static class BatchRejectBo {
@NotEmpty(message = "审核ID列表不能为空")
private List<Long> ids;
@NotBlank(message = "拒绝原因不能为空")
private String rejectReason;
public List<Long> getIds() {
return ids;
}
public void setIds(List<Long> ids) {
this.ids = ids;
}
public String getRejectReason() {
return rejectReason;
}
public void setRejectReason(String rejectReason) {
this.rejectReason = rejectReason;
}
}
}
@@ -0,0 +1,115 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorBo;
import org.dromara.bzrkh.service.IBmzrAssessmentIndicatorService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 班主任考核指标体系
*
* @author ruoyi
* @date 2025-01-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentIndicator")
public class BmzrAssessmentIndicatorController extends BaseController {
private final IBmzrAssessmentIndicatorService bmzrAssessmentIndicatorService;
/**
* 查询班主任考核指标体系列表
*/
@SaCheckPermission("bzrkh:assessmentIndicator:list")
@GetMapping("/list")
public TableDataInfo<BmzrAssessmentIndicatorVo> list(BmzrAssessmentIndicatorBo bo, PageQuery pageQuery) {
return bmzrAssessmentIndicatorService.queryPageList(bo, pageQuery);
}
/**
* 查询班主任考核指标体系树形结构(用于父级选择)
*/
@SaCheckPermission("bzrkh:assessmentIndicator:list")
@GetMapping("/treeselect")
public R<List<BmzrAssessmentIndicatorVo>> treeselect(BmzrAssessmentIndicatorBo bo) {
List<BmzrAssessmentIndicatorVo> list = bmzrAssessmentIndicatorService.queryTreeList(bo);
return R.ok(list);
}
/**
* 导出班主任考核指标体系列表
*/
@SaCheckPermission("bzrkh:assessmentIndicator:export")
@Log(title = "班主任考核指标体系", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BmzrAssessmentIndicatorBo bo, HttpServletResponse response) {
List<BmzrAssessmentIndicatorVo> list = bmzrAssessmentIndicatorService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核指标体系", BmzrAssessmentIndicatorVo.class, response);
}
/**
* 获取班主任考核指标体系详细信息
*
* @param id 主键
*/
@SaCheckPermission("bzrkh:assessmentIndicator:query")
@GetMapping("/{id}")
public R<BmzrAssessmentIndicatorVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bmzrAssessmentIndicatorService.queryById(id));
}
/**
* 新增班主任考核指标体系
*/
@SaCheckPermission("bzrkh:assessmentIndicator:add")
@Log(title = "班主任考核指标体系", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BmzrAssessmentIndicatorBo bo) {
return toAjax(bmzrAssessmentIndicatorService.insertByBo(bo));
}
/**
* 修改班主任考核指标体系
*/
@SaCheckPermission("bzrkh:assessmentIndicator:edit")
@Log(title = "班主任考核指标体系", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BmzrAssessmentIndicatorBo bo) {
return toAjax(bmzrAssessmentIndicatorService.updateByBo(bo));
}
/**
* 删除班主任考核指标体系
*
* @param ids 主键串
*/
@SaCheckPermission("bzrkh:assessmentIndicator:remove")
@Log(title = "班主任考核指标体系", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bmzrAssessmentIndicatorService.deleteWithValidByIds(List.of(ids), true));
}
}
@@ -0,0 +1,115 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorTypeVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorTypeBo;
import org.dromara.bzrkh.service.IBmzrAssessmentIndicatorTypeService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 班主任考核指标类型
*
* @author ruoyi
* @date 2025-01-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentIndicatorType")
public class BmzrAssessmentIndicatorTypeController extends BaseController {
private final IBmzrAssessmentIndicatorTypeService bmzrAssessmentIndicatorTypeService;
/**
* 查询班主任考核指标类型列表
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:list")
@GetMapping("/list")
public TableDataInfo<BmzrAssessmentIndicatorTypeVo> list(BmzrAssessmentIndicatorTypeBo bo, PageQuery pageQuery) {
return bmzrAssessmentIndicatorTypeService.queryPageList(bo, pageQuery);
}
/**
* 查询所有班主任考核指标类型列表(包括已逻辑删除的)
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:list")
@GetMapping("/listAllIncludeDeleted")
public R<List<BmzrAssessmentIndicatorTypeVo>> listAllIncludeDeleted(BmzrAssessmentIndicatorTypeBo bo) {
List<BmzrAssessmentIndicatorTypeVo> list = bmzrAssessmentIndicatorTypeService.queryListWithDeleted(bo);
return R.ok(list);
}
/**
* 导出班主任考核指标类型列表
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:export")
@Log(title = "班主任考核指标类型", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BmzrAssessmentIndicatorTypeBo bo, HttpServletResponse response) {
List<BmzrAssessmentIndicatorTypeVo> list = bmzrAssessmentIndicatorTypeService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核指标类型", BmzrAssessmentIndicatorTypeVo.class, response);
}
/**
* 获取班主任考核指标类型详细信息
*
* @param id 主键
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:query")
@GetMapping("/{id}")
public R<BmzrAssessmentIndicatorTypeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bmzrAssessmentIndicatorTypeService.queryById(id));
}
/**
* 新增班主任考核指标类型
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:add")
@Log(title = "班主任考核指标类型", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BmzrAssessmentIndicatorTypeBo bo) {
return toAjax(bmzrAssessmentIndicatorTypeService.insertByBo(bo));
}
/**
* 修改班主任考核指标类型
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:edit")
@Log(title = "班主任考核指标类型", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BmzrAssessmentIndicatorTypeBo bo) {
return toAjax(bmzrAssessmentIndicatorTypeService.updateByBo(bo));
}
/**
* 删除班主任考核指标类型
*
* @param ids 主键串
*/
@SaCheckPermission("bzrkh:assessmentIndicatorType:remove")
@Log(title = "班主任考核指标类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bmzrAssessmentIndicatorTypeService.deleteWithValidByIds(List.of(ids), true));
}
}
@@ -0,0 +1,120 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo;
import org.dromara.bzrkh.service.IBmzrAssessmentPlanService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 班主任考核计划Controller
*
* @author ruoyi
* @date 2025-01-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentPlan")
public class BmzrAssessmentPlanController extends BaseController {
private final IBmzrAssessmentPlanService bmzrAssessmentPlanService;
/**
* 查询班主任考核计划列表
*/
@SaCheckPermission("bzrkh:assessmentPlan:list")
@GetMapping("/list")
public TableDataInfo<BmzrAssessmentPlanVo> list(BmzrAssessmentPlanBo bo, PageQuery pageQuery) {
return bmzrAssessmentPlanService.queryPageList(bo, pageQuery);
}
/**
* 导出班主任考核计划列表
*/
@SaCheckPermission("bzrkh:assessmentPlan:export")
@Log(title = "班主任考核计划", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BmzrAssessmentPlanBo bo, HttpServletResponse response) {
List<BmzrAssessmentPlanVo> list = bmzrAssessmentPlanService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核计划", BmzrAssessmentPlanVo.class, response);
}
/**
* 获取班主任考核计划详细信息
*/
@SaCheckPermission("bzrkh:assessmentPlan:query")
@GetMapping("/{id}")
public R<BmzrAssessmentPlanVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bmzrAssessmentPlanService.queryById(id));
}
/**
* 新增班主任考核计划
*/
@SaCheckPermission("bzrkh:assessmentPlan:add")
@Log(title = "班主任考核计划", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BmzrAssessmentPlanBo bo) {
return toAjax(bmzrAssessmentPlanService.insertByBo(bo));
}
/**
* 修改班主任考核计划
*/
@SaCheckPermission("bzrkh:assessmentPlan:edit")
@Log(title = "班主任考核计划", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BmzrAssessmentPlanBo bo) {
return toAjax(bmzrAssessmentPlanService.updateByBo(bo));
}
/**
* 删除班主任考核计划
*/
@SaCheckPermission("bzrkh:assessmentPlan:remove")
@Log(title = "班主任考核计划", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bmzrAssessmentPlanService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 修改考核计划状态
*/
@SaCheckPermission("bzrkh:assessmentPlan:edit")
@Log(title = "班主任考核计划", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody BmzrAssessmentPlanBo bo) {
return toAjax(bmzrAssessmentPlanService.updatePlanStatus(bo.getId(), bo.getPlanStatus()));
}
/**
* 获取可用的考核方案选项
*/
@SaCheckPermission("bzrkh:assessmentPlan:list")
@GetMapping("/schemes/options")
public R<List<BmzrAssessmentPlanVo>> getAvailableSchemes() {
return R.ok(bmzrAssessmentPlanService.getAvailableSchemes());
}
}
@@ -0,0 +1,103 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeBo;
import org.dromara.bzrkh.service.IBmzrAssessmentSchemeService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 班主任考核方案
*
* @author system
* @date 2025-01-08
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentScheme")
public class BmzrAssessmentSchemeController extends BaseController {
private final IBmzrAssessmentSchemeService bmzrAssessmentSchemeService;
/**
* 查询班主任考核方案列表
*/
@SaCheckPermission("bzrkh:assessmentScheme:list")
@GetMapping("/list")
public TableDataInfo<BmzrAssessmentSchemeVo> list(BmzrAssessmentSchemeBo bo, PageQuery pageQuery) {
return bmzrAssessmentSchemeService.queryPageList(bo, pageQuery);
}
/**
* 导出班主任考核方案列表
*/
@SaCheckPermission("bzrkh:assessmentScheme:export")
@Log(title = "班主任考核方案", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BmzrAssessmentSchemeBo bo, HttpServletResponse response) {
List<BmzrAssessmentSchemeVo> list = bmzrAssessmentSchemeService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核方案", BmzrAssessmentSchemeVo.class, response);
}
/**
* 获取班主任考核方案详细信息
*
* @param id 主键
*/
@SaCheckPermission("bzrkh:assessmentScheme:query")
@GetMapping("/{id}")
public R<BmzrAssessmentSchemeVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(bmzrAssessmentSchemeService.queryById(id));
}
/**
* 新增班主任考核方案
*/
@SaCheckPermission("bzrkh:assessmentScheme:add")
@Log(title = "班主任考核方案", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping
public R<Void> add(@Validated(AddGroup.class) @RequestBody BmzrAssessmentSchemeBo bo) {
return toAjax(bmzrAssessmentSchemeService.insertByBo(bo));
}
/**
* 修改班主任考核方案
*/
@SaCheckPermission("bzrkh:assessmentScheme:edit")
@Log(title = "班主任考核方案", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BmzrAssessmentSchemeBo bo) {
return toAjax(bmzrAssessmentSchemeService.updateByBo(bo));
}
/**
* 删除班主任考核方案
*/
@SaCheckPermission("bzrkh:assessmentScheme:remove")
@Log(title = "班主任考核方案", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(bmzrAssessmentSchemeService.deleteWithValidByIds(List.of(ids), true));
}
}
@@ -0,0 +1,130 @@
package org.dromara.bzrkh.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeIndicatorBo;
import org.dromara.bzrkh.service.IBmzrAssessmentSchemeIndicatorService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 班主任考核方案指标关联
*
* @author ruoyi
* @date 2025-01-08
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/assessmentSchemeIndicator")
public class BmzrAssessmentSchemeIndicatorController extends BaseController {
private final IBmzrAssessmentSchemeIndicatorService bmzrAssessmentSchemeIndicatorService;
/**
* 查询班主任考核方案指标关联列表
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:list")
@GetMapping("/list")
public TableDataInfo<BmzrAssessmentSchemeIndicatorVo> list(BmzrAssessmentSchemeIndicatorBo bo, PageQuery pageQuery) {
return bmzrAssessmentSchemeIndicatorService.queryPageList(bo, pageQuery);
}
/**
* 根据方案ID查询指标关联列表(无分页)
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:list")
@GetMapping("/listBySchemeId/{schemeId}")
public R<List<BmzrAssessmentSchemeIndicatorVo>> listBySchemeId(@PathVariable Long schemeId) {
List<BmzrAssessmentSchemeIndicatorVo> list = bmzrAssessmentSchemeIndicatorService.queryBySchemeId(schemeId);
return R.ok(list);
}
/**
* 导出班主任考核方案指标关联列表
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:export")
@Log(title = "班主任考核方案指标关联", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BmzrAssessmentSchemeIndicatorBo bo, HttpServletResponse response) {
List<BmzrAssessmentSchemeIndicatorVo> list = bmzrAssessmentSchemeIndicatorService.queryList(bo);
ExcelUtil.exportExcel(list, "班主任考核方案指标关联", BmzrAssessmentSchemeIndicatorVo.class, response);
}
/**
* 获取班主任考核方案指标关联详细信息
*
* @param id 主键
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:query")
@GetMapping("/{id}")
public R<BmzrAssessmentSchemeIndicatorVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bmzrAssessmentSchemeIndicatorService.queryById(id));
}
/**
* 新增班主任考核方案指标关联
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:add")
@Log(title = "班主任考核方案指标关联", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BmzrAssessmentSchemeIndicatorBo bo) {
return toAjax(bmzrAssessmentSchemeIndicatorService.insertByBo(bo));
}
/**
* 修改班主任考核方案指标关联
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:edit")
@Log(title = "班主任考核方案指标关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BmzrAssessmentSchemeIndicatorBo bo) {
return toAjax(bmzrAssessmentSchemeIndicatorService.updateByBo(bo));
}
/**
* 删除班主任考核方案指标关联
*
* @param ids 主键串
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:remove")
@Log(title = "班主任考核方案指标关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bmzrAssessmentSchemeIndicatorService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 批量保存方案指标关联
*
* @param schemeId 方案ID
* @param indicatorList 指标列表
*/
@SaCheckPermission("bzrkh:assessmentSchemeIndicator:edit")
@Log(title = "批量保存方案指标关联", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/batchSave/{schemeId}")
public R<Void> batchSave(@PathVariable Long schemeId,
@RequestBody List<BmzrAssessmentSchemeIndicatorBo> indicatorList) {
return toAjax(bmzrAssessmentSchemeIndicatorService.batchSaveSchemeIndicators(schemeId, indicatorList));
}
}
@@ -0,0 +1,189 @@
package org.dromara.bzrkh.controller;
import java.math.BigDecimal;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.bzrkh.domain.vo.TeacherClassVo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.vo.AssessmentDetailVo;
import org.dromara.bzrkh.domain.vo.ClassStudentRecordsVo;
import org.dromara.bzrkh.domain.bo.TeacherAssessmentQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentSubmitBo;
import org.dromara.bzrkh.service.ITeacherAssessmentService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
/**
* 班主任考核管理Controller
*
* @author ruoyi
* @date 2025-01-27
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/bzrkh/teacherAssessment")
public class TeacherAssessmentController extends BaseController {
private final ITeacherAssessmentService teacherAssessmentService;
/**
* 查询班主任管理的班级列表
*/
@SaCheckPermission("bzrkh:teacherAssessment:list")
@GetMapping("/classes")
public R<List<TeacherClassVo>> getTeacherClasses(@RequestParam(required = false) Long teacherId) {
// 如果没有传入teacherId,则使用当前登录用户ID
Long currentTeacherId = teacherId != null ? teacherId : LoginHelper.getUserId();
List<TeacherClassVo> list = teacherAssessmentService.queryTeacherClassList(currentTeacherId);
return R.ok(list);
}
/**
* 查询班主任考核计划列表
*/
@SaCheckPermission("bzrkh:teacherAssessment:list")
@GetMapping("/plans")
public TableDataInfo<BmzrAssessmentPlanVo> getTeacherAssessmentPlans(TeacherAssessmentQueryBo bo, PageQuery pageQuery) {
// 如果没有传入teacherId,则使用当前登录用户ID
if (bo.getTeacherId() == null) {
bo.setTeacherId(LoginHelper.getUserId());
}
return teacherAssessmentService.queryTeacherAssessmentPlanPageList(bo, pageQuery);
}
/**
* 提交考核
*/
@SaCheckPermission("bzrkh:teacherAssessment:submit")
@Log(title = "班主任考核管理", businessType = BusinessType.UPDATE)
@PostMapping("/submit")
public R<Void> submitAssessment(@RequestBody TeacherAssessmentSubmitRequest request) {
try {
Long teacherId = LoginHelper.getUserId();
boolean result = teacherAssessmentService.submitAssessment(request.getPlanId(), request.getClassId(), teacherId);
return toAjax(result);
} catch (RuntimeException e) {
// 返回具体的错误信息
return R.fail(e.getMessage());
} catch (Exception e) {
// 记录详细的异常信息
log.error("提交考核异常", e);
return R.fail("系统异常,请联系管理员");
}
}
/**
* 撤销考核提交
*/
@SaCheckPermission("bzrkh:teacherAssessment:withdraw")
@Log(title = "班主任考核管理", businessType = BusinessType.UPDATE)
@PostMapping("/withdraw")
public R<Void> withdrawAssessment(@RequestBody TeacherAssessmentSubmitRequest request) {
Long teacherId = LoginHelper.getUserId();
boolean result = teacherAssessmentService.withdrawAssessment(request.getPlanId(), request.getClassId(), teacherId);
return toAjax(result);
}
/**
* 查看考核详情
*/
@SaCheckPermission("bzrkh:teacherAssessment:detail")
@GetMapping("/detail")
public R<Object> getAssessmentDetail(@RequestParam Long planId, @RequestParam Long classId) {
Long teacherId = LoginHelper.getUserId();
Object detail = teacherAssessmentService.getAssessmentDetail(planId, classId, teacherId);
return R.ok(detail);
}
/**
* 获取考核提交详情数据
*/
@SaCheckPermission("bzrkh:teacherAssessment:detail")
@GetMapping("/submitDetail")
public R<AssessmentDetailVo> getAssessmentSubmitDetail(@RequestParam Long planId, @RequestParam Long classId) {
Long teacherId = LoginHelper.getUserId();
AssessmentDetailVo detail = teacherAssessmentService.getAssessmentSubmitDetail(planId, classId, teacherId);
return R.ok(detail);
}
/**
* 提交考核评分数据
*/
@SaCheckPermission("bzrkh:teacherAssessment:submit")
@Log(title = "班主任考核管理", businessType = BusinessType.INSERT)
@PostMapping("/submitScore")
public R<Void> submitAssessmentScore(@RequestBody AssessmentSubmitBo bo) {
try {
Long teacherId = LoginHelper.getUserId();
boolean result = teacherAssessmentService.submitAssessmentScore(bo, teacherId);
return toAjax(result);
} catch (RuntimeException e) {
// 返回具体的错误信息
return R.fail(e.getMessage());
} catch (Exception e) {
// 记录详细的异常信息
log.error("提交考核评分数据异常", e);
return R.fail("系统异常,请联系管理员");
}
}
/**
* 测试人数系数计算(临时调试接口)
* 用于验证特定人数的系数计算是否正确
*/
@GetMapping("/testCoefficient")
public R<Object> testStudentCountCoefficient(@RequestParam int studentCount) {
BigDecimal coefficient = teacherAssessmentService.testStudentCountCoefficient(studentCount);
return R.ok("学生人数: " + studentCount + ", 计算系数: " + coefficient);
}
/**
* 查询班级学生违纪记录和奖励记录
*/
@SaCheckPermission("bzrkh:teacherAssessment:detail")
@GetMapping("/classStudentRecords")
public R<ClassStudentRecordsVo> getClassStudentRecords(@RequestParam Long classId) {
ClassStudentRecordsVo records = teacherAssessmentService.queryClassStudentRecords(classId);
return R.ok(records);
}
/**
* 提交考核请求对象
*/
public static class TeacherAssessmentSubmitRequest {
@NotNull(message = "计划ID不能为空")
private Long planId;
@NotNull(message = "班级ID不能为空")
private Long classId;
public Long getPlanId() {
return planId;
}
public void setPlanId(Long planId) {
this.planId = planId;
}
public Long getClassId() {
return classId;
}
public void setClassId(Long classId) {
this.classId = classId;
}
}
}
@@ -0,0 +1,91 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 班主任考核指标体系对象 bmzr_assessment_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_indicator")
public class BmzrAssessmentIndicator extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标类型
*/
private String indicatorType;
/**
* 父级指标ID
*/
private Long parentId;
/**
* 排序
*/
private Integer sortOrder;
/**
* 权重比例(0-1之间)
*/
private BigDecimal weightRatio;
/**
* 最高分值
*/
private BigDecimal maxScore;
/**
* 分值
*/
private BigDecimal score;
/**
* 允许自评(0=否 1=是)
*/
private String allowSelfEvaluation;
/**
* 允许上级评(0=否 1=是)
*/
private String allowSuperiorEvaluation;
/**
* 状态(0正常 1停用)
*/
private String status;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,56 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 班主任考核指标类型对象 bmzr_assessment_indicator_type
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_indicator_type")
public class BmzrAssessmentIndicatorType extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 删除标志(0代表存在 1代表删除)
*/
@TableLogic(value = "0", delval = "1")
private Integer deleted;
/**
* 指标类型名称
*/
private String indicatorTypeName;
/**
* 指标类型编码
*/
private String indicatorTypeCode;
/**
* 状态(0正常 1停用)
*/
private String status;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,95 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 班主任考核计划对象 bmzr_assessment_plan
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_plan")
public class BmzrAssessmentPlan extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 计划名称
*/
private String planName;
/**
* 计划编码
*/
private String planCode;
/**
* 考核方案ID
*/
private Long schemeId;
/**
* 学年
*/
private String academicYear;
/**
* 学期(1=上学期 2=下学期)
*/
private String semester;
/**
* 计划开始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date planStartTime;
/**
* 计划结束时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date planEndTime;
/**
* 数据提取开始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date dataExtractStartTime;
/**
* 数据提取结束时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date dataExtractEndTime;
/**
* 计划状态(0=禁用 1=启用)
*/
private String planStatus;
/**
* 计划描述
*/
private String description;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,82 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 班主任考核方案对象 bmzr_assessment_scheme
*
* @author system
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_scheme")
public class BmzrAssessmentScheme extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 删除标志
*/
@TableLogic(value = "0", delval = "1")
private Long deleted;
/**
* 方案名称
*/
private String schemeName;
/**
* 方案编码
*/
private String schemeCode;
/**
* 学年
*/
private String academicYear;
/**
* 学期
*/
private String semester;
/**
* 方案描述
*/
private String schemeDescription;
/**
* 是否需要自评
*/
private String selfEvaluationRequired;
/**
* 是否需要上级评
*/
private String superiorEvaluationRequired;
/**
* 状态
*/
private String status;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,71 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.math.BigDecimal;
/**
* 班主任考核方案指标关联对象 bmzr_assessment_scheme_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_scheme_indicator")
public class BmzrAssessmentSchemeIndicator extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 租户编号
*/
private String tenantId;
/**
* 考核方案ID
*/
private Long schemeId;
/**
* 考核指标ID
*/
private Long indicatorId;
/**
* 在方案中的权重比例
*/
private BigDecimal weightRatio;
/**
* 自定义最高分值
*/
private BigDecimal customMaxScore;
/**
* 排序
*/
private Integer sortOrder;
/**
* 备注
*/
private String remark;
/**
* 删除标志(0代表存在 1代表删除)
*/
@TableLogic
private Integer deleted;
}
@@ -0,0 +1,141 @@
package org.dromara.bzrkh.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 班主任考核得分对象 bmzr_assessment_score
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("bmzr_assessment_score")
public class BmzrAssessmentScore extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 考核计划ID
*/
private Long planId;
/**
* 考核方案ID
*/
private Long schemeId;
/**
* 考核指标ID
*/
private Long indicatorId;
/**
* 被评价用户ID
*/
private Long evaluatedUserId;
/**
* 被评价用户姓名
*/
private String evaluatedUserName;
/**
* 被评价用户部门ID
*/
private Long evaluatedDeptId;
/**
* 自评分数
*/
private Double selfScore;
/**
* 自评意见
*/
private String selfComment;
/**
* 自评提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date selfSubmitTime;
/**
* 上级评分数
*/
private Double superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
/**
* 上级评价人ID
*/
private Long superiorEvaluatorId;
/**
* 上级评提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date superiorSubmitTime;
/**
* 评价等级 dict_type = bmzr_evaluation_level
*/
private String evaluationLevel;
/**
* 审核状态(9=草稿 0=待审核 1=审核通过 2=审核不通过)
*/
private String auditStatus;
/**
* 最终得分
*/
private Double finalScore;
/**
* 提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date submitTime;
/**
* 班级ID
*/
private Long classId;
/**
* 自我总体评价
*/
private String selfOverallComment;
/**
* 上级总体评价
*/
private String superiorOverallComment;
/**
* 逻辑删除标志(0代表存在 1代表删除)
*/
@TableLogic
private Integer deleted;
}
@@ -0,0 +1,35 @@
package org.dromara.bzrkh.domain.bo;
import lombok.Data;
import java.math.BigDecimal;
/**
* 指标审核提交业务对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentApprovalIndicatorSubmitBo {
/**
* 主键ID
*/
private Long id;
/**
* 指标ID
*/
private Long indicatorId;
/**
* 上级评分数
*/
private BigDecimal superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
}
@@ -0,0 +1,56 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 班主任考核审核查询对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class AssessmentApprovalQueryBo extends BaseEntity {
/**
* 计划名称
*/
private String planName;
/**
* 考核方案名称
*/
private String schemeName;
/**
* 审核状态(0=待审核 1=审核通过 2=审核不通过)
*/
private String auditStatus;
/**
* 班级名称
*/
private String className;
/**
* 班主任姓名
*/
private String teacherName;
/**
* 被评价用户姓名
*/
private String evaluatedUserName;
/**
* 学年
*/
private String academicYear;
/**
* 学期
*/
private String semester;
}
@@ -0,0 +1,35 @@
package org.dromara.bzrkh.domain.bo;
import lombok.Data;
import java.math.BigDecimal;
/**
* 特色工作审核提交业务对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentApprovalSpecialWorkSubmitBo {
/**
* 主键ID
*/
private Long id;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 上级评分数
*/
private BigDecimal superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
}
@@ -0,0 +1,70 @@
package org.dromara.bzrkh.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import jakarta.validation.constraints.NotNull;
import java.util.List;
/**
* 考核审核提交业务对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class AssessmentApprovalSubmitBo extends BaseEntity {
/**
* 考核计划ID
*/
@NotNull(message = "考核计划ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long planId;
/**
* 班级ID
*/
@NotNull(message = "班级ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long classId;
/**
* 被评价用户ID
*/
@NotNull(message = "被评价用户ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long evaluatedUserId;
/**
* 班主任常规工作审核数据
*/
private List<AssessmentApprovalIndicatorSubmitBo> routineWorkApproval;
/**
* 班级管理实效审核数据
*/
private AssessmentApprovalIndicatorSubmitBo classDeductionApproval;
/**
* 特色工作审核数据
*/
private List<AssessmentApprovalSpecialWorkSubmitBo> specialWorkApproval;
/**
* 上级总体评价
*/
private String superiorOverallComment;
/**
* 审核状态 0=待审核 1=审核通过 2=审核不通过
*/
@NotNull(message = "审核状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String auditStatus;
/**
* 审核意见
*/
private String auditComment;
}
@@ -0,0 +1,60 @@
package org.dromara.bzrkh.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.bzrkh.domain.vo.AssessmentIndicatorScoreVo;
import org.dromara.bzrkh.domain.vo.SpecialWorkIndicatorVo;
import jakarta.validation.constraints.NotNull;
import java.util.List;
/**
* 考核提交业务对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class AssessmentSubmitBo extends BaseEntity {
/**
* 考核计划ID
*/
@NotNull(message = "考核计划ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long planId;
/**
* 班级ID
*/
@NotNull(message = "班级ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long classId;
/**
* 班主任常规工作指标评分
*/
private List<AssessmentIndicatorScoreVo> routineWorkScores;
/**
* 班级扣分
*/
private Double classDeduction;
/**
* 班级扣分意见
*/
private String classDeductionComment;
/**
* 特色工作指标评分
*/
private List<SpecialWorkIndicatorVo> specialWorkScores;
/**
* 总体评价
*/
private String overallComment;
}
@@ -0,0 +1,28 @@
package org.dromara.bzrkh.domain.bo;
import lombok.Data;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
/**
* 批量审核业务对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class BatchApprovalBo {
/**
* 审核ID列表
*/
@NotEmpty(message = "审核ID列表不能为空")
private List<Long> ids;
/**
* 拒绝原因(批量拒绝时必填)
*/
private String rejectReason;
}
@@ -0,0 +1,106 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicator;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
/**
* 班主任考核指标体系业务对象 bmzr_assessment_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BmzrAssessmentIndicator.class, reverseConvertGenerate = false)
public class BmzrAssessmentIndicatorBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 指标名称
*/
@NotBlank(message = "指标名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String indicatorName;
/**
* 指标编码
*/
@NotBlank(message = "指标编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String indicatorCode;
/**
* 指标类型
*/
@NotBlank(message = "指标类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String indicatorType;
/**
* 父级指标ID
*/
private Long parentId;
/**
* 排序
*/
@NotNull(message = "排序不能为空", groups = { AddGroup.class, EditGroup.class })
@Min(value = 1, message = "排序必须大于等于1")
private Integer sortOrder;
/**
* 权重比例(0-1之间)
*/
@NotNull(message = "权重比例不能为空", groups = { AddGroup.class, EditGroup.class })
@DecimalMin(value = "0", message = "权重比例必须大于等于0")
@DecimalMax(value = "1", message = "权重比例必须小于等于1")
private BigDecimal weightRatio;
/**
* 最高分值
*/
@NotNull(message = "最高分值不能为空", groups = { AddGroup.class, EditGroup.class })
@DecimalMin(value = "0", message = "最高分值必须大于等于0")
private BigDecimal maxScore;
/**
* 分值
*/
@NotNull(message = "分值不能为空", groups = { AddGroup.class, EditGroup.class })
@DecimalMin(value = "0", message = "分值必须大于等于0")
private BigDecimal score;
/**
* 允许自评(0=否 1=是)
*/
@NotBlank(message = "允许自评不能为空", groups = { AddGroup.class, EditGroup.class })
private String allowSelfEvaluation;
/**
* 允许上级评(0=否 1=是)
*/
@NotBlank(message = "允许上级评不能为空", groups = { AddGroup.class, EditGroup.class })
private String allowSuperiorEvaluation;
/**
* 状态(0正常 1停用)
*/
@NotBlank(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String status;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,59 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicatorType;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 班主任考核指标类型业务对象 bmzr_assessment_indicator_type
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BmzrAssessmentIndicatorType.class, reverseConvertGenerate = false)
public class BmzrAssessmentIndicatorTypeBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 删除标志
*/
private Integer deleted;
/**
* 指标类型名称
*/
@NotBlank(message = "指标类型名称不能为空", groups = { AddGroup.class, EditGroup.class })
@Size(max = 100, message = "指标类型名称长度不能超过100个字符")
private String indicatorTypeName;
/**
* 指标类型编码
*/
@NotBlank(message = "指标类型编码不能为空", groups = { AddGroup.class, EditGroup.class })
@Size(max = 50, message = "指标类型编码长度不能超过50个字符")
private String indicatorTypeCode;
/**
* 状态
*/
private String status;
/**
* 备注
*/
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}
@@ -0,0 +1,109 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.bzrkh.domain.BmzrAssessmentPlan;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
/**
* 班主任考核计划业务对象 bmzr_assessment_plan
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BmzrAssessmentPlan.class, reverseConvertGenerate = false)
public class BmzrAssessmentPlanBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 租户编号
*/
private String tenantId;
/**
* 计划名称
*/
@NotBlank(message = "计划名称不能为空", groups = { AddGroup.class, EditGroup.class })
@Size(max = 100, message = "计划名称长度不能超过100个字符")
private String planName;
/**
* 计划编码
*/
@NotBlank(message = "计划编码不能为空", groups = { AddGroup.class, EditGroup.class })
@Size(max = 50, message = "计划编码长度不能超过50个字符")
private String planCode;
/**
* 考核方案ID
*/
@NotNull(message = "考核方案ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long schemeId;
/**
* 学年
*/
@NotBlank(message = "学年不能为空", groups = { AddGroup.class, EditGroup.class })
@Size(max = 10, message = "学年长度不能超过10个字符")
private String academicYear;
/**
* 学期(1=上学期 2=下学期)
*/
@NotBlank(message = "学期不能为空", groups = { AddGroup.class, EditGroup.class })
@Pattern(regexp = "^[12]$", message = "学期只能是1或2")
private String semester;
/**
* 计划开始时间
*/
@NotNull(message = "计划开始时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date planStartTime;
/**
* 计划结束时间
*/
@NotNull(message = "计划结束时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date planEndTime;
/**
* 数据提取开始时间
*/
private Date dataExtractStartTime;
/**
* 数据提取结束时间
*/
private Date dataExtractEndTime;
/**
* 计划状态(0=禁用 1=启用)
*/
@Pattern(regexp = "^[01]$", message = "计划状态只能是0或1")
private String planStatus;
/**
* 计划描述
*/
@Size(max = 500, message = "计划描述长度不能超过500个字符")
private String description;
/**
* 备注
*/
@Size(max = 500, message = "备注长度不能超过500个字符")
private String remark;
}
@@ -0,0 +1,89 @@
package org.dromara.bzrkh.domain.bo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.bzrkh.domain.BmzrAssessmentScheme;
import java.util.Date;
/**
* 班主任考核方案业务对象 bmzr_assessment_scheme
*
* @author system
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BmzrAssessmentScheme.class, reverseConvertGenerate = false)
public class BmzrAssessmentSchemeBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 删除标志
*/
private Long deleted;
/**
* 方案名称
*/
@NotBlank(message = "方案名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String schemeName;
/**
* 方案编码
*/
@NotBlank(message = "方案编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String schemeCode;
/**
* 学年
*/
@NotBlank(message = "学年不能为空", groups = { AddGroup.class, EditGroup.class })
private String academicYear;
/**
* 学期
*/
@NotBlank(message = "学期不能为空", groups = { AddGroup.class, EditGroup.class })
private String semester;
/**
* 方案描述
*/
private String schemeDescription;
/**
* 是否需要自评
*/
@NotBlank(message = "是否需要自评不能为空", groups = { AddGroup.class, EditGroup.class })
private String selfEvaluationRequired;
/**
* 是否需要上级评
*/
@NotBlank(message = "是否需要上级评不能为空", groups = { AddGroup.class, EditGroup.class })
private String superiorEvaluationRequired;
/**
* 状态
*/
@NotBlank(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String status;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,77 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.bzrkh.domain.BmzrAssessmentSchemeIndicator;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
/**
* 班主任考核方案指标关联业务对象 bmzr_assessment_scheme_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BmzrAssessmentSchemeIndicator.class, reverseConvertGenerate = false)
public class BmzrAssessmentSchemeIndicatorBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 考核方案ID
*/
@NotNull(message = "考核方案ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long schemeId;
/**
* 考核指标ID
*/
@NotNull(message = "考核指标ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long indicatorId;
/**
* 在方案中的权重比例
*/
@DecimalMin(value = "0", message = "权重比例必须大于等于0")
@DecimalMax(value = "1", message = "权重比例必须小于等于1")
private BigDecimal weightRatio;
/**
* 自定义最高分值
*/
@DecimalMin(value = "0", message = "自定义最高分值必须大于等于0")
private BigDecimal customMaxScore;
/**
* 指标分值(用于前端传递,保存时映射到customMaxScore)
*/
@DecimalMin(value = "0", message = "指标分值必须大于等于0")
private BigDecimal score;
/**
* 排序
*/
@Min(value = 1, message = "排序必须大于等于1")
private Integer sortOrder;
/**
* 备注
*/
private String remark;
/**
* 指标名称(用于查询条件)
*/
private String indicatorName;
}
@@ -0,0 +1,46 @@
package org.dromara.bzrkh.domain.bo;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 班主任考核查询业务对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class TeacherAssessmentQueryBo extends BaseEntity {
/**
* 计划名称
*/
private String planName;
/**
* 班级ID
*/
private Long classId;
/**
* 班主任ID
*/
private Long teacherId;
/**
* 学年
*/
private String academicYear;
/**
* 学期(1=上学期 2=下学期)
*/
private String semester;
/**
* 计划状态(0=禁用 1=启用)
*/
private String planStatus;
}
@@ -0,0 +1,111 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 考核审核详情视图对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentApprovalDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 考核计划ID
*/
private Long planId;
/**
* 班级ID
*/
private Long classId;
/**
* 班级详细信息
*/
private ClassDetailVo classDetail;
/**
* 系数信息
*/
private CoefficientVo coefficient;
/**
* 班主任常规工作指标列表 - 包含自评和上级评分
*/
private List<AssessmentApprovalIndicatorVo> routineWorkIndicators;
/**
* 班级扣分指标 - 班级管理实效
*/
private AssessmentApprovalIndicatorVo classDeductionIndicator;
/**
* 特色工作指标列表
*/
private List<AssessmentApprovalSpecialWorkVo> specialWorkIndicators;
/**
* 自我总体评价
*/
private String selfOverallComment;
/**
* 上级总体评价
*/
private String superiorOverallComment;
/**
* 月考核得分
*/
private BigDecimal monthlyScore;
/**
* 审核状态
*/
private String auditStatus;
/**
* 提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date submitTime;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,82 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 审核指标视图对象 - 包含自评和上级评分
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentApprovalIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 指标ID
*/
private Long indicatorId;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标描述
*/
private String description;
/**
* 指标分值
*/
private BigDecimal score;
/**
* 最高分值
*/
private BigDecimal maxScore;
// 自评相关
/**
* 自评分数
*/
private BigDecimal selfScore;
/**
* 自评意见
*/
private String selfComment;
// 上级评相关
/**
* 上级评分数
*/
private BigDecimal superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
/**
* 审核状态
*/
private String auditStatus;
}
@@ -0,0 +1,67 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 特色工作审核视图对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentApprovalSpecialWorkVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标名称
*/
private String indicatorName;
// 自评相关
/**
* 自评分数(兼容字段)
*/
private BigDecimal score;
/**
* 自评分数
*/
private BigDecimal selfScore;
/**
* 自评意见
*/
private String selfComment;
// 上级评相关
/**
* 上级评分数
*/
private BigDecimal superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
/**
* 审核状态
*/
private String auditStatus;
}
@@ -0,0 +1,163 @@
package org.dromara.bzrkh.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 班主任考核审核视图对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
@ExcelIgnoreUnannotated
public class AssessmentApprovalVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 考核计划ID
*/
private Long planId;
/**
* 考核计划名称
*/
@ExcelProperty(value = "计划名称")
private String planName;
/**
* 考核计划编码
*/
@ExcelProperty(value = "计划编码")
private String planCode;
/**
* 考核方案ID
*/
private Long schemeId;
/**
* 考核方案名称
*/
@ExcelProperty(value = "考核方案")
private String schemeName;
/**
* 学年
*/
@ExcelProperty(value = "学年")
private String academicYear;
/**
* 学期
*/
@ExcelProperty(value = "学期")
private String semester;
/**
* 班级ID
*/
private Long classId;
/**
* 班级名称
*/
@ExcelProperty(value = "班级名称")
private String className;
/**
* 班主任用户ID
*/
private Long teacherId;
/**
* 班主任姓名
*/
@ExcelProperty(value = "班主任姓名")
private String teacherName;
/**
* 被评价用户ID
*/
private Long evaluatedUserId;
/**
* 被评价用户姓名
*/
@ExcelProperty(value = "被评价用户姓名")
private String evaluatedUserName;
/**
* 提交时间
*/
@ExcelProperty(value = "提交时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date submitTime;
/**
* 审核状态(0=待审核 1=审核通过 2=审核不通过)
*/
@ExcelProperty(value = "审核状态")
private String auditStatus;
/**
* 审核状态文本
*/
private String auditStatusText;
/**
* 自评总分
*/
@ExcelProperty(value = "自评总分")
private BigDecimal selfScore;
/**
* 上级评总分
*/
@ExcelProperty(value = "上级评总分")
private BigDecimal superiorScore;
/**
* 最终得分
*/
@ExcelProperty(value = "最终得分")
private BigDecimal finalScore;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 创建者
*/
private Long createBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 更新者
*/
private Long updateBy;
}
@@ -0,0 +1,80 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 考核详情视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
public class AssessmentDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 班级详细信息
*/
private ClassDetailVo classDetail;
/**
* 系数信息
*/
private CoefficientVo coefficient;
/**
* 班主任常规工作指标列表
*/
private List<AssessmentIndicatorScoreVo> routineWorkIndicators;
/**
* 班级扣分指标
*/
private AssessmentIndicatorScoreVo classDeductionIndicator;
/**
* 特色工作指标列表
*/
private List<SpecialWorkIndicatorVo> specialWorkIndicators;
/**
* 月考核得分
*/
private BigDecimal monthlyScore;
/**
* 总体评价
*/
private String overallComment;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,93 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 考核指标评分视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
public class AssessmentIndicatorScoreVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 指标ID
*/
private Long id;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标描述
*/
private String description;
/**
* 指标分值
*/
private Double score;
/**
* 自评分数
*/
private Double selfScore;
/**
* 自评意见
*/
private String selfComment;
/**
* 自我总体评价
*/
private String selfOverallComment;
/**
* 排序
*/
private Integer sortOrder;
/**
* 审核状态(0=待审核,1=审核通过,2=审核不通过)
*/
private String auditStatus;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,80 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 班主任考核自评数据详情视图对象
*
* 包含从bmzr_assessment_score表查询的完整自评数据
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentScoreDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 考核计划ID
*/
private Long planId;
/**
* 班级ID
*/
private Long classId;
/**
* 被评价用户ID
*/
private Long evaluatedUserId;
/**
* 被评价用户姓名
*/
private String evaluatedUserName;
/**
* 班主任常规工作自评数据列表
*/
private List<AssessmentScoreIndicatorVo> routineWorkScores;
/**
* 班级管理实效自评数据
*/
private AssessmentScoreIndicatorVo classDeductionScore;
/**
* 特色工作自评数据列表
*/
private List<AssessmentScoreSpecialWorkVo> specialWorkScores;
/**
* 自我总体评价
*/
private String selfOverallComment;
/**
* 自评提交时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date selfSubmitTime;
/**
* 审核状态
*/
private String auditStatus;
/**
* 是否有自评数据
*/
private Boolean hasAssessmentData;
}
@@ -0,0 +1,77 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 班主任考核自评指标视图对象
*
* 用于班主任常规工作和班级管理实效的自评数据
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentScoreIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 评分记录ID
*/
private Long id;
/**
* 指标ID
*/
private Long indicatorId;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标描述
*/
private String description;
/**
* 指标分值
*/
private BigDecimal score;
/**
* 最高分值
*/
private BigDecimal maxScore;
/**
* 自评分数
*/
private Double selfScore;
/**
* 自评意见
*/
private String selfComment;
/**
* 上级评分
*/
private Double superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
}
@@ -0,0 +1,66 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 班主任考核特色工作自评视图对象
*
* 用于特色工作的自评数据
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class AssessmentScoreSpecialWorkVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 评分记录ID
*/
private Long id;
/**
* 指标ID
*/
private Long indicatorId;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标名称
*/
private String indicatorName;
/**
* 自评分数
*/
private Double score;
/**
* 自评分数(兼容字段)
*/
private Double selfScore;
/**
* 自评意见
*/
private String selfComment;
/**
* 上级评分
*/
private Double superiorScore;
/**
* 上级评意见
*/
private String superiorComment;
}
@@ -0,0 +1,90 @@
package org.dromara.bzrkh.domain.vo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicatorType;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 班主任考核指标类型视图对象 bmzr_assessment_indicator_type
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BmzrAssessmentIndicatorType.class)
public class BmzrAssessmentIndicatorTypeVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 删除标志
*/
@ExcelProperty(value = "删除标志", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_item_delete")
private Integer deleted;
/**
* 指标类型名称
*/
@ExcelProperty(value = "指标类型名称")
private String indicatorTypeName;
/**
* 指标类型编码
*/
@ExcelProperty(value = "指标类型编码")
private String indicatorTypeCode;
/**
* 状态
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_item_enable")
private String status;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,157 @@
package org.dromara.bzrkh.domain.vo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicator;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicatorType;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
import java.util.List;
/**
* 班主任考核指标体系视图对象 bmzr_assessment_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BmzrAssessmentIndicator.class)
public class BmzrAssessmentIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 租户编号
*/
@ExcelProperty(value = "租户编号")
private String tenantId;
/**
* 指标名称
*/
@ExcelProperty(value = "指标名称")
private String indicatorName;
/**
* 指标编码
*/
@ExcelProperty(value = "指标编码")
private String indicatorCode;
/**
* 指标类型
*/
@ExcelProperty(value = "指标类型")
private String indicatorType;
/**
* 父级指标ID
*/
@ExcelProperty(value = "父级指标ID")
private Long parentId;
/**
* 排序
*/
@ExcelProperty(value = "排序")
private Integer sortOrder;
/**
* 权重比例(0-1之间)
*/
@ExcelProperty(value = "权重比例")
private BigDecimal weightRatio;
/**
* 最高分值
*/
@ExcelProperty(value = "最高分值")
private BigDecimal maxScore;
/**
* 分值
*/
@ExcelProperty(value = "分值")
private BigDecimal score;
/**
* 允许自评(0=否 1=是)
*/
@ExcelProperty(value = "允许自评", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_yes_no")
private String allowSelfEvaluation;
/**
* 允许上级评(0=否 1=是)
*/
@ExcelProperty(value = "允许上级评", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_yes_no")
private String allowSuperiorEvaluation;
/**
* 状态(0正常 1停用)
*/
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_item_enable")
private String status;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建部门
*/
private Long createDept;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 删除标志(0代表存在 1代表删除)
*/
private Integer deleted;
/**
* 子节点列表(用于树形结构)
*/
private List<BmzrAssessmentIndicatorVo> children;
}
@@ -0,0 +1,170 @@
package org.dromara.bzrkh.domain.vo;
import org.dromara.bzrkh.domain.BmzrAssessmentPlan;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 班主任考核计划视图对象 bmzr_assessment_plan
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BmzrAssessmentPlan.class)
public class BmzrAssessmentPlanVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 租户编号
*/
@ExcelProperty(value = "租户编号")
private String tenantId;
/**
* 计划名称
*/
@ExcelProperty(value = "计划名称")
private String planName;
/**
* 计划编码
*/
@ExcelProperty(value = "计划编码")
private String planCode;
/**
* 考核方案ID
*/
@ExcelProperty(value = "考核方案ID")
private Long schemeId;
/**
* 考核方案名称
*/
@ExcelProperty(value = "考核方案名称")
private String schemeName;
/**
* 学年
*/
@ExcelProperty(value = "学年")
private String academicYear;
/**
* 学期(1=上学期 2=下学期)
*/
@ExcelProperty(value = "学期", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_semester")
private String semester;
/**
* 计划开始时间
*/
@ExcelProperty(value = "计划开始时间")
private Date planStartTime;
/**
* 计划结束时间
*/
@ExcelProperty(value = "计划结束时间")
private Date planEndTime;
/**
* 数据提取开始时间
*/
@ExcelProperty(value = "数据提取开始时间")
private Date dataExtractStartTime;
/**
* 数据提取结束时间
*/
@ExcelProperty(value = "数据提取结束时间")
private Date dataExtractEndTime;
/**
* 计划状态(0=禁用 1=启用)
*/
@ExcelProperty(value = "计划状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_normal_disable")
private String planStatus;
/**
* 计划描述
*/
@ExcelProperty(value = "计划描述")
private String description;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建部门
*/
@ExcelProperty(value = "创建部门")
private Long createDept;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@ExcelProperty(value = "更新时间")
private Date updateTime;
/**
* 删除标志(0代表存在 1代表删除)
*/
private String deleted;
/**
* 审核状态(null=未提交,0=已提交待审核,1=审核通过,2=审核不通过)
*/
@ExcelProperty(value = "审核状态")
private String auditStatus;
/**
* 提交时间
*/
@ExcelProperty(value = "提交时间")
private Date submitTime;
/**
* 是否已提交(用于前端按钮状态控制)
*/
private Boolean submitted;
}
@@ -0,0 +1,126 @@
package org.dromara.bzrkh.domain.vo;
import org.dromara.bzrkh.domain.BmzrAssessmentSchemeIndicator;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
/**
* 班主任考核方案指标关联视图对象 bmzr_assessment_scheme_indicator
*
* @author ruoyi
* @date 2025-01-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BmzrAssessmentSchemeIndicator.class)
public class BmzrAssessmentSchemeIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 租户编号
*/
@ExcelProperty(value = "租户编号")
private String tenantId;
/**
* 考核方案ID
*/
@ExcelProperty(value = "考核方案ID")
private Long schemeId;
/**
* 考核指标ID
*/
@ExcelProperty(value = "考核指标ID")
private Long indicatorId;
/**
* 指标名称
*/
@ExcelProperty(value = "指标名称")
private String indicatorName;
/**
* 指标编码
*/
@ExcelProperty(value = "指标编码")
private String indicatorCode;
/**
* 在方案中的权重比例
*/
@ExcelProperty(value = "权重比例")
private BigDecimal weightRatio;
/**
* 自定义最高分值
*/
@ExcelProperty(value = "自定义最高分值")
private BigDecimal customMaxScore;
/**
* 分值
*/
@ExcelProperty(value = "分值")
private BigDecimal score;
/**
* 排序
*/
@ExcelProperty(value = "排序")
private Integer sortOrder;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建部门
*/
private Long createDept;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 删除标志(0代表存在 1代表删除)
*/
private Integer deleted;
}
@@ -0,0 +1,131 @@
package org.dromara.bzrkh.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.bzrkh.domain.BmzrAssessmentScheme;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 班主任考核方案视图对象 bmzr_assessment_scheme
*
* @author system
* @date 2025-01-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BmzrAssessmentScheme.class)
public class BmzrAssessmentSchemeVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 租户编号
*/
@ExcelProperty(value = "租户编号")
private String tenantId;
/**
* 删除标志
*/
@ExcelProperty(value = "删除标志")
private Long deleted;
/**
* 方案名称
*/
@ExcelProperty(value = "方案名称")
private String schemeName;
/**
* 方案编码
*/
@ExcelProperty(value = "方案编码")
private String schemeCode;
/**
* 学年
*/
@ExcelProperty(value = "学年")
private String academicYear;
/**
* 学期
*/
@ExcelProperty(value = "学期")
private String semester;
/**
* 方案描述
*/
@ExcelProperty(value = "方案描述")
private String schemeDescription;
/**
* 是否需要自评
*/
@ExcelProperty(value = "是否需要自评")
private String selfEvaluationRequired;
/**
* 是否需要上级评
*/
@ExcelProperty(value = "是否需要上级评")
private String superiorEvaluationRequired;
/**
* 状态
*/
@ExcelProperty(value = "状态")
private String status;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 创建部门
*/
@ExcelProperty(value = "创建部门")
private Long createDept;
/**
* 创建者
*/
@ExcelProperty(value = "创建者")
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 更新者
*/
@ExcelProperty(value = "更新者")
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "更新时间")
private Date updateTime;
}
@@ -0,0 +1,78 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 班级详细信息视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
public class ClassDetailVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 班级ID
*/
private Long id;
/**
* 学院名称
*/
private String collegeName;
/**
* 专业名称
*/
private String majorName;
/**
* 班级名称
*/
private String className;
/**
* 班级层次:1-中级工 2-高级工 3-预备技师 4-技师 5-中高职一体
*/
private String classType;
/**
* 班级总人数
*/
private Integer totalStudentCount;
/**
* 住校生人数
*/
private Integer boardingStudentCount;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,51 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 班级学生记录综合视图对象
*
* @author ruoyi
* @date 2025-01-03
*/
@Data
public class ClassStudentRecordsVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 班级ID
*/
private Long classId;
/**
* 班级名称
*/
private String className;
/**
* 学生违纪记录列表
*/
private List<StudentDisciplineRecordVo> disciplineRecords;
/**
* 学生奖励记录列表
*/
private List<StudentRewardRecordVo> rewardRecords;
/**
* 违纪记录总数
*/
private Integer disciplineCount;
/**
* 奖励记录总数
*/
private Integer rewardCount;
}
@@ -0,0 +1,64 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 系数信息视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
public class CoefficientVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 人数系数(K2)
*/
private BigDecimal studentCountCoefficient;
/**
* 住校生系数(K3)
*/
private BigDecimal boardingCoefficient;
/**
* 层次系数(K1)
*/
private BigDecimal levelCoefficient;
/**
* 总系数(K = K1 * (K2 + K3))
*/
private BigDecimal totalCoefficient;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,48 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 评价等级统计数据视图对象
*
* @author ruoyi
* @date 2025-01-30
*/
@Data
public class EvaluationLevelStatsVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 总班主任数量
*/
private Integer totalTeachers;
/**
* 分数排名列表
*/
private List<ScoreRankingVo> scoreRankings;
/**
* 评价等级规则
*/
private EvaluationLevelRules evaluationLevelRules;
@Data
public static class EvaluationLevelRules {
/**
* A等最大占比(如20%)
*/
private Double aLevelMaxPercentage;
/**
* 及格分数(如60分)
*/
private Double passScore;
}
}
@@ -0,0 +1,39 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 考核方案选项视图对象
*
* @author ruoyi
* @date 2025-01-28
*/
@Data
public class SchemeOptionVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 选项值
*/
private String value;
/**
* 选项标签
*/
private String label;
/**
* 方案ID
*/
private Long schemeId;
/**
* 方案编码
*/
private String schemeCode;
}
@@ -0,0 +1,39 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 分数排名视图对象
*
* @author ruoyi
* @date 2025-01-30
*/
@Data
public class ScoreRankingVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 考核得分
*/
private Double score;
/**
* 排名(从1开始)
*/
private Integer ranking;
/**
* 百分比排名(前X%)
*/
private Double percentage;
/**
* 被评价用户ID(可选,用于标识当前用户)
*/
private Long evaluatedUserId;
}
@@ -0,0 +1,63 @@
package org.dromara.bzrkh.domain.vo;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 特色工作指标视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
public class SpecialWorkIndicatorVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标名称
*/
private String indicatorName;
/**
* 分值
*/
private Double score;
/**
* 自评意见
*/
private String selfComment;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,157 @@
package org.dromara.bzrkh.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 学生违纪记录视图对象 xskh_discipline_record
*
* @author ruoyi
* @date 2025-01-03
*/
@Data
@ExcelIgnoreUnannotated
public class StudentDisciplineRecordVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 学生ID
*/
@ExcelProperty(value = "学生ID")
private Long studentId;
/**
* 学号
*/
@ExcelProperty(value = "学号")
private String studentNo;
/**
* 学生姓名
*/
@ExcelProperty(value = "学生姓名")
private String studentName;
/**
* 学院ID
*/
@ExcelProperty(value = "学院ID")
private Long collegeId;
/**
* 学院名称
*/
@ExcelProperty(value = "学院名称")
private String collegeName;
/**
* 专业ID
*/
@ExcelProperty(value = "专业ID")
private Long majorId;
/**
* 专业名称
*/
@ExcelProperty(value = "专业名称")
private String majorName;
/**
* 班级ID
*/
@ExcelProperty(value = "班级ID")
private Long classId;
/**
* 班级名称
*/
@ExcelProperty(value = "班级名称")
private String className;
/**
* 违纪处分类型ID
*/
@ExcelProperty(value = "违纪处分类型ID")
private Long disciplineTypeId;
/**
* 违纪处分类型名称
*/
@ExcelProperty(value = "违纪处分类型名称")
private String disciplineTypeName;
/**
* 违纪处分日期
*/
@ExcelProperty(value = "违纪处分日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date disciplineDate;
/**
* 违纪处分原因
*/
@ExcelProperty(value = "违纪处分原因")
private String disciplineReason;
/**
* 违纪处分内容
*/
@ExcelProperty(value = "违纪处分内容")
private String disciplineContent;
/**
* 扣分分值
*/
@ExcelProperty(value = "扣分分值")
private BigDecimal scoreDeduction;
/**
* 状态(1-生效 2-已撤销)
*/
@ExcelProperty(value = "状态")
private String status;
/**
* 附件OSS文件ID,多个用逗号分隔
*/
@ExcelProperty(value = "附件OSS文件ID")
private String attachmentOssIds;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,151 @@
package org.dromara.bzrkh.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 学生奖励记录视图对象 xskh_reward_record
*
* @author ruoyi
* @date 2025-01-03
*/
@Data
@ExcelIgnoreUnannotated
public class StudentRewardRecordVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 学生ID
*/
@ExcelProperty(value = "学生ID")
private Long studentId;
/**
* 学号
*/
@ExcelProperty(value = "学号")
private String studentNo;
/**
* 学生姓名
*/
@ExcelProperty(value = "学生姓名")
private String studentName;
/**
* 学院ID
*/
@ExcelProperty(value = "学院ID")
private Long collegeId;
/**
* 学院名称
*/
@ExcelProperty(value = "学院名称")
private String collegeName;
/**
* 专业ID
*/
@ExcelProperty(value = "专业ID")
private Long majorId;
/**
* 专业名称
*/
@ExcelProperty(value = "专业名称")
private String majorName;
/**
* 班级ID
*/
@ExcelProperty(value = "班级ID")
private Long classId;
/**
* 班级名称
*/
@ExcelProperty(value = "班级名称")
private String className;
/**
* 奖励类型ID
*/
@ExcelProperty(value = "奖励类型ID")
private Long rewardTypeId;
/**
* 奖励类型名称
*/
@ExcelProperty(value = "奖励类型名称")
private String rewardTypeName;
/**
* 奖励日期
*/
@ExcelProperty(value = "奖励日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date rewardDate;
/**
* 奖励内容
*/
@ExcelProperty(value = "奖励内容")
private String rewardContent;
/**
* 加分分值
*/
@ExcelProperty(value = "加分分值")
private BigDecimal scoreAddition;
/**
* 附件OSS文件ID,多个用逗号分隔
*/
@ExcelProperty(value = "附件OSS文件ID")
private String attachmentOssIds;
/**
* 状态(1-生效 2-撤销)
*/
@ExcelProperty(value = "状态")
private String status;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,117 @@
package org.dromara.bzrkh.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 班主任班级信息视图对象
*
* @author ruoyi
* @date 2025-01-27
*/
@Data
@ExcelIgnoreUnannotated
public class TeacherClassVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 班级ID
*/
@ExcelProperty(value = "班级ID")
private Long id;
/**
* 班级代码
*/
@ExcelProperty(value = "班级代码")
private String classCode;
/**
* 班级名称
*/
@ExcelProperty(value = "班级名称")
private String className;
/**
* 班主任ID
*/
@ExcelProperty(value = "班主任ID")
private Long classTeacherId;
/**
* 班主任姓名
*/
@ExcelProperty(value = "班主任姓名")
private String classTeacherName;
/**
* 年级
*/
@ExcelProperty(value = "年级")
private String grade;
/**
* 学院ID
*/
@ExcelProperty(value = "学院ID")
private Long collegeId;
/**
* 学院名称
*/
@ExcelProperty(value = "学院名称")
private String collegeName;
/**
* 专业ID
*/
@ExcelProperty(value = "专业ID")
private Long majorId;
/**
* 专业名称
*/
@ExcelProperty(value = "专业名称")
private String majorName;
/**
* 班级状态:1-正常,2-暂停,3-毕业,4-解散
*/
@ExcelProperty(value = "班级状态")
private String classStatus;
/**
* 当前学生人数
*/
@ExcelProperty(value = "当前学生人数")
private Integer currentStudentCount;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private java.util.Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private java.util.Date updateTime;
}
@@ -0,0 +1,153 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo;
import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
import org.dromara.bzrkh.domain.vo.ClassDetailVo;
import org.dromara.bzrkh.domain.vo.CoefficientVo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
import org.dromara.bzrkh.domain.BmzrAssessmentScore;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 班主任考核审核Mapper接口
*
* @author ruoyi
* @date 2025-01-28
*/
public interface AssessmentApprovalMapper extends BaseMapperPlus<BmzrAssessmentScore, AssessmentApprovalVo> {
/**
* 查询班主任考核审核列表
*
* @param bo 查询条件
* @return 班主任考核审核列表
*/
List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo);
/**
* 获取考核审核基本信息
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 审核基本信息
*/
AssessmentApprovalDetailVo getApprovalBasicInfo(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取班主任常规工作指标列表
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 常规工作指标列表
*/
List<AssessmentApprovalIndicatorVo> getRoutineWorkIndicators(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取班级扣分指标(班级管理实效)
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 班级扣分指标
*/
AssessmentApprovalIndicatorVo getClassDeductionIndicator(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取特色工作指标列表
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 特色工作指标列表
*/
List<AssessmentApprovalSpecialWorkVo> getSpecialWorkIndicators(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 更新上级评分和意见
*
* @param id 分数记录ID
* @param superiorScore 上级评分
* @param superiorComment 上级评意见
* @param approverUserId 审核人用户ID
* @return 更新条数
*/
int updateSuperiorScore(@Param("id") Long id,
@Param("superiorScore") String superiorScore,
@Param("superiorComment") String superiorComment,
@Param("approverUserId") Long approverUserId);
/**
* 更新审核状态和意见
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @param auditStatus 审核状态
* @param auditComment 审核意见
* @param superiorOverallComment 上级总体评价
* @param approverUserId 审核人用户ID
* @return 更新条数
*/
int updateAuditStatus(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId,
@Param("auditStatus") String auditStatus,
@Param("auditComment") String auditComment,
@Param("superiorOverallComment") String superiorOverallComment,
@Param("approverUserId") Long approverUserId);
/**
* 批量更新审核状态
*
* @param ids 审核ID列表
* @param auditStatus 审核状态
* @param auditComment 审核意见
* @param approverUserId 审核人用户ID
* @return 更新条数
*/
int batchUpdateAuditStatus(@Param("ids") List<Long> ids,
@Param("auditStatus") String auditStatus,
@Param("auditComment") String auditComment,
@Param("approverUserId") Long approverUserId);
/**
* 获取考核方案下拉选项
*
* @return 方案选项列表
*/
List<SchemeOptionVo> getSchemeOptions();
/**
* 删除异常的审批记录(管理员专用)
* 逻辑删除指定计划下指定用户的所有评分记录
*
* @param planId 计划ID
* @param evaluatedUserId 被评价用户ID
* @return 删除记录数
*/
int deleteAbnormalAssessmentRecord(@Param("planId") Long planId, @Param("evaluatedUserId") Long evaluatedUserId);
/**
* 根据计划ID查询所有审批数据
*
* @param planId 计划ID
* @return 审批数据列表
*/
List<AssessmentApprovalVo> selectApprovalListByPlan(@Param("planId") Long planId);
}
@@ -0,0 +1,81 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.vo.AssessmentScoreDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreIndicatorVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreSpecialWorkVo;
import org.dromara.bzrkh.domain.BmzrAssessmentScore;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 班主任考核评分数据Mapper接口
*
* 提供统一的自评数据查询,确保数据一致性
*
* @author ruoyi
* @date 2025-01-28
*/
public interface AssessmentScoreMapper extends BaseMapperPlus<BmzrAssessmentScore, BmzrAssessmentScore> {
/**
* 获取自评数据基本信息
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 自评数据基本信息
*/
AssessmentScoreDetailVo getAssessmentScoreBasicInfo(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取班主任常规工作自评数据
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 常规工作自评数据列表
*/
List<AssessmentScoreIndicatorVo> getRoutineWorkScores(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取班级管理实效自评数据
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 班级管理实效自评数据
*/
AssessmentScoreIndicatorVo getClassDeductionScore(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 获取特色工作自评数据
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 特色工作自评数据列表
*/
List<AssessmentScoreSpecialWorkVo> getSpecialWorkScores(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
/**
* 检查是否存在自评数据
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 记录数量
*/
int countAssessmentScore(@Param("planId") Long planId,
@Param("classId") Long classId,
@Param("evaluatedUserId") Long evaluatedUserId);
}
@@ -0,0 +1,15 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicator;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 班主任考核指标体系Mapper接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface BmzrAssessmentIndicatorMapper extends BaseMapperPlus<BmzrAssessmentIndicator, BmzrAssessmentIndicatorVo> {
}
@@ -0,0 +1,15 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicatorType;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorTypeVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 班主任考核指标类型Mapper接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface BmzrAssessmentIndicatorTypeMapper extends BaseMapperPlus<BmzrAssessmentIndicatorType, BmzrAssessmentIndicatorTypeVo> {
}
@@ -0,0 +1,39 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentPlan;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Collection;
/**
* 班主任考核计划Mapper接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface BmzrAssessmentPlanMapper extends BaseMapperPlus<BmzrAssessmentPlan, BmzrAssessmentPlanVo> {
/**
* 查询班主任考核计划列表(包含方案名称)
*/
List<BmzrAssessmentPlanVo> selectAssessmentPlanListWithScheme(BmzrAssessmentPlanBo bo);
/**
* 分页查询班主任考核计划列表(包含方案名称)
*/
IPage<BmzrAssessmentPlanVo> selectAssessmentPlanPageWithScheme(Page<BmzrAssessmentPlanVo> page, BmzrAssessmentPlanBo bo);
/**
* 根据考核计划ID批量逻辑删除关联的考核得分数据
* @param planIds 考核计划ID集合
* @return 影响行数
*/
int deleteAssessmentScoresByPlanIds(@Param("planIds") Collection<Long> planIds);
}
@@ -0,0 +1,27 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentSchemeIndicator;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeIndicatorBo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 班主任考核方案指标关联Mapper接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface BmzrAssessmentSchemeIndicatorMapper extends BaseMapperPlus<BmzrAssessmentSchemeIndicator, BmzrAssessmentSchemeIndicatorVo> {
/**
* 查询班主任考核方案指标关联列表(使用自定义SQL,包含score字段映射)
*
* @param bo 查询条件
* @return 班主任考核方案指标关联列表
*/
List<BmzrAssessmentSchemeIndicatorVo> queryList(@Param("bo") BmzrAssessmentSchemeIndicatorBo bo);
}
@@ -0,0 +1,15 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentScheme;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 班主任考核方案Mapper接口
*
* @author system
* @date 2025-01-08
*/
public interface BmzrAssessmentSchemeMapper extends BaseMapperPlus<BmzrAssessmentScheme, BmzrAssessmentSchemeVo> {
}
@@ -0,0 +1,14 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.BmzrAssessmentScore;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 班主任考核得分Mapper接口
*
* @author ruoyi
* @date 2025-01-27
*/
public interface BmzrAssessmentScoreMapper extends BaseMapperPlus<BmzrAssessmentScore, BmzrAssessmentScore> {
}
@@ -0,0 +1,154 @@
package org.dromara.bzrkh.mapper;
import org.dromara.bzrkh.domain.vo.TeacherClassVo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.vo.ClassDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentIndicatorScoreVo;
import org.dromara.bzrkh.domain.vo.SpecialWorkIndicatorVo;
import org.dromara.bzrkh.domain.vo.StudentDisciplineRecordVo;
import org.dromara.bzrkh.domain.vo.StudentRewardRecordVo;
import org.dromara.bzrkh.domain.bo.TeacherAssessmentQueryBo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
/**
* 班主任考核管理Mapper接口
*
* @author ruoyi
* @date 2025-01-27
*/
public interface TeacherAssessmentMapper extends BaseMapperPlus<Object, Object> {
/**
* 查询班主任管理的班级列表
*
* @param teacherId 班主任ID
* @return 班级列表
*/
List<TeacherClassVo> selectTeacherClassList(@Param("teacherId") Long teacherId);
/**
* 查询班主任考核计划列表
*
* @param bo 查询条件
* @return 考核计划列表
*/
List<BmzrAssessmentPlanVo> selectTeacherAssessmentPlanList(TeacherAssessmentQueryBo bo);
/**
* 查询班级详细信息
*
* @param classId 班级ID
* @return 班级详细信息
*/
ClassDetailVo selectClassDetail(@Param("classId") Long classId);
/**
* 查询班主任常规工作指标列表
*
* @param planId 计划ID
* @return 指标列表
*/
List<AssessmentIndicatorScoreVo> selectRoutineWorkIndicators(@Param("planId") Long planId);
/**
* 查询班级扣分指标
*
* @return 班级扣分指标
*/
AssessmentIndicatorScoreVo selectClassDeductionIndicator();
/**
* 查询特色工作指标列表
*
* @return 特色工作指标列表
*/
List<SpecialWorkIndicatorVo> selectSpecialWorkIndicators();
/**
* 查询已保存的评分数据(草稿状态)
*
* @param planId 计划ID
* @param teacherId 班主任ID
* @param classId 班级ID
* @return 评分数据列表
*/
List<AssessmentIndicatorScoreVo> selectSavedAssessmentScores(@Param("planId") Long planId, @Param("teacherId") Long teacherId, @Param("classId") Long classId);
/**
* 查询已提交的评分数据(待审核状态,用于撤销功能)
*
* @param planId 计划ID
* @param teacherId 班主任ID
* @param classId 班级ID
* @return 评分数据列表
*/
List<AssessmentIndicatorScoreVo> selectSubmittedAssessmentScores(@Param("planId") Long planId, @Param("teacherId") Long teacherId, @Param("classId") Long classId);
/**
* 根据计划ID查询方案ID
*
* @param planId 计划ID
* @return 方案ID
*/
Long selectSchemeIdByPlanId(@Param("planId") Long planId);
/**
* 根据指标编码查询指标ID
*
* @param indicatorCode 指标编码
* @return 指标ID
*/
Long selectIndicatorIdByCode(@Param("indicatorCode") String indicatorCode);
/**
* 逻辑删除指定计划、班级和教师的评分数据
*
* @param planId 计划ID
* @param teacherId 教师ID
* @param classId 班级ID
*/
void deleteAssessmentScoresByPlanAndTeacher(@Param("planId") Long planId, @Param("teacherId") Long teacherId, @Param("classId") Long classId);
/**
* 更新评分数据的备注
*
* @param planId 计划ID
* @param indicatorId 指标ID
* @param teacherId 教师ID
* @param remark 备注
*/
void updateAssessmentScoreRemark(@Param("planId") Long planId,
@Param("indicatorId") Long indicatorId,
@Param("teacherId") Long teacherId,
@Param("remark") String remark);
/**
* 根据班级ID查询班级名称
*
* @param classId 班级ID
* @return 班级名称
*/
String selectClassNameById(@Param("classId") Long classId);
/**
* 根据班级ID查询学生违纪记录
*
* @param classId 班级ID
* @return 学生违纪记录列表
*/
List<StudentDisciplineRecordVo> selectStudentDisciplineRecordsByClassId(@Param("classId") Long classId);
/**
* 根据班级ID查询学生奖励记录
*
* @param classId 班级ID
* @return 学生奖励记录列表
*/
List<StudentRewardRecordVo> selectStudentRewardRecordsByClassId(@Param("classId") Long classId);
}
@@ -0,0 +1,101 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
import org.dromara.bzrkh.domain.vo.EvaluationLevelStatsVo;
import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.List;
/**
* 班主任考核审核Service接口
*
* @author ruoyi
* @date 2025-01-28
*/
public interface IAssessmentApprovalService {
/**
* 查询班主任考核审核列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 班主任考核审核列表
*/
TableDataInfo<AssessmentApprovalVo> queryPageList(AssessmentApprovalQueryBo bo, PageQuery pageQuery);
/**
* 查询班主任考核审核列表
*
* @param bo 查询条件
* @return 班主任考核审核列表
*/
List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo);
/**
* 获取考核审核详情
*
* @param planId 计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 审核详情
*/
AssessmentApprovalDetailVo getApprovalDetail(Long planId, Long classId, Long evaluatedUserId);
/**
* 提交考核审核
*
* @param bo 审核数据
* @param approverUserId 审核人用户ID
* @return 是否成功
*/
boolean submitApproval(AssessmentApprovalSubmitBo bo, Long approverUserId);
/**
* 批量审核通过
*
* @param ids 审核ID列表
* @param approverUserId 审核人用户ID
* @return 是否成功
*/
boolean batchApprove(List<Long> ids, Long approverUserId);
/**
* 批量审核拒绝
*
* @param ids 审核ID列表
* @param rejectReason 拒绝原因
* @param approverUserId 审核人用户ID
* @return 是否成功
*/
boolean batchReject(List<Long> ids, String rejectReason, Long approverUserId);
/**
* 删除异常的审批记录(管理员专用)
* 用于清理审批列表中显示但实际已被删除的异常数据
*
* @param planId 计划ID
* @param evaluatedUserId 被评价用户ID
* @return 是否成功
*/
boolean deleteAbnormalRecord(Long planId, Long evaluatedUserId);
/**
* 获取考核方案下拉选项
*
* @return 方案选项列表
*/
List<SchemeOptionVo> getSchemeOptions();
/**
* 获取评价等级统计数据
*
* @param planId 计划ID
* @return 评价等级统计数据
*/
EvaluationLevelStatsVo getEvaluationLevelStats(Long planId);
}
@@ -0,0 +1,38 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.AssessmentScoreDetailVo;
/**
* 班主任考核评分数据Service接口
*
* 提供统一的自评数据查询服务,确保提交API和审批API使用相同的数据源
*
* @author ruoyi
* @date 2025-01-28
*/
public interface IAssessmentScoreService {
/**
* 获取班主任考核的完整自评数据
*
* 从bmzr_assessment_score表中查询指定计划、班级的所有自评数据,
* 包括常规工作、班级管理实效、特色工作的自评分数和自评意见,
* 以及自我总体评价
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID(班主任用户ID)
* @return 完整的自评数据详情
*/
AssessmentScoreDetailVo getAssessmentScoreDetail(Long planId, Long classId, Long evaluatedUserId);
/**
* 检查指定计划和班级是否已有自评数据
*
* @param planId 考核计划ID
* @param classId 班级ID
* @param evaluatedUserId 被评价用户ID
* @return 是否存在自评数据
*/
boolean hasAssessmentScore(Long planId, Long classId, Long evaluatedUserId);
}
@@ -0,0 +1,53 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 班主任考核指标体系Service接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface IBmzrAssessmentIndicatorService {
/**
* 查询班主任考核指标体系
*/
BmzrAssessmentIndicatorVo queryById(Long id);
/**
* 查询班主任考核指标体系列表
*/
TableDataInfo<BmzrAssessmentIndicatorVo> queryPageList(BmzrAssessmentIndicatorBo bo, PageQuery pageQuery);
/**
* 查询班主任考核指标体系列表
*/
List<BmzrAssessmentIndicatorVo> queryList(BmzrAssessmentIndicatorBo bo);
/**
* 查询班主任考核指标体系树形列表
*/
List<BmzrAssessmentIndicatorVo> queryTreeList(BmzrAssessmentIndicatorBo bo);
/**
* 新增班主任考核指标体系
*/
Boolean insertByBo(BmzrAssessmentIndicatorBo bo);
/**
* 修改班主任考核指标体系
*/
Boolean updateByBo(BmzrAssessmentIndicatorBo bo);
/**
* 校验并批量删除班主任考核指标体系信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
@@ -0,0 +1,76 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorTypeVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorTypeBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 班主任考核指标类型Service接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface IBmzrAssessmentIndicatorTypeService {
/**
* 查询班主任考核指标类型
*
* @param id 主键
* @return 班主任考核指标类型
*/
BmzrAssessmentIndicatorTypeVo queryById(Long id);
/**
* 分页查询班主任考核指标类型列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 班主任考核指标类型分页列表
*/
TableDataInfo<BmzrAssessmentIndicatorTypeVo> queryPageList(BmzrAssessmentIndicatorTypeBo bo, PageQuery pageQuery);
/**
* 查询符合条件的班主任考核指标类型列表
*
* @param bo 查询条件
* @return 班主任考核指标类型列表
*/
List<BmzrAssessmentIndicatorTypeVo> queryList(BmzrAssessmentIndicatorTypeBo bo);
/**
* 查询所有班主任考核指标类型列表,包括已逻辑删除的
*
* @param bo 查询条件
* @return 包含已删除记录的班主任考核指标类型列表
*/
List<BmzrAssessmentIndicatorTypeVo> queryListWithDeleted(BmzrAssessmentIndicatorTypeBo bo);
/**
* 新增班主任考核指标类型
*
* @param bo 班主任考核指标类型
* @return 是否新增成功
*/
Boolean insertByBo(BmzrAssessmentIndicatorTypeBo bo);
/**
* 修改班主任考核指标类型
*
* @param bo 班主任考核指标类型
* @return 是否修改成功
*/
Boolean updateByBo(BmzrAssessmentIndicatorTypeBo bo);
/**
* 校验并批量删除班主任考核指标类型信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
@@ -0,0 +1,58 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 班主任考核计划Service接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface IBmzrAssessmentPlanService {
/**
* 查询班主任考核计划
*/
BmzrAssessmentPlanVo queryById(Long id);
/**
* 查询班主任考核计划列表
*/
TableDataInfo<BmzrAssessmentPlanVo> queryPageList(BmzrAssessmentPlanBo bo, PageQuery pageQuery);
/**
* 查询班主任考核计划列表
*/
List<BmzrAssessmentPlanVo> queryList(BmzrAssessmentPlanBo bo);
/**
* 新增班主任考核计划
*/
Boolean insertByBo(BmzrAssessmentPlanBo bo);
/**
* 修改班主任考核计划
*/
Boolean updateByBo(BmzrAssessmentPlanBo bo);
/**
* 校验并批量删除班主任考核计划信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 修改考核计划状态
*/
Boolean updatePlanStatus(Long id, String planStatus);
/**
* 获取可用的考核方案选项
*/
List<BmzrAssessmentPlanVo> getAvailableSchemes();
}
@@ -0,0 +1,85 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeIndicatorBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 班主任考核方案指标关联Service接口
*
* @author ruoyi
* @date 2025-01-08
*/
public interface IBmzrAssessmentSchemeIndicatorService {
/**
* 查询班主任考核方案指标关联
*
* @param id 主键
* @return 班主任考核方案指标关联
*/
BmzrAssessmentSchemeIndicatorVo queryById(Long id);
/**
* 查询班主任考核方案指标关联列表
*
* @param bo 查询条件
* @return 班主任考核方案指标关联集合
*/
List<BmzrAssessmentSchemeIndicatorVo> queryList(BmzrAssessmentSchemeIndicatorBo bo);
/**
* 分页查询班主任考核方案指标关联列表
*
* @param bo 查询条件
* @param pageQuery 分页查询条件
* @return 班主任考核方案指标关联分页列表
*/
TableDataInfo<BmzrAssessmentSchemeIndicatorVo> queryPageList(BmzrAssessmentSchemeIndicatorBo bo, PageQuery pageQuery);
/**
* 新增班主任考核方案指标关联
*
* @param bo 班主任考核方案指标关联
* @return 新增结果
*/
Boolean insertByBo(BmzrAssessmentSchemeIndicatorBo bo);
/**
* 修改班主任考核方案指标关联
*
* @param bo 班主任考核方案指标关联
* @return 修改结果
*/
Boolean updateByBo(BmzrAssessmentSchemeIndicatorBo bo);
/**
* 校验并批量删除班主任考核方案指标关联信息
*
* @param ids 主键集合
* @param isValid 是否校验,true-删除前校验,false-不校验
* @return 删除结果
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 根据方案ID查询指标关联列表
*
* @param schemeId 方案ID
* @return 指标关联列表
*/
List<BmzrAssessmentSchemeIndicatorVo> queryBySchemeId(Long schemeId);
/**
* 批量保存方案指标关联
*
* @param schemeId 方案ID
* @param indicatorList 指标列表
* @return 保存结果
*/
Boolean batchSaveSchemeIndicators(Long schemeId, List<BmzrAssessmentSchemeIndicatorBo> indicatorList);
}
@@ -0,0 +1,48 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 班主任考核方案Service接口
*
* @author system
* @date 2025-01-08
*/
public interface IBmzrAssessmentSchemeService {
/**
* 查询班主任考核方案
*/
BmzrAssessmentSchemeVo queryById(Long id);
/**
* 查询班主任考核方案列表
*/
TableDataInfo<BmzrAssessmentSchemeVo> queryPageList(BmzrAssessmentSchemeBo bo, PageQuery pageQuery);
/**
* 查询班主任考核方案列表
*/
List<BmzrAssessmentSchemeVo> queryList(BmzrAssessmentSchemeBo bo);
/**
* 新增班主任考核方案
*/
Boolean insertByBo(BmzrAssessmentSchemeBo bo);
/**
* 修改班主任考核方案
*/
Boolean updateByBo(BmzrAssessmentSchemeBo bo);
/**
* 校验并批量删除班主任考核方案信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
@@ -0,0 +1,105 @@
package org.dromara.bzrkh.service;
import org.dromara.bzrkh.domain.vo.TeacherClassVo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.vo.AssessmentDetailVo;
import org.dromara.bzrkh.domain.vo.ClassStudentRecordsVo;
import org.dromara.bzrkh.domain.bo.TeacherAssessmentQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentSubmitBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.math.BigDecimal;
import java.util.List;
/**
* 班主任考核管理Service接口
*
* @author ruoyi
* @date 2025-01-27
*/
public interface ITeacherAssessmentService {
/**
* 查询班主任管理的班级列表
*
* @param teacherId 班主任ID
* @return 班级列表
*/
List<TeacherClassVo> queryTeacherClassList(Long teacherId);
/**
* 查询班主任考核计划列表(分页)
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 考核计划列表
*/
TableDataInfo<BmzrAssessmentPlanVo> queryTeacherAssessmentPlanPageList(TeacherAssessmentQueryBo bo, PageQuery pageQuery);
/**
* 提交考核
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 是否成功
*/
boolean submitAssessment(Long planId, Long classId, Long teacherId);
/**
* 查看考核详情
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 考核详情
*/
Object getAssessmentDetail(Long planId, Long classId, Long teacherId);
/**
* 获取考核提交详情数据
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 考核提交详情
*/
AssessmentDetailVo getAssessmentSubmitDetail(Long planId, Long classId, Long teacherId);
/**
* 提交考核评分数据
*
* @param bo 考核提交数据
* @param teacherId 班主任ID
* @return 是否成功
*/
boolean submitAssessmentScore(AssessmentSubmitBo bo, Long teacherId);
/**
* 撤销考核提交
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 是否成功
*/
boolean withdrawAssessment(Long planId, Long classId, Long teacherId);
/**
* 测试人数系数计算(临时调试方法)
* 用于验证特定人数的系数计算是否正确
*
* @param studentCount 学生人数
* @return 计算出的系数
*/
BigDecimal testStudentCountCoefficient(int studentCount);
/**
* 查询班级学生违纪记录和奖励记录
*
* @param classId 班级ID
* @return 班级学生记录
*/
ClassStudentRecordsVo queryClassStudentRecords(Long classId);
}
@@ -0,0 +1,543 @@
package org.dromara.bzrkh.service.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo;
import org.dromara.bzrkh.domain.vo.AssessmentDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo;
import org.dromara.bzrkh.domain.vo.EvaluationLevelStatsVo;
import org.dromara.bzrkh.domain.vo.ScoreRankingVo;
import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
import org.dromara.bzrkh.domain.vo.ClassDetailVo;
import org.dromara.bzrkh.domain.vo.CoefficientVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreIndicatorVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreSpecialWorkVo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalIndicatorSubmitBo;
import org.dromara.bzrkh.domain.bo.AssessmentApprovalSpecialWorkSubmitBo;
import org.dromara.bzrkh.mapper.AssessmentApprovalMapper;
import org.dromara.bzrkh.service.IAssessmentApprovalService;
import org.dromara.bzrkh.service.ITeacherAssessmentService;
import org.dromara.bzrkh.service.IAssessmentScoreService;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Date;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 班主任考核审核Service业务层处理
*
* @author ruoyi
* @date 2025-01-28
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class AssessmentApprovalServiceImpl implements IAssessmentApprovalService {
private final AssessmentApprovalMapper assessmentApprovalMapper;
private final ITeacherAssessmentService teacherAssessmentService;
private final IAssessmentScoreService assessmentScoreService;
@Override
public TableDataInfo<AssessmentApprovalVo> queryPageList(AssessmentApprovalQueryBo bo, PageQuery pageQuery) {
Page<AssessmentApprovalVo> page = pageQuery.build();
List<AssessmentApprovalVo> list = assessmentApprovalMapper.queryList(bo);
// 手动分页处理
int total = list.size();
int start = (int) ((page.getCurrent() - 1) * page.getSize());
int end = Math.min(start + (int) page.getSize(), total);
List<AssessmentApprovalVo> pageList = list.subList(start, end);
page.setRecords(pageList);
page.setTotal(total);
return TableDataInfo.build(page);
}
@Override
public List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo) {
return assessmentApprovalMapper.queryList(bo);
}
@Override
public AssessmentApprovalDetailVo getApprovalDetail(Long planId, Long classId, Long evaluatedUserId) {
log.info("获取审批详情 - planId: {}, classId: {}, evaluatedUserId: {}", planId, classId, evaluatedUserId);
// 1. 获取基本信息
AssessmentApprovalDetailVo detail = assessmentApprovalMapper.getApprovalBasicInfo(planId, classId, evaluatedUserId);
if (detail == null) {
throw new RuntimeException("未找到考核审核数据");
}
// 2. 获取班级详细信息和系数信息(复用现有service)
try {
// 使用现有的获取考核详情方法来获取班级信息和系数
var assessmentDetail = teacherAssessmentService.getAssessmentSubmitDetail(planId, classId, evaluatedUserId);
ClassDetailVo classDetail = new ClassDetailVo();
classDetail.setId(assessmentDetail.getClassDetail().getId());
classDetail.setClassName(assessmentDetail.getClassDetail().getClassName());
classDetail.setCollegeName(assessmentDetail.getClassDetail().getCollegeName());
classDetail.setMajorName(assessmentDetail.getClassDetail().getMajorName());
classDetail.setClassType(assessmentDetail.getClassDetail().getClassType());
classDetail.setTotalStudentCount(assessmentDetail.getClassDetail().getTotalStudentCount());
classDetail.setBoardingStudentCount(assessmentDetail.getClassDetail().getBoardingStudentCount());
detail.setClassDetail(classDetail);
CoefficientVo coefficient = new CoefficientVo();
coefficient.setTotalCoefficient(assessmentDetail.getCoefficient().getTotalCoefficient());
coefficient.setLevelCoefficient(assessmentDetail.getCoefficient().getLevelCoefficient());
coefficient.setStudentCountCoefficient(assessmentDetail.getCoefficient().getStudentCountCoefficient());
coefficient.setBoardingCoefficient(assessmentDetail.getCoefficient().getBoardingCoefficient());
detail.setCoefficient(coefficient);
} catch (Exception e) {
log.warn("获取班级信息和系数信息失败: {}", e.getMessage());
// 如果获取失败,使用默认值
detail.setClassDetail(new ClassDetailVo());
detail.setCoefficient(new CoefficientVo());
}
// 3. 使用统一的自评数据服务获取完整的自评数据
AssessmentScoreDetailVo scoreDetail = assessmentScoreService.getAssessmentScoreDetail(planId, classId, evaluatedUserId);
if (scoreDetail != null && scoreDetail.getHasAssessmentData()) {
log.info("通过统一服务获取到自评数据 - 自我总体评价: {}", scoreDetail.getSelfOverallComment());
// 3.1 设置自我总体评价
detail.setSelfOverallComment(scoreDetail.getSelfOverallComment());
// 3.2 转换班主任常规工作自评数据
List<AssessmentApprovalIndicatorVo> routineWorkIndicators = convertRoutineWorkScores(scoreDetail.getRoutineWorkScores());
detail.setRoutineWorkIndicators(routineWorkIndicators);
log.info("转换常规工作自评数据 - 数量: {}", routineWorkIndicators.size());
// 3.3 转换班级管理实效自评数据
AssessmentApprovalIndicatorVo classDeductionIndicator = convertClassDeductionScore(scoreDetail.getClassDeductionScore());
detail.setClassDeductionIndicator(classDeductionIndicator);
if (classDeductionIndicator != null) {
log.info("转换班级管理实效自评数据 - 自评分数: {}", classDeductionIndicator.getSelfScore());
}
// 3.4 转换特色工作自评数据
List<AssessmentApprovalSpecialWorkVo> specialWorkIndicators = convertSpecialWorkScores(scoreDetail.getSpecialWorkScores());
detail.setSpecialWorkIndicators(specialWorkIndicators);
log.info("转换特色工作自评数据 - 数量: {}", specialWorkIndicators.size());
} else {
log.warn("未获取到自评数据,使用原有查询方式作为备用");
// 备用方案:使用原有的查询方式
List<AssessmentApprovalIndicatorVo> routineWorkIndicators =
assessmentApprovalMapper.getRoutineWorkIndicators(planId, classId, evaluatedUserId);
detail.setRoutineWorkIndicators(routineWorkIndicators);
AssessmentApprovalIndicatorVo classDeductionIndicator =
assessmentApprovalMapper.getClassDeductionIndicator(planId, classId, evaluatedUserId);
detail.setClassDeductionIndicator(classDeductionIndicator);
List<AssessmentApprovalSpecialWorkVo> specialWorkIndicators =
assessmentApprovalMapper.getSpecialWorkIndicators(planId, classId, evaluatedUserId);
detail.setSpecialWorkIndicators(specialWorkIndicators);
}
// 4. 验证自评数据完整性
validateSelfAssessmentData(detail);
return detail;
}
/**
* 转换班主任常规工作自评数据
*/
private List<AssessmentApprovalIndicatorVo> convertRoutineWorkScores(List<AssessmentScoreIndicatorVo> routineWorkScores) {
if (routineWorkScores == null) {
return new ArrayList<>();
}
List<AssessmentApprovalIndicatorVo> result = new ArrayList<>();
for (AssessmentScoreIndicatorVo score : routineWorkScores) {
AssessmentApprovalIndicatorVo indicator = new AssessmentApprovalIndicatorVo();
indicator.setId(score.getId());
indicator.setIndicatorId(score.getIndicatorId());
indicator.setIndicatorName(score.getIndicatorName());
indicator.setIndicatorCode(score.getIndicatorCode());
indicator.setDescription(score.getDescription());
indicator.setScore(score.getScore());
indicator.setMaxScore(score.getMaxScore());
// 类型转换:Double -> BigDecimal
indicator.setSelfScore(score.getSelfScore() != null ? BigDecimal.valueOf(score.getSelfScore()) : null);
indicator.setSelfComment(score.getSelfComment());
indicator.setSuperiorScore(score.getSuperiorScore() != null ? BigDecimal.valueOf(score.getSuperiorScore()) : null);
indicator.setSuperiorComment(score.getSuperiorComment());
result.add(indicator);
}
return result;
}
/**
* 转换班级管理实效自评数据
*/
private AssessmentApprovalIndicatorVo convertClassDeductionScore(AssessmentScoreIndicatorVo classDeductionScore) {
if (classDeductionScore == null) {
return null;
}
AssessmentApprovalIndicatorVo indicator = new AssessmentApprovalIndicatorVo();
indicator.setId(classDeductionScore.getId());
indicator.setIndicatorId(classDeductionScore.getIndicatorId());
indicator.setIndicatorName(classDeductionScore.getIndicatorName());
indicator.setIndicatorCode(classDeductionScore.getIndicatorCode());
indicator.setDescription(classDeductionScore.getDescription());
indicator.setScore(classDeductionScore.getScore());
indicator.setMaxScore(classDeductionScore.getMaxScore());
// 类型转换:Double -> BigDecimal
indicator.setSelfScore(classDeductionScore.getSelfScore() != null ? BigDecimal.valueOf(classDeductionScore.getSelfScore()) : null);
indicator.setSelfComment(classDeductionScore.getSelfComment());
indicator.setSuperiorScore(classDeductionScore.getSuperiorScore() != null ? BigDecimal.valueOf(classDeductionScore.getSuperiorScore()) : null);
indicator.setSuperiorComment(classDeductionScore.getSuperiorComment());
return indicator;
}
/**
* 转换特色工作自评数据
*/
private List<AssessmentApprovalSpecialWorkVo> convertSpecialWorkScores(List<AssessmentScoreSpecialWorkVo> specialWorkScores) {
if (specialWorkScores == null) {
return new ArrayList<>();
}
List<AssessmentApprovalSpecialWorkVo> result = new ArrayList<>();
for (AssessmentScoreSpecialWorkVo score : specialWorkScores) {
AssessmentApprovalSpecialWorkVo specialWork = new AssessmentApprovalSpecialWorkVo();
specialWork.setId(score.getId());
specialWork.setIndicatorCode(score.getIndicatorCode());
specialWork.setIndicatorName(score.getIndicatorName());
// 类型转换:Double -> BigDecimal
specialWork.setScore(score.getScore() != null ? BigDecimal.valueOf(score.getScore()) : null);
specialWork.setSelfScore(score.getSelfScore() != null ? BigDecimal.valueOf(score.getSelfScore()) : null);
specialWork.setSelfComment(score.getSelfComment());
specialWork.setSuperiorScore(score.getSuperiorScore() != null ? BigDecimal.valueOf(score.getSuperiorScore()) : null);
specialWork.setSuperiorComment(score.getSuperiorComment());
result.add(specialWork);
}
return result;
}
/**
* 验证自评数据完整性
*/
private void validateSelfAssessmentData(AssessmentApprovalDetailVo detail) {
// 检查常规工作指标的自评数据
if (detail.getRoutineWorkIndicators() != null) {
for (AssessmentApprovalIndicatorVo indicator : detail.getRoutineWorkIndicators()) {
if (indicator.getSelfScore() == null || indicator.getSelfComment() == null) {
log.warn("常规工作指标缺少自评数据 - ID: {}, 指标名称: {}",
indicator.getId(), indicator.getIndicatorName());
}
}
}
// 检查班级管理实效的自评数据
if (detail.getClassDeductionIndicator() != null) {
AssessmentApprovalIndicatorVo indicator = detail.getClassDeductionIndicator();
if (indicator.getSelfScore() == null || indicator.getSelfComment() == null) {
log.warn("班级管理实效缺少自评数据 - ID: {}", indicator.getId());
}
}
// 检查特色工作的自评数据
if (detail.getSpecialWorkIndicators() != null) {
for (AssessmentApprovalSpecialWorkVo indicator : detail.getSpecialWorkIndicators()) {
if (indicator.getScore() == null || indicator.getSelfComment() == null) {
log.warn("特色工作指标缺少自评数据 - ID: {}, 指标名称: {}",
indicator.getId(), indicator.getIndicatorName());
}
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean submitApproval(AssessmentApprovalSubmitBo bo, Long approverUserId) {
try {
// 1. 更新班主任常规工作指标的上级评分和意见
if (bo.getRoutineWorkApproval() != null) {
for (AssessmentApprovalIndicatorSubmitBo indicator : bo.getRoutineWorkApproval()) {
if (indicator.getId() != null) {
assessmentApprovalMapper.updateSuperiorScore(
indicator.getId(),
indicator.getSuperiorScore() != null ? indicator.getSuperiorScore().toString() : null,
indicator.getSuperiorComment(),
approverUserId
);
}
}
}
// 2. 更新班级管理实效的上级评分和意见
if (bo.getClassDeductionApproval() != null && bo.getClassDeductionApproval().getId() != null) {
assessmentApprovalMapper.updateSuperiorScore(
bo.getClassDeductionApproval().getId(),
bo.getClassDeductionApproval().getSuperiorScore() != null ?
bo.getClassDeductionApproval().getSuperiorScore().toString() : null,
bo.getClassDeductionApproval().getSuperiorComment(),
approverUserId
);
}
// 3. 更新特色工作指标的上级评分和意见
if (bo.getSpecialWorkApproval() != null) {
for (AssessmentApprovalSpecialWorkSubmitBo specialWork : bo.getSpecialWorkApproval()) {
if (specialWork.getId() != null) {
assessmentApprovalMapper.updateSuperiorScore(
specialWork.getId(),
specialWork.getSuperiorScore() != null ? specialWork.getSuperiorScore().toString() : null,
specialWork.getSuperiorComment(),
approverUserId
);
}
}
}
// 4. 更新审核状态和总体评价
int result = assessmentApprovalMapper.updateAuditStatus(
bo.getPlanId(),
bo.getClassId(),
bo.getEvaluatedUserId(),
bo.getAuditStatus(),
bo.getAuditComment(),
bo.getSuperiorOverallComment(),
approverUserId
);
return result > 0;
} catch (Exception e) {
throw new RuntimeException("提交审核失败: " + e.getMessage(), e);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean batchApprove(List<Long> ids, Long approverUserId) {
try {
int result = assessmentApprovalMapper.batchUpdateAuditStatus(
ids,
"1", // 审核通过
"批量审核通过",
approverUserId
);
return result > 0;
} catch (Exception e) {
throw new RuntimeException("批量审核通过失败: " + e.getMessage(), e);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean batchReject(List<Long> ids, String rejectReason, Long approverUserId) {
try {
int result = assessmentApprovalMapper.batchUpdateAuditStatus(
ids,
"2", // 审核不通过
rejectReason,
approverUserId
);
return result > 0;
} catch (Exception e) {
throw new RuntimeException("批量审核拒绝失败: " + e.getMessage(), e);
}
}
@Override
public List<SchemeOptionVo> getSchemeOptions() {
return assessmentApprovalMapper.getSchemeOptions();
}
/**
* 删除异常的审批记录(管理员专用)
* 用于清理审批列表中显示但实际已被删除的异常数据
*
* @param planId 计划ID
* @param evaluatedUserId 被评价用户ID
* @return 是否成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteAbnormalRecord(Long planId, Long evaluatedUserId) {
try {
// 参数验证
if (planId == null || evaluatedUserId == null) {
throw new RuntimeException("计划ID和用户ID不能为空");
}
// 逻辑删除该计划下该用户的所有评分记录
int result = assessmentApprovalMapper.deleteAbnormalAssessmentRecord(planId, evaluatedUserId);
return result > 0;
} catch (Exception e) {
throw new RuntimeException("删除异常记录失败: " + e.getMessage(), e);
}
}
@Override
public EvaluationLevelStatsVo getEvaluationLevelStats(Long planId) {
log.info("获取评价等级统计数据 - planId: {}", planId);
try {
// 获取指定计划下所有班主任的考核得分
List<AssessmentApprovalVo> approvalList = assessmentApprovalMapper.selectApprovalListByPlan(planId);
log.info("查询到的审批数据数量: {}", approvalList.size());
if (approvalList.isEmpty()) {
log.warn("⚠️ 计划ID: {} 下没有找到任何已提交的班主任考核数据,将使用简化评级", planId);
}
EvaluationLevelStatsVo statsVo = new EvaluationLevelStatsVo();
statsVo.setTotalTeachers(approvalList.size());
if (approvalList.isEmpty()) {
statsVo.setScoreRankings(new ArrayList<>());
statsVo.setEvaluationLevelRules(getDefaultEvaluationLevelRules());
log.warn("返回空统计数据,前端将使用简化评级规则");
return statsVo;
}
// 计算每个班主任的得分并排序
List<ScoreRankingVo> scoreRankings = new ArrayList<>();
for (AssessmentApprovalVo approval : approvalList) {
try {
// 获取详细信息用于计算得分
AssessmentDetailVo detailVo = teacherAssessmentService.getAssessmentSubmitDetail(
approval.getPlanId(), approval.getClassId(), approval.getEvaluatedUserId());
// 计算月考核得分
Double monthlyScore = calculateMonthlyScore(detailVo, approval);
ScoreRankingVo ranking = new ScoreRankingVo();
ranking.setScore(monthlyScore);
ranking.setEvaluatedUserId(approval.getEvaluatedUserId());
scoreRankings.add(ranking);
} catch (Exception e) {
log.warn("计算用户{}得分失败: {}", approval.getEvaluatedUserId(), e.getMessage());
// 对于计算失败的用户,设置默认得分0
ScoreRankingVo ranking = new ScoreRankingVo();
ranking.setScore(0.0);
ranking.setEvaluatedUserId(approval.getEvaluatedUserId());
scoreRankings.add(ranking);
}
}
// 按得分降序排序
Collections.sort(scoreRankings, Comparator.comparing(ScoreRankingVo::getScore, Comparator.reverseOrder()));
// 计算排名和百分比
for (int i = 0; i < scoreRankings.size(); i++) {
ScoreRankingVo ranking = scoreRankings.get(i);
ranking.setRanking(i + 1);
// 计算前百分之几(保留2位小数)
double percentage = ((double)(i + 1) / scoreRankings.size()) * 100;
ranking.setPercentage(BigDecimal.valueOf(percentage).setScale(2, RoundingMode.HALF_UP).doubleValue());
}
statsVo.setScoreRankings(scoreRankings);
statsVo.setEvaluationLevelRules(getDefaultEvaluationLevelRules());
log.info("统计数据计算完成 - 总人数: {}, 有效得分人数: {}", statsVo.getTotalTeachers(), scoreRankings.size());
return statsVo;
} catch (Exception e) {
log.error("获取评价等级统计数据失败", e);
throw new RuntimeException("获取评价等级统计数据失败: " + e.getMessage(), e);
}
}
/**
* 计算月考核得分
*/
private Double calculateMonthlyScore(AssessmentDetailVo detailVo, AssessmentApprovalVo approval) {
// 总系数(K)
BigDecimal totalCoefficient = detailVo.getCoefficient().getTotalCoefficient();
// 获取已审批的评分数据
AssessmentScoreDetailVo scoreDetail = assessmentScoreService.getAssessmentScoreDetail(
approval.getPlanId(), approval.getClassId(), approval.getEvaluatedUserId());
if (scoreDetail == null) {
return 0.0;
}
// 班主任常规工作上级评分之和(使用上级评分,如果没有则使用自评分)
double routineWorkTotal = 0.0;
if (scoreDetail.getRoutineWorkScores() != null) {
for (AssessmentScoreIndicatorVo score : scoreDetail.getRoutineWorkScores()) {
Double superiorScore = score.getSuperiorScore();
if (superiorScore != null) {
routineWorkTotal += superiorScore;
} else if (score.getSelfScore() != null) {
routineWorkTotal += score.getSelfScore();
}
}
}
// 班级管理实效评分(班级扣分,使用上级评分,如果没有则使用自评分)
double classDeductionScore = 0.0;
if (scoreDetail.getClassDeductionScore() != null) {
Double superiorScore = scoreDetail.getClassDeductionScore().getSuperiorScore();
if (superiorScore != null) {
classDeductionScore = superiorScore;
} else if (scoreDetail.getClassDeductionScore().getSelfScore() != null) {
classDeductionScore = scoreDetail.getClassDeductionScore().getSelfScore();
}
}
// 计算按班级扣分50%计的分值
double deductionHalf = classDeductionScore * 0.5;
// 特色工作上级评分之和(使用上级评分,如果没有则使用自评分)
double specialWorkTotal = 0.0;
if (scoreDetail.getSpecialWorkScores() != null) {
for (AssessmentScoreSpecialWorkVo score : scoreDetail.getSpecialWorkScores()) {
Double superiorScore = score.getSuperiorScore();
if (superiorScore != null) {
specialWorkTotal += superiorScore;
} else if (score.getSelfScore() != null) {
specialWorkTotal += score.getSelfScore();
}
}
}
// 月考核得分 = 总系数(K)* (班主任常规工作评分 - 按班级扣分50%计的分值 + 特色工作评分)
// 注意:班级扣分是减法,因为它是扣分项
BigDecimal monthlyScore = totalCoefficient.multiply(
BigDecimal.valueOf(routineWorkTotal - deductionHalf + specialWorkTotal));
return monthlyScore.setScale(2, RoundingMode.HALF_UP).doubleValue();
}
/**
* 获取默认评价等级规则
*/
private EvaluationLevelStatsVo.EvaluationLevelRules getDefaultEvaluationLevelRules() {
EvaluationLevelStatsVo.EvaluationLevelRules rules = new EvaluationLevelStatsVo.EvaluationLevelRules();
rules.setALevelMaxPercentage(20.0); // A等最大占比20%
rules.setPassScore(60.0); // 及格分数60分
return rules;
}
}
@@ -0,0 +1,100 @@
package org.dromara.bzrkh.service.impl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.service.IAssessmentScoreService;
import org.dromara.bzrkh.mapper.AssessmentScoreMapper;
import org.dromara.bzrkh.domain.vo.AssessmentScoreDetailVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreIndicatorVo;
import org.dromara.bzrkh.domain.vo.AssessmentScoreSpecialWorkVo;
import java.util.List;
/**
* 班主任考核评分数据Service业务层处理
*
* 提供统一的自评数据查询服务,确保提交API和审批API使用相同的数据源
*
* @author ruoyi
* @date 2025-01-28
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class AssessmentScoreServiceImpl implements IAssessmentScoreService {
private final AssessmentScoreMapper assessmentScoreMapper;
@Override
public AssessmentScoreDetailVo getAssessmentScoreDetail(Long planId, Long classId, Long evaluatedUserId) {
log.info("获取自评数据详情 - planId: {}, classId: {}, evaluatedUserId: {}", planId, classId, evaluatedUserId);
// 1. 获取自评数据基本信息
AssessmentScoreDetailVo detail = assessmentScoreMapper.getAssessmentScoreBasicInfo(planId, classId, evaluatedUserId);
if (detail == null) {
log.warn("未找到自评数据 - planId: {}, classId: {}, evaluatedUserId: {}", planId, classId, evaluatedUserId);
// 返回空的详情对象,表示没有自评数据
detail = new AssessmentScoreDetailVo();
detail.setPlanId(planId);
detail.setClassId(classId);
detail.setEvaluatedUserId(evaluatedUserId);
detail.setHasAssessmentData(false);
return detail;
}
log.info("找到自评数据基本信息 - 自我总体评价: {}, 提交时间: {}",
detail.getSelfOverallComment(), detail.getSelfSubmitTime());
// 2. 获取班主任常规工作自评数据
List<AssessmentScoreIndicatorVo> routineWorkScores =
assessmentScoreMapper.getRoutineWorkScores(planId, classId, evaluatedUserId);
detail.setRoutineWorkScores(routineWorkScores);
log.info("获取常规工作自评数据 - 数量: {}", routineWorkScores.size());
for (AssessmentScoreIndicatorVo score : routineWorkScores) {
log.debug("常规工作自评 - 指标: {}, 自评分数: {}, 自评意见: {}",
score.getIndicatorName(), score.getSelfScore(), score.getSelfComment());
}
// 3. 获取班级管理实效自评数据
AssessmentScoreIndicatorVo classDeductionScore =
assessmentScoreMapper.getClassDeductionScore(planId, classId, evaluatedUserId);
detail.setClassDeductionScore(classDeductionScore);
if (classDeductionScore != null) {
log.info("获取班级管理实效自评数据 - 自评分数: {}, 自评意见: {}",
classDeductionScore.getSelfScore(), classDeductionScore.getSelfComment());
} else {
log.warn("未找到班级管理实效自评数据");
}
// 4. 获取特色工作自评数据
List<AssessmentScoreSpecialWorkVo> specialWorkScores =
assessmentScoreMapper.getSpecialWorkScores(planId, classId, evaluatedUserId);
detail.setSpecialWorkScores(specialWorkScores);
log.info("获取特色工作自评数据 - 数量: {}", specialWorkScores.size());
for (AssessmentScoreSpecialWorkVo score : specialWorkScores) {
log.debug("特色工作自评 - 指标: {}, 自评分数: {}, 自评意见: {}",
score.getIndicatorName(), score.getScore(), score.getSelfComment());
}
// 5. 标记有自评数据
detail.setHasAssessmentData(true);
log.info("自评数据详情获取完成 - 总体评价: {}, 常规工作: {}项, 班级管理: {}, 特色工作: {}项",
detail.getSelfOverallComment(),
routineWorkScores.size(),
classDeductionScore != null ? "有" : "无",
specialWorkScores.size());
return detail;
}
@Override
public boolean hasAssessmentScore(Long planId, Long classId, Long evaluatedUserId) {
int count = assessmentScoreMapper.countAssessmentScore(planId, classId, evaluatedUserId);
boolean hasData = count > 0;
log.info("检查自评数据存在性 - planId: {}, classId: {}, evaluatedUserId: {}, 结果: {}",
planId, classId, evaluatedUserId, hasData ? "存在" : "不存在");
return hasData;
}
}
@@ -0,0 +1,180 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorBo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorVo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicator;
import org.dromara.bzrkh.mapper.BmzrAssessmentIndicatorMapper;
import org.dromara.bzrkh.service.IBmzrAssessmentIndicatorService;
import java.util.List;
import java.util.Collection;
import java.util.ArrayList;
import java.util.stream.Collectors;
/**
* 班主任考核指标体系Service业务层处理
*
* @author ruoyi
* @date 2025-01-08
*/
@RequiredArgsConstructor
@Service
public class BmzrAssessmentIndicatorServiceImpl implements IBmzrAssessmentIndicatorService {
private final BmzrAssessmentIndicatorMapper baseMapper;
/**
* 查询班主任考核指标体系
*/
@Override
public BmzrAssessmentIndicatorVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询班主任考核指标体系列表
*/
@Override
public TableDataInfo<BmzrAssessmentIndicatorVo> queryPageList(BmzrAssessmentIndicatorBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BmzrAssessmentIndicator> lqw = buildQueryWrapper(bo);
Page<BmzrAssessmentIndicatorVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询班主任考核指标体系列表
*/
@Override
public List<BmzrAssessmentIndicatorVo> queryList(BmzrAssessmentIndicatorBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicator> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 查询班主任考核指标体系树形列表
*/
@Override
public List<BmzrAssessmentIndicatorVo> queryTreeList(BmzrAssessmentIndicatorBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicator> lqw = buildQueryWrapper(bo);
lqw.orderByAsc(BmzrAssessmentIndicator::getSortOrder);
List<BmzrAssessmentIndicatorVo> list = baseMapper.selectVoList(lqw);
return buildTree(list);
}
private LambdaQueryWrapper<BmzrAssessmentIndicator> buildQueryWrapper(BmzrAssessmentIndicatorBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicator> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getIndicatorName()), BmzrAssessmentIndicator::getIndicatorName, bo.getIndicatorName());
lqw.eq(StringUtils.isNotBlank(bo.getIndicatorCode()), BmzrAssessmentIndicator::getIndicatorCode, bo.getIndicatorCode());
lqw.eq(StringUtils.isNotBlank(bo.getIndicatorType()), BmzrAssessmentIndicator::getIndicatorType, bo.getIndicatorType());
lqw.eq(bo.getParentId() != null, BmzrAssessmentIndicator::getParentId, bo.getParentId());
lqw.eq(StringUtils.isNotBlank(bo.getAllowSelfEvaluation()), BmzrAssessmentIndicator::getAllowSelfEvaluation, bo.getAllowSelfEvaluation());
lqw.eq(StringUtils.isNotBlank(bo.getAllowSuperiorEvaluation()), BmzrAssessmentIndicator::getAllowSuperiorEvaluation, bo.getAllowSuperiorEvaluation());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BmzrAssessmentIndicator::getStatus, bo.getStatus());
lqw.orderByAsc(BmzrAssessmentIndicator::getSortOrder);
return lqw;
}
/**
* 构建树形结构
*/
private List<BmzrAssessmentIndicatorVo> buildTree(List<BmzrAssessmentIndicatorVo> list) {
List<BmzrAssessmentIndicatorVo> tree = new ArrayList<>();
List<Long> tempList = list.stream().map(BmzrAssessmentIndicatorVo::getId).collect(Collectors.toList());
for (BmzrAssessmentIndicatorVo vo : list) {
// 如果是顶级节点,遍历该父节点的所有子节点
if (vo.getParentId() == null || vo.getParentId() == 0 || !tempList.contains(vo.getParentId())) {
recursionFn(list, vo);
tree.add(vo);
}
}
if (tree.isEmpty()) {
tree = list;
}
return tree;
}
/**
* 递归列表
*/
private void recursionFn(List<BmzrAssessmentIndicatorVo> list, BmzrAssessmentIndicatorVo vo) {
// 得到子节点列表
List<BmzrAssessmentIndicatorVo> childList = getChildList(list, vo);
vo.setChildren(childList);
for (BmzrAssessmentIndicatorVo tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 得到子节点列表
*/
private List<BmzrAssessmentIndicatorVo> getChildList(List<BmzrAssessmentIndicatorVo> list, BmzrAssessmentIndicatorVo vo) {
List<BmzrAssessmentIndicatorVo> tlist = new ArrayList<>();
for (BmzrAssessmentIndicatorVo n : list) {
if (n.getParentId() != null && n.getParentId().longValue() == vo.getId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
/**
* 判断是否有子节点
*/
private boolean hasChild(List<BmzrAssessmentIndicatorVo> list, BmzrAssessmentIndicatorVo vo) {
return getChildList(list, vo).size() > 0;
}
/**
* 新增班主任考核指标体系
*/
@Override
public Boolean insertByBo(BmzrAssessmentIndicatorBo bo) {
BmzrAssessmentIndicator add = MapstructUtils.convert(bo, BmzrAssessmentIndicator.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改班主任考核指标体系
*/
@Override
public Boolean updateByBo(BmzrAssessmentIndicatorBo bo) {
BmzrAssessmentIndicator update = MapstructUtils.convert(bo, BmzrAssessmentIndicator.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BmzrAssessmentIndicator entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除班主任考核指标体系
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}
@@ -0,0 +1,168 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentIndicatorTypeBo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentIndicatorTypeVo;
import org.dromara.bzrkh.domain.BmzrAssessmentIndicatorType;
import org.dromara.bzrkh.mapper.BmzrAssessmentIndicatorTypeMapper;
import org.dromara.bzrkh.service.IBmzrAssessmentIndicatorTypeService;
import java.util.List;
import java.util.Collection;
/**
* 班主任考核指标类型Service业务层处理
*
* @author ruoyi
* @date 2025-01-08
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class BmzrAssessmentIndicatorTypeServiceImpl implements IBmzrAssessmentIndicatorTypeService {
private final BmzrAssessmentIndicatorTypeMapper baseMapper;
/**
* 查询班主任考核指标类型
*
* @param id 主键
* @return 班主任考核指标类型
*/
@Override
public BmzrAssessmentIndicatorTypeVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询班主任考核指标类型列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 班主任考核指标类型分页列表
*/
@Override
public TableDataInfo<BmzrAssessmentIndicatorTypeVo> queryPageList(BmzrAssessmentIndicatorTypeBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = buildQueryWrapper(bo);
Page<BmzrAssessmentIndicatorTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的班主任考核指标类型列表
*
* @param bo 查询条件
* @return 班主任考核指标类型列表
*/
@Override
public List<BmzrAssessmentIndicatorTypeVo> queryList(BmzrAssessmentIndicatorTypeBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 查询所有班主任考核指标类型列表,包括已逻辑删除的
*
* @param bo 查询条件
* @return 包含已删除记录的班主任考核指标类型列表
*/
@Override
public List<BmzrAssessmentIndicatorTypeVo> queryListWithDeleted(BmzrAssessmentIndicatorTypeBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = buildQueryWrapperWithDeleted(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BmzrAssessmentIndicatorType> buildQueryWrapper(BmzrAssessmentIndicatorTypeBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getDeleted() != null, BmzrAssessmentIndicatorType::getDeleted, bo.getDeleted());
lqw.like(StringUtils.isNotBlank(bo.getIndicatorTypeName()), BmzrAssessmentIndicatorType::getIndicatorTypeName, bo.getIndicatorTypeName());
lqw.eq(StringUtils.isNotBlank(bo.getIndicatorTypeCode()), BmzrAssessmentIndicatorType::getIndicatorTypeCode, bo.getIndicatorTypeCode());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BmzrAssessmentIndicatorType::getStatus, bo.getStatus());
lqw.orderByAsc(BmzrAssessmentIndicatorType::getCreateTime);
return lqw;
}
private LambdaQueryWrapper<BmzrAssessmentIndicatorType> buildQueryWrapperWithDeleted(BmzrAssessmentIndicatorTypeBo bo) {
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = Wrappers.lambdaQuery();
// 禁用逻辑删除过滤器,查询包含已删除的记录
lqw.in(BmzrAssessmentIndicatorType::getDeleted, 0, 1);
lqw.like(StringUtils.isNotBlank(bo.getIndicatorTypeName()), BmzrAssessmentIndicatorType::getIndicatorTypeName, bo.getIndicatorTypeName());
lqw.eq(StringUtils.isNotBlank(bo.getIndicatorTypeCode()), BmzrAssessmentIndicatorType::getIndicatorTypeCode, bo.getIndicatorTypeCode());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BmzrAssessmentIndicatorType::getStatus, bo.getStatus());
lqw.orderByAsc(BmzrAssessmentIndicatorType::getCreateTime);
return lqw;
}
/**
* 新增班主任考核指标类型
*
* @param bo 班主任考核指标类型
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BmzrAssessmentIndicatorTypeBo bo) {
BmzrAssessmentIndicatorType add = MapstructUtils.convert(bo, BmzrAssessmentIndicatorType.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改班主任考核指标类型
*
* @param bo 班主任考核指标类型
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BmzrAssessmentIndicatorTypeBo bo) {
BmzrAssessmentIndicatorType update = MapstructUtils.convert(bo, BmzrAssessmentIndicatorType.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*
* @param entity 实体类数据
*/
private void validEntityBeforeSave(BmzrAssessmentIndicatorType entity) {
// TODO 做一些数据校验,如唯一约束
// 检查指标类型编码是否重复
LambdaQueryWrapper<BmzrAssessmentIndicatorType> lqw = Wrappers.lambdaQuery();
lqw.eq(BmzrAssessmentIndicatorType::getIndicatorTypeCode, entity.getIndicatorTypeCode());
if (entity.getId() != null) {
lqw.ne(BmzrAssessmentIndicatorType::getId, entity.getId());
}
boolean exists = baseMapper.exists(lqw);
if (exists) {
throw new RuntimeException("指标类型编码已存在,请修改后重试");
}
}
/**
* 批量删除班主任考核指标类型
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}
@@ -0,0 +1,166 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.BmzrAssessmentPlan;
import org.dromara.bzrkh.mapper.BmzrAssessmentPlanMapper;
import org.dromara.bzrkh.service.IBmzrAssessmentPlanService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 班主任考核计划Service业务层处理
*
* @author ruoyi
* @date 2025-01-08
*/
@RequiredArgsConstructor
@Service
public class BmzrAssessmentPlanServiceImpl implements IBmzrAssessmentPlanService {
private final BmzrAssessmentPlanMapper baseMapper;
/**
* 查询班主任考核计划
*/
@Override
public BmzrAssessmentPlanVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询班主任考核计划列表
*/
@Override
public TableDataInfo<BmzrAssessmentPlanVo> queryPageList(BmzrAssessmentPlanBo bo, PageQuery pageQuery) {
IPage<BmzrAssessmentPlanVo> page = baseMapper.selectAssessmentPlanPageWithScheme(pageQuery.build(), bo);
return TableDataInfo.build(page);
}
/**
* 查询班主任考核计划列表
*/
@Override
public List<BmzrAssessmentPlanVo> queryList(BmzrAssessmentPlanBo bo) {
return baseMapper.selectAssessmentPlanListWithScheme(bo);
}
private LambdaQueryWrapper<BmzrAssessmentPlan> buildQueryWrapper(BmzrAssessmentPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BmzrAssessmentPlan> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getPlanName()), BmzrAssessmentPlan::getPlanName, bo.getPlanName());
lqw.eq(StringUtils.isNotBlank(bo.getPlanCode()), BmzrAssessmentPlan::getPlanCode, bo.getPlanCode());
lqw.eq(bo.getSchemeId() != null, BmzrAssessmentPlan::getSchemeId, bo.getSchemeId());
lqw.like(StringUtils.isNotBlank(bo.getAcademicYear()), BmzrAssessmentPlan::getAcademicYear, bo.getAcademicYear());
lqw.eq(StringUtils.isNotBlank(bo.getSemester()), BmzrAssessmentPlan::getSemester, bo.getSemester());
lqw.eq(StringUtils.isNotBlank(bo.getPlanStatus()), BmzrAssessmentPlan::getPlanStatus, bo.getPlanStatus());
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
BmzrAssessmentPlan::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
lqw.orderByDesc(BmzrAssessmentPlan::getCreateTime);
return lqw;
}
/**
* 新增班主任考核计划
*/
@Override
public Boolean insertByBo(BmzrAssessmentPlanBo bo) {
BmzrAssessmentPlan add = MapstructUtils.convert(bo, BmzrAssessmentPlan.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改班主任考核计划
*/
@Override
public Boolean updateByBo(BmzrAssessmentPlanBo bo) {
BmzrAssessmentPlan update = MapstructUtils.convert(bo, BmzrAssessmentPlan.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BmzrAssessmentPlan entity){
// 计划编码唯一性校验
LambdaQueryWrapper<BmzrAssessmentPlan> lqw = Wrappers.lambdaQuery();
lqw.eq(BmzrAssessmentPlan::getPlanCode, entity.getPlanCode());
if (entity.getId() != null) {
lqw.ne(BmzrAssessmentPlan::getId, entity.getId());
}
long count = baseMapper.selectCount(lqw);
if (count > 0) {
throw new RuntimeException("计划编码已存在");
}
}
/**
* 批量删除班主任考核计划
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
// 删除前校验
// 这里可以添加删除前的业务校验逻辑
}
// 1. 先删除关联的考核得分数据
deleteRelatedAssessmentScores(ids);
// 2. 再删除考核计划主表数据
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 删除关联的考核得分数据
* @param planIds 考核计划ID集合
*/
private void deleteRelatedAssessmentScores(Collection<Long> planIds) {
if (planIds == null || planIds.isEmpty()) {
return;
}
// 通过SQL更新关联表的deleted字段,实现逻辑删除
// 这里需要直接执行SQL,因为可能没有对应的Service
baseMapper.deleteAssessmentScoresByPlanIds(planIds);
}
/**
* 修改考核计划状态
*/
@Override
public Boolean updatePlanStatus(Long id, String planStatus) {
BmzrAssessmentPlan plan = new BmzrAssessmentPlan();
plan.setId(id);
plan.setPlanStatus(planStatus);
return baseMapper.updateById(plan) > 0;
}
/**
* 获取可用的考核方案选项
*/
@Override
public List<BmzrAssessmentPlanVo> getAvailableSchemes() {
// 这里应该查询考核方案表,暂时返回空列表
// 需要根据实际的考核方案表来实现
return List.of();
}
}
@@ -0,0 +1,187 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.bzrkh.domain.BmzrAssessmentSchemeIndicator;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeIndicatorVo;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeIndicatorBo;
import org.dromara.bzrkh.mapper.BmzrAssessmentSchemeIndicatorMapper;
import org.dromara.bzrkh.service.IBmzrAssessmentSchemeIndicatorService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 班主任考核方案指标关联Service业务层处理
*
* @author ruoyi
* @date 2025-01-08
*/
@RequiredArgsConstructor
@Service
public class BmzrAssessmentSchemeIndicatorServiceImpl implements IBmzrAssessmentSchemeIndicatorService {
private final BmzrAssessmentSchemeIndicatorMapper baseMapper;
/**
* 查询班主任考核方案指标关联
*
* @param id 主键
* @return 班主任考核方案指标关联
*/
@Override
public BmzrAssessmentSchemeIndicatorVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 查询班主任考核方案指标关联列表
*
* @param bo 查询条件
* @return 班主任考核方案指标关联
*/
@Override
public List<BmzrAssessmentSchemeIndicatorVo> queryList(BmzrAssessmentSchemeIndicatorBo bo) {
// 使用自定义SQL查询,确保score字段正确映射
return baseMapper.queryList(bo);
}
private LambdaQueryWrapper<BmzrAssessmentSchemeIndicator> buildQueryWrapper(BmzrAssessmentSchemeIndicatorBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BmzrAssessmentSchemeIndicator> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSchemeId() != null, BmzrAssessmentSchemeIndicator::getSchemeId, bo.getSchemeId());
lqw.eq(bo.getIndicatorId() != null, BmzrAssessmentSchemeIndicator::getIndicatorId, bo.getIndicatorId());
lqw.eq(bo.getSortOrder() != null, BmzrAssessmentSchemeIndicator::getSortOrder, bo.getSortOrder());
lqw.like(StringUtils.isNotBlank(bo.getRemark()), BmzrAssessmentSchemeIndicator::getRemark, bo.getRemark());
lqw.orderByAsc(BmzrAssessmentSchemeIndicator::getSortOrder);
return lqw;
}
/**
* 分页查询班主任考核方案指标关联列表
*
* @param bo 查询条件
* @param pageQuery 分页查询条件
* @return 班主任考核方案指标关联分页列表
*/
@Override
public TableDataInfo<BmzrAssessmentSchemeIndicatorVo> queryPageList(BmzrAssessmentSchemeIndicatorBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BmzrAssessmentSchemeIndicator> lqw = buildQueryWrapper(bo);
Page<BmzrAssessmentSchemeIndicatorVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 新增班主任考核方案指标关联
*
* @param bo 班主任考核方案指标关联
* @return 新增结果
*/
@Override
public Boolean insertByBo(BmzrAssessmentSchemeIndicatorBo bo) {
BmzrAssessmentSchemeIndicator add = MapstructUtils.convert(bo, BmzrAssessmentSchemeIndicator.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改班主任考核方案指标关联
*
* @param bo 班主任考核方案指标关联
* @return 修改结果
*/
@Override
public Boolean updateByBo(BmzrAssessmentSchemeIndicatorBo bo) {
BmzrAssessmentSchemeIndicator update = MapstructUtils.convert(bo, BmzrAssessmentSchemeIndicator.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*
* @param entity 实体类数据
*/
private void validEntityBeforeSave(BmzrAssessmentSchemeIndicator entity) {
// TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除班主任考核方案指标关联信息
*
* @param ids 主键集合
* @param isValid 是否校验,true-删除前校验,false-不校验
* @return 删除结果
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 根据方案ID查询指标关联列表
*
* @param schemeId 方案ID
* @return 指标关联列表
*/
@Override
public List<BmzrAssessmentSchemeIndicatorVo> queryBySchemeId(Long schemeId) {
BmzrAssessmentSchemeIndicatorBo bo = new BmzrAssessmentSchemeIndicatorBo();
bo.setSchemeId(schemeId);
return queryList(bo);
}
/**
* 批量保存方案指标关联
*
* @param schemeId 方案ID
* @param indicatorList 指标列表
* @return 保存结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean batchSaveSchemeIndicators(Long schemeId, List<BmzrAssessmentSchemeIndicatorBo> indicatorList) {
// 先删除原有关联
LambdaQueryWrapper<BmzrAssessmentSchemeIndicator> deleteWrapper = Wrappers.lambdaQuery();
deleteWrapper.eq(BmzrAssessmentSchemeIndicator::getSchemeId, schemeId);
baseMapper.delete(deleteWrapper);
// 批量新增
if (indicatorList != null && !indicatorList.isEmpty()) {
AtomicInteger sortOrder = new AtomicInteger(1);
for (BmzrAssessmentSchemeIndicatorBo bo : indicatorList) {
// 清空ID字段,避免主键冲突
bo.setId(null);
bo.setSchemeId(schemeId);
bo.setSortOrder(sortOrder.getAndIncrement());
// 关键修复:将score字段的值映射到customMaxScore字段
if (bo.getScore() != null) {
bo.setCustomMaxScore(bo.getScore());
}
BmzrAssessmentSchemeIndicator entity = MapstructUtils.convert(bo, BmzrAssessmentSchemeIndicator.class);
baseMapper.insert(entity);
}
}
return true;
}
}
@@ -0,0 +1,141 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.domain.bo.BmzrAssessmentSchemeBo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentSchemeVo;
import org.dromara.bzrkh.domain.BmzrAssessmentScheme;
import org.dromara.bzrkh.mapper.BmzrAssessmentSchemeMapper;
import org.dromara.bzrkh.service.IBmzrAssessmentSchemeService;
import java.util.List;
import java.util.Collection;
import java.util.Map;
/**
* 班主任考核方案Service业务层处理
*
* @author system
* @date 2025-01-08
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class BmzrAssessmentSchemeServiceImpl implements IBmzrAssessmentSchemeService {
private final BmzrAssessmentSchemeMapper baseMapper;
/**
* 查询班主任考核方案
*
* @param id 主键
* @return 班主任考核方案
*/
@Override
public BmzrAssessmentSchemeVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 查询班主任考核方案列表
*
* @param bo 查询条件
* @param pageQuery 分页查询条件
* @return 班主任考核方案分页列表
*/
@Override
public TableDataInfo<BmzrAssessmentSchemeVo> queryPageList(BmzrAssessmentSchemeBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BmzrAssessmentScheme> lqw = buildQueryWrapper(bo);
Page<BmzrAssessmentSchemeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询班主任考核方案列表
*
* @param bo 查询条件
* @return 班主任考核方案列表
*/
@Override
public List<BmzrAssessmentSchemeVo> queryList(BmzrAssessmentSchemeBo bo) {
LambdaQueryWrapper<BmzrAssessmentScheme> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BmzrAssessmentScheme> buildQueryWrapper(BmzrAssessmentSchemeBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BmzrAssessmentScheme> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getSchemeName()), BmzrAssessmentScheme::getSchemeName, bo.getSchemeName());
lqw.eq(StringUtils.isNotBlank(bo.getSchemeCode()), BmzrAssessmentScheme::getSchemeCode, bo.getSchemeCode());
lqw.eq(StringUtils.isNotBlank(bo.getAcademicYear()), BmzrAssessmentScheme::getAcademicYear, bo.getAcademicYear());
lqw.eq(StringUtils.isNotBlank(bo.getSemester()), BmzrAssessmentScheme::getSemester, bo.getSemester());
lqw.eq(StringUtils.isNotBlank(bo.getSelfEvaluationRequired()), BmzrAssessmentScheme::getSelfEvaluationRequired, bo.getSelfEvaluationRequired());
lqw.eq(StringUtils.isNotBlank(bo.getSuperiorEvaluationRequired()), BmzrAssessmentScheme::getSuperiorEvaluationRequired, bo.getSuperiorEvaluationRequired());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BmzrAssessmentScheme::getStatus, bo.getStatus());
lqw.orderByDesc(BmzrAssessmentScheme::getCreateTime);
return lqw;
}
/**
* 新增班主任考核方案
*
* @param bo 班主任考核方案
* @return 结果
*/
@Override
public Boolean insertByBo(BmzrAssessmentSchemeBo bo) {
BmzrAssessmentScheme add = MapstructUtils.convert(bo, BmzrAssessmentScheme.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改班主任考核方案
*
* @param bo 班主任考核方案
* @return 结果
*/
@Override
public Boolean updateByBo(BmzrAssessmentSchemeBo bo) {
BmzrAssessmentScheme update = MapstructUtils.convert(bo, BmzrAssessmentScheme.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*
* @param entity 实体类数据
*/
private void validEntityBeforeSave(BmzrAssessmentScheme entity) {
// TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除班主任考核方案
*
* @param ids 需要删除的班主任考核方案主键集合
* @param isValid 是否校验,true-删除前校验,false-不校验
* @return 结果
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}
@@ -0,0 +1,692 @@
package org.dromara.bzrkh.service.impl;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.dromara.bzrkh.domain.vo.TeacherClassVo;
import org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo;
import org.dromara.bzrkh.domain.vo.AssessmentDetailVo;
import org.dromara.bzrkh.domain.vo.ClassDetailVo;
import org.dromara.bzrkh.domain.vo.CoefficientVo;
import org.dromara.bzrkh.domain.vo.AssessmentIndicatorScoreVo;
import org.dromara.bzrkh.domain.vo.SpecialWorkIndicatorVo;
import org.dromara.bzrkh.domain.vo.ClassStudentRecordsVo;
import org.dromara.bzrkh.domain.vo.StudentDisciplineRecordVo;
import org.dromara.bzrkh.domain.vo.StudentRewardRecordVo;
import org.dromara.bzrkh.domain.bo.TeacherAssessmentQueryBo;
import org.dromara.bzrkh.domain.bo.AssessmentSubmitBo;
import org.dromara.bzrkh.mapper.TeacherAssessmentMapper;
import org.dromara.bzrkh.mapper.BmzrAssessmentScoreMapper;
import org.dromara.bzrkh.service.ITeacherAssessmentService;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.bzrkh.domain.BmzrAssessmentScore;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
/**
* 班主任考核管理Service业务层处理
*
* @author ruoyi
* @date 2025-01-27
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class TeacherAssessmentServiceImpl implements ITeacherAssessmentService {
private final TeacherAssessmentMapper teacherAssessmentMapper;
private final BmzrAssessmentScoreMapper assessmentScoreMapper;
/**
* 查询班主任管理的班级列表
*
* @param teacherId 班主任ID
* @return 班级列表
*/
@Override
public List<TeacherClassVo> queryTeacherClassList(Long teacherId) {
return teacherAssessmentMapper.selectTeacherClassList(teacherId);
}
/**
* 查询班主任考核计划列表(分页)
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 考核计划列表
*/
@Override
public TableDataInfo<BmzrAssessmentPlanVo> queryTeacherAssessmentPlanPageList(TeacherAssessmentQueryBo bo, PageQuery pageQuery) {
log.info("🔍 查询班主任考核计划列表 - 参数: teacherId={}, classId={}, planName={}, planStatus={}",
bo.getTeacherId(), bo.getClassId(), bo.getPlanName(), bo.getPlanStatus());
Page<BmzrAssessmentPlanVo> page = pageQuery.build();
List<BmzrAssessmentPlanVo> list = teacherAssessmentMapper.selectTeacherAssessmentPlanList(bo);
log.info("📊 查询结果: 总数={}, 第一条数据状态={}",
list.size(),
list.isEmpty() ? "无数据" : "auditStatus=" + list.get(0).getAuditStatus() + ",submitted=" + list.get(0).getSubmitted());
// 手动分页处理
int total = list.size();
int start = (int) ((page.getCurrent() - 1) * page.getSize());
int end = Math.min(start + (int) page.getSize(), total);
List<BmzrAssessmentPlanVo> pageList = list.subList(start, end);
page.setRecords(pageList);
page.setTotal(total);
return TableDataInfo.build(page);
}
/**
* 提交考核
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 是否成功
*/
@Override
public boolean submitAssessment(Long planId, Long classId, Long teacherId) {
log.info("开始提交考核到审批流程 - planId: {}, classId: {}, teacherId: {}", planId, classId, teacherId);
try {
// 参数验证
if (planId == null || classId == null || teacherId == null) {
log.error("参数验证失败 - planId: {}, classId: {}, teacherId: {}", planId, classId, teacherId);
throw new RuntimeException("必要参数不能为空");
}
// 1. 验证是否存在草稿状态的评分数据
log.info("1. 验证是否存在草稿状态的评分数据...");
List<AssessmentIndicatorScoreVo> draftScores = teacherAssessmentMapper.selectSavedAssessmentScores(planId, teacherId, classId);
if (draftScores == null || draftScores.isEmpty()) {
log.error("未找到任何评分数据 - planId: {}, teacherId: {}, classId: {}", planId, teacherId, classId);
throw new RuntimeException("请先保存考核评分数据后再提交");
}
log.info("找到评分数据记录数: {}", draftScores.size());
// 2. 验证所有草稿数据的审核状态
log.info("2. 验证草稿数据的审核状态...");
long draftCount = draftScores.stream().filter(score -> "9".equals(score.getAuditStatus())).count();
long otherStatusCount = draftScores.size() - draftCount;
log.info("草稿状态记录数: {}, 其他状态记录数: {}", draftCount, otherStatusCount);
if (draftCount == 0) {
log.error("未找到可提交的草稿数据 - planId: {}, teacherId: {}", planId, teacherId);
throw new RuntimeException("未找到可提交的草稿数据,可能已经提交过了");
}
// 3. 将所有草稿状态的评分记录更新为待审核状态
log.info("3. 更新评分记录状态为待审核...");
try {
Date now = new Date();
int updateCount = assessmentScoreMapper.update(null,
new LambdaUpdateWrapper<BmzrAssessmentScore>()
.set(BmzrAssessmentScore::getAuditStatus, "0") // 设置为待审核状态
.set(BmzrAssessmentScore::getSubmitTime, now) // 更新提交时间
.set(BmzrAssessmentScore::getSelfSubmitTime, now) // 设置自评提交时间,使数据出现在审批列表中
.eq(BmzrAssessmentScore::getPlanId, planId)
.eq(BmzrAssessmentScore::getEvaluatedUserId, teacherId)
.eq(BmzrAssessmentScore::getClassId, classId) // 添加班级ID过滤条件,确保班级隔离
.eq(BmzrAssessmentScore::getAuditStatus, "9") // 只更新草稿状态的记录
.eq(BmzrAssessmentScore::getDeleted, 0)
);
if (updateCount <= 0) {
log.error("更新评分记录状态失败 - planId: {}, teacherId: {}", planId, teacherId);
throw new RuntimeException("更新评分记录状态失败");
}
log.info("成功更新评分记录状态,更新记录数: {}", updateCount);
} catch (Exception e) {
log.error("更新评分记录状态异常 - planId: {}, teacherId: {}, error: {}", planId, teacherId, e.getMessage(), e);
throw new RuntimeException("更新评分记录状态失败: " + e.getMessage());
}
log.info("考核提交到审批流程成功 - planId: {}, classId: {}, teacherId: {}", planId, classId, teacherId);
return true;
} catch (Exception e) {
log.error("提交考核失败:planId={}, classId={}, teacherId={}, error={}", planId, classId, teacherId, e.getMessage(), e);
throw new RuntimeException("提交考核失败:" + e.getMessage());
}
}
/**
* 查看考核详情
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 考核详情
*/
@Override
public Object getAssessmentDetail(Long planId, Long classId, Long teacherId) {
// TODO: 实现查看考核详情逻辑
// 1. 验证班主任是否有权限查看该班级的考核
// 2. 获取考核计划详情
// 3. 获取考核指标详情
// 4. 获取考核记录和评分
return null;
}
/**
* 获取考核提交详情数据
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 考核提交详情
*/
@Override
public AssessmentDetailVo getAssessmentSubmitDetail(Long planId, Long classId, Long teacherId) {
AssessmentDetailVo detailVo = new AssessmentDetailVo();
// 1. 获取班级详细信息
ClassDetailVo classDetail = teacherAssessmentMapper.selectClassDetail(classId);
detailVo.setClassDetail(classDetail);
// 2. 计算系数信息
CoefficientVo coefficient = calculateCoefficient(classDetail);
detailVo.setCoefficient(coefficient);
// 3. 获取班主任常规工作指标
List<AssessmentIndicatorScoreVo> routineWorkIndicators = teacherAssessmentMapper.selectRoutineWorkIndicators(planId);
detailVo.setRoutineWorkIndicators(routineWorkIndicators);
// 4. 获取班级扣分指标
AssessmentIndicatorScoreVo classDeductionIndicator = teacherAssessmentMapper.selectClassDeductionIndicator();
detailVo.setClassDeductionIndicator(classDeductionIndicator);
// 5. 获取特色工作指标
List<SpecialWorkIndicatorVo> specialWorkIndicators = teacherAssessmentMapper.selectSpecialWorkIndicators();
detailVo.setSpecialWorkIndicators(specialWorkIndicators);
// 6. 获取已保存的评分数据(如果有)
List<AssessmentIndicatorScoreVo> savedScores = teacherAssessmentMapper.selectSavedAssessmentScores(planId, teacherId, classId);
if (savedScores != null && !savedScores.isEmpty()) {
// 将已保存的评分数据合并到指标中
mergeAssessmentScores(detailVo, savedScores);
// 获取总体评价(从任意一条记录中获取,因为都是同样的总体评价)
savedScores.stream()
.findFirst()
.ifPresent(saved -> detailVo.setOverallComment(saved.getSelfOverallComment()));
}
return detailVo;
}
/**
* 提交考核评分数据
*
* @param bo 考核提交数据
* @param teacherId 班主任ID
* @return 是否成功
*/
@Override
public boolean submitAssessmentScore(AssessmentSubmitBo bo, Long teacherId) {
log.info("开始提交考核评分数据 - planId: {}, classId: {}, teacherId: {}", bo.getPlanId(), bo.getClassId(), teacherId);
try {
// 参数验证
if (bo.getPlanId() == null || bo.getClassId() == null || teacherId == null) {
log.error("参数验证失败 - planId: {}, classId: {}, teacherId: {}", bo.getPlanId(), bo.getClassId(), teacherId);
throw new RuntimeException("必要参数不能为空");
}
log.info("1. 开始逻辑删除历史评分数据...");
// 1. 先逻辑删除该计划下该教师该班级的历史评分数据
teacherAssessmentMapper.deleteAssessmentScoresByPlanAndTeacher(bo.getPlanId(), teacherId, bo.getClassId());
log.info("逻辑删除历史评分数据完成");
log.info("2. 查询方案ID...");
Long schemeId = teacherAssessmentMapper.selectSchemeIdByPlanId(bo.getPlanId());
if (schemeId == null) {
log.error("根据计划ID查询方案ID失败 - planId: {}", bo.getPlanId());
throw new RuntimeException("找不到对应的考核方案,请检查考核计划配置");
}
log.info("查询方案ID成功: {}", schemeId);
String currentUserName = LoginHelper.getUsername();
Long currentDeptId = LoginHelper.getDeptId();
Date now = new Date();
log.info("当前用户信息 - username: {}, deptId: {}", currentUserName, currentDeptId);
// 2. 插入班主任常规工作指标评分
if (bo.getRoutineWorkScores() != null && !bo.getRoutineWorkScores().isEmpty()) {
log.info("3. 开始插入班主任常规工作指标评分,共{}条", bo.getRoutineWorkScores().size());
for (int i = 0; i < bo.getRoutineWorkScores().size(); i++) {
AssessmentIndicatorScoreVo score = bo.getRoutineWorkScores().get(i);
log.info("插入常规工作指标 {}/{} - indicatorId: {}, selfScore: {}",
i + 1, bo.getRoutineWorkScores().size(), score.getId(), score.getSelfScore());
try {
BmzrAssessmentScore assessmentScore = new BmzrAssessmentScore();
assessmentScore.setPlanId(bo.getPlanId());
assessmentScore.setSchemeId(schemeId);
assessmentScore.setIndicatorId(score.getId());
assessmentScore.setEvaluatedUserId(teacherId);
assessmentScore.setEvaluatedUserName(currentUserName);
assessmentScore.setEvaluatedDeptId(currentDeptId);
assessmentScore.setSelfScore(score.getSelfScore());
assessmentScore.setSelfComment(score.getSelfComment());
// 保存操作不设置 self_submit_time,只有提交到审批流程时才设置
// assessmentScore.setSelfSubmitTime(now);
assessmentScore.setSubmitTime(now);
assessmentScore.setAuditStatus("9"); // 设置为草稿状态
// 设置班级ID和自我总体评价
assessmentScore.setClassId(bo.getClassId());
assessmentScore.setSelfOverallComment(bo.getOverallComment());
int insertResult = assessmentScoreMapper.insert(assessmentScore);
if (insertResult <= 0) {
log.error("插入常规工作指标评分失败 - indicatorId: {}", score.getId());
throw new RuntimeException("插入常规工作指标评分失败");
}
log.info("插入常规工作指标评分成功 - indicatorId: {}, 新记录ID: {}", score.getId(), assessmentScore.getId());
} catch (Exception e) {
log.error("插入常规工作指标评分异常 - indicatorId: {}, error: {}", score.getId(), e.getMessage(), e);
throw new RuntimeException("插入常规工作指标评分失败: " + e.getMessage());
}
}
log.info("班主任常规工作指标评分插入完成");
} else {
log.warn("班主任常规工作指标评分数据为空");
}
// 3. 插入班级扣分指标评分
log.info("4. 开始插入班级扣分指标评分...");
Long classDeductionIndicatorId = teacherAssessmentMapper.selectIndicatorIdByCode("bzrwjkf001");
if (classDeductionIndicatorId == null) {
log.error("找不到班级扣分指标 - indicatorCode: bzrwjkf001");
throw new RuntimeException("找不到班级扣分指标,请检查指标配置");
}
log.info("班级扣分指标ID: {}", classDeductionIndicatorId);
try {
BmzrAssessmentScore assessmentScore = new BmzrAssessmentScore();
assessmentScore.setPlanId(bo.getPlanId());
assessmentScore.setSchemeId(schemeId);
assessmentScore.setIndicatorId(classDeductionIndicatorId);
assessmentScore.setEvaluatedUserId(teacherId);
assessmentScore.setEvaluatedUserName(currentUserName);
assessmentScore.setEvaluatedDeptId(currentDeptId);
assessmentScore.setSelfScore(bo.getClassDeduction());
assessmentScore.setSelfComment(bo.getClassDeductionComment());
// 保存操作不设置 self_submit_time,只有提交到审批流程时才设置
// assessmentScore.setSelfSubmitTime(now);
assessmentScore.setSubmitTime(now);
assessmentScore.setAuditStatus("9"); // 设置为草稿状态
// 设置班级ID和自我总体评价
assessmentScore.setClassId(bo.getClassId());
assessmentScore.setSelfOverallComment(bo.getOverallComment());
int insertResult = assessmentScoreMapper.insert(assessmentScore);
if (insertResult <= 0) {
log.error("插入班级扣分指标评分失败");
throw new RuntimeException("插入班级扣分指标评分失败");
}
log.info("插入班级扣分指标评分成功 - 新记录ID: {}", assessmentScore.getId());
} catch (Exception e) {
log.error("插入班级扣分指标评分异常: {}", e.getMessage(), e);
throw new RuntimeException("插入班级扣分指标评分失败: " + e.getMessage());
}
// 4. 插入特色工作指标评分
if (bo.getSpecialWorkScores() != null && !bo.getSpecialWorkScores().isEmpty()) {
log.info("5. 开始插入特色工作指标评分,共{}条", bo.getSpecialWorkScores().size());
for (int i = 0; i < bo.getSpecialWorkScores().size(); i++) {
SpecialWorkIndicatorVo score = bo.getSpecialWorkScores().get(i);
log.info("插入特色工作指标 {}/{} - indicatorCode: {}, score: {}",
i + 1, bo.getSpecialWorkScores().size(), score.getIndicatorCode(), score.getScore());
Long indicatorId = teacherAssessmentMapper.selectIndicatorIdByCode(score.getIndicatorCode());
if (indicatorId == null) {
log.error("找不到特色工作指标 - indicatorCode: {}", score.getIndicatorCode());
throw new RuntimeException("找不到特色工作指标: " + score.getIndicatorCode());
}
log.info("特色工作指标ID: {} - {}", score.getIndicatorCode(), indicatorId);
try {
BmzrAssessmentScore assessmentScore = new BmzrAssessmentScore();
assessmentScore.setPlanId(bo.getPlanId());
assessmentScore.setSchemeId(schemeId);
assessmentScore.setIndicatorId(indicatorId);
assessmentScore.setEvaluatedUserId(teacherId);
assessmentScore.setEvaluatedUserName(currentUserName);
assessmentScore.setEvaluatedDeptId(currentDeptId);
assessmentScore.setSelfScore(score.getScore());
assessmentScore.setSelfComment(score.getSelfComment());
// 保存操作不设置 self_submit_time,只有提交到审批流程时才设置
// assessmentScore.setSelfSubmitTime(now);
assessmentScore.setSubmitTime(now);
assessmentScore.setAuditStatus("9"); // 设置为草稿状态
// 设置班级ID和自我总体评价
assessmentScore.setClassId(bo.getClassId());
assessmentScore.setSelfOverallComment(bo.getOverallComment());
int insertResult = assessmentScoreMapper.insert(assessmentScore);
if (insertResult <= 0) {
log.error("插入特色工作指标评分失败 - indicatorCode: {}", score.getIndicatorCode());
throw new RuntimeException("插入特色工作指标评分失败");
}
log.info("插入特色工作指标评分成功 - indicatorCode: {}, 新记录ID: {}",
score.getIndicatorCode(), assessmentScore.getId());
} catch (Exception e) {
log.error("插入特色工作指标评分异常 - indicatorCode: {}, error: {}",
score.getIndicatorCode(), e.getMessage(), e);
throw new RuntimeException("插入特色工作指标评分失败: " + e.getMessage());
}
}
log.info("特色工作指标评分插入完成");
} else {
log.warn("特色工作指标评分数据为空");
}
log.info("考核评分数据提交成功 - planId: {}, classId: {}, teacherId: {}", bo.getPlanId(), bo.getClassId(), teacherId);
return true;
} catch (Exception e) {
log.error("提交考核评分数据失败 - planId: {}, classId: {}, teacherId: {}, error: {}",
bo.getPlanId(), bo.getClassId(), teacherId, e.getMessage(), e);
// 重新抛出异常,让Controller能够捕获并返回错误信息
throw new RuntimeException("提交考核评分数据失败: " + e.getMessage());
}
}
/**
* 计算系数信息
*
* @param classDetail 班级详细信息
* @return 系数信息
*/
private CoefficientVo calculateCoefficient(ClassDetailVo classDetail) {
CoefficientVo coefficient = new CoefficientVo();
// 计算人数系数(K2)
int totalStudents = classDetail.getTotalStudentCount() != null ? classDetail.getTotalStudentCount() : 0;
log.info("计算人数系数 - 班级ID: {}, 班级名称: {}, 学生总人数: {}",
classDetail.getId(), classDetail.getClassName(), totalStudents);
// 数据验证:如果学生人数为0但前端显示有人数,可能是数据同步问题
if (totalStudents == 0) {
log.warn("警告:班级{}学生人数为0,请检查xg_student_msg表数据", classDetail.getClassName());
}
BigDecimal studentCountCoefficient = calculateStudentCountCoefficient(totalStudents);
log.info("计算人数系数结果: {}", studentCountCoefficient);
// 关键修复:确保人数系数不为0
if (studentCountCoefficient == null || studentCountCoefficient.compareTo(BigDecimal.ZERO) == 0) {
log.error("人数系数计算异常,学生人数: {},计算结果: {},进行修复", totalStudents, studentCountCoefficient);
// 直接重新计算并设置最低值
if (totalStudents > 0) {
// 手动计算25人的系数:1 - (36-25)*0.02 = 1 - 0.22 = 0.78
if (totalStudents < 36) {
int missingStudents = 36 - totalStudents;
BigDecimal deduction = BigDecimal.valueOf(missingStudents).multiply(BigDecimal.valueOf(0.02));
studentCountCoefficient = BigDecimal.ONE.subtract(deduction);
if (studentCountCoefficient.compareTo(BigDecimal.valueOf(0.7)) < 0) {
studentCountCoefficient = BigDecimal.valueOf(0.7);
}
studentCountCoefficient = studentCountCoefficient.setScale(4, RoundingMode.HALF_UP);
log.info("修复后的人数系数: {}", studentCountCoefficient);
} else {
studentCountCoefficient = BigDecimal.valueOf(0.7).setScale(4, RoundingMode.HALF_UP);
}
} else {
studentCountCoefficient = BigDecimal.valueOf(0.7).setScale(4, RoundingMode.HALF_UP);
}
}
coefficient.setStudentCountCoefficient(studentCountCoefficient);
// 验证系数设置是否成功
if (coefficient.getStudentCountCoefficient() == null ||
coefficient.getStudentCountCoefficient().compareTo(BigDecimal.ZERO) == 0) {
log.error("错误:人数系数设置仍然失败,当前值: {}", coefficient.getStudentCountCoefficient());
}
// 计算住校生系数(K3)
int boardingStudents = classDetail.getBoardingStudentCount() != null ? classDetail.getBoardingStudentCount() : 0;
BigDecimal boardingCoefficient = calculateBoardingCoefficient(boardingStudents);
coefficient.setBoardingCoefficient(boardingCoefficient);
// 计算层次系数(K1)
BigDecimal levelCoefficient = calculateLevelCoefficient(classDetail.getClassType());
coefficient.setLevelCoefficient(levelCoefficient);
// 计算总系数(K = K1 * (K2 + K3))
BigDecimal totalCoefficient = levelCoefficient.multiply(studentCountCoefficient.add(boardingCoefficient));
coefficient.setTotalCoefficient(totalCoefficient);
return coefficient;
}
/**
* 计算人数系数(K2)
* 班级人数36~40人(含36人),系数为1;
* 超过40人,每增加1名学生,系数增加0.02;
* 少于36人,每减少1名学生,系数减少0.02;
* 本项系数最低0.7
*/
private BigDecimal calculateStudentCountCoefficient(int studentCount) {
log.info("开始计算人数系数 - 输入学生人数: {}", studentCount);
// 数据验证:如果学生人数异常,使用保护性默认值
if (studentCount < 0) {
log.warn("学生人数为负数({}),使用默认值0", studentCount);
studentCount = 0;
}
BigDecimal coefficient;
if (studentCount >= 36 && studentCount <= 40) {
coefficient = BigDecimal.ONE;
log.info("人数在36-40人范围内,系数为1.0");
} else if (studentCount > 40) {
int extraStudents = studentCount - 40;
coefficient = BigDecimal.ONE.add(BigDecimal.valueOf(extraStudents * 0.02));
log.info("人数超过40人,额外{}人,系数为{}", extraStudents, coefficient);
} else {
// 少于36人的情况
int missingStudents = 36 - studentCount;
// 使用更精确的BigDecimal计算,避免精度问题
BigDecimal deduction = BigDecimal.valueOf(missingStudents).multiply(BigDecimal.valueOf(0.02));
coefficient = BigDecimal.ONE.subtract(deduction);
log.info("人数少于36人,缺少{}人,扣减{},计算系数为{}", missingStudents, deduction, coefficient);
// 最低0.7
BigDecimal minCoefficient = BigDecimal.valueOf(0.7);
if (coefficient.compareTo(minCoefficient) < 0) {
log.info("系数{}低于最低值0.7,调整为0.7", coefficient);
coefficient = minCoefficient;
}
}
BigDecimal result = coefficient.setScale(4, RoundingMode.HALF_UP);
log.info("最终人数系数: {}", result);
// 额外验证:确保结果不为0
if (result.compareTo(BigDecimal.ZERO) == 0) {
log.error("严重错误:人数系数计算结果为0,学生人数: {},强制设置为最低值0.7", studentCount);
result = BigDecimal.valueOf(0.7).setScale(4, RoundingMode.HALF_UP);
}
return result;
}
/**
* 撤销考核提交
*
* @param planId 计划ID
* @param classId 班级ID
* @param teacherId 班主任ID
* @return 是否成功
*/
@Override
public boolean withdrawAssessment(Long planId, Long classId, Long teacherId) {
try {
// 验证是否有权限撤销(只能撤销自己提交的且状态为待审核的考核)
List<AssessmentIndicatorScoreVo> submittedScores = teacherAssessmentMapper.selectSubmittedAssessmentScores(planId, teacherId, classId);
if (submittedScores == null || submittedScores.isEmpty()) {
log.warn("未找到可撤销的考核提交记录,计划ID: {}, 教师ID: {}, 班级ID: {}", planId, teacherId, classId);
return false;
}
// 检查审核状态,只有待审核状态("0")的才能撤销
boolean canWithdraw = submittedScores.stream().anyMatch(score -> "0".equals(score.getAuditStatus()));
if (!canWithdraw) {
log.warn("考核已审核,无法撤销,计划ID: {}, 教师ID: {}", planId, teacherId);
return false;
}
// 将待审核状态的评分记录恢复为草稿状态
assessmentScoreMapper.update(null,
new LambdaUpdateWrapper<BmzrAssessmentScore>()
.set(BmzrAssessmentScore::getAuditStatus, "9") // 设置为草稿状态
.set(BmzrAssessmentScore::getSubmitTime, null) // 清空提交时间
.set(BmzrAssessmentScore::getSelfSubmitTime, null) // 清空自评提交时间
.eq(BmzrAssessmentScore::getPlanId, planId)
.eq(BmzrAssessmentScore::getEvaluatedUserId, teacherId)
.eq(BmzrAssessmentScore::getClassId, classId) // 添加班级ID过滤条件,确保班级隔离
.eq(BmzrAssessmentScore::getAuditStatus, "0") // 只更新待审核状态的记录
.eq(BmzrAssessmentScore::getDeleted, 0)
);
log.info("成功撤销考核提交,数据已恢复为草稿状态,计划ID: {}, 教师ID: {}", planId, teacherId);
return true;
} catch (Exception e) {
log.error("撤销考核提交失败,计划ID: {}, 教师ID: {}", planId, teacherId, e);
return false;
}
}
/**
* 测试人数系数计算(临时调试方法)
* 可以通过调用这个方法来验证具体人数的系数计算
*/
public BigDecimal testStudentCountCoefficient(int studentCount) {
log.info("=== 测试人数系数计算 ===");
log.info("输入学生人数: {}", studentCount);
BigDecimal result = calculateStudentCountCoefficient(studentCount);
log.info("计算结果: {}", result);
log.info("=== 测试结束 ===");
return result;
}
/**
* 计算住校生系数(K3)
* 根据住校生人数,按人均0.005计算
*/
private BigDecimal calculateBoardingCoefficient(int boardingCount) {
return BigDecimal.valueOf(boardingCount * 0.005).setScale(4, RoundingMode.HALF_UP);
}
/**
* 计算层次系数(K1)
* 技师班(K1=0.95),高级工班(K1=1),中级工班(K1=1.05)
*/
private BigDecimal calculateLevelCoefficient(String classType) {
if (classType == null) {
return BigDecimal.ONE;
}
switch (classType) {
case "1": // 中级工
return BigDecimal.valueOf(1.05);
case "2": // 高级工
return BigDecimal.ONE;
case "3": // 预备技师
return BigDecimal.valueOf(0.95);
case "4": // 技师
return BigDecimal.valueOf(0.95);
case "5": // 中高职一体
return BigDecimal.ONE;
default:
return BigDecimal.ONE;
}
}
/**
* 合并已保存的评分数据
*/
private void mergeAssessmentScores(AssessmentDetailVo detailVo, List<AssessmentIndicatorScoreVo> savedScores) {
// 合并班主任常规工作指标评分
if (detailVo.getRoutineWorkIndicators() != null) {
for (AssessmentIndicatorScoreVo indicator : detailVo.getRoutineWorkIndicators()) {
savedScores.stream()
.filter(saved -> saved.getId().equals(indicator.getId()))
.findFirst()
.ifPresent(saved -> {
indicator.setSelfScore(saved.getSelfScore());
indicator.setSelfComment(saved.getSelfComment());
});
}
}
// 合并班级扣分指标评分
if (detailVo.getClassDeductionIndicator() != null) {
savedScores.stream()
.filter(saved -> "bzrwjkf001".equals(saved.getIndicatorCode()))
.findFirst()
.ifPresent(saved -> {
detailVo.getClassDeductionIndicator().setSelfScore(saved.getSelfScore());
detailVo.getClassDeductionIndicator().setSelfComment(saved.getSelfComment());
});
}
// 合并特色工作指标评分
if (detailVo.getSpecialWorkIndicators() != null) {
for (SpecialWorkIndicatorVo indicator : detailVo.getSpecialWorkIndicators()) {
savedScores.stream()
.filter(saved -> indicator.getIndicatorCode().equals(saved.getIndicatorCode()))
.findFirst()
.ifPresent(saved -> {
indicator.setScore(saved.getSelfScore());
indicator.setSelfComment(saved.getSelfComment());
});
}
}
}
/**
* 查询班级学生违纪记录和奖励记录
*
* @param classId 班级ID
* @return 班级学生记录
*/
@Override
public ClassStudentRecordsVo queryClassStudentRecords(Long classId) {
// 查询班级信息
String className = teacherAssessmentMapper.selectClassNameById(classId);
// 查询班级学生违纪记录
List<StudentDisciplineRecordVo> disciplineRecords = teacherAssessmentMapper.selectStudentDisciplineRecordsByClassId(classId);
// 查询班级学生奖励记录
List<StudentRewardRecordVo> rewardRecords = teacherAssessmentMapper.selectStudentRewardRecordsByClassId(classId);
// 构建返回对象
ClassStudentRecordsVo result = new ClassStudentRecordsVo();
result.setClassId(classId);
result.setClassName(className);
result.setDisciplineRecords(disciplineRecords);
result.setRewardRecords(rewardRecords);
result.setDisciplineCount(disciplineRecords != null ? disciplineRecords.size() : 0);
result.setRewardCount(rewardRecords != null ? rewardRecords.size() : 0);
return result;
}
}
@@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.bzrkh.mapper.AssessmentApprovalMapper">
<!-- 审核列表结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalVo" id="AssessmentApprovalVoResult">
<result property="id" column="id"/>
<result property="planId" column="plan_id"/>
<result property="planName" column="plan_name"/>
<result property="planCode" column="plan_code"/>
<result property="schemeId" column="scheme_id"/>
<result property="schemeName" column="scheme_name"/>
<result property="academicYear" column="academic_year"/>
<result property="semester" column="semester"/>
<result property="classId" column="class_id"/>
<result property="className" column="class_name"/>
<result property="teacherId" column="teacher_id"/>
<result property="teacherName" column="teacher_name"/>
<result property="evaluatedUserId" column="evaluated_user_id"/>
<result property="evaluatedUserName" column="evaluated_user_name"/>
<result property="submitTime" column="submit_time"/>
<result property="auditStatus" column="audit_status"/>
<result property="selfScore" column="self_score"/>
<result property="superiorScore" column="superior_score"/>
<result property="finalScore" column="final_score"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
</resultMap>
<!-- 审核详情结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo" id="AssessmentApprovalDetailVoResult">
<result property="id" column="id"/>
<result property="planId" column="plan_id"/>
<result property="classId" column="class_id"/>
<result property="selfOverallComment" column="self_overall_comment"/>
<result property="superiorOverallComment" column="superior_overall_comment"/>
<result property="auditStatus" column="audit_status"/>
<result property="submitTime" column="submit_time"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<!-- 审核指标结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo" id="AssessmentApprovalIndicatorVoResult">
<result property="id" column="id"/>
<result property="indicatorId" column="indicator_id"/>
<result property="indicatorName" column="indicator_name"/>
<result property="indicatorCode" column="indicator_code"/>
<result property="description" column="description"/>
<result property="score" column="score"/>
<result property="maxScore" column="max_score"/>
<result property="selfScore" column="self_score"/>
<result property="selfComment" column="self_comment"/>
<result property="superiorScore" column="superior_score"/>
<result property="superiorComment" column="superior_comment"/>
<result property="auditStatus" column="audit_status"/>
</resultMap>
<!-- 特色工作审核结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo" id="AssessmentApprovalSpecialWorkVoResult">
<result property="id" column="id"/>
<result property="indicatorCode" column="indicator_code"/>
<result property="indicatorName" column="indicator_name"/>
<result property="score" column="self_score"/>
<result property="selfScore" column="self_score"/>
<result property="selfComment" column="self_comment"/>
<result property="superiorScore" column="superior_score"/>
<result property="superiorComment" column="superior_comment"/>
<result property="auditStatus" column="audit_status"/>
</resultMap>
<!-- 方案选项结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.SchemeOptionVo" id="SchemeOptionVoResult">
<result property="value" column="scheme_name"/>
<result property="label" column="scheme_name"/>
<result property="schemeId" column="id"/>
<result property="schemeCode" column="scheme_code"/>
</resultMap>
<!-- 查询班主任考核审核列表 -->
<select id="queryList" parameterType="org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo" resultMap="AssessmentApprovalVoResult">
SELECT
MIN(s.id) as id,
s.plan_id,
p.plan_name,
p.plan_code,
s.scheme_id,
sch.scheme_name,
p.academic_year,
p.semester,
s.class_id,
c.class_name,
c.class_teacher_id as teacher_id,
c.class_teacher_name as teacher_name,
s.evaluated_user_id,
s.evaluated_user_name,
MAX(s.submit_time) as submit_time,
MAX(s.audit_status) as audit_status,
SUM(s.self_score) as self_score,
SUM(s.superior_score) as superior_score,
SUM(s.final_score) as final_score,
MAX(s.create_time) as create_time,
MAX(s.create_by) as create_by,
MAX(s.update_time) as update_time,
MAX(s.update_by) as update_by
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_plan p ON s.plan_id = p.id AND p.deleted = 0
LEFT JOIN bmzr_assessment_scheme sch ON s.scheme_id = sch.id AND sch.deleted = 0
LEFT JOIN xg_class_msg c ON s.class_id = c.id AND c.deleted = 0
WHERE s.deleted = 0
AND s.self_submit_time IS NOT NULL
<if test="planName != null and planName != ''">
AND p.plan_name LIKE CONCAT('%', #{planName}, '%')
</if>
<if test="schemeName != null and schemeName != ''">
AND sch.scheme_name LIKE CONCAT('%', #{schemeName}, '%')
</if>
<if test="auditStatus != null and auditStatus != ''">
AND s.audit_status = #{auditStatus}
</if>
<if test="className != null and className != ''">
AND c.class_name LIKE CONCAT('%', #{className}, '%')
</if>
<if test="teacherName != null and teacherName != ''">
AND c.class_teacher_name LIKE CONCAT('%', #{teacherName}, '%')
</if>
<if test="evaluatedUserName != null and evaluatedUserName != ''">
AND s.evaluated_user_name LIKE CONCAT('%', #{evaluatedUserName}, '%')
</if>
<if test="academicYear != null and academicYear != ''">
AND p.academic_year = #{academicYear}
</if>
<if test="semester != null and semester != ''">
AND p.semester = #{semester}
</if>
GROUP BY s.plan_id, s.class_id, s.evaluated_user_id, s.scheme_id, s.audit_status, s.evaluated_user_name,
p.plan_name, p.plan_code, p.academic_year, p.semester,
c.class_name, c.class_teacher_id, c.class_teacher_name,
sch.scheme_name
ORDER BY MAX(s.create_time) DESC
</select>
<!-- 获取考核审核基本信息 -->
<select id="getApprovalBasicInfo" resultMap="AssessmentApprovalDetailVoResult">
SELECT
MIN(s.id) as id,
s.plan_id,
s.class_id,
-- 确保获取自我总体评价(可能存在于不同指标中)
COALESCE(
MAX(CASE WHEN s.self_overall_comment IS NOT NULL AND s.self_overall_comment != ''
THEN s.self_overall_comment END),
''
) as self_overall_comment,
MAX(s.superior_overall_comment) as superior_overall_comment,
MAX(s.audit_status) as audit_status,
MAX(s.submit_time) as submit_time,
MAX(s.create_by) as create_by,
MAX(s.create_time) as create_time,
MAX(s.update_by) as update_by,
MAX(s.update_time) as update_time
FROM bmzr_assessment_score s
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
GROUP BY s.plan_id, s.class_id, s.evaluated_user_id
LIMIT 1
</select>
<!-- 获取班主任常规工作指标列表 -->
<select id="getRoutineWorkIndicators" resultMap="AssessmentApprovalIndicatorVoResult">
SELECT
s.id,
s.indicator_id,
i.indicator_name,
i.indicator_code,
CONCAT(i.indicator_name, '(', i.remark, ')') as description,
i.score,
i.max_score,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment,
s.audit_status
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND i.indicator_type = 'routine_work'
ORDER BY i.sort_order ASC
</select>
<!-- 获取班级扣分指标(班级管理实效) -->
<select id="getClassDeductionIndicator" resultMap="AssessmentApprovalIndicatorVoResult">
SELECT
s.id,
s.indicator_id,
i.indicator_name,
i.indicator_code,
CONCAT(i.indicator_name, '(', i.remark, ')') as description,
i.score,
i.max_score,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment,
s.audit_status
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND i.indicator_type = 'class_deduction'
LIMIT 1
</select>
<!-- 获取特色工作指标列表 -->
<select id="getSpecialWorkIndicators" resultMap="AssessmentApprovalSpecialWorkVoResult">
SELECT
s.id,
i.indicator_code,
i.indicator_name,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment,
s.audit_status
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND i.indicator_type = 'special_work'
ORDER BY i.sort_order ASC
</select>
<!-- 更新上级评分和意见 -->
<update id="updateSuperiorScore">
UPDATE bmzr_assessment_score
SET superior_score = #{superiorScore},
superior_comment = #{superiorComment},
superior_evaluator_id = #{approverUserId},
superior_submit_time = NOW(),
update_by = #{approverUserId},
update_time = NOW()
WHERE id = #{id}
AND deleted = 0
</update>
<!-- 更新审核状态和意见 -->
<update id="updateAuditStatus">
UPDATE bmzr_assessment_score
SET audit_status = #{auditStatus},
superior_overall_comment = #{superiorOverallComment},
update_by = #{approverUserId},
update_time = NOW()
WHERE plan_id = #{planId}
AND class_id = #{classId}
AND evaluated_user_id = #{evaluatedUserId}
AND deleted = 0
</update>
<!-- 批量更新审核状态 -->
<update id="batchUpdateAuditStatus">
UPDATE bmzr_assessment_score
SET audit_status = #{auditStatus},
superior_overall_comment = #{auditComment},
update_by = #{approverUserId},
update_time = NOW()
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
AND deleted = 0
</update>
<!-- 获取考核方案选项 -->
<select id="getSchemeOptions" resultType="org.dromara.bzrkh.domain.vo.SchemeOptionVo">
SELECT
id as value,
scheme_name as label
FROM bmzr_assessment_scheme
WHERE deleted = 0
AND status = '0'
ORDER BY create_time DESC
</select>
<!-- 删除异常的审批记录(管理员专用) -->
<update id="deleteAbnormalAssessmentRecord">
UPDATE bmzr_assessment_score
SET deleted = 1,
update_time = NOW()
WHERE plan_id = #{planId}
AND evaluated_user_id = #{evaluatedUserId}
AND deleted = 0
</update>
<!-- 根据计划ID查询所有审批数据 -->
<select id="selectApprovalListByPlan" resultType="org.dromara.bzrkh.domain.vo.AssessmentApprovalVo">
SELECT DISTINCT
p.id as planId,
p.plan_name as planName,
c.id as classId,
c.class_name as className,
u.user_id as evaluatedUserId,
u.nick_name as evaluatedUserName,
u.dept_id as evaluatedDeptId,
d.dept_name as evaluatedDeptName,
sch.id as schemeId,
sch.scheme_name as schemeName,
sc.audit_status as auditStatus,
sc.create_time as createTime
FROM bmzr_assessment_score sc
LEFT JOIN bmzr_assessment_plan p ON sc.plan_id = p.id AND p.deleted = 0
LEFT JOIN xg_class_msg c ON sc.class_id = c.id AND c.deleted = 0
LEFT JOIN bmzr_assessment_scheme sch ON sc.scheme_id = sch.id AND sch.deleted = 0
LEFT JOIN sys_user u ON sc.evaluated_user_id = u.user_id
LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
WHERE sc.plan_id = #{planId}
AND sc.deleted = 0
AND sc.self_submit_time IS NOT NULL
ORDER BY sc.create_time DESC
</select>
</mapper>
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.bzrkh.mapper.AssessmentScoreMapper">
<!-- 自评数据基本信息结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentScoreDetailVo" id="AssessmentScoreDetailVoResult">
<result property="planId" column="plan_id"/>
<result property="classId" column="class_id"/>
<result property="evaluatedUserId" column="evaluated_user_id"/>
<result property="evaluatedUserName" column="evaluated_user_name"/>
<result property="selfOverallComment" column="self_overall_comment"/>
<result property="selfSubmitTime" column="self_submit_time"/>
<result property="auditStatus" column="audit_status"/>
<result property="hasAssessmentData" column="has_assessment_data"/>
</resultMap>
<!-- 自评指标结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentScoreIndicatorVo" id="AssessmentScoreIndicatorVoResult">
<result property="id" column="id"/>
<result property="indicatorId" column="indicator_id"/>
<result property="indicatorName" column="indicator_name"/>
<result property="indicatorCode" column="indicator_code"/>
<result property="description" column="description"/>
<result property="score" column="score"/>
<result property="maxScore" column="max_score"/>
<result property="selfScore" column="self_score"/>
<result property="selfComment" column="self_comment"/>
<result property="superiorScore" column="superior_score"/>
<result property="superiorComment" column="superior_comment"/>
</resultMap>
<!-- 特色工作自评结果映射 -->
<resultMap type="org.dromara.bzrkh.domain.vo.AssessmentScoreSpecialWorkVo" id="AssessmentScoreSpecialWorkVoResult">
<result property="id" column="id"/>
<result property="indicatorId" column="indicator_id"/>
<result property="indicatorCode" column="indicator_code"/>
<result property="indicatorName" column="indicator_name"/>
<result property="score" column="self_score"/>
<result property="selfScore" column="self_score"/>
<result property="selfComment" column="self_comment"/>
<result property="superiorScore" column="superior_score"/>
<result property="superiorComment" column="superior_comment"/>
</resultMap>
<!-- 获取自评数据基本信息 -->
<select id="getAssessmentScoreBasicInfo" resultMap="AssessmentScoreDetailVoResult">
SELECT
s.plan_id,
s.class_id,
s.evaluated_user_id,
s.evaluated_user_name,
-- 获取自我总体评价(优先获取非空值)
COALESCE(
MAX(CASE WHEN s.self_overall_comment IS NOT NULL AND s.self_overall_comment != ''
THEN s.self_overall_comment END),
''
) as self_overall_comment,
MAX(s.self_submit_time) as self_submit_time,
MAX(s.audit_status) as audit_status,
CASE WHEN COUNT(s.id) > 0 THEN 1 ELSE 0 END as has_assessment_data
FROM bmzr_assessment_score s
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND s.self_submit_time IS NOT NULL
GROUP BY s.plan_id, s.class_id, s.evaluated_user_id, s.evaluated_user_name
LIMIT 1
</select>
<!-- 获取班主任常规工作自评数据 -->
<select id="getRoutineWorkScores" resultMap="AssessmentScoreIndicatorVoResult">
SELECT
s.id,
s.indicator_id,
i.indicator_name,
i.indicator_code,
CONCAT(i.indicator_name, CASE WHEN i.remark IS NOT NULL AND i.remark != ''
THEN CONCAT('(', i.remark, ')') ELSE '' END) as description,
i.score,
i.max_score,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND s.self_submit_time IS NOT NULL
AND i.indicator_type = 'bzr-001'
ORDER BY i.sort_order ASC, s.id ASC
</select>
<!-- 获取班级管理实效自评数据 -->
<select id="getClassDeductionScore" resultMap="AssessmentScoreIndicatorVoResult">
SELECT
s.id,
s.indicator_id,
i.indicator_name,
i.indicator_code,
CONCAT(i.indicator_name, CASE WHEN i.remark IS NOT NULL AND i.remark != ''
THEN CONCAT('(', i.remark, ')') ELSE '' END) as description,
i.score,
i.max_score,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND s.self_submit_time IS NOT NULL
AND i.indicator_type = 'bzr-002'
LIMIT 1
</select>
<!-- 获取特色工作自评数据 -->
<select id="getSpecialWorkScores" resultMap="AssessmentScoreSpecialWorkVoResult">
SELECT
s.id,
s.indicator_id,
i.indicator_code,
i.indicator_name,
s.self_score,
s.self_comment,
s.superior_score,
s.superior_comment
FROM bmzr_assessment_score s
LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND s.self_submit_time IS NOT NULL
AND i.indicator_type = 'bzr-003'
ORDER BY i.sort_order ASC, s.id ASC
</select>
<!-- 检查是否存在自评数据 -->
<select id="countAssessmentScore" resultType="int">
SELECT COUNT(1)
FROM bmzr_assessment_score s
WHERE s.plan_id = #{planId}
AND s.class_id = #{classId}
AND s.evaluated_user_id = #{evaluatedUserId}
AND s.deleted = 0
AND s.self_submit_time IS NOT NULL
</select>
</mapper>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.bzrkh.mapper.BmzrAssessmentIndicatorMapper">
<resultMap type="org.dromara.bzrkh.domain.BmzrAssessmentIndicator" id="BmzrAssessmentIndicatorResult">
<result property="id" column="id" />
<result property="tenantId" column="tenant_id" />
<result property="indicatorName" column="indicator_name" />
<result property="indicatorCode" column="indicator_code" />
<result property="indicatorType" column="indicator_type" />
<result property="parentId" column="parent_id" />
<result property="sortOrder" column="sort_order" />
<result property="weightRatio" column="weight_ratio" />
<result property="maxScore" column="max_score" />
<result property="score" column="score" />
<result property="allowSelfEvaluation" column="allow_self_evaluation" />
<result property="allowSuperiorEvaluation" column="allow_superior_evaluation" />
<result property="status" column="status" />
<result property="remark" column="remark" />
<result property="createDept" column="create_dept" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="deleted" column="deleted" />
</resultMap>
</mapper>
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.bzrkh.mapper.BmzrAssessmentPlanMapper">
<!-- 班主任考核计划结果映射(包含方案名称) -->
<resultMap type="org.dromara.bzrkh.domain.vo.BmzrAssessmentPlanVo" id="BmzrAssessmentPlanVoResult">
<result property="id" column="id"/>
<result property="tenantId" column="tenant_id"/>
<result property="planName" column="plan_name"/>
<result property="planCode" column="plan_code"/>
<result property="schemeId" column="scheme_id"/>
<result property="schemeName" column="scheme_name"/>
<result property="academicYear" column="academic_year"/>
<result property="semester" column="semester"/>
<result property="planStartTime" column="plan_start_time"/>
<result property="planEndTime" column="plan_end_time"/>
<result property="dataExtractStartTime" column="data_extract_start_time"/>
<result property="dataExtractEndTime" column="data_extract_end_time"/>
<result property="planStatus" column="plan_status"/>
<result property="description" column="description"/>
<result property="remark" column="remark"/>
<result property="createDept" column="create_dept"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="deleted" column="deleted"/>
</resultMap>
<!-- 查询班主任考核计划列表(包含方案名称) -->
<select id="selectAssessmentPlanListWithScheme" parameterType="org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo" resultMap="BmzrAssessmentPlanVoResult">
SELECT
p.id,
p.tenant_id,
p.plan_name,
p.plan_code,
p.scheme_id,
s.scheme_name,
p.academic_year,
p.semester,
p.plan_start_time,
p.plan_end_time,
p.data_extract_start_time,
p.data_extract_end_time,
p.plan_status,
p.description,
p.remark,
p.create_dept,
p.create_by,
p.create_time,
p.update_by,
p.update_time,
p.deleted
FROM bmzr_assessment_plan p
LEFT JOIN bmzr_assessment_scheme s ON p.scheme_id = s.id AND s.deleted = 0
WHERE p.deleted = 0
<if test="planName != null and planName != ''">
AND p.plan_name LIKE CONCAT('%', #{planName}, '%')
</if>
<if test="planCode != null and planCode != ''">
AND p.plan_code LIKE CONCAT('%', #{planCode}, '%')
</if>
<if test="schemeId != null">
AND p.scheme_id = #{schemeId}
</if>
<if test="academicYear != null and academicYear != ''">
AND p.academic_year = #{academicYear}
</if>
<if test="semester != null and semester != ''">
AND p.semester = #{semester}
</if>
<if test="planStatus != null and planStatus != ''">
AND p.plan_status = #{planStatus}
</if>
<if test="planStartTime != null">
AND p.plan_start_time &gt;= #{planStartTime}
</if>
<if test="planEndTime != null">
AND p.plan_end_time &lt;= #{planEndTime}
</if>
<if test="params.beginCreateTime != null and params.endCreateTime != null">
AND p.create_time BETWEEN #{params.beginCreateTime} AND #{params.endCreateTime}
</if>
ORDER BY p.create_time DESC
</select>
<!-- 分页查询班主任考核计划列表(包含方案名称) -->
<select id="selectAssessmentPlanPageWithScheme" parameterType="org.dromara.bzrkh.domain.bo.BmzrAssessmentPlanBo" resultMap="BmzrAssessmentPlanVoResult">
SELECT
p.id,
p.tenant_id,
p.plan_name,
p.plan_code,
p.scheme_id,
s.scheme_name,
p.academic_year,
p.semester,
p.plan_start_time,
p.plan_end_time,
p.data_extract_start_time,
p.data_extract_end_time,
p.plan_status,
p.description,
p.remark,
p.create_dept,
p.create_by,
p.create_time,
p.update_by,
p.update_time,
p.deleted
FROM bmzr_assessment_plan p
LEFT JOIN bmzr_assessment_scheme s ON p.scheme_id = s.id AND s.deleted = 0
WHERE p.deleted = 0
<if test="bo.planName != null and bo.planName != ''">
AND p.plan_name LIKE CONCAT('%', #{bo.planName}, '%')
</if>
<if test="bo.planCode != null and bo.planCode != ''">
AND p.plan_code LIKE CONCAT('%', #{bo.planCode}, '%')
</if>
<if test="bo.schemeId != null">
AND p.scheme_id = #{bo.schemeId}
</if>
<if test="bo.academicYear != null and bo.academicYear != ''">
AND p.academic_year = #{bo.academicYear}
</if>
<if test="bo.semester != null and bo.semester != ''">
AND p.semester = #{bo.semester}
</if>
<if test="bo.planStatus != null and bo.planStatus != ''">
AND p.plan_status = #{bo.planStatus}
</if>
<if test="bo.planStartTime != null">
AND p.plan_start_time &gt;= #{bo.planStartTime}
</if>
<if test="bo.planEndTime != null">
AND p.plan_end_time &lt;= #{bo.planEndTime}
</if>
<if test="bo.params.beginCreateTime != null and bo.params.endCreateTime != null">
AND p.create_time BETWEEN #{bo.params.beginCreateTime} AND #{bo.params.endCreateTime}
</if>
ORDER BY p.create_time DESC
</select>
<!-- 根据考核计划ID批量逻辑删除关联的考核得分数据 -->
<update id="deleteAssessmentScoresByPlanIds">
UPDATE bmzr_assessment_score
SET deleted = 1,
update_time = NOW()
WHERE deleted = 0
AND plan_id IN
<foreach collection="planIds" item="planId" open="(" separator="," close=")">
#{planId}
</foreach>
</update>
</mapper>
Loaded 100 of 2419 files, more files were not shown because too many files have changed in this diff. Show more