Merge remote-tracking branch 'origin/main'

This commit is contained in:
2025-08-26 11:17:44 +08:00
6 changed files with 295 additions and 21 deletions

View File

@@ -6,6 +6,8 @@ import com.srs.dormitory.domain.DmsNewRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.srs.dormitory.domain.Dto.DmsSearch;
import com.srs.dormitory.domain.Vo.DomInfo;
import com.srs.comprehensive.domain.CphMsg;
import org.apache.ibatis.annotations.Param;
/**
* 住宿记录Mapper接口
@@ -16,6 +18,7 @@ import com.srs.dormitory.domain.Vo.DomInfo;
public interface DmsNewRecordMapper extends BaseMapper<DmsNewRecord> {
int fastConfirm();
int confirmUnconfirmedStudents();
List<DmsNewRecord> findByParam(DmsSearch param);
@@ -65,8 +68,33 @@ public interface DmsNewRecordMapper extends BaseMapper<DmsNewRecord> {
/**
* 批量删除住宿记录
*
* @param ids 需要删除的数据主键集合
* @param ids 需要删除的住宿记录主键集合
* @return 结果
*/
int deleteDmsNewRecordByIds(Long[] ids);
/**
* 批量插入消息
*
* @param messages 消息列表
* @return 结果
*/
int batchInsertCphMsg(List<CphMsg> messages);
/**
* 根据年级ID列表查询学生用户ID
*
* @param gradeIds 年级ID列表
* @return 学生用户ID列表
*/
List<Long> selectStudentIdsByGrades(@Param("gradeIds") List<String> gradeIds);
/**
* 根据年级ID列表查询学生学号列表
*
* @param gradeIds 年级ID列表
* @return 学生学号列表
*/
List<String> selectStudentNosByGrades(@Param("gradeIds") List<String> gradeIds);
}

View File

