短信回执修改

This commit is contained in:
zhangheng 2026-06-25 17:55:01 +08:00
parent 011cd5f978
commit 058af30d73
14 changed files with 164 additions and 32 deletions

View File

@ -122,4 +122,13 @@ public interface PhoneDialRecordMapper {
* @return PhoneDialRecord
*/
List<PhoneDialRecord> selectPhoneDialBySendTime(@Param("startMonth") LocalDateTime startMonth, @Param("endMonth") LocalDateTime endMonth);
/**
* 根据ids修改账单id
*
* @param ids
* @param billId
* @return int
*/
int updatePhoneDialRecordByIds(@Param("ids") List<Long> ids, @Param("billId") Long billId);
}

View File

@ -114,4 +114,13 @@ public interface ShortMessageSendRecordMapper {
* @return PhoneDialRecord
*/
List<ShortMessageSendRecord> selectRecordBySendTime(@Param("startMonth") LocalDateTime startMonth, @Param("endMonth") LocalDateTime endMonth);
/**
* 根据ids修改账单id
*
* @param ids
* @param billId
* @return int
*/
int updateShortMessageSendRecordByIds(@Param("ids") List<Long> ids , @Param("billId") Long billId);
}

View File

@ -156,4 +156,6 @@ public interface SignPatientManageRouteMapper {
* @return int
*/
int insertBatch(List<SignPatientManageRoute> signPatientManageRoutes);
List<SignPatientManageRouteVO> selectRouteByBatchSendTaskRecordId(List<Long> batchSendTaskRecordId);
}

View File

@ -265,4 +265,12 @@ public interface SignPatientManageRouteNodeMapper {
* @return SignPatientManageRouteNode
*/
SignPatientManageRouteNode selectSignPatientManageRouteNode(SignPatientManageRouteNode signPatientManageRouteNode);
/**
* 查询签约患者管理任务路径节点
*
* @param routeId 签约患者管理任务路径节点主键
* @return 签约患者管理任务路径节点
*/
List<SignPatientManageRouteNode> selectNodeByRouteId(Long routeId);
}

View File

@ -42,4 +42,9 @@ public class SignPatientManageRouteVO extends SignPatientManageRoute {
* 触发条件
*/
List<SignRouteTriggerConditionVO> triggerConditionList;
/**
* 联系方式短信任务回调使用
*/
private String phone;
}

View File

@ -398,4 +398,13 @@
and dial_time &lt;= #{endMonth}
</if>
</select>
<update id="updatePhoneDialRecordByIds">
UPDATE phone_dial_record
SET bill_id = #{billId}
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@ -421,4 +421,13 @@
and send_time &lt;= #{endMonth}
</if>
</select>
<update id="updateShortMessageSendRecordByIds">
UPDATE short_message_send_record
SET bill_id = #{billId}
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@ -781,4 +781,22 @@
#{id}
</foreach>
</select>
<select id="selectRouteByBatchSendTaskRecordId" resultType="com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO">
select spmr.id,
bsti.patient_phone phone
from sign_patient_manage_route spmr
LEFT JOIN batch_send_task_info bsti on spmr.batch_send_task_id = bsti.id
<where>
<if test="batchSendTaskRecordId != null and batchSendTaskRecordId.size() > 0">
spmr.batch_send_task_record_id IN
<foreach collection="batchSendTaskRecordId" item="recordId" open="(" separator="," close=")">
#{recordId}
</foreach>
</if>
<if test="batchSendTaskRecordId == null or batchSendTaskRecordId.size() == 0">
1 = 0 <!-- 如果列表为空,则返回空结果,避免 IN () 导致 SQL 报错 -->
</if>
</where>
</select>
</mapper>

View File

@ -1429,4 +1429,11 @@
where create_by = #{createBy}
order by create_time desc limit 1
</select>
<select id="selectNodeByRouteId"
resultType="com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode">
select *
from sign_patient_manage_route_node
where manage_route_id = #{routeId}
</select>
</mapper>

View File

@ -5,6 +5,8 @@ import com.aliyuncs.exceptions.ClientException;
import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.domain.textmessage.SmsReport;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
import com.xinelu.quartz.service.SendTextMessageService;
import com.xinelu.quartz.task.SendTextMessageTask;
import org.apache.commons.collections4.CollectionUtils;
@ -36,6 +38,8 @@ public class SendTextMessageController {
private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
@Resource
private SendTextMessageTask sendTextMessageTask;
@Resource
private SignPatientManageRouteMapper signPatientManageRouteMapper;
/**
* 手动执行短信发送定时任务
@ -52,8 +56,18 @@ public class SendTextMessageController {
if (Objects.isNull(data) || StringUtils.isBlank(data.getPhone_number())) {
return retObj;
}
List<Long> longs = new ArrayList<>();
longs.add(Long.valueOf(data.getOut_id()));
List<SignPatientManageRouteVO> signPatientManageRoutes = signPatientManageRouteMapper.selectRouteByBatchSendTaskRecordId(longs);
if (CollectionUtils.isEmpty(signPatientManageRoutes)){
return retObj;
}
SignPatientManageRouteVO signPatientManageRoute = signPatientManageRoutes.stream().filter(Objects::nonNull).filter(item -> data.getPhone_number().equals(item.getPhone())).findFirst().orElse(new SignPatientManageRouteVO());
if (Objects.isNull(signPatientManageRoute.getId())){
return retObj;
}
List<ShortMessageSendRecord> shortMessageSendRecords = new ArrayList<>();
JSONObject jsonObject = sendTextMessageService.taskTextMessageSendBack(data, shortMessageSendRecords);
JSONObject jsonObject = sendTextMessageService.taskTextMessageSendBack(data, shortMessageSendRecords, signPatientManageRoute);
if (CollectionUtils.isNotEmpty(shortMessageSendRecords)) {
shortMessageSendRecordMapper.insertShortMessageSendRecords(shortMessageSendRecords);
}

View File

@ -5,6 +5,7 @@ import com.aliyuncs.exceptions.ClientException;
import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.domain.textmessage.SmsReport;
import com.xinelu.manage.domain.textmessage.TaskMessageBackEntity;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
import java.util.List;
@ -28,7 +29,7 @@ public interface SendTextMessageService {
* @param data 任务单通电话回调传输data
* @return JSONObject
*/
JSONObject taskTextMessageSendBack(SmsReport data, List<ShortMessageSendRecord> shortMessageSendRecords);
JSONObject taskTextMessageSendBack(SmsReport data, List<ShortMessageSendRecord> shortMessageSendRecords, SignPatientManageRouteVO signPatientManageRoute);
Integer updateReadState(Integer readState, List<Integer> ids);

View File

@ -15,6 +15,7 @@ import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.service.patienttaskstatistics.IPatientTaskStatisticsService;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage;
import com.xinelu.manage.vo.subscribemessagesendrecord.RecordNum;
import com.xinelu.mobile.utils.SmsSendUtils;
@ -247,10 +248,14 @@ public class SendTextMessageServiceImpl implements SendTextMessageService {
}
@Override
public JSONObject taskTextMessageSendBack(SmsReport data, List<ShortMessageSendRecord> shortMessageSendRecords) {
public JSONObject taskTextMessageSendBack(SmsReport data, List<ShortMessageSendRecord> shortMessageSendRecords, SignPatientManageRouteVO signPatientManageRouteVO) {
JSONObject retObj = new JSONObject();
retObj.fluentPut("code", 0).fluentPut("msg", "成功");
SignPatientManageRouteNode signPatientManageRouteNode = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeById(Long.valueOf(data.getOut_id()));
List<SignPatientManageRouteNode> signPatientManageRouteNodes = signPatientManageRouteNodeMapper.selectNodeByRouteId(signPatientManageRouteVO.getId());
if (CollectionUtils.isEmpty(signPatientManageRouteNodes)){
return retObj;
}
SignPatientManageRouteNode signPatientManageRouteNode = signPatientManageRouteNodes.stream().filter(Objects::nonNull).findFirst().orElse(new SignPatientManageRouteNode());
if (Objects.isNull(signPatientManageRouteNode) || signPatientManageRouteNode.getNodeExecuteStatus().equals(NodeExecuteStatusEnum.EXECUTED.getInfo())) {
return retObj;
}

View File

@ -13,6 +13,7 @@ import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMap
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
@ -20,6 +21,7 @@ import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @description: 月初生成上月的的账单任务
@ -39,6 +41,7 @@ public class BillTask {
@Resource
private BillInfoMapper billInfoMapper;
@Transactional(rollbackFor = Exception.class)
public void generateBillTask() {
// 1.1 获取上个月的 YearMonth 对象
YearMonth lastMonth = YearMonth.now().minusMonths(1);
@ -49,8 +52,8 @@ public class BillTask {
//2.查询上月短信推送记录
BillInfo shortBillInfo = new BillInfo();
shortBillInfo.setBillCode(Constants.BILL_CODE + generateSystemCodeUtil.generateSystemCode(Constants.AGENCY_CODE));
shortBillInfo.setBillName(lastMonth.getMonth().toString() + "月份短信账单");
shortBillInfo.setBillMonth(lastMonth.getMonth().toString());
shortBillInfo.setBillName(lastMonth.getMonthValue() + "月份短信账单");
shortBillInfo.setBillMonth(lastMonth.toString());
shortBillInfo.setPaymentStatus(PaymentStatusConstants.UNPAID_FEES);
shortBillInfo.setBillSource(BillSourceEnum.MESSAGE.getInfo());
List<ShortMessageSendRecord> shortMessageSendRecords = shortMessageSendRecordMapper.selectRecordBySendTime(startOfLastMonth, endOfLastMonth);
@ -65,12 +68,14 @@ public class BillTask {
.reduce(BigDecimal.ZERO, BigDecimal::add);
shortBillInfo.setBillExpense(totalAmount);
billInfoMapper.insertBillInfo(shortBillInfo);
List<Long> shortIds = shortMessageSendRecords.stream().filter(Objects::nonNull).map(ShortMessageSendRecord::getId).collect(Collectors.toList());
shortMessageSendRecordMapper.updateShortMessageSendRecordByIds(shortIds, shortBillInfo.getId());
}
//2.查询上月电话推送记录
BillInfo phoneBillInfo = new BillInfo();
phoneBillInfo.setBillCode(Constants.BILL_CODE + generateSystemCodeUtil.generateSystemCode(Constants.AGENCY_CODE));
phoneBillInfo.setBillName(lastMonth.getMonth().toString() + "月份电话账单");
phoneBillInfo.setBillMonth(lastMonth.getMonth().toString());
phoneBillInfo.setBillName(lastMonth.getMonthValue() + "月份电话账单");
phoneBillInfo.setBillMonth(lastMonth.toString());
phoneBillInfo.setPaymentStatus(PaymentStatusConstants.UNPAID_FEES);
phoneBillInfo.setBillSource(BillSourceEnum.TELEPHONE.getInfo());
List<PhoneDialRecord> phoneDialRecords = phoneDialRecordMapper.selectPhoneDialBySendTime(startOfLastMonth, endOfLastMonth);
@ -78,13 +83,15 @@ public class BillTask {
BigDecimal sum = phoneDialRecords.stream().filter(Objects::nonNull)
.map(PhoneDialRecord::getPhoneDuration)
.reduce(BigDecimal.ZERO, BigDecimal::add);
shortBillInfo.setPushLength(sum);
phoneBillInfo.setPushLength(sum);
BigDecimal totalAmount = phoneDialRecords.stream().filter(Objects::nonNull)
.map(PhoneDialRecord::getPhoneExpense)
.reduce(BigDecimal.ZERO, BigDecimal::add);
shortBillInfo.setBillExpense(totalAmount);
phoneBillInfo.setBillExpense(totalAmount);
billInfoMapper.insertBillInfo(phoneBillInfo);
List<Long> phoneIds = phoneDialRecords.stream().filter(Objects::nonNull).map(PhoneDialRecord::getId).collect(Collectors.toList());
phoneDialRecordMapper.updatePhoneDialRecordByIds(phoneIds, phoneBillInfo.getId());
}
}
}

View File

@ -7,9 +7,12 @@ import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.domain.textmessage.SmsReport;
import com.xinelu.manage.domain.textmessage.TaskMessageBackEntity;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
import com.xinelu.quartz.service.SendTextMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@ -31,6 +34,8 @@ public class SendTextMessageTask {
private SendTextMessageService sendTextMessageService;
@Resource
private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
@Resource
private SignPatientManageRouteMapper signPatientManageRouteMapper;
/**
* 签约患者管理任务路径节点短信发送定时任务
@ -47,30 +52,54 @@ public class SendTextMessageTask {
taskMessageBackEntity.setReadState(0);
List<TaskMessageBackEntity> taskMessageBackEntityList = sendTextMessageService.taskMessageBack(taskMessageBackEntity);
List<ShortMessageSendRecord> shortMessageSendRecords = new ArrayList<>();
if (!CollectionUtils.isEmpty(taskMessageBackEntityList)) {
// 回调数据提取
List<SmsReport> smsReports = new ArrayList<>();
taskMessageBackEntityList.forEach(entity -> {
// JSONString SmsReport
smsReports.addAll(JSON.parseArray(entity.getMessageBackData().toString(), SmsReport.class));
});
log.info("短信数据提取完成共" + smsReports.size() + "");
if (CollectionUtils.isNotEmpty(smsReports)) {
for (SmsReport smsReport : smsReports) {
// 回调数据解析
sendTextMessageService.taskTextMessageSendBack(smsReport, shortMessageSendRecords);
if (CollectionUtils.isEmpty(taskMessageBackEntityList)) {
log.info("完成同步短信回调数据定时任务,未查询到未读短信回执......");
}
// 回调数据提取
List<SmsReport> smsReports = new ArrayList<>();
taskMessageBackEntityList.forEach(entity -> {
// JSONString SmsReport
smsReports.addAll(JSON.parseArray(entity.getMessageBackData().toString(), SmsReport.class));
});
log.info("短信数据提取完成,共" + smsReports.size() + "");
if (CollectionUtils.isNotEmpty(smsReports)) {
List<Long> outIds = smsReports.stream().filter(Objects::nonNull).map(SmsReport::getOut_id).filter(Objects::nonNull)
.map(id -> {
try {
return Long.parseLong(id);
} catch (NumberFormatException e) {
// 打印日志或忽略这里返回 null 然后被下一个 filter 过滤
return null;
}
})
.filter(Objects::nonNull) // 过滤掉转换失败的 null
.distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(outIds)) {
log.info("短信数据缺少任务信息!");
return;
}
List<SignPatientManageRouteVO> signPatientManageRoutes = signPatientManageRouteMapper.selectRouteByBatchSendTaskRecordId(outIds);
for (SmsReport smsReport : smsReports) {
// 回调数据解析
SignPatientManageRouteVO signPatientManageRoute = signPatientManageRoutes.stream().filter(Objects::nonNull).filter(item -> smsReport.getPhone_number().equals(item.getPhone())).findFirst().orElse(new SignPatientManageRouteVO());
if (StringUtils.isBlank(signPatientManageRoute.getPhone()) || Objects.isNull(signPatientManageRoute.getId())){
continue;
}
sendTextMessageService.taskTextMessageSendBack(smsReport, shortMessageSendRecords, signPatientManageRoute);
}
if (CollectionUtils.isNotEmpty(shortMessageSendRecords)) {
log.info("新增短信发送记录" + shortMessageSendRecords.size() + "");
shortMessageSendRecordMapper.insertShortMessageSendRecords(shortMessageSendRecords);
}
List<Integer> ids = taskMessageBackEntityList.stream().filter(Objects::nonNull).map(TaskMessageBackEntity::getId).collect(Collectors.toList());
// 修改阿里云服务器回调数据已读状态
if (CollectionUtils.isNotEmpty(ids)) {
log.info("修改中站记录" + ids.size() + "");
sendTextMessageService.updateReadState(1, ids);
}
}
if (CollectionUtils.isNotEmpty(shortMessageSendRecords) && shortMessageSendRecords.size() > 0) {
log.info("新增短信发送记录" + shortMessageSendRecords.size() + "");
shortMessageSendRecordMapper.insertShortMessageSendRecords(shortMessageSendRecords);
}
if (CollectionUtils.isEmpty(shortMessageSendRecords) && shortMessageSendRecords.size() == 0) {
return;
}
List<Integer> ids = taskMessageBackEntityList.stream().filter(Objects::nonNull).map(TaskMessageBackEntity::getId).collect(Collectors.toList());
// 修改阿里云服务器回调数据已读状态
if (CollectionUtils.isNotEmpty(ids)) {
log.info("修改中站记录" + ids.size() + "");
sendTextMessageService.updateReadState(1, ids);
}
log.info("完成同步短信回调数据定时任务......");
}