diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/controller/MeetingPrintController.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/controller/MeetingPrintController.java new file mode 100644 index 0000000..d73ad46 --- /dev/null +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/controller/MeetingPrintController.java @@ -0,0 +1,181 @@ +package com.ics.admin.controller; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.ics.admin.service.IMeetingReservationService; +import com.ics.admin.vo.MeetingRecordVo; +import com.ics.common.core.domain.R; +import com.ics.common.utils.DateUtils; +import com.ics.common.utils.StringUtils; +import com.ics.system.domain.DictData; +import com.ics.system.service.IDictDataService; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.crypto.Cipher; +import java.security.KeyFactory; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.List; + +/** + * 打印调用接口 + * created at 2025-1-13 20:13 + * + * @author lujiang + * @version 1.0.0 + * @since 1.0.0 + */ +@RestController +@RequestMapping("/interface/print") +public class MeetingPrintController { + + private final static String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIQyBF4zI63LsxKknhyt+v84/FphsiQbC3UmuysLHyROqDmjigBngB/ln2SUUR0XQx2dDWDvtGbdIPHns/LoGuQ/za7+FzXpOMz5OxkyKLQ3bMMaCMMTyhCoUIZMp/tzVVu7l7+JZFQWSCP9C3sz8xZvsfiYiJiYZuSflmjGqXQHAgMBAAECgYAPHLirHCWEBLlf9DmvBaSf8J/IpUp8HitdJSRYc1kICYXpsOxhx3M6MkHaeaocLUCa7g1Ne5mf+L9/aAGGT0pjis7jjPhWBUymXNDPhsUOT+uBi4ufnW4ah1U0Oweo5EXGkEcA9+BFI7nIO7XjdeX4FrZqUZ2efZiogAoy0ZK+gQJBANm7mRNKLfj09F0afQYoLIxMdmF27DZePOBv2sgsXYsLM6bVTJO1+tGe0XaqwrOAWEC2APlMZ4VsNrCZUD2R8vcCQQCbbdp3cpV7cyYOjloIlRAtdLei7zhH+OGsRw69EmBncmFHjPcHri1k9FxQlyW3NStd6pLjcKw/s87ZcBT9WjNxAkBMxlaas6x0PcOw1LdDJYVXz1pq0alHHoGuziJCNUqizcdfy5Sd/Sw9IBhSFLJk4xu7bbH4NhXGuTqrmNPvcfhPAkBK8+rKd2NGqPzNQDCCuv+WLBbyZ9IIQyjw30NoQhhjSnFHA9+MwJ37dSufYYQ6mVVUcO5s58To41j42mgE1R7BAkBHCgGh2lyUAQvVM6D/N4YeJDIBQ4iLZEgBZ2f75bHZjfZr4O7s8lQHZWt4om4rgxVlFcy338dLLEfKrx6JS/Ip"; + + private final static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEMgReMyOty7MSpJ4crfr/OPxaYbIkGwt1JrsrCx8kTqg5o4oAZ4Af5Z9klFEdF0MdnQ1g77Rm3SDx57Py6BrkP82u/hc16TjM+TsZMii0N2zDGgjDE8oQqFCGTKf7c1Vbu5e/iWRUFkgj/Qt7M/MWb7H4mIiYmGbkn5Zoxql0BwIDAQAB"; + + @Autowired + private IDictDataService dictDataService; + + @Autowired + private IMeetingReservationService meetingReservationService; + + /** + * 获取token + * + * @param appId 系统分配的应用id + */ + @PostMapping("getAccessToekn") + public R getToekn(String appId) { + if (!checkAppId(appId)) return R.error().put("msg", "非法appId"); + String content = appId + "|" + System.currentTimeMillis(); + try { + String token = encrypt(content); + return R.ok().put("accessToken", token); + } catch (Exception e) { + return R.error().put("msg", "获取Token失败"); + } + } + + @PostMapping("getMeeting") + public R getMeeting(String accessToken) { + if (!checkToken(accessToken)) return R.error().put("msg", "accessToken无效"); + MeetingRecordVo mrv = new MeetingRecordVo(); + mrv.setRole(5); + //mrv.setStatus(7); + mrv.setExt1("all"); + List list = meetingReservationService.selectMeetingReservationList(mrv); + JSONArray datas = new JSONArray(); + for (int i = 0; i < list.size(); i++) { + JSONObject data = new JSONObject(); + MeetingRecordVo meetingRecordVo = list.get(i); + data.put("id", meetingRecordVo.getId()); + data.put("room", meetingRecordVo.getRoomNum()); + data.put("start", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, meetingRecordVo.getStart())); + data.put("end", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, meetingRecordVo.getEnd())); + data.put("title", meetingRecordVo.getTitle()); + data.put("dept", meetingRecordVo.getUserOrg()); + data.put("status", meetingRecordVo.getStatus()); + data.put("updateTime", meetingRecordVo.getUpdateTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, meetingRecordVo.getUpdateTime())); +// String operate = meetingRecordVo.getOperate(); +// JSONArray jsonArray = JSONArray.parseArray(operate); +// if (jsonArray != null && jsonArray.size() > 0) { +// JSONObject jsonObject = jsonArray.getJSONObject(jsonArray.size() - 1); +// data.put("updateTime", jsonObject.getString("time")); +// } else { +// data.put("updateTime", ""); +// } + datas.add(data); + } + return R.ok().put("data", datas); + } + + @PostMapping("callBack") + public R callBack(String accessToken, String ids) { + if (!checkToken(accessToken)) return R.error().put("msg", "accessToken无效"); + if (StringUtils.isBlank(ids)) return R.error().put("msg", "无效参数"); + try { + meetingReservationService.updateMeetingReservationByIds(ids); + } catch (Exception e) { + return R.error().put("msg", "failed"); + } + return R.ok().put("msg", "success"); + } + + /** + * 校验token,appid 合法,时间在2小时以内 + * + * @param token 待校验token + * @return + */ + private boolean checkToken(String token) { + if(StringUtils.isNotBlank(token)){ + try { + String content = decrypt(token); + String[] keys = content.split("\\|"); + if (keys != null && keys.length == 2) { + if (checkAppId(keys[0])) { + long tokenTime = Long.parseLong(keys[1]); + if (System.currentTimeMillis() - tokenTime <= 7200000l) { + return true; + } + } + } + } catch (Exception e) { + } + } + return false; + } + + /** + * 检验appId 是否合法 + * + * @param appId 带校验 + * @return true 合法 ,false 不合法 + */ + private boolean checkAppId(String appId) { + List list = dictDataService.selectDictDataByType("appId"); + if (list != null && list.size() > 0) { + for (int i = 0; i < list.size(); i++) { + DictData dictData = list.get(i); + if (dictData.getDictValue().equals(appId)) { + return true; + } + } + } + return false; + } + + /** + * rsa 公钥加密 + */ + private String encrypt(String token) throws Exception { + byte[] buffer = Base64.decodeBase64(PUBLIC_KEY); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); + RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] data = cipher.doFinal(token.getBytes()); + return Base64.encodeBase64URLSafeString(data); + } + + /** + * rsa 私钥解密 + */ + private String decrypt(String token) throws Exception { + byte[] buffer = Base64.decodeBase64(PRIVATE_KEY); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] data = cipher.doFinal(Base64.decodeBase64(token)); + return new String(data); + } +} diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/MeetingReservation.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/MeetingReservation.java index b8df88c..0679bcf 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/MeetingReservation.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/MeetingReservation.java @@ -67,7 +67,7 @@ public class MeetingReservation extends BaseEntity { /** 备注 */ private String remark; - /** 扩展1 */ + /** 扩展1 1 表示接口已经标记不在返回数据*/ private String ext1; /** 扩展2 */ diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/RepairRemind.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/RepairRemind.java index 0755ed2..aa62b3f 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/RepairRemind.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/domain/RepairRemind.java @@ -53,7 +53,7 @@ public class RepairRemind extends BaseEntity { private String ext1; /** - * 扩展2 + * 扩展2 默认为空,3 短信发送成功 5 短信发送失败 */ private String ext2; diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/MeetingReservationMapper.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/MeetingReservationMapper.java index 9d652ff..8ad3cb9 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/MeetingReservationMapper.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/MeetingReservationMapper.java @@ -97,4 +97,6 @@ public interface MeetingReservationMapper { * @return 结果 */ int deleteMeetingReservationByIds(String[] ids); + + int updateMeetingReservationByIds(String[] ids); } diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/RepairRemindMapper.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/RepairRemindMapper.java index 725fc17..d8b6878 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/RepairRemindMapper.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/mapper/RepairRemindMapper.java @@ -114,4 +114,12 @@ public interface RepairRemindMapper { * @return */ int afterWxPush(@Param("state") String state, @Param("ids") List ids); + + /** + * 短信后更新提醒消息 + * @param state + * @param ids + * @return + */ + int afterSMS(@Param("state") String state, @Param("ids") List ids); } \ No newline at end of file diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IMeetingReservationService.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IMeetingReservationService.java index a847a10..5fc1725 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IMeetingReservationService.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IMeetingReservationService.java @@ -126,5 +126,13 @@ public interface IMeetingReservationService { */ int deleteMeetingReservationByIds(String ids); + /** + * 接口标记,标记后的数据不再被接口调用返回数据 + * + * @param ids + * @return + */ + int updateMeetingReservationByIds(String ids); + } diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IRepairRemindService.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IRepairRemindService.java index 3c1107a..830ce46 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IRepairRemindService.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/IRepairRemindService.java @@ -89,4 +89,13 @@ public interface IRepairRemindService { * @return */ int afterWxPush(List success, List failed); + + /** + * 短信后更新提醒消息 + * + * @param success + * @param failed + * @return + */ + int afterSMS(List success, List failed); } diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/MeetingReservationServiceImpl.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/MeetingReservationServiceImpl.java index 6c63d93..e608ecc 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/MeetingReservationServiceImpl.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/MeetingReservationServiceImpl.java @@ -315,12 +315,13 @@ public class MeetingReservationServiceImpl implements IMeetingReservationService p.setRoomRole(5); List admins = customerStaffMapper.selectIcsCustomerStaffList(p);//获取所有会议管理员 boolean isAdmin = false;//是否管理员创建的预约 - for (IcsCustomerStaff staff : admins) { - if (staff.getId().toString().equals(meetingReservation.getCreateBy())) { - isAdmin = true; - break; - } - } + //-- 2025-01-08 会议管理员创建的预约,在审核、审核通过环节均不会有提示。甲方提出需要有提醒。 +// for (IcsCustomerStaff staff : admins) { +// if (staff.getId().toString().equals(meetingReservation.getCreateBy())) { +// isAdmin = true; +// break; +// } +// } if (status == -1) {//提醒会务人员 if (StringUtils.isNotBlank(voiceWaiter)) { String[] voices = voiceWaiter.split(","); @@ -483,4 +484,9 @@ public class MeetingReservationServiceImpl implements IMeetingReservationService return meetingReservationMapper.deleteMeetingReservationByIds(idsArray); } + @Override + public int updateMeetingReservationByIds(String ids) { + String[] idsArray = StrUtil.split(ids, ","); + return meetingReservationMapper.updateMeetingReservationByIds(idsArray); + } } diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/RepairRemindServiceImpl.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/RepairRemindServiceImpl.java index e72f2b0..6e08d85 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/RepairRemindServiceImpl.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/service/impl/RepairRemindServiceImpl.java @@ -136,4 +136,17 @@ public class RepairRemindServiceImpl implements IRepairRemindService { } return a + b; } + + @Transactional(rollbackFor = Exception.class) + @Override + public int afterSMS(List success, List failed) { + int a = 0, b = 0; + if (success != null && success.size() > 0) { + a = repairRemindMapper.afterSMS("3", success); + } + if (failed != null && failed.size() > 0) { + b = repairRemindMapper.afterSMS("5", failed); + } + return a + b; + } } diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/utils/SMSUtil.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/utils/SMSUtil.java new file mode 100644 index 0000000..867c265 --- /dev/null +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/utils/SMSUtil.java @@ -0,0 +1,103 @@ +package com.ics.admin.utils; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +/** + * 电信 短信发送 + * created at 2025-1-8 15:47 + * + * @author lujiang + * @version 1.0.0 + * @since 1.0.0 + */ +@Slf4j +@Component("smsSender") +public class SMSUtil { + + private RestTemplate restTemplate = new RestTemplate(); + + private final static String SIGN_NAME = ""; + private final static String SEND_URL = "https://qxtapi.js118114.com:9003/SMSController/sendSms.do"; + private final static String SPID = ""; + private final static String AUTH_CODE = ""; + private final static String AUTH_KEY = ""; + + public JSONObject sendSms(String message, String mobiles) { + // 准备请求参数 + String content = "【" + SIGN_NAME + "】" + message; + String timestamp = String.valueOf(System.currentTimeMillis()); + String sign = ""; + try { + content = URLEncoder.encode(content, "utf-8"); + sign = calculateSign("", "", mobiles, "", content, timestamp); + } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) { + log.error("短信内容编码失败:{}", e.getMessage()); + } + // 构建请求体 + Map requestBody = new HashMap<>(); + requestBody.put("auth_code", AUTH_CODE); + requestBody.put("spid", SPID); + requestBody.put("extport", ""); + requestBody.put("smsid", ""); + requestBody.put("mobiles", mobiles); + requestBody.put("content", content); + requestBody.put("sendtime", ""); + requestBody.put("timestamp", timestamp); + requestBody.put("sign", sign); + // 发送POST请求 + JSONObject response = null; + try { + response = restTemplate.postForObject(SEND_URL, requestBody, JSONObject.class); + } catch (Exception e) { + log.error("** 发送电信短信失败:{}", e.getMessage()); + } + return response; + } + + /** + * 计算签名方法 + * + * @param extport 扩展码,暂不支持,默认"" + * @param smsid 短信任务编号,默认"" + * @param mobiles 手机号码列表,多个用英文逗号分隔 + * @param sendtime 定时发送时间,暂不支持,默认"" + * @param content 短信内容:【签名】+内容 + * @param timestamp 时间戳 + * @return 使用SHA-1算法计算后的sign值 + * @throws NoSuchAlgorithmException + */ + private String calculateSign(String extport, String smsid, String mobiles, String sendtime, String content, String timestamp) throws NoSuchAlgorithmException { + StringBuilder sb = new StringBuilder(); + sb.append(AUTH_CODE); + sb.append(SPID); + sb.append(extport); + sb.append(smsid); + sb.append(mobiles); + sb.append(sendtime); + sb.append(content); + sb.append(timestamp); + sb.append(AUTH_KEY); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + byte[] hash = digest.digest(sb.toString().getBytes(StandardCharsets.UTF_8)); + StringBuilder hexString = new StringBuilder(); + for (byte b : hash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } +} diff --git a/shoot-hand/ics-admin/src/main/java/com/ics/admin/vo/MeetingRecordVo.java b/shoot-hand/ics-admin/src/main/java/com/ics/admin/vo/MeetingRecordVo.java index cdc67bc..36b1a15 100644 --- a/shoot-hand/ics-admin/src/main/java/com/ics/admin/vo/MeetingRecordVo.java +++ b/shoot-hand/ics-admin/src/main/java/com/ics/admin/vo/MeetingRecordVo.java @@ -90,6 +90,8 @@ public class MeetingRecordVo implements Serializable { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; /** * 所属楼层值 */ diff --git a/shoot-hand/ics-admin/src/main/resources/mapper/admin/MeetingReservationMapper.xml b/shoot-hand/ics-admin/src/main/resources/mapper/admin/MeetingReservationMapper.xml index 45fc967..416b5db 100644 --- a/shoot-hand/ics-admin/src/main/resources/mapper/admin/MeetingReservationMapper.xml +++ b/shoot-hand/ics-admin/src/main/resources/mapper/admin/MeetingReservationMapper.xml @@ -96,7 +96,7 @@