提交
This commit is contained in:
1 parent
774e8d1137
commit
f85b9b258a
13 files changed
+2468
-522
No files matched your search
+22
@@ -112,6 +112,18 @@ public class XskhDisciplineRecordController extends BaseController {
|
||||
return R.ok(xskhDisciplineRecordService.getStudentOptions(keyword));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询学生选项列表(用于移动端)
|
||||
*/
|
||||
@SaCheckPermission("disciplineRecord:disciplineRecord:query")
|
||||
@GetMapping("/studentOptionsPage")
|
||||
public R<List<XskhStudentOptionVo>> getStudentOptionsPage(
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "20") Integer pageSize) {
|
||||
return R.ok(xskhDisciplineRecordService.getStudentOptionsPage(keyword, pageNum, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录学生的违纪处分记录列表
|
||||
*/
|
||||
@@ -166,4 +178,14 @@ public class XskhDisciplineRecordController extends BaseController {
|
||||
@RequestParam String endTime) {
|
||||
return R.ok(xskhDisciplineRecordService.getMaxScoreByTypeAndPeriod(typeId, startTime, endTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索)
|
||||
*/
|
||||
@SaCheckPermission("disciplineRecord:disciplineRecord:query")
|
||||
@GetMapping("/myCreated")
|
||||
public TableDataInfo<XskhDisciplineRecordVo> getMyCreatedDisciplineRecords(XskhDisciplineRecordBo bo,
|
||||
PageQuery pageQuery) {
|
||||
return xskhDisciplineRecordService.queryMyCreatedPageList(bo, pageQuery);
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -23,9 +23,13 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus<XskhDisciplin
|
||||
* 查询学生选项列表(用于下拉框)
|
||||
*
|
||||
* @param keyword 搜索关键词(学号或姓名)
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 每页数量
|
||||
* @return 学生选项列表
|
||||
*/
|
||||
List<XskhStudentOptionVo> selectStudentOptions(String keyword);
|
||||
List<XskhStudentOptionVo> selectStudentOptions(@Param("keyword") String keyword,
|
||||
@Param("pageNum") Integer pageNum,
|
||||
@Param("pageSize") Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询班主任班级的违纪处分记录列表(班主任专用)
|
||||
|
||||
+22
@@ -50,9 +50,22 @@ public interface IXskhDisciplineRecordService {
|
||||
|
||||
/**
|
||||
* 查询学生选项列表(用于下拉框)
|
||||
*
|
||||
* @param keyword 搜索关键词
|
||||
* @return 学生选项列表
|
||||
*/
|
||||
List<XskhStudentOptionVo> getStudentOptions(String keyword);
|
||||
|
||||
/**
|
||||
* 分页查询学生选项列表(用于移动端)
|
||||
*
|
||||
* @param keyword 搜索关键词
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 每页数量
|
||||
* @return 学生选项列表
|
||||
*/
|
||||
List<XskhStudentOptionVo> getStudentOptionsPage(String keyword, Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询当前登录学生的违纪处分记录列表
|
||||
*/
|
||||
@@ -101,4 +114,13 @@ public interface IXskhDisciplineRecordService {
|
||||
* @return 最高总扣分
|
||||
*/
|
||||
java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime);
|
||||
|
||||
/**
|
||||
* 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索)
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 违纪记录分页列表
|
||||
*/
|
||||
TableDataInfo<XskhDisciplineRecordVo> queryMyCreatedPageList(XskhDisciplineRecordBo bo, PageQuery pageQuery);
|
||||
}
|
||||
+51
-1
@@ -165,7 +165,15 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer
|
||||
*/
|
||||
@Override
|
||||
public List<XskhStudentOptionVo> getStudentOptions(String keyword) {
|
||||
return baseMapper.selectStudentOptions(keyword);
|
||||
return baseMapper.selectStudentOptions(keyword, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询学生选项列表(用于移动端)
|
||||
*/
|
||||
@Override
|
||||
public List<XskhStudentOptionVo> getStudentOptionsPage(String keyword, Integer pageNum, Integer pageSize) {
|
||||
return baseMapper.selectStudentOptions(keyword, pageNum, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,4 +294,46 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer
|
||||
log.info("违纪类型 {} 的最高总扣分为: {}", typeId, maxScore);
|
||||
return maxScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索)
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<XskhDisciplineRecordVo> queryMyCreatedPageList(XskhDisciplineRecordBo bo,
|
||||
PageQuery pageQuery) {
|
||||
// 获取当前登录用户ID
|
||||
Long currentUserId = LoginHelper.getUserId();
|
||||
log.info("查询用户 {} 创建的违纪记录列表", currentUserId);
|
||||
|
||||
// 构建查询条件,强制只查询当前用户创建的记录
|
||||
LambdaQueryWrapper<XskhDisciplineRecord> lqw = Wrappers.lambdaQuery();
|
||||
|
||||
// 核心条件:只查询当前用户创建的记录
|
||||
lqw.eq(XskhDisciplineRecord::getCreateBy, currentUserId);
|
||||
|
||||
// 支持按学生姓名或学号模糊搜索(使用OR连接)
|
||||
if (StringUtils.isNotBlank(bo.getStudentName()) || StringUtils.isNotBlank(bo.getStudentNo())) {
|
||||
String keyword = StringUtils.isNotBlank(bo.getStudentName()) ? bo.getStudentName() : bo.getStudentNo();
|
||||
lqw.and(wrapper -> wrapper
|
||||
.like(XskhDisciplineRecord::getStudentName, keyword)
|
||||
.or()
|
||||
.like(XskhDisciplineRecord::getStudentNo, keyword));
|
||||
}
|
||||
|
||||
// 其他可选查询条件
|
||||
lqw.eq(bo.getStudentId() != null, XskhDisciplineRecord::getStudentId, bo.getStudentId());
|
||||
lqw.eq(bo.getCollegeId() != null, XskhDisciplineRecord::getCollegeId, bo.getCollegeId());
|
||||
lqw.eq(bo.getMajorId() != null, XskhDisciplineRecord::getMajorId, bo.getMajorId());
|
||||
lqw.eq(bo.getClassId() != null, XskhDisciplineRecord::getClassId, bo.getClassId());
|
||||
lqw.eq(bo.getDisciplineTypeId() != null, XskhDisciplineRecord::getDisciplineTypeId, bo.getDisciplineTypeId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XskhDisciplineRecord::getStatus, bo.getStatus());
|
||||
|
||||
// 按创建时间倒序排列
|
||||
lqw.orderByDesc(XskhDisciplineRecord::getCreateTime);
|
||||
|
||||
// 执行分页查询
|
||||
Page<XskhDisciplineRecordVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
log.info("查询到 {} 条记录", result.getTotal());
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -49,7 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
select id, student_id, student_no, student_name, college_id, college_name, major_id, major_name, class_id, class_name, discipline_type_id, discipline_type_name, discipline_date, discipline_reason, discipline_content, score_deduction, status, violation_source, attachment_oss_ids, create_by, create_time, create_dept, update_by, update_time, deleted, tenant_id from xskh_discipline_record
|
||||
</sql>
|
||||
|
||||
<select id="selectStudentOptions" parameterType="String" resultMap="StudentOptionResult">
|
||||
<select id="selectStudentOptions" resultMap="StudentOptionResult">
|
||||
select
|
||||
id, student_no, name, college_id, college_name,
|
||||
major_id, major_name, class_id, class_name
|
||||
@@ -61,7 +61,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
or name like concat('%', #{keyword}, '%'))
|
||||
</if>
|
||||
order by student_no
|
||||
<choose>
|
||||
<when test="pageNum != null and pageSize != null">
|
||||
limit ${(pageNum - 1) * pageSize}, #{pageSize, jdbcType=INTEGER}
|
||||
</when>
|
||||
<otherwise>
|
||||
limit 50
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<select id="selectClassTeacherVoPage" resultType="XskhDisciplineRecordVo">
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
# 代码调整记录 - 2025-01-08 - Cursor AI
|
||||
|
||||
## 📝 变更概述
|
||||
**变更时间**: 2025-01-08 15:30:00
|
||||
**变更人员**: Cursor AI
|
||||
**变更类型**: 数据库结构修复
|
||||
**影响模块**: 社团管理 - 活动报名功能
|
||||
|
||||
## 🔴 **问题描述**
|
||||
**问题现象**: 活动报名接口数据插入失败,报错缺少字段
|
||||
**根本原因**: `stgl_activity_registration` 数据库表结构与实体类不匹配,缺失多个字段
|
||||
|
||||
**缺失字段清单**:
|
||||
- `remark` - 申请理由(非必填)
|
||||
- `gender` - 性别
|
||||
- `phone` - 联系电话
|
||||
- `email` - 邮箱
|
||||
- `department` - 院系
|
||||
- `major` - 专业
|
||||
- `class_name` - 班级
|
||||
|
||||
## ✅ **解决方案**
|
||||
|
||||
### 1. 创建修复SQL脚本
|
||||
**文件**: `docs/设计文档/database/社团管理/修复活动报名表字段.sql`
|
||||
- 添加7个缺失字段到 `stgl_activity_registration` 表
|
||||
- 新增性能优化索引 (`idx_gender`, `idx_phone`, `idx_department`)
|
||||
- 包含验证和检查语句
|
||||
|
||||
### 2. 更新建表脚本
|
||||
**文件**: `docs/设计文档/database/社团管理/社团管理建表脚本.sql`
|
||||
- 在 `stgl_activity_registration` 表中补充完整字段定义
|
||||
- 调整字段顺序,符合逻辑分组(基本信息、审核信息、成绩信息、学生个人信息)
|
||||
- 新增对应索引
|
||||
|
||||
## 📊 **影响范围**
|
||||
- ✅ **后端**: StglActivityRegistration 实体类字段完整匹配
|
||||
- ✅ **数据库**: 表结构字段补全,支持完整业务数据
|
||||
- ✅ **API**: 活动报名相关接口正常工作
|
||||
- ✅ **前端**: 报名表单数据可正常提交和保存
|
||||
|
||||
## 🧪 **验证方法**
|
||||
```sql
|
||||
-- 1. 执行修复脚本
|
||||
source docs/设计文档/database/社团管理/修复活动报名表字段.sql
|
||||
|
||||
-- 2. 验证表结构
|
||||
DESCRIBE stgl_activity_registration;
|
||||
|
||||
-- 3. 测试插入数据
|
||||
-- 使用活动报名API接口测试完整数据提交
|
||||
```
|
||||
|
||||
## 📋 **待执行任务**
|
||||
- [x] 分析问题原因
|
||||
- [x] 创建修复SQL脚本
|
||||
- [x] 更新建表脚本
|
||||
- [x] 记录变更日志
|
||||
- [ ] **需要执行**: 在数据库中运行修复脚本
|
||||
- [ ] **需要测试**: 验证活动报名功能正常
|
||||
|
||||
## 🔗 **相关文件**
|
||||
- `backend/ruoyi-modules/ruoyi-stgl/src/main/java/org/dromara/stgl/domain/StglActivityRegistration.java`
|
||||
- `backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityRegistrationMapper.xml`
|
||||
- `docs/设计文档/database/社团管理/社团管理建表脚本.sql`
|
||||
- `docs/设计文档/database/社团管理/修复活动报名表字段.sql` (新增)
|
||||
|
||||
## 💡 **经验总结**
|
||||
1. **数据库与实体类一致性**: 开发时必须确保数据库表结构与实体类字段完全匹配
|
||||
2. **渐进式开发问题**: 实体类后续添加字段时,必须同步更新数据库表结构
|
||||
3. **文档同步重要性**: 建表脚本必须与实际代码保持同步,避免部署时出现问题
|
||||
4. **字段分组设计**: 表字段应该按业务逻辑分组,提高可读性和维护性
|
||||
|
||||
---
|
||||
*本记录严格按照项目规范要求,代码变更与文档同步更新*
|
||||
@@ -1,241 +0,0 @@
|
||||
# 代码调整记录 - 2025-01-14 - cursor
|
||||
|
||||
## 📝 变更概述
|
||||
**变更日期**: 2025-01-14 15:30:00
|
||||
**处理人员**: cursor
|
||||
**变更类型**: 前端功能修复 + UI优化
|
||||
|
||||
## 🎯 变更内容
|
||||
|
||||
### 1. 修复预约时段状态切换功能 (XljkConsultationSchedule)
|
||||
|
||||
**问题描述**:
|
||||
- 心理健康咨询预约时段管理页面,点击编辑按钮后状态切换异常
|
||||
- 无论当前状态如何,都会变成停用状态
|
||||
- 显示双重状态标签,界面异常
|
||||
|
||||
**根本原因分析**:
|
||||
1. **状态值类型不一致**: 前端接收的`status`是字符串类型(`"0"`, `"1"`),但切换逻辑使用数字比较(`=== 1`)
|
||||
2. **字典数据缺失**: `schedule_status`字典未正确配置,导致显示异常
|
||||
3. **状态更新接口数据类型错误**: 发送数字状态但接收端可能期望字符串
|
||||
|
||||
**修复方案**:
|
||||
|
||||
#### 1.1 修复状态切换逻辑
|
||||
**文件**: `web/src/views/xljk/consultation/schedule/index.vue`
|
||||
|
||||
**修改前**:
|
||||
```typescript
|
||||
const handleUpdate = async (row?: XljkConsultationScheduleVO) => {
|
||||
if (row && row.id) {
|
||||
try {
|
||||
await updateXljkSchedule({
|
||||
id: row.id,
|
||||
status: row.status === 1 ? 0 : 1 // 错误:字符串与数字比较
|
||||
} as XljkConsultationScheduleForm);
|
||||
ElMessage.success('状态更新成功');
|
||||
getList();
|
||||
} catch (error) {
|
||||
console.error('更新时段状态失败', error);
|
||||
ElMessage.error('状态更新失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```typescript
|
||||
const handleUpdate = async (row?: XljkConsultationScheduleVO) => {
|
||||
if (row && row.id) {
|
||||
try {
|
||||
// 修复:将字符串状态正确转换为数字进行比较
|
||||
const currentStatus = parseInt(row.status as string);
|
||||
const newStatus = currentStatus === 1 ? 0 : 1;
|
||||
|
||||
console.log(`状态切换调试 - 当前状态: ${row.status} (${typeof row.status}), 转换后: ${currentStatus}, 新状态: ${newStatus}`);
|
||||
|
||||
await updateXljkSchedule({
|
||||
id: row.id,
|
||||
status: newStatus.toString()
|
||||
} as XljkConsultationScheduleForm);
|
||||
|
||||
ElMessage.success(`状态已${newStatus === 0 ? '启用' : '停用'}`);
|
||||
getList();
|
||||
} catch (error) {
|
||||
console.error('更新时段状态失败', error);
|
||||
ElMessage.error('状态更新失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**修复要点**:
|
||||
- ✅ 使用 `parseInt()` 将字符串状态转换为数字进行比较
|
||||
- ✅ 添加调试日志输出,便于问题排查
|
||||
- ✅ 改进用户提示消息,明确显示状态变更结果
|
||||
- ✅ 确保发送的状态值类型一致性
|
||||
|
||||
#### 1.2 创建字典数据配置
|
||||
**文件**: `backend/script/sql/xljk-dict-data.sql`
|
||||
|
||||
**新增内容**:
|
||||
```sql
|
||||
-- 预约时段状态字典
|
||||
INSERT INTO sys_dict_type VALUES (102, '000000', '预约时段状态', 'schedule_status', 103, 1, sysdate(), NULL, NULL, '预约时段状态列表');
|
||||
|
||||
-- 预约时段状态字典数据
|
||||
INSERT INTO sys_dict_data VALUES (300, '000000', 1, '正常', '0', 'schedule_status', '', 'success', 'Y', 103, 1, sysdate(), NULL, NULL, '正常状态');
|
||||
INSERT INTO sys_dict_data VALUES (301, '000000', 2, '停用', '1', 'schedule_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '停用状态');
|
||||
```
|
||||
|
||||
**配置要点**:
|
||||
- ✅ 创建 `schedule_status` 字典类型
|
||||
- ✅ 配置状态值:`0-正常`(success样式)、`1-停用`(danger样式)
|
||||
- ✅ 同时创建相关的预约状态和时段类型字典
|
||||
|
||||
### 2. 优化预约时段管理列表列宽 (2025-01-14 15:45:00)
|
||||
|
||||
**调整目标**: 缩小上午时段、下午时段、创建时间3个列的列宽,优化页面布局
|
||||
|
||||
**列宽调整对比**:
|
||||
|
||||
| 字段名称 | 调整前 | 调整后 | 变化 |
|
||||
|----------|--------|--------|------|
|
||||
| **上午时段** | `min-width="150"` | `min-width="120"` | -30px |
|
||||
| **下午时段** | `min-width="150"` | `min-width="120"` | -30px |
|
||||
| **创建时间** | `width="150"` | `width="120"` | -30px |
|
||||
|
||||
**修改位置**: `web/src/views/xljk/consultation/schedule/index.vue` (第84-102行)
|
||||
|
||||
**修改内容**:
|
||||
```vue
|
||||
<!-- 上午时段列 -->
|
||||
<el-table-column label="上午时段" align="center" min-width="120">
|
||||
|
||||
<!-- 下午时段列 -->
|
||||
<el-table-column label="下午时段" align="center" min-width="120">
|
||||
|
||||
<!-- 创建时间列 -->
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="120">
|
||||
```
|
||||
|
||||
**优化效果**:
|
||||
- ✅ 总体节省空间:90px (30px × 3列)
|
||||
- ✅ 上午/下午时段列保持响应式 (`min-width`)
|
||||
- ✅ 创建时间列固定宽度更紧凑
|
||||
- ✅ 为其他列提供更多显示空间
|
||||
- ✅ 提升页面整体布局效率
|
||||
|
||||
**表格布局更新**:
|
||||
- **原总最小宽度**: 1115px
|
||||
- **新总最小宽度**: 1025px
|
||||
- **空间优化**: 节省90px宽度
|
||||
|
||||
### 3. 移除预约限制管理页面创建时间字段 (2025-01-14 16:00:00)
|
||||
|
||||
**调整目标**: 移除预约限制管理(未到访记录)列表界面的创建时间字段显示
|
||||
|
||||
**页面位置**: `web/src/views/xljk/consultation/noshow/index.vue`
|
||||
|
||||
**移除字段**:
|
||||
```vue
|
||||
<!-- 已移除的创建时间列 -->
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="150">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
```
|
||||
|
||||
**修改位置**: 第92-96行
|
||||
|
||||
**优化效果**:
|
||||
- ✅ **简化界面**: 移除不必要的时间信息显示
|
||||
- ✅ **节省空间**: 释放150px列宽空间
|
||||
- ✅ **聚焦核心**: 突出学生信息、限制状态等关键信息
|
||||
- ✅ **提升体验**: 减少信息冗余,提高页面简洁度
|
||||
|
||||
**当前保留字段**:
|
||||
- 学生姓名、学号、院系、专业、班级
|
||||
- 未到访日期、限制到期日、状态
|
||||
- 操作(查看、解除限制)
|
||||
|
||||
**表格布局优化**:
|
||||
- **移除列宽**: 150px
|
||||
- **界面更简洁**: 专注于业务核心信息
|
||||
- **操作便捷**: 保留查看详情和解除限制功能
|
||||
|
||||
## 🔧 技术细节
|
||||
|
||||
### 问题原因深度分析
|
||||
|
||||
1. **JavaScript类型转换问题**:
|
||||
```javascript
|
||||
// 问题代码
|
||||
"1" === 1 // false (字符串与数字比较)
|
||||
|
||||
// 修复代码
|
||||
parseInt("1") === 1 // true (转换后比较)
|
||||
```
|
||||
|
||||
2. **数据流类型不一致**:
|
||||
```
|
||||
后端返回 → status: "0" (字符串)
|
||||
前端比较 → status === 1 (数字)
|
||||
结果 → 永远返回false,总是执行 : 1 分支
|
||||
```
|
||||
|
||||
3. **字典配置缺失**:
|
||||
```vue
|
||||
<dict-tag :options="schedule_status" :value="scope.row.status" />
|
||||
```
|
||||
当 `schedule_status` 字典为空时,`dict-tag` 组件无法正确渲染,可能显示原始值或双重标签。
|
||||
|
||||
### 测试验证
|
||||
|
||||
**验证步骤**:
|
||||
1. ✅ 启动前端开发服务器
|
||||
2. ✅ 导航至心理健康 → 咨询管理 → 预约时段
|
||||
3. ✅ 检查状态列显示是否正常(应显示"正常"或"停用")
|
||||
4. ✅ 点击编辑按钮测试状态切换
|
||||
5. ✅ 观察控制台调试日志
|
||||
6. ✅ 验证状态在正常/停用之间正确切换
|
||||
|
||||
**预期结果**:
|
||||
- 状态列正确显示"正常"/"停用"标签
|
||||
- 点击编辑按钮后状态正确切换
|
||||
- 用户提示消息明确显示变更结果
|
||||
- 控制台输出调试信息供问题排查
|
||||
|
||||
## 📊 影响范围
|
||||
|
||||
**直接影响**:
|
||||
- ✅ 心理健康咨询预约时段管理功能恢复正常
|
||||
- ✅ 状态切换功能可正确启用/停用时段
|
||||
|
||||
**间接影响**:
|
||||
- ✅ 改善用户体验,操作反馈更清晰
|
||||
- ✅ 为类似的状态切换功能提供标准修复模式
|
||||
- ✅ 完善了心理健康模块的字典数据配置
|
||||
|
||||
## 🚀 后续优化建议
|
||||
|
||||
1. **统一类型处理**: 考虑在前端建立统一的状态值处理工具函数
|
||||
2. **完善错误处理**: 添加更详细的错误处理和用户提示
|
||||
3. **字典数据管理**: 建立字典数据的统一管理和维护机制
|
||||
4. **测试用例**: 为状态切换功能添加单元测试和集成测试
|
||||
|
||||
## 📋 变更文件清单
|
||||
|
||||
| 文件路径 | 变更类型 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `web/src/views/xljk/consultation/schedule/index.vue` | 修改 | 修复状态切换逻辑 + 优化列宽布局 |
|
||||
| `web/src/views/xljk/consultation/noshow/index.vue` | 修改 | 移除创建时间字段显示 |
|
||||
| `backend/script/sql/xljk-dict-data.sql` | 新增 | 创建心理健康模块字典数据配置 |
|
||||
| `docs/变更管理/code-adjust-record-2025-01-14-cursor.md` | 新增 | 本变更记录文档 |
|
||||
|
||||
---
|
||||
|
||||
**验证完成**: ✅ 功能测试通过
|
||||
**文档更新**: ✅ 已同步更新
|
||||
**代码审查**: ✅ 自检完成
|
||||
@@ -1,66 +0,0 @@
|
||||
# 代码调整记录 - 2025-01-15 - cursor
|
||||
|
||||
## 🔧 数据库字段修复
|
||||
|
||||
### 📅 变更时间
|
||||
2025-01-15 14:30:00
|
||||
|
||||
### 🎯 变更目标
|
||||
修复 `stgl_activity` 表缺失的 `remark` 字段
|
||||
|
||||
### ⚠️ 问题描述
|
||||
在社团活动管理功能中出现以下错误:
|
||||
```
|
||||
Unknown column 'sa.remark' in 'field list'
|
||||
```
|
||||
|
||||
**错误原因分析:**
|
||||
1. 实体类 `StglActivity.java` 中定义了 `remark` 字段
|
||||
2. MyBatis映射文件 `StglActivityMapper.xml` 中的SQL查询包含了 `sa.remark` 字段
|
||||
3. 但数据库表 `stgl_activity` 中实际缺少 `remark` 字段
|
||||
|
||||
### 🔍 修复过程
|
||||
|
||||
#### 1. 问题定位
|
||||
- 检查实体类:`StglActivity.java` 第216-217行定义了remark字段
|
||||
- 检查映射文件:`StglActivityMapper.xml` 第59行和第40行引用了remark字段
|
||||
- 检查数据库表:`stgl_activity` 表确实缺少remark字段
|
||||
|
||||
#### 2. 修复方案
|
||||
为 `stgl_activity` 表添加缺失的 `remark` 字段
|
||||
|
||||
#### 3. 执行的SQL语句
|
||||
```sql
|
||||
ALTER TABLE `stgl_activity`
|
||||
ADD COLUMN `remark` varchar(500) DEFAULT NULL COMMENT '备注' AFTER `import_source`;
|
||||
```
|
||||
|
||||
#### 4. 修复结果验证
|
||||
- ✅ remark字段成功添加到stgl_activity表
|
||||
- ✅ 字段类型:varchar(500)
|
||||
- ✅ 字段注释:备注
|
||||
- ✅ 字段位置:import_source字段之后
|
||||
|
||||
### 📁 相关文件
|
||||
- **实体类**: `backend/ruoyi-modules/ruoyi-stgl/src/main/java/org/dromara/stgl/domain/StglActivity.java`
|
||||
- **映射文件**: `backend/ruoyi-modules/ruoyi-stgl/src/main/resources/mapper/stgl/StglActivityMapper.xml`
|
||||
- **修复脚本**: `backend/script/sql/fix-stgl-activity-remark-field.sql`
|
||||
- **建表脚本**: `docs/设计文档/database/社团管理/社团管理建表脚本.sql`
|
||||
|
||||
### 🎯 影响范围
|
||||
- **功能模块**: 社团活动管理
|
||||
- **影响接口**: 所有涉及stgl_activity表查询的接口
|
||||
- **数据完整性**: 修复后代码与数据库结构保持一致
|
||||
|
||||
### ✅ 验证结果
|
||||
修复完成后,社团活动管理相关功能应该能正常运行,不再出现字段缺失错误。
|
||||
|
||||
### 📝 经验教训
|
||||
1. **数据库同步**: 确保实体类、映射文件与数据库表结构完全一致
|
||||
2. **建表脚本**: 需要检查建表脚本是否包含所有必要字段
|
||||
3. **字段映射**: MyBatis映射文件中的字段必须在数据库表中实际存在
|
||||
|
||||
---
|
||||
**修复人员**: Cursor AI
|
||||
**修复时间**: 2025-01-15 14:30:00
|
||||
**状态**: ✅ 已完成
|
||||
@@ -1,137 +0,0 @@
|
||||
# 代码调整记录 - 2025-01-21 - Cursor AI
|
||||
|
||||
## 📋 变更概述
|
||||
|
||||
**时间**: 2025-01-21 10:30:00
|
||||
**操作人**: Cursor AI
|
||||
**变更类型**: 🐛 Bug修复
|
||||
**影响范围**: 志愿者成员管理模块
|
||||
|
||||
## 🔍 问题描述
|
||||
|
||||
**问题现象**: 当前登录用户`2025LY23117`是志愿者马拉松工作组的队长,该队伍总共有3个人,但在志愿者成员管理页面只能看到一个成员。
|
||||
|
||||
**根本原因**: 志愿者角色类型(roleType)在前后端定义不一致,导致权限过滤逻辑失效。
|
||||
|
||||
### 问题详情
|
||||
|
||||
| 组件 | 队长值 | 队员值 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| 前端字典(修复前) | 1 | 2 | ❌ 错误 |
|
||||
| 后端权限过滤 | 0 | 1 | ✅ 正确 |
|
||||
| 数据库SQL映射 | 0 | 1 | ✅ 正确 |
|
||||
| 字典表(修复前) | 1 | 2 | ❌ 错误 |
|
||||
|
||||
**影响**:
|
||||
- 权限过滤方法`getCaptainTeamIds`查找`roleType=0`时找不到队长记录
|
||||
- 查询条件被设置为`relationId=-1L`,导致返回空结果
|
||||
- 用户只能看到第一个队伍的数据
|
||||
|
||||
## 🛠️ 解决方案
|
||||
|
||||
**采用方案A**: 统一使用数据库SQL的定义(队长=0,队员=1)
|
||||
|
||||
### 修复内容
|
||||
|
||||
#### 1. 修改字典表数据
|
||||
**文件**: `backend/script/sql/stgl_volunteer_role_dict.sql`
|
||||
- 队长的`dict_value`从'1'改为'0'
|
||||
- 队员的`dict_value`从'2'改为'1'
|
||||
|
||||
#### 2. 修改前端字典定义
|
||||
**文件**: `web/src/views/stgl/volunteer/member/index.vue`
|
||||
- 第358-361行:更新手动定义的字典
|
||||
- 第432行:修改默认角色值为'1'(队员)
|
||||
- 第242行:移除parseInt转换,保持字符串类型
|
||||
- 第632行:修改类型转换为String()
|
||||
|
||||
#### 3. 创建数据库更新脚本
|
||||
**文件**: `script/update-volunteer-role-dict.sql`
|
||||
- 创建线上数据库更新脚本
|
||||
- 包含验证查询和完成提示
|
||||
|
||||
## 📝 修改细节
|
||||
|
||||
### 代码变更
|
||||
|
||||
```javascript
|
||||
// 修复前
|
||||
const stgl_volunteer_role = ref([
|
||||
{ value: '1', label: '队长' },
|
||||
{ value: '2', label: '队员' }
|
||||
]);
|
||||
|
||||
// 修复后
|
||||
const stgl_volunteer_role = ref([
|
||||
{ value: '0', label: '队长' },
|
||||
{ value: '1', label: '队员' }
|
||||
]);
|
||||
```
|
||||
|
||||
```sql
|
||||
-- 修复前字典数据
|
||||
VALUES (..., '队长', '1', ...)
|
||||
VALUES (..., '队员', '2', ...)
|
||||
|
||||
-- 修复后字典数据
|
||||
VALUES (..., '队长', '0', ...)
|
||||
VALUES (..., '队员', '1', ...)
|
||||
```
|
||||
|
||||
### 权限过滤逻辑验证
|
||||
|
||||
后端权限过滤逻辑保持不变(已正确):
|
||||
```java
|
||||
captainBo.setRoleType(0); // 队长角色 = 0
|
||||
```
|
||||
|
||||
数据库SQL映射保持不变(已正确):
|
||||
```xml
|
||||
WHEN 0 THEN '队长' <!-- 队长 = 0 -->
|
||||
WHEN 1 THEN '队员' <!-- 队员 = 1 -->
|
||||
```
|
||||
|
||||
## 🎯 预期效果
|
||||
|
||||
修复完成后:
|
||||
1. ✅ 志愿者队长能够正确查看所属队伍的所有成员
|
||||
2. ✅ 权限过滤逻辑正常工作
|
||||
3. ✅ 前后端角色类型定义统一
|
||||
4. ✅ 字典数据显示正确
|
||||
|
||||
## 📋 部署步骤
|
||||
|
||||
1. **执行数据库更新脚本**:
|
||||
```bash
|
||||
mysql -u username -p database < script/update-volunteer-role-dict.sql
|
||||
```
|
||||
|
||||
2. **重新构建前端**:
|
||||
```bash
|
||||
cd web
|
||||
npm run build
|
||||
```
|
||||
|
||||
3. **重启后端服务**(如有缓存)
|
||||
|
||||
4. **验证功能**:
|
||||
- 使用队长账号登录
|
||||
- 访问志愿者成员管理页面
|
||||
- 确认能看到所有队伍成员
|
||||
|
||||
## 🔍 验证要点
|
||||
|
||||
- [ ] 队长能查看所属队伍的所有成员
|
||||
- [ ] 角色显示正确(队长/队员)
|
||||
- [ ] 新增成员时角色选择正常
|
||||
- [ ] 权限过滤按预期工作
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- **问题分析**: 本文档"问题描述"部分
|
||||
- **技术规范**: `.cursor/cursorrules-backend.md` - 权限管理规范
|
||||
- **API文档**: `docs/开发文档/API/志愿者管理API.md`
|
||||
|
||||
## 🏷️ 标签
|
||||
|
||||
`#志愿者管理` `#权限过滤` `#角色类型` `#前后端统一` `#字典数据` `#Bug修复`
|
||||
@@ -246,6 +246,22 @@
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/xskh/wjjlEntry/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "违纪记录录入",
|
||||
"navigationBarBackgroundColor": "#0051d9",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/xskh/wjjlEntry/disciplineRecordForm",
|
||||
"style": {
|
||||
"navigationBarTitleText": "违纪记录",
|
||||
"navigationBarBackgroundColor": "#0051d9",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/xskh/khsq/khsq",
|
||||
"style": {
|
||||
|
||||
@@ -263,6 +263,20 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:violation:entry'])"
|
||||
title="违纪记录录入"
|
||||
@click="gotoViolationEntry"
|
||||
>
|
||||
<template #icon>
|
||||
<image
|
||||
src="/static/00125.png"
|
||||
mode="aspectFit"
|
||||
style="width: 24px; height: 24px"
|
||||
/>
|
||||
</template>
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:assessment:applyapp'])"
|
||||
title="考核申请"
|
||||
@@ -739,6 +753,7 @@ export default {
|
||||
this.hasPermi(['student:dynamics:list']) ||
|
||||
this.hasPermi(['student:workstudy:list']) ||
|
||||
this.hasPermi(['student:violation:listapp']) ||
|
||||
this.hasPermi(['student:violation:entry']) ||
|
||||
this.hasPermi(['student:assessment:applyapp']) ||
|
||||
this.hasPermi(['student:counsel:reservation'])
|
||||
);
|
||||
@@ -989,6 +1004,13 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到违纪记录录入页面
|
||||
gotoViolationEntry() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/xskh/wjjlEntry/index',
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到考核申请页面
|
||||
gotoAssessmentApply() {
|
||||
uni.navigateTo({
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,511 @@
|
||||
<template>
|
||||
<view class="discipline-record-container">
|
||||
<!-- 顶部导航 -->
|
||||
<u-navbar title="违纪记录录入" :border-bottom="false" bg-color="#3c9cff" title-color="#fff">
|
||||
<view slot="left" @click="goBack">
|
||||
<u-icon name="arrow-left" color="#fff" size="22"></u-icon>
|
||||
</view>
|
||||
</u-navbar>
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<u-search
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索学生姓名或学号"
|
||||
:show-action="false"
|
||||
@search="handleSearch"
|
||||
@custom="handleSearch"
|
||||
bg-color="#f6f6f6"
|
||||
shape="round"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<u-loading-page :loading="loading" loading-text="加载中..."></u-loading-page>
|
||||
|
||||
<!-- 违纪记录列表 -->
|
||||
<view v-if="!loading" class="content-wrapper">
|
||||
<!-- 空状态 -->
|
||||
<view v-if="disciplineRecordList.length === 0" class="empty-container">
|
||||
<u-empty text="暂无违纪记录" mode="data"></u-empty>
|
||||
</view>
|
||||
|
||||
<!-- 记录卡片列表 -->
|
||||
<view v-else class="record-list">
|
||||
<view
|
||||
v-for="(item, index) in disciplineRecordList"
|
||||
:key="item.id || index"
|
||||
class="record-card"
|
||||
>
|
||||
<!-- 卡片头部 -->
|
||||
<view class="card-header">
|
||||
<view class="student-info">
|
||||
<text class="student-name">{{ item.studentName || '-' }}</text>
|
||||
<text class="student-no">({{ item.studentNo || '-' }})</text>
|
||||
</view>
|
||||
<view class="record-status">
|
||||
<u-tag
|
||||
:text="getDictLabel(item.status)"
|
||||
:type="getStatusType(item.status)"
|
||||
size="mini"
|
||||
></u-tag>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 卡片内容 -->
|
||||
<view class="card-content">
|
||||
<view class="info-item">
|
||||
<text class="label">违纪类型:</text>
|
||||
<text class="value">{{ item.disciplineTypeName || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">违纪日期:</text>
|
||||
<text class="value">{{ item.disciplineDate || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">扣分分值:</text>
|
||||
<text class="value value-score">-{{ item.scoreDeduction || '0' }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">学院班级:</text>
|
||||
<text class="value">
|
||||
{{ item.collegeName || '-' }} / {{ item.className || '-' }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="item.disciplineReason" class="info-item">
|
||||
<text class="label">违纪原因:</text>
|
||||
<text class="value">{{ item.disciplineReason }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="card-actions">
|
||||
<!-- 查看按钮 -->
|
||||
<u-button
|
||||
type="info"
|
||||
size="small"
|
||||
class="action-btn"
|
||||
@click="handleView(item)"
|
||||
>
|
||||
<u-icon name="eye" size="16" color="#323233"></u-icon>
|
||||
<text>查看</text>
|
||||
</u-button>
|
||||
|
||||
<!-- 编辑按钮 -->
|
||||
<u-button
|
||||
type="primary"
|
||||
size="small"
|
||||
class="action-btn"
|
||||
@click="handleEdit(item)"
|
||||
>
|
||||
<u-icon name="edit-pen" size="16" color="#ffffff"></u-icon>
|
||||
<text class="btn-text">编辑</text>
|
||||
</u-button>
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
<u-button
|
||||
type="error"
|
||||
size="small"
|
||||
class="action-btn"
|
||||
@click="handleDelete(item)"
|
||||
>
|
||||
<u-icon name="trash" size="16" color="#ffffff"></u-icon>
|
||||
<text class="btn-text">删除</text>
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view v-if="disciplineRecordList.length > 0" class="load-more">
|
||||
<u-loadmore :status="loadMoreStatus" @loadmore="loadMore" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 浮动新增按钮 -->
|
||||
<view class="float-add-button" @click="handleAdd">
|
||||
<u-icon name="plus" color="#fff" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request } from '@/common/request.js';
|
||||
import { getDictLabel, getDictTagType, getDict } from '@/common/dict.js';
|
||||
|
||||
export default {
|
||||
name: 'DisciplineRecordEntry',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
disciplineRecordList: [],
|
||||
total: 0,
|
||||
|
||||
// 搜索关键词
|
||||
searchKeyword: '',
|
||||
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
studentName: '',
|
||||
studentNo: '',
|
||||
},
|
||||
|
||||
// 加载更多状态
|
||||
loadMoreStatus: 'loadmore',
|
||||
|
||||
// 字典数据
|
||||
statusDict: [],
|
||||
};
|
||||
},
|
||||
async created() {
|
||||
await this.loadDictData();
|
||||
await this.getList();
|
||||
|
||||
// 监听页面刷新事件
|
||||
uni.$on('refreshDisciplineRecordList', () => {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
onUnload() {
|
||||
// 移除监听
|
||||
uni.$off('refreshDisciplineRecordList');
|
||||
},
|
||||
methods: {
|
||||
// 返回上一页
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
|
||||
// 加载字典数据
|
||||
async loadDictData() {
|
||||
try {
|
||||
this.statusDict = await getDict('student_discipline_status');
|
||||
} catch (error) {
|
||||
console.error('加载字典数据失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 获取字典标签
|
||||
getDictLabel(value) {
|
||||
return getDictLabel(this.statusDict, value) || value;
|
||||
},
|
||||
|
||||
// 获取状态类型
|
||||
getStatusType(status) {
|
||||
const fallbackMap = {
|
||||
1: 'success', // 生效
|
||||
2: 'info', // 已撤销
|
||||
};
|
||||
return getDictTagType(this.statusDict, status, fallbackMap);
|
||||
},
|
||||
|
||||
// 获取违纪记录列表(仅显示当前用户创建的)
|
||||
async getList() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/disciplineRecord/disciplineRecord/myCreated',
|
||||
method: 'GET',
|
||||
params: this.queryParams,
|
||||
});
|
||||
|
||||
if (res && res.code === 200) {
|
||||
const newList = res.rows || [];
|
||||
|
||||
if (this.queryParams.pageNum === 1) {
|
||||
this.disciplineRecordList = newList;
|
||||
} else {
|
||||
this.disciplineRecordList = [...this.disciplineRecordList, ...newList];
|
||||
}
|
||||
|
||||
this.total = res.total || 0;
|
||||
|
||||
// 更新加载更多状态
|
||||
if (this.disciplineRecordList.length >= this.total) {
|
||||
this.loadMoreStatus = 'nomore';
|
||||
} else {
|
||||
this.loadMoreStatus = 'loadmore';
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res?.msg || '获取数据失败',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取违纪记录列表失败:', error);
|
||||
uni.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'none',
|
||||
});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 搜索处理
|
||||
handleSearch() {
|
||||
// 解析搜索关键词
|
||||
const keyword = this.searchKeyword.trim();
|
||||
|
||||
// 重置查询参数
|
||||
this.queryParams.pageNum = 1;
|
||||
|
||||
// 如果关键词为空,清空搜索条件
|
||||
if (!keyword) {
|
||||
this.queryParams.studentName = '';
|
||||
this.queryParams.studentNo = '';
|
||||
} else {
|
||||
// 同时按学生姓名和学号搜索
|
||||
this.queryParams.studentName = keyword;
|
||||
this.queryParams.studentNo = keyword;
|
||||
}
|
||||
|
||||
// 重新加载列表
|
||||
this.getList();
|
||||
},
|
||||
|
||||
// 加载更多
|
||||
loadMore() {
|
||||
if (this.loadMoreStatus === 'loading' || this.loadMoreStatus === 'nomore') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadMoreStatus = 'loading';
|
||||
this.queryParams.pageNum += 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
// 刷新列表
|
||||
handleSuccess() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
// 新增按钮操作
|
||||
handleAdd() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/xskh/wjjlEntry/disciplineRecordForm?mode=add',
|
||||
});
|
||||
},
|
||||
|
||||
// 查看按钮操作
|
||||
handleView(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/xskh/wjjlEntry/disciplineRecordForm?mode=view&id=${row.id}`,
|
||||
});
|
||||
},
|
||||
|
||||
// 编辑按钮操作
|
||||
handleEdit(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/xskh/wjjlEntry/disciplineRecordForm?mode=edit&id=${row.id}`,
|
||||
});
|
||||
},
|
||||
|
||||
// 删除按钮操作
|
||||
handleDelete(row) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: `确定要删除学生"${row.studentName}"的违纪记录吗?`,
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
uni.showLoading({ title: '删除中...' });
|
||||
|
||||
await request({
|
||||
url: `/disciplineRecord/disciplineRecord/${row.id}`,
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success',
|
||||
});
|
||||
|
||||
this.handleSuccess();
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
console.error('删除失败:', error);
|
||||
uni.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.discipline-record-container {
|
||||
background-color: #f5f6fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
padding: 20rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
padding: 20rpx;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.empty-container {
|
||||
padding: 100rpx 20rpx;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.record-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.student-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.student-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.student-no {
|
||||
font-size: 26rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.record-status {
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #606266;
|
||||
min-width: 140rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.value-score {
|
||||
color: #f56c6c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.card-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 20rpx;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 120rpx;
|
||||
border-radius: 20rpx;
|
||||
|
||||
::v-deep .u-button {
|
||||
border-radius: 20rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
min-width: 120rpx;
|
||||
height: auto;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
/* 浮动新增按钮 */
|
||||
.float-add-button {
|
||||
position: fixed;
|
||||
right: 40rpx;
|
||||
bottom: 100rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #3c9cff, #0051d9);
|
||||
box-shadow: 0 8rpx 24rpx rgba(60, 156, 255, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
// uview组件样式调整
|
||||
::v-deep .u-tag {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
::v-deep .u-button {
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user