反馈提醒、报送信息逻辑删除、用户设置是否开启短信提醒

master
YIN 2026-03-09 18:16:48 +08:00
parent 2b79b18fc9
commit ededca0cff
14 changed files with 200 additions and 49 deletions

View File

@ -92,6 +92,8 @@
<logging.level>warn</logging.level>
<monitor.username>ruoyi</monitor.username>
<monitor.password>123456</monitor.password>
<!-- 打包 prod 时自动跳过测试 -->
<maven.test.skip>true</maven.test.skip>
</properties>
</profile>
</profiles>

View File

@ -154,6 +154,8 @@ public class SysLoginService {
loginUser.setTenantId(user.getTenantId());
loginUser.setUserId(userId);
loginUser.setDeptId(user.getDeptId());
loginUser.setWorkDeptId(user.getWorkDeptId());
loginUser.setWorkDeptName(user.getWorkDeptName());
loginUser.setUsername(user.getUserName());
loginUser.setNickname(user.getNickName());
loginUser.setUserType(user.getUserType());

View File

@ -8,7 +8,7 @@ ruoyi:
copyrightYear: 2024
captcha:
enable: true
enable: false
# 页面 <参数设置> 可开启关闭 验证码校验
# 验证码类型 math 数组计算 char 字符验证
type: MATH
@ -102,10 +102,16 @@ sa-token:
token-name: Authorization
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# token 有效期(单位:秒) 默认30天-1代表永久有效
timeout: -1
# token 最低活跃频率(单位:秒)如果token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: 86400
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# jwt秘钥
jwt-secret-key: abcdefghijklmnopqrstuvwxyz
# 是否在每次访问时刷新Token有效期默认false需结合active-timeout生效
is-auto-renew: true
# security配置
security:

View File

@ -7,6 +7,11 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.biz.domain.BizReportInfo;
import org.dromara.biz.mapper.BizReportInfoMapper;
import org.dromara.biz.service.IBizReportInfoService;
import org.dromara.common.core.enums.ReportInfoStatusEnum;
import org.dromara.common.core.utils.Helper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
@ -37,6 +42,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
public class BizReportReceiverController extends BaseController {
private final IBizReportReceiverService bizReportReceiverService;
private final BizReportInfoMapper infoMapper;
/**
*
@ -98,7 +104,10 @@ public class BizReportReceiverController extends BaseController {
@Log(title = "报送记录签收", businessType = BusinessType.UPDATE)
@PostMapping("/sign")
public R<Void> sign(@Validated(EditGroup.class) @RequestBody BizReportReceiverBo bo) {
BizReportInfo dbinfo = infoMapper.selectById(bo.getReportId());
if (dbinfo==null || Helper.NStr(dbinfo.getStatus()).equals(ReportInfoStatusEnum.INVALID.getStatus())) {
return R.fail("报送记录已作废,无法签收");
}
return toAjax(bizReportReceiverService.sign(bo));
}

View File

@ -134,5 +134,15 @@ public class BizReportInfo extends BaseEntity {
*/
private Long updateUserId;
/**
* ID
*/
private Long shareId;
/**
*
*/
private String shareContent;
}

View File

@ -158,4 +158,15 @@ public class BizReportInfoBo extends BaseEntity {
* 线
*/
private List<BizReportPerson> personList;
/**
* ID
*/
private Long shareId;
/**
*
*/
private String shareContent;
}

View File

@ -195,4 +195,25 @@ public class BizReportInfoVo implements Serializable {
*
*/
private List<BizReportLog> logList;
/**
*
*/
@ExcelProperty(value = "上报状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "biz_report_status")
private String receiverStatus;
private BizReportReceiver myReceiver;
/**
* ID
*/
private Long shareId;
/**
*
*/
private String shareContent;
}

View File

@ -80,6 +80,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
*/
@Override
public BizReportInfoVo queryById(Long id){
if (Helper.FInt(id)==0) return new BizReportInfoVo();
BizReportInfoVo info = baseMapper.selectBizReportInfoVoById(id);
LambdaQueryWrapper<BizReportReceiver> lqw = Wrappers.lambdaQuery();
@ -123,6 +124,28 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
public TableDataInfo<BizReportInfoVo> queryPageList(BizReportInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizReportInfo> lqw = buildQueryWrapper(bo);
Page<BizReportInfoVo> result = baseMapper.selectBizReportInfoVoPage(pageQuery.build(), lqw);
List<BizReportInfoVo> infolist = result.getRecords();
for (BizReportInfoVo info : infolist) {
LambdaQueryWrapper<BizReportReceiver> lqwr = Wrappers.lambdaQuery();
lqwr.eq(BizReportReceiver::getReportId, info.getId());
lqwr.eq(BizReportReceiver::getDeptId, LoginHelper.getDeptId());
List<BizReportReceiver> dblist = receiverMapper.selectList(lqwr);
BizReportReceiver dbreceiver = dblist!=null && dblist.size()>0 ? dblist.get(0):null;
info.setMyReceiver(dbreceiver);
if (dbreceiver!=null){
if (dbreceiver.getIsSign()){
if (dbreceiver.getIsFeedback()){
info.setStatus(ReportInfoStatusEnum.REPLIED.getStatus());
}else{
info.setStatus(ReportInfoStatusEnum.WAITING_REPLY.getStatus());
}
}else{
info.setStatus(ReportInfoStatusEnum.WAITING_SIGN.getStatus());
}
}
}
return TableDataInfo.build(result);
}
@ -142,6 +165,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizReportInfo> lqw = Wrappers.lambdaQuery();
lqw.orderByDesc(BizReportInfo::getReportTime);
lqw.ne(BizReportInfo::getStatus, ReportInfoStatusEnum.INVALID.getStatus());
lqw.like(StringUtils.isNotBlank(bo.getTitle()), BizReportInfo::getTitle, bo.getTitle());
lqw.eq(bo.getCategoryId() != null, BizReportInfo::getCategoryId, bo.getCategoryId());
lqw.like(StringUtils.isNotBlank(bo.getTags()), BizReportInfo::getTags, bo.getTags());
@ -170,19 +194,22 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
LoginUser user = LoginHelper.getLoginUser();
if (dcl.equals("dcl")){
lqw.exists("select id from biz_report_receiver where dept_id = '" + Helper.NStr(user.getDeptId()) + "' and is_sign = 0 and report_id = v.id ");
lqw.exists("select id from biz_report_receiver where (dept_id = '" + Helper.NStr(user.getDeptId()) + "' or dept_id = '" + Helper.NStr(user.getWorkDeptId()) + "') and is_sign = 0 and report_id = v.id ");
}else {
if (table.equals("xxcl")) {
lqw.and(w -> {
w.eq(user.getDeptId()!=null, BizReportInfo::getReportDeptId, user.getDeptId());
lqw.and(w -> {
w.eq(user.getDeptId()!=null, BizReportInfo::getReportDeptId, user.getDeptId());
// w.eq(BizReportInfo::getReportDeptId, Helper.PrefixDeptid(user.getDeptId()));
w.or(ww -> {
ww.exists("select id from biz_report_receiver where dept_id = '" + Helper.NStr(user.getDeptId()) + "' and report_id = v.id ");
});
w.or(ww -> {
ww.exists("select id from biz_report_receiver where report_id = v.id " +
" and (dept_id = '" + Helper.NStr(user.getDeptId()) +
"' or dept_id = '" + Helper.NStr(user.getWorkDeptId()) + "')");
});
} else if (table.equals("xxbs")) {
lqw.likeRight(BizReportInfo::getReportDeptId, Helper.PrefixDeptid(user.getDeptId()));
}
});
// if (table.equals("xxcl")) {
//
// } else if (table.equals("xxbs")) {
// lqw.likeRight(BizReportInfo::getReportDeptId, Helper.PrefixDeptid(user.getDeptId()));
// }
}
return lqw;
}
@ -297,7 +324,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
scheduledExecutorService.schedule(() -> {
SseMessageDto dto = new SseMessageDto();
dto.setMessage("您有新的待办信息,请前往查看!");
dto.setMessage("您有新的待办信息,请前往查看!#$#todo#$#"+bo.getId());
dto.setType("todo");
dto.setUserIds(userIds);
SseMessageUtils.publishMessage(dto);
@ -305,8 +332,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
for (SysUserVo userVo : list) {
String phone = Helper.NStr(userVo.getPhonenumber());
if (Helper.validPhoneNum("0", phone)) {
if (Helper.NStr(userVo.getEnableMsg()).equals("Y") && Helper.validPhoneNum("0", phone)) {
SmsUtils.sendSMS(phone, "您有一条新的信息待签收,请前往综合情报信息报送处理系统处理");
}
}
@ -426,7 +452,17 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
int num = 0;
for (Long id : ids) {
BizReportInfo info = new BizReportInfo();
info.setId(id);
info.setStatus(ReportInfoStatusEnum.INVALID.getStatus());
num += baseMapper.updateById(info);
// 添加日志
logService.saveLog(id, ReportLogTypeEnum.DELETE.getStatus(), "", "删除记录");
}
return num > 0;
}
@ -474,9 +510,18 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
System.out.println(firstDay + " ========= " + lastDay);
lqw.between(BizReportInfo::getReportTime , firstDay, lastDay);
lqw.orderByDesc(BizReportInfo::getReportTime);
lqw.last(" limit 1");
int count = Helper.FInt(baseMapper.selectCount(lqw));
String result = String.format("%0" + 4 + "d", count+1);
List<BizReportInfo> list = baseMapper.selectList(lqw);
int count = 0;
if (list!=null && list.size()>0){
BizReportInfo info = list.get(0);
count = Helper.FInt(info.getQh());
}
// int count = Helper.FInt(baseMapper.selectCount(lqw));
String result = (count+1)+""; // String.format("%0" + 4 + "d", count+1);
return result;
}
@ -542,7 +587,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
scheduledExecutorService.schedule(() -> {
SseMessageDto dto = new SseMessageDto();
dto.setMessage("您有新的待办信息,请前往查看!");
dto.setMessage("您有新的待办信息,请前往查看!#$#todo#$#"+bo.getReportId());
dto.setType("todo");
dto.setUserIds(userIds);
SseMessageUtils.publishMessage(dto);
@ -550,7 +595,7 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService {
for (SysUserVo userVo : list) {
String phone = Helper.NStr(userVo.getPhonenumber());
if (Helper.validPhoneNum("0", phone)) {
if (Helper.NStr(userVo.getEnableMsg()).equals("Y") && Helper.validPhoneNum("0", phone)) {
SmsUtils.sendSMS(phone, "您有一条新的信息待签收,请前往综合情报信息报送处理系统处理");
}
}

View File

@ -178,6 +178,11 @@ public class BizReportReceiverServiceImpl implements IBizReportReceiverService {
*/
@Override
public Boolean sign(BizReportReceiverBo bo) {
BizReportInfo dbinfo = reportInfoMapper.selectById(bo.getReportId());
if (dbinfo==null || Helper.NStr(dbinfo.getStatus()).equals(ReportInfoStatusEnum.INVALID.getStatus())) {
return true;
}
LoginUser user = LoginHelper.getLoginUser();
if (Helper.FInt(bo.getId()) == 0){
BizReportReceiverBo sbo = new BizReportReceiverBo();
@ -202,7 +207,6 @@ public class BizReportReceiverServiceImpl implements IBizReportReceiverService {
// 添加日志
logService.saveLog(bo.getReportId(), ReportLogTypeEnum.SIGN.getStatus(), bo.getId().toString(), "签收");
BizReportInfo dbinfo = reportInfoMapper.selectById(bo.getReportId());
BizReportInfo info = new BizReportInfo();
info.setId(bo.getReportId());
@ -232,28 +236,30 @@ public class BizReportReceiverServiceImpl implements IBizReportReceiverService {
SseMessageUtils.publishMessage(dto);
}, 1, TimeUnit.SECONDS);
if (dbinfo.getOldTable().equals("xxbs")){
info.setStatus(ReportInfoStatusEnum.FINISH.getStatus());
}else {
LambdaQueryWrapper<BizReportReceiver> lqw = new LambdaQueryWrapper<>();
lqw.eq(BizReportReceiver::getReportId, bo.getReportId());
lqw.eq(BizReportReceiver::getIsSign, 0);
Long notSignCount = baseMapper.selectCount(lqw);
if (dbinfo!=null && !dbinfo.getStatus().equals(ReportInfoStatusEnum.INVALID.getStatus())) {
if (dbinfo.getOldTable().equals("xxbs")) {
info.setStatus(ReportInfoStatusEnum.FINISH.getStatus());
} else {
LambdaQueryWrapper<BizReportReceiver> lqw = new LambdaQueryWrapper<>();
lqw.eq(BizReportReceiver::getReportId, bo.getReportId());
lqw.eq(BizReportReceiver::getIsSign, 0);
Long notSignCount = baseMapper.selectCount(lqw);
if (Helper.FInt(notSignCount) > 0)
info.setStatus(ReportInfoStatusEnum.ANY_SIGN.getStatus());
else {
LambdaQueryWrapper<BizReportReceiver> lqw2 = new LambdaQueryWrapper<>();
lqw2.eq(BizReportReceiver::getReportId, bo.getReportId());
lqw2.eq(BizReportReceiver::getIsFeedback, 1);
Long replyCount = baseMapper.selectCount(lqw2);
if (replyCount > 0)
info.setStatus(ReportInfoStatusEnum.ANY_REPLY.getStatus());
else
info.setStatus(ReportInfoStatusEnum.WAITING_REPLY.getStatus());
if (Helper.FInt(notSignCount) > 0)
info.setStatus(ReportInfoStatusEnum.ANY_SIGN.getStatus());
else {
LambdaQueryWrapper<BizReportReceiver> lqw2 = new LambdaQueryWrapper<>();
lqw2.eq(BizReportReceiver::getReportId, bo.getReportId());
lqw2.eq(BizReportReceiver::getIsFeedback, 1);
Long replyCount = baseMapper.selectCount(lqw2);
if (replyCount > 0)
info.setStatus(ReportInfoStatusEnum.ANY_REPLY.getStatus());
else
info.setStatus(ReportInfoStatusEnum.WAITING_REPLY.getStatus());
}
}
reportInfoMapper.updateById(info);
}
reportInfoMapper.updateById(info);
}
return flag > 0;
}

View File

@ -1,5 +1,7 @@
package org.dromara.biz.service.impl;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.biz.domain.BizReportInfo;
import org.dromara.biz.domain.BizReportReceiver;
import org.dromara.biz.domain.bo.BizReportReceiverBo;
@ -20,6 +22,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.springframework.stereotype.Service;
import org.dromara.biz.domain.bo.BizReportReplyBo;
import org.dromara.biz.domain.vo.BizReportReplyVo;
@ -27,9 +31,9 @@ import org.dromara.biz.domain.BizReportReply;
import org.dromara.biz.mapper.BizReportReplyMapper;
import org.dromara.biz.service.IBizReportReplyService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Service
@ -39,11 +43,13 @@ import java.util.Collection;
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class BizReportReplyServiceImpl implements IBizReportReplyService {
private final BizReportReplyMapper baseMapper;
private final BizReportReceiverMapper receiverMapper;
private final BizReportInfoMapper reportInfoMapper;
private final ScheduledExecutorService scheduledExecutorService;
private final IBizReportLogService logService;
/**
@ -141,6 +147,25 @@ public class BizReportReplyServiceImpl implements IBizReportReplyService {
info.setStatus(ReportInfoStatusEnum.REPLIED.getStatus());
reportInfoMapper.updateById(info);
BizReportInfo dbinfo = reportInfoMapper.selectById(bo.getReportId());
HashMap item = new HashMap();
item.put("id", bo.getReportId());
item.put("title", dbinfo.getTitle());
item.put("time", new Date());
item.put("userIds", dbinfo.getReportUserId());
log.info("推送任务: " + JSONUtil.toJsonStr(item));
List<Long> userIds = new ArrayList<>();
userIds.add(dbinfo.getReportUserId());
scheduledExecutorService.schedule(() -> {
SseMessageDto dto = new SseMessageDto();
dto.setMessage("您有新的反馈信息,请前往查看!#$#reply#$#"+dbinfo.getId()+"#$#待办");
dto.setType("reply");
dto.setUserIds(userIds);
SseMessageUtils.publishMessage(dto);
}, 1, TimeUnit.SECONDS);
}
return flag;
}

View File

@ -116,6 +116,10 @@ public class SysUser extends TenantEntity {
*/
private Integer orderNum;
/**
*
*/
private String enableMsg;
public SysUser(Long userId) {
this.userId = userId;

View File

@ -137,4 +137,8 @@ public class SysUserBo extends BaseEntity {
@NotNull(message = "显示顺序不能为空")
private Integer orderNum;
/**
*
*/
private String enableMsg;
}

View File

@ -161,4 +161,8 @@ public class SysUserVo implements Serializable {
*
*/
private Integer orderNum;
/**
*
*/
private String enableMsg;
}

View File

@ -18,7 +18,7 @@
</if>
<if test="ew.getSqlSelect == null">
u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num, u.enable_msg
</if>
from sys_user u
${ew.getCustomSqlSegment}
@ -31,7 +31,7 @@
</if>
<if test="ew.getSqlSelect == null">
u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num, u.enable_msg
</if>
from sys_user u
${ew.getCustomSqlSegment}
@ -45,7 +45,7 @@
</if>
<if test="ew.getSqlSelect == null">
u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num, u.enable_msg
</if>
from sys_user u
${ew.getCustomSqlSegment}
@ -53,7 +53,7 @@
<select id="selectUserExportList" resultMap="SysUserExportResult">
select u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num, u.enable_msg,
d.dept_name, d.leader, wd.dept_name work_dept_name, u1.user_name as leaderName
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
@ -63,7 +63,8 @@
</select>
<select id="selectAllocatedList" resultMap="SysUserResult">
select distinct u.work_dept_id, u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time, u.order_num
select distinct u.work_dept_id, u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,
u.create_time, u.order_num, u.enable_msg
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role sur on u.user_id = sur.user_id
@ -72,7 +73,8 @@
</select>
<select id="selectUnallocatedList" resultMap="SysUserResult">
select distinct u.user_id, u.work_dept_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time, u.order_num
select distinct u.user_id, u.work_dept_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status,
u.create_time, u.order_num, u.enable_msg
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role sur on u.user_id = sur.user_id