|
@@ -746,4 +746,145 @@ public class SmsServiceImpl implements ISmsService
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 发送医生通知
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R sendDoctorNotice(String phone) {
|
|
|
|
|
+ // 参数校验
|
|
|
|
|
+ if (StringUtils.isEmpty(phone)) {
|
|
|
|
|
+ return R.error("手机号不能为空");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 获取短信模板
|
|
|
|
|
+ CompanySmsTemp temp = smsTempService.selectCompanySmsTempByCode("doctor_notice");
|
|
|
|
|
+ if (temp == null) {
|
|
|
|
|
+ log.error("发送医生通知失败:未找到短信模板");
|
|
|
|
|
+ return R.error("没有模板");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (temp.getStatus() == 0) {
|
|
|
|
|
+ log.error("发送医生通知失败:模板已停用");
|
|
|
|
|
+ return R.error("模板已停用");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 2. 获取短信配置
|
|
|
|
|
+ SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
|
|
+ if (sysConfig == null || StringUtils.isEmpty(sysConfig.getConfigValue())) {
|
|
|
|
|
+ log.error("发送医生通知失败:短信配置不存在");
|
|
|
|
|
+ return R.error("短信配置不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
|
|
+ if (sms == null || StringUtils.isEmpty(sms.getType())) {
|
|
|
|
|
+ log.error("发送医生通知失败:短信配置解析失败");
|
|
|
|
|
+ return R.error("短信配置解析失败");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 构建短信内容
|
|
|
|
|
+ String sign = "rf".equals(sms.getType()) ? sms.getRfSign() : sms.getDhSign();
|
|
|
|
|
+ if (StringUtils.isEmpty(sign)) {
|
|
|
|
|
+ log.error("发送医生通知失败:短信签名为空");
|
|
|
|
|
+ return R.error("短信签名为空");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String content = temp.getContent();
|
|
|
|
|
+ if (StringUtils.isEmpty(content)) {
|
|
|
|
|
+ log.error("发送医生通知失败:模板内容为空");
|
|
|
|
|
+ return R.error("模板内容为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ content = content.replace("${sms.sign}", sign);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 根据类型发送短信
|
|
|
|
|
+ String mid = dispatchSend(sms, phone, content);
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 发送成功则记录日志
|
|
|
|
|
+ if (mid != null) {
|
|
|
|
|
+ saveSmsLog(temp, phone, content, sms.getType(), mid);
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log.error("发送医生通知失败:phone={}", phone);
|
|
|
|
|
+ return R.error("短信发送失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("发送医生通知异常:phone={}", phone, e);
|
|
|
|
|
+ return R.error("发送异常: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据短信类型分发发送逻辑,返回 mid(失败返回 null)
|
|
|
|
|
+ */
|
|
|
|
|
+ private String dispatchSend(FsSmsConfig sms, String phone, String content) {
|
|
|
|
|
+ switch (sms.getType()) {
|
|
|
|
|
+ case "rf": return sendByRf(sms, phone, content);
|
|
|
|
|
+ case "dh": return sendByDh(sms, phone, content);
|
|
|
|
|
+ default:
|
|
|
|
|
+ log.warn("未知的短信类型: {}", sms.getType());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * RF 通道发送
|
|
|
|
|
+ */
|
|
|
|
|
+ private String sendByRf(FsSmsConfig sms, String phone, String content) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ String url = sms.getRfUrl1() + "sms?action=send"
|
|
|
|
|
+ + "&account=" + sms.getRfAccount1()
|
|
|
|
|
+ + "&password=" + sms.getRfPassword1()
|
|
|
|
|
+ + "&mobile=" + phone
|
|
|
|
|
+ + "&content=" + URLEncoder.encode(content, "UTF-8")
|
|
|
|
|
+ + "&extno=" + sms.getRfCode1()
|
|
|
|
|
+ + "&rt=json";
|
|
|
|
|
+
|
|
|
|
|
+ String body = HttpRequest.get(url).execute().body();
|
|
|
|
|
+ SmsSendVO vo = JSONUtil.toBean(body, SmsSendVO.class);
|
|
|
|
|
+
|
|
|
|
|
+ if (vo.getStatus().equals(0)) {
|
|
|
|
|
+ return vo.getList().stream()
|
|
|
|
|
+ .filter(item -> "0".equals(item.getResult()))
|
|
|
|
|
+ .map(SmsSendItemVO::getMid)
|
|
|
|
|
+ .findFirst()
|
|
|
|
|
+ .orElse(null);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
|
|
+ log.error("RF短信发送失败,URL编码异常,phone={}", phone, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * DH 通道发送
|
|
|
|
|
+ */
|
|
|
|
|
+ private String sendByDh(FsSmsConfig sms, String phone, String content) {
|
|
|
|
|
+ SendSmsReturn result = smsTService.sendSms(sms.getDhAccount1(), sms.getDhPassword1(), content, phone);
|
|
|
|
|
+ if (result != null && "0".equals(result.getResult())) {
|
|
|
|
|
+ return result.getMsgid();
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算短信条数并保存发送日志
|
|
|
|
|
+ */
|
|
|
|
|
+ private void saveSmsLog(CompanySmsTemp temp, String phone, String content, String type, String mid) {
|
|
|
|
|
+ int counts = Math.max(1, (int) Math.ceil(content.length() / 67.0));
|
|
|
|
|
+
|
|
|
|
|
+ CompanySmsLogs logs = new CompanySmsLogs();
|
|
|
|
|
+ logs.setContent(content);
|
|
|
|
|
+ logs.setTempCode(temp.getTempCode());
|
|
|
|
|
+ logs.setTempId(temp.getTempId());
|
|
|
|
|
+ logs.setPhone(phone);
|
|
|
|
|
+ logs.setSendTime(new Date());
|
|
|
|
|
+ logs.setStatus(0);
|
|
|
|
|
+ logs.setType(type);
|
|
|
|
|
+ logs.setMid(mid);
|
|
|
|
|
+ logs.setNumber(counts);
|
|
|
|
|
+
|
|
|
|
|
+ smsLogsService.insertCompanySmsLogs(logs);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|