@@ -1,5 +1,8 @@
package com.srs.dormitory.service;
import java.util.List;
import com.srs.comprehensive.domain.CphMsg;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
public interface IDmsNewRecordService extends IService<DmsNewRecord> {
public AjaxResult fdyManyConfirm(List<Long> ids);
public AjaxResult confirmUnconfirmedStudents();
public AjaxResult fullInfo(Long id);
public AjaxResult fastConfirm();
public AjaxResult initRecord(DmsSearch param);
@@ -32,6 +36,21 @@ public interface IDmsNewRecordService extends IService<DmsNewRecord> {
public AjaxResult exportJwc(DmsSearch param);
/**
* 发送企业微信消息
*
* @param stuNoList 学生学号列表
* @param content 消息内容
*/
void sendWechatMessage(List<String> stuNoList, String content);
/**
* 发送系统消息
*
* @param userIdList 用户ID列表
* @param content 消息内容
*/
void sendSystemMessage(List<Long> userIdList, String content);
/**
* 查询住宿记录

View File

@@ -9,10 +9,13 @@ import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.utils.WeChatUtil;
import com.srs.comprehensive.domain.SrsStuYear;
import com.srs.comprehensive.domain.SrsStudent;
import com.srs.comprehensive.domain.CphMsg;
import com.srs.comprehensive.mapper.SrsStuYearMapper;
import com.srs.comprehensive.mapper.SrsStudentMapper;
import com.srs.comprehensive.mapper.CphMsgMapper;
import com.srs.dormitory.domain.DmsNewRange;
import com.srs.dormitory.domain.Dto.DmsSearch;
import com.srs.dormitory.domain.Vo.DomInfo;
@@ -52,6 +55,12 @@ public class DmsNewRecordServiceImpl extends ServiceImpl<DmsNewRecordMapper,DmsN
@Autowired
public SrsStudentMapper _stuMapper;
@Autowired
public WeChatUtil weChatUtil;
@Autowired
private CphMsgMapper cphMsgMapper;
@Autowired
public PlatformTransactionManager transactionManager;
@@ -148,6 +157,30 @@ public class DmsNewRecordServiceImpl extends ServiceImpl<DmsNewRecordMapper,DmsN
}
}
// 发送住宿费用确认消息
try {
String messageContent = "请前往电脑端学工系统-宿舍管理-住宿费用-学生住宿,进行宿舍费用确认,如不进行手动确认,系统将会在一周后自动确认!";
// 构建年级ID列表
List<String> gradeIds = new ArrayList<>();
gradeIds.add(String.valueOf(param.gradeId));
// 发送企业微信消息
List<String> studentNos = dmsNewRecordMapper.selectStudentNosByGrades(gradeIds);
if (studentNos != null && !studentNos.isEmpty()) {
sendWechatMessage(studentNos, messageContent);
}
// 发送系统消息
List<Long> studentIds = dmsNewRecordMapper.selectStudentIdsByGrades(gradeIds);
if (studentIds != null && !studentIds.isEmpty()) {
sendSystemMessage(studentIds, messageContent);
}
} catch (Exception e) {
// 消息发送失败不影响主流程,只记录日志
System.err.println("发送住宿费用确认消息失败: " + e.getMessage());
}
transactionManager.commit(status);
return AjaxResult.success();
}catch(Exception ex){
@@ -252,6 +285,20 @@ public class DmsNewRecordServiceImpl extends ServiceImpl<DmsNewRecordMapper,DmsN
}
}
@Override
public AjaxResult confirmUnconfirmedStudents(){
try{
int res = dmsNewRecordMapper.confirmUnconfirmedStudents();
if(res == 0){
throw new Exception("无未确认的学生记录");
}
return AjaxResult.success("成功确认 " + res + " 条学生记录");
}catch(Exception ex){
return AjaxResult.error(ex.getMessage());
}
}
@Override
public AjaxResult fdyConfirm(Long id){
@@ -392,7 +439,7 @@ public class DmsNewRecordServiceImpl extends ServiceImpl<DmsNewRecordMapper,DmsN
*/
@Override
public int insertDmsNewRecord(DmsNewRecord dmsNewRecord) {
return dmsNewRecordMapper.insertDmsNewRecord(dmsNewRecord);
return dmsNewRecordMapper.insertDmsNewRecord(dmsNewRecord);
}
/**
@@ -427,4 +474,71 @@ public class DmsNewRecordServiceImpl extends ServiceImpl<DmsNewRecordMapper,DmsN
public int deleteDmsNewRecordById(Long id) {
return dmsNewRecordMapper.deleteDmsNewRecordById(id);
}
/**
* 发送系统消息
*
* @param userIdList 用户ID列表
* @param content 消息内容
*/
@Override
public void sendSystemMessage(List<Long> userIdList, String content) {
if (userIdList == null || userIdList.isEmpty()) {
return;
}
try {
List<CphMsg> messages = new ArrayList<>();
Date now = new Date();
String currentUser = getUsername();
for (Long userId : userIdList) {
CphMsg msg = new CphMsg();
msg.setSender(1L); // 系统发送者ID
msg.setReceiver(userId);
msg.setContent(content);
msg.setCreateBy(currentUser);
msg.setCreateTime(now);
msg.setUpdateBy(currentUser);
msg.setUpdateTime(now);
messages.add(msg);
}
// 使用批量插入提高性能
dmsNewRecordMapper.batchInsertCphMsg(messages);
} catch (Exception e) {
// 记录日志但不影响主流程
System.err.println("发送系统消息失败: " + e.getMessage());
}
}
/**
* 发送企业微信消息
*
* @param stuNoList 学生学号列表
* @param content 消息内容
*/
@Override
public void sendWechatMessage(List<String> stuNoList, String content) {
if (stuNoList == null || stuNoList.isEmpty()) {
return;
}
try {
// 企业微信批量发送限制每次最多发送1000个用户
int batchSize = 1000;
for (int i = 0; i < stuNoList.size(); i += batchSize) {
List<String> batch = stuNoList.subList(i, Math.min(i + batchSize, stuNoList.size()));
// 拼接成"2023001|2023002|2023003"格式
String toUser = String.join("|", batch);
// 调用企业微信发送消息方法
// TODO: 发送消息
//weChatUtil.sendTextMessage(toUser, content);
// System.out.println("企业微信消息发送到: " + toUser + ", 内容: " + content);
}
} catch (Exception e) {
System.err.println("发送企业微信消息失败: " + e.getMessage());
}
}
}

View File

@@ -50,7 +50,7 @@
<if test="applyStatus != null and applyStatus != ''">and t1.apply_status = #{applyStatus}</if>
<if test="tNo != null">and t1.employee_id = #{tNo}</if>
</where>
order by t1.apply_status asc,t1.id asc
order by t1.id desc
</if>
<if test="searchRole == 'jwc'">
select t1.* from
@@ -77,6 +77,7 @@
<if test="applyStatus != null and applyStatus != ''">and t1.apply_status = #{applyStatus}</if>
<if test="tNo != null">and t1.employee_id = #{tNo}</if>
</where>
order by t1.id desc
</if>
<if test="searchRole == null">
select t1.*
@@ -95,7 +96,7 @@
<if test="applyStatus != null and applyStatus != ''">and t1.apply_status = #{applyStatus}</if>
<if test="tNo != null">and t1.employee_id = #{tNo}</if>
</where>
order by t1.id
order by t1.id desc
</if>
</select>
@@ -172,13 +173,38 @@
<select id="listView" resultType="DomInfo">
select a.*,b.`name` as stu_name,c.class_name,d.`name` as teacher_name ,d.phone_number as teacher_phone
from view_dms_stu_total_record as a
left join srs_student as b on a.stu_no = b.stu_no
left join srs_class as c on b.class_id = c.class_id
left join cph_teacher as d on c.teacher_id = d.teacher_id
left join srs_student as b on a.stu_no = b.stu_no
left join srs_class as c on b.class_id = c.class_id
left join cph_teacher as d on c.teacher_id = d.teacher_id
<where>
<if test="stuYearId != null and stuYearId != ''"> and a.stu_year_id = #{stuYearId}</if>
</where>
order by b.class_id asc
order by b.class_id desc
</select>
<!-- 根据年级ID列表查询学生用户ID -->
<select id="selectStudentIdsByGrades" resultType="Long">
SELECT DISTINCT u.user_id
FROM srs_student ss
left JOIN srs_class sc ON ss.class_id = sc.class_id
left JOIN sys_user u ON ss.stu_no = u.user_name
WHERE u.user_id IS NOT NULL
AND sc.grade_id IN
<foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")">
#{gradeId}
</foreach>
</select>
<!-- 根据年级ID列表查询学生学号列表 -->
<select id="selectStudentNosByGrades" resultType="String">
SELECT DISTINCT ss.stu_no
FROM srs_student ss
left JOIN srs_class sc ON ss.class_id = sc.class_id
WHERE ss.stu_no IS NOT NULL
AND sc.grade_id IN
<foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")">
#{gradeId}
</foreach>
</select>
<select id="findByParam" resultType="DmsNewRecord" parameterType="DmsSearch">
@@ -194,8 +220,56 @@
</select>
<update id="fastConfirm" >
update dms_new_record as a set a.apply_status = '3' where a.apply_status = '2'
UPDATE dms_new_record
SET apply_status = (
SELECT dict_value
FROM sys_dict_data
WHERE dict_type = 'dms_record_status'
AND dict_label = '学工已确认'
LIMIT 1
)
WHERE apply_status = (
SELECT dict_value
FROM sys_dict_data
WHERE dict_type = 'dms_record_status'
AND dict_label = '辅导员已确认'
LIMIT 1
)
</update>
<update id="confirmUnconfirmedStudents" >
UPDATE dms_new_record
SET apply_status = (
SELECT dict_value
FROM sys_dict_data
WHERE dict_type = 'dms_record_status'
AND dict_label = '学工已确认'
LIMIT 1
)
WHERE apply_status = (
SELECT dict_value
FROM sys_dict_data
WHERE dict_type = 'dms_record_status'
AND dict_label = '待确认'
LIMIT 1
)
</update>
</mapper>
<!-- 批量插入消息 -->
<insert id="batchInsertCphMsg" parameterType="java.util.List">
insert into cph_msg (sender, receiver, content, create_by, create_time, update_by, update_time)
values
<foreach collection="list" item="item" separator=",">
(
#{item.sender},
#{item.receiver},
#{item.content},
#{item.createBy},
#{item.createTime},
#{item.updateBy},
#{item.updateTime}
)
</foreach>
</insert>
</mapper>

View File

@@ -55,6 +55,17 @@ public class DmsNewRecordController extends BaseController {
}
}
@ApiOperation("学工一键确认未进行住宿费用确认的学生")
@PostMapping("/confirmUnconfirmedStudents")
public AjaxResult confirmUnconfirmedStudents() {
boolean hasRole = RoleBool.isHigh(getUserId(), _postService);
if (hasRole) {
return dmsNewRecordService.confirmUnconfirmedStudents();
} else {
return AjaxResult.error(401, "你无权做这些");
}
}
@ApiOperation("学生填充信息")
@PostMapping("/fullInfo/{id}")

View File

@@ -92,22 +92,27 @@ public class DmsStuDailyController extends BaseController {
// 获取用户角色组
String roleGroup = userService.selectUserRoleGroup(username);
// 检查是否同时拥有学务干事和辅导员角色
// 检查用户拥有的角色
boolean isXuegongRole = roleGroup.contains("学工");
boolean isDeptRole = roleGroup.contains("学务干事") || roleGroup.contains("学务办初审");
boolean isTeacherRole = roleGroup.contains("辅导员");
// 根据前端传递的roleType参数进行过滤
if (isDeptRole && isTeacherRole) {
// 同时拥有两个角色根据roleType参数决定查看哪种数据
// 根据角色组合和前端传递的roleType参数进行过滤
if ((isXuegongRole && isTeacherRole) || (isDeptRole && isTeacherRole)) {
// 多角色用户根据roleType参数决定查看哪种数据
if ("teacher".equals(param.getRoleType())) {
// 查看个人班级数据
// 辅导员权限:查看个人班级数据
param.setTeacherNo(username);
} else {
// 默认查看学院数据
} else if ("dept".equals(param.getRoleType())) {
// 学务干事权限:查看学院数据
if (currentUser.getDept() != null) {
param.setDeptName(currentUser.getDept().getDeptName());
}
} else if ("xuegong".equals(param.getRoleType()) || param.getRoleType() == null) {
// 学工权限:查看所有数据,不设置过滤条件
}
} else if (isXuegongRole) {
// 只有学工角色,查看所有数据,不设置过滤条件
} else if (isDeptRole) {
// 只有学务干事角色,查看学院数据
if (currentUser.getDept() != null) {
@@ -135,16 +140,39 @@ public class DmsStuDailyController extends BaseController {
String roleGroup = userService.selectUserRoleGroup(username);
SysUser currentUser = userService.selectUserByUserName(username);
boolean isXuegongRole = roleGroup.contains("学工");
boolean isDeptRole = roleGroup.contains("学务干事");
boolean isTeacherRole = roleGroup.contains("辅导员");
boolean hasMultipleRoles = isDeptRole && isTeacherRole;
// 判断多角色情况
boolean hasMultipleRoles = (isXuegongRole && isTeacherRole) || (isDeptRole && isTeacherRole);
Map<String, Object> roleInfo = new HashMap<>();
roleInfo.put("hasMultipleRoles", hasMultipleRoles);
roleInfo.put("defaultRole", "dept"); // 默认显示学院数据
roleInfo.put("isAdmin", SecurityUtils.isAdmin(SecurityUtils.getUserId()));
roleInfo.put("isXuewu", roleGroup.contains("学务干事"));
roleInfo.put("isFudaoyuan", roleGroup.contains("辅导员"));
roleInfo.put("isXuegong", isXuegongRole);
roleInfo.put("isXuewu", isDeptRole);
roleInfo.put("isFudaoyuan", isTeacherRole);
// 设置默认角色和可用角色选项
if (isXuegongRole && isTeacherRole) {
// 学工+辅导员组合
roleInfo.put("defaultRole", "xuegong");
roleInfo.put("availableRoles", new String[]{"xuegong", "teacher"});
} else if (isDeptRole && isTeacherRole) {
// 学务干事+辅导员组合
roleInfo.put("defaultRole", "dept");
roleInfo.put("availableRoles", new String[]{"dept", "teacher"});
} else if (isXuegongRole) {
// 只有学工角色
roleInfo.put("defaultRole", "xuegong");
} else if (isDeptRole) {
// 只有学务干事角色
roleInfo.put("defaultRole", "dept");
} else if (isTeacherRole) {
// 只有辅导员角色
roleInfo.put("defaultRole", "teacher");
}
// 添加用户部门信息
if (currentUser != null && currentUser.getDept() != null) {