skjcmanager/skjcmanager-service-api/skjcmanager-alerts-api/src/main/java/cn/gistack/alerts/notice/enums/PersonEnum.java
New file @@ -0,0 +1,57 @@ package cn.gistack.alerts.notice.enums; import lombok.AllArgsConstructor; import lombok.Getter; /** * 责任人枚举类 * * @author Chill */ @Getter @AllArgsConstructor public enum PersonEnum { /** * 行政责任人 */ AREA_TYPE("行政责任人",1), /** * 主管部门责任人 */ SUPERVISOR_TYPE("主管部门责任人",2), /** * 管理单位责任人 */ MANAGE_TYPE("管理单位责任人",3), /** * 技术责任人 */ TECHNOLOGY_TYPE("技术责任人",4), /** * 巡查责任人 */ PERSON_TYPE("巡查责任人",5), ; final String name; final Integer type; /** * findByType * @param name * @return */ public static PersonEnum findByName(String name) { //循环遍历对应的 PersonEnum for (PersonEnum item : values()) { if(item.getName().equals(name)) { return item; } } return null; } } skjcmanager/skjcmanager-service-api/skjcmanager-sm-api/src/main/java/cn/gistack/sm/sjztmd/vo/PersonVO.java
New file @@ -0,0 +1,27 @@ package cn.gistack.sm.sjztmd.vo; import lombok.Data; /** * 人员信息vo * @author zhongrj * @date 2023-05-31 */ @Data public class PersonVO { /** * 姓名 */ private String name; /** * 角色 */ private String roleName; /** * 手机号 */ private String phone; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/constant/PtInfoConstant.java
New file @@ -0,0 +1,15 @@ package cn.gistack.alerts.alarmRule.notice.constant; /** * 平台服务信息常量 * @author zhongrj * @since 2023-04-21 */ public class PtInfoConstant { /** * 平台服务电话 */ public static final String serverPhone = "01234567890"; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/constant/ZtApiDataColumnConstant.java
New file @@ -0,0 +1,23 @@ package cn.gistack.alerts.alarmRule.notice.constant; import java.util.ArrayList; import java.util.List; /** * 中台接口响应列常量 * @author zhongrj * @since 2023-04-21 */ public class ZtApiDataColumnConstant { /** * 水位数据缺失字段(不包含责任人相关信息) */ public static List<String> waterInfoNotList = new ArrayList<String>() {{ add("county_nm,town_nm"); add("res_nm"); }}; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/constant/ZtApiUrlConstant.java
New file @@ -0,0 +1,16 @@ package cn.gistack.alerts.alarmRule.notice.constant; /** * 中台接口请求信息常量 * @author zhongrj * @since 2023-04-21 */ public class ZtApiUrlConstant { /** * 水位数据缺失 */ public static final String res_z_null_api = "http://10.42.6.192/services/1234567890ABCDEFGHIJKLMN/res/z_null"; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/constant/ZtConfigConstant.java
New file @@ -0,0 +1,20 @@ package cn.gistack.alerts.alarmRule.notice.constant; /** * 中台接口请求信息常量 * @author zhongrj * @since 2023-04-21 */ public class ZtConfigConstant { /** * 请求头 key */ public static final String header_key = "apiKey"; /** * 请求头 value */ public static final String header_value = "F1DBECD719108635189480CF60E6553ADB3109616426BD537F25A430DFC613B491A025C4A51E77FD08C6E5B7CBE05917A461286E7B6D69F1AB1B14F946149D2065B0C675F8FEDF4B9B05C1496881BC5A"; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/controller/NoticeController.java
New file @@ -0,0 +1,34 @@ package cn.gistack.alerts.notice.controller; import cn.gistack.alerts.notice.strategy.NoticeStrategyContext; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 通知信息控制层 * @author zhongrj * @date 2023-05-29 */ @RestController @AllArgsConstructor @RequestMapping("/notice/notice") public class NoticeController { private final NoticeStrategyContext applicationContext; /** * 调用任务通知 * @param type 策略分类 * @param name 任务名称 * @param content 内容(可以不传) * @return */ @GetMapping("/toNotice") public Object toNotice(String type,String name,String content){ return applicationContext.doSomethingByStrategy(name, content, type); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/controller/NoticeTypeController.java
New file @@ -0,0 +1,28 @@ package cn.gistack.alerts.notice.controller; import cn.gistack.alerts.notice.entity.Notice; import cn.gistack.alerts.notice.strategy.NoticeTypeStrategyContext; import cn.gistack.alerts.notice.strategy.service.INoticeService; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 通知信息控制层 * @author zhongrj * @date 2023-05-29 */ @RestController @AllArgsConstructor @RequestMapping("/noticeType/noticeType") public class NoticeTypeController { private final NoticeTypeStrategyContext applicationContext; @GetMapping("/toNotice") public Object toNotice(Notice notice){ INoticeService noticeService = applicationContext.getResource(notice); return noticeService.toNotice(notice); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/entity/Notice.java
New file @@ -0,0 +1,31 @@ package cn.gistack.alerts.notice.entity; import cn.gistack.alerts.sms.entity.SmsTemplate; import cn.gistack.alerts.sms.vo.SmsRequestTemplate; import lombok.Data; import java.io.Serializable; /** * 通知类 * @author zhongrj * @date 2023-05-29 */ @Data public class Notice implements Serializable { /** * 通知类型 */ private String type; /** * 通知内容 */ private String content; /** * 短信通知发送模板 */ private SmsRequestTemplate smsRequestTemplate; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/service/impl/NoticeStrategyImpl.java
New file @@ -0,0 +1,462 @@ package cn.gistack.alerts.notice.service.impl; import cn.gistack.alerts.alarmRule.entity.AlarmRecord; import cn.gistack.alerts.alarmRule.entity.AlarmRule; import cn.gistack.alerts.alarmRule.service.AlarmRecordService; import cn.gistack.alerts.alarmRule.service.AlarmRuleService; import cn.gistack.alerts.sms.service.ISmsTemplateService; import cn.gistack.sm.intelligentCall.constant.ZtConstant; import cn.gistack.alerts.alarmRule.notice.constant.PtInfoConstant; import cn.gistack.alerts.alarmRule.notice.constant.ZtApiDataColumnConstant; import cn.gistack.alerts.alarmRule.notice.constant.ZtApiUrlConstant; import cn.gistack.alerts.notice.enums.PersonEnum; import cn.gistack.alerts.notice.util.FormatUtil; import cn.gistack.sm.sjztmd.vo.PersonVO; import cn.gistack.sm.sjztmd.feign.IAttResManagePersonClient; import cn.gistack.alerts.sms.entity.SmsTemplate; import cn.gistack.alerts.sms.service.SmsService; import cn.gistack.alerts.sms.vo.SmsRequestTemplate; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.List; /** * 通知策略 * * @author zhongrj * @date 2023-05-30 */ @Component public class NoticeStrategyImpl { @Autowired private SmsService smsService; @Autowired private AlarmRuleService alarmRuleService; @Autowired private AlarmRecordService alarmRecordService; @Autowired private ISmsTemplateService smsTemplateService; @Autowired private RestTemplate restTemplate; @Autowired private IAttResManagePersonClient attResManagePersonClient; /** * 短信发送数据组装 * * @param jsonArray * @param templateId * @param columnsList 列名集合信息 * @return */ private SmsRequestTemplate getSendSmsTemplate(JSONArray jsonArray, String templateId,AlarmRule alarmRule,List<String> columnsList) { // 通过模板id 查询模板相关信息 SmsTemplate smsTemplate = smsTemplateService.getOne(new QueryWrapper<SmsTemplate>().eq("template_id",templateId).eq("is_deleted",0)); if (null != smsTemplate) { SmsRequestTemplate smsRequestTemplate = new SmsRequestTemplate(); // 设置短信模板信息 smsRequestTemplate.setSmsTemplate(smsTemplate); // 解析模板并设置 title smsRequestTemplate.setTitle(FormatUtil.composeMessage(smsTemplate.getContent())); getColumnData(jsonArray, columnsList,smsRequestTemplate,templateId,alarmRule); //返回 return smsRequestTemplate; } return null; } /** * 列名数据转换 * @param jsonArray * @param columnsList * @param smsRequestTemplate * @param templateId * @return */ private void getColumnData(JSONArray jsonArray, List<String> columnsList, SmsRequestTemplate smsRequestTemplate, String templateId, AlarmRule alarmRule) { List<PersonVO> personLists = new ArrayList<>(); List<List<String>> lists = new ArrayList<>(); for (int i = 0; i < jsonArray.size(); i++) { // 根据水库编号,所在区域查询需要发送的人员手机号及设置 String res_cd = jsonArray.getJSONObject(i).getString("res_cd"); // 查询告警人员信息 List<PersonVO> personVOList = getPersonListByResGuid(res_cd,templateId,alarmRule); if (personVOList.size() > 0) { for (PersonVO personVO : personVOList) { List<String> list = new ArrayList<>(); list.add(res_cd); list.add(personVO.getPhone()); // 变量将值放入集合中 for (String column : columnsList) { String[] split = column.split(","); String format = ""; for (String s : split) { format = format + jsonArray.getJSONObject(i).getString(s); } list.add(format); } lists.add(list); } } personLists.addAll(personVOList); } // 设置信息 smsRequestTemplate.setPersonVOList(personLists); smsRequestTemplate.setTemplateContent(lists); } /** * 保存告警记录信息 * @param list * @param alarmRule 告警规则 * @return */ private AlarmRecord saveAlarmRecord(List<String> list,AlarmRule alarmRule) { AlarmRecord alarmRecord = new AlarmRecord(); // 设置相关信息 alarmRecord.setAlarmRuleId(alarmRule.getId().toString()); alarmRecord.setReservoirNumber(list.get(0)); alarmRecord.setAlarmCondition(alarmRule.getRuleRemark()); // 新增 boolean save = alarmRecordService.save(alarmRecord); if (save){ return alarmRecord; } // 返回 return null; } /** * 查询告警人员信息 * @param res_cd 水库 guid * @param templateId * @param alarmRule * @return */ private List<PersonVO> getPersonListByResGuid(String res_cd,String templateId,AlarmRule alarmRule) { // 查询对应的角色信息 String roles = alarmRule.getAlarmPerson(); String[] roleArray = roles.split(","); List<String> personList = new ArrayList<>(); List<String> areaList = new ArrayList<>(); // 遍历 for (String role : roleArray) { if (role.contains("责任人")){ personList.add(PersonEnum.findByName(role).getType().toString()); }else { areaList.add(role); } } // 根据角色,水库编号查询对应的告警人员信息 //1. 根据水库编号查询除责任人之外的人员信息 List<PersonVO> personVOList = attResManagePersonClient.getUserListByResGuid(res_cd); //2. 根据水库编号及责任人类型查询相关责任人信息 List<PersonVO> personVOList1 = attResManagePersonClient.getPersonListByResGuid(res_cd,String.join(",",personList)); // 合并人员数据 personVOList.addAll(personVOList1); // 返回数据 return personVOList; } /** * 默认实现 * * @param arg1 * @param arg2 * @return */ public String doSomethingDefault(String arg1, String arg2) { // 默认业务逻辑处理... return "默认实现"; } /** * 策略1: 水位信息接收不到 * * @param arg1 告警规则名称 * @param arg2 * @return */ public String waterInfoNotHandle(String arg1, String arg2) { // 查询当前策略对应的告警规则信息 AlarmRule alarmRule = alarmRuleService.getOne(new QueryWrapper<AlarmRule>().eq("rule_name", arg1)); if (null!=alarmRule) { // 调用中台服务接口查询数据 JSONArray ztData = getZtData("", ZtApiUrlConstant.res_z_null_api); // 只发短信,将发短信信息组装好 SmsRequestTemplate smsRequestTemplate = getSendSmsTemplate(ztData, "2431012216668",alarmRule, ZtApiDataColumnConstant.waterInfoNotList); // 拼接内容后面的联系方式,当前模板拼接平台服务电话 // 遍历,拼接平台服务电话 for (List<String> list : smsRequestTemplate.getTemplateContent()) { // 添加平台电话 list.add(PtInfoConstant.serverPhone); // 保存告警记录信息 // AlarmRecord alarmRecord = saveAlarmRecord(list,alarmRule); // if (null != alarmRecord) { // list.add(alarmRecord.getId().toString()); list.add("1123"); // } } // 调用短信服务 smsService.sendSignMsg(smsRequestTemplate); } // 保存预警记录 return "水位信息接收不到"; } /** * 策略2: 水位数据异常 * * @param arg1 * @param arg2 * @return */ public String waterDataExcHandle(String arg1, String arg2) { // 业务逻辑处理 2... return "水位数据异常"; } /** * 策略3: 水位超低于死水位 * * @param arg1 * @param arg2 * @return */ public String waterLessDeadHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略4: 水位高于死水位,低于旱警水位 * * @param arg1 * @param arg2 * @return */ public String waterMoreDeadLessHJHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略5: 水位接近汛限告警 * * @param arg1 * @param arg2 * @return */ public String waterComeOverHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略6: 水位初次超汛限告警 * * @param arg1 * @param arg2 * @return */ public String waterFirstOverHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略7: 水位小幅超汛限告警 * * @param arg1 * @param arg2 * @return */ public String waterSmallScaleOverHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略8: 水位大幅超汛限告警 * * @param arg1 * @param arg2 * @return */ public String waterBigScaleOverHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略9: 水位接近设计洪水位告警 * * @param arg1 * @param arg2 * @return */ public String waterComeDesignHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略10: 水位超设计洪水位告警 * * @param arg1 * @param arg2 * @return */ public String waterMoreDesignHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略11: 水位超校核洪水位告警 * * @param arg1 * @param arg2 * @return */ public String waterMoreCheckHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略12: 近1h水位陡升 * * @param arg1 * @param arg2 * @return */ public String waterComeOneHourUpHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略13: 近1h水位陡降 * * @param arg1 * @param arg2 * @return */ public String waterComeOneHourDownHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略14: 暴雨降雨预警 * * @param arg1 * @param arg2 * @return */ public String rainstormHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略15: 已降大雨告警 * * @param arg1 * @param arg2 * @return */ public String alreadyHeavyRainHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略16: 已降暴雨告警 * * @param arg1 * @param arg2 * @return */ public String alreadyRainstormHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略17: 2小时降雨告警 * * @param arg1 * @param arg2 * @return */ public String twoHourRainHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 策略18: 6小时降雨告警 * * @param arg1 * @param arg2 * @return */ public String sixHourRainHandle(String arg1, String arg2) { // 业务逻辑处理 2... return ""; } /** * 调用中台接口查询数据 * * @param params * @param url * @return */ private JSONArray getZtData(String params, String url) { //设置请求头 HttpHeaders headers = new HttpHeaders(); headers.add(ZtConstant.header_key, ZtConstant.header_value); //封装请求头 HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<MultiValueMap<String, Object>>(headers); try { //有请求头,有参数请求 ResponseEntity<String> responseEntity = restTemplate.exchange(url + params, HttpMethod.GET, formEntity, String.class); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONArray jsonArray = JSONArray.parseArray(jsonObject.get("data").toString()); // 返回 return jsonArray; } catch (Exception e) { e.printStackTrace(); } return null; } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/NoticeStrategyContext.java
New file @@ -0,0 +1,60 @@ package cn.gistack.alerts.notice.strategy; import cn.gistack.alerts.notice.service.impl.NoticeStrategyImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.function.BiFunction; /** * 通知方式策略 * @author zhongrj * @date 2023-05-29 * */ @Service @Slf4j public class NoticeStrategyContext { /** * 存放所有策略. */ private Map<String, BiFunction<String, String, String>> strategyMap = new HashMap<>(18); /** * 具体的策略细节. */ @Autowired private NoticeStrategyImpl noticeStrategyImpl; /** * 加载所有策略 */ @PostConstruct public void initStrategies() { strategyMap.put("waterInfoNotHandle", (arg1, arg2) -> noticeStrategyImpl.waterInfoNotHandle(arg1, arg2)); strategyMap.put("waterDataExcHandle", (arg1, arg2) -> noticeStrategyImpl.waterDataExcHandle(arg1, arg2)); } /** * 指派具体的策略去执行. * * @param arg1 参数1 * @param arg2 参数2 * @param key 根据key 来获取不同的策略 * @return */ public String doSomethingByStrategy(String arg1, String arg2, String key) { BiFunction<String, String, String> biFunction = strategyMap.get(key); if (Objects.isNull(biFunction)) { // 没有找到特定的策略,则采用默认实现(一般只有加了新的类型,但是没有配置对应的处理策略才会走到这里) log.warn("========= 没有配置该处理策略,采用默认实现,key {} ====== " + key); return noticeStrategyImpl.doSomethingDefault(arg1, arg2); } return biFunction.apply(arg1, arg2); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/NoticeTypeStrategyContext.java
New file @@ -0,0 +1,30 @@ package cn.gistack.alerts.notice.strategy; import cn.gistack.alerts.notice.entity.Notice; import cn.gistack.alerts.notice.strategy.service.INoticeService; import org.springframework.stereotype.Service; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 通知策略 * @author zhongrj * @date 2023-05-30 * @Description : 利用Spring的发现机制,将实现了NoticeStrategyService的类都put到noticeStrategyMap里面。 * 后面只需要根据type对应好 各个实现类的注解 如: @Component("tel") 就可以取出不同的业务实现类 */ @Service public class NoticeTypeStrategyContext { private final Map<String, INoticeService> noticeStrategyMap = new ConcurrentHashMap<>(); public NoticeTypeStrategyContext(Map<String, INoticeService> strategyMap) { this.noticeStrategyMap.clear(); strategyMap.forEach((k, v)-> this.noticeStrategyMap.put(k, v)); } public INoticeService getResource(Notice notice){ return noticeStrategyMap.get(notice.getType()); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/service/INoticeService.java
New file @@ -0,0 +1,18 @@ package cn.gistack.alerts.notice.strategy.service; import cn.gistack.alerts.notice.entity.Notice; /** * 通知策略接口 * @author zhongrj * @date 2023-05-29 */ public interface INoticeService { /** * 通知接口 * @param notice * @return */ Object toNotice(Notice notice); } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/service/impl/InStationNoticeServiceImpl.java
New file @@ -0,0 +1,24 @@ package cn.gistack.alerts.notice.strategy.service.impl; import cn.gistack.alerts.notice.entity.Notice; import cn.gistack.alerts.notice.strategy.service.INoticeService; import org.springframework.stereotype.Component; /** * 站内信通知 * @author zhongrj * @date 2023-05-29 */ @Component("inStation") public class InStationNoticeServiceImpl implements INoticeService { /** * 站内信通知实现 * @param notice * @return */ @Override public Object toNotice(Notice notice) { return "inStation"; } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/service/impl/SmsNoticeServiceImpl.java
New file @@ -0,0 +1,30 @@ package cn.gistack.alerts.notice.strategy.service.impl; import cn.gistack.alerts.notice.entity.Notice; import cn.gistack.alerts.notice.strategy.service.INoticeService; import cn.gistack.alerts.sms.service.SmsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 短信通知 * @author zhongrj * @date 2023-05-29 */ @Component("sms") public class SmsNoticeServiceImpl implements INoticeService { @Autowired private SmsService smsService; /** * 短信通知实现 * @param notice * @return */ @Override public Object toNotice(Notice notice) { // 短信发送 return smsService.sendSignMsg(notice.getSmsRequestTemplate()); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/strategy/service/impl/TelNoticeServiceImpl.java
New file @@ -0,0 +1,24 @@ package cn.gistack.alerts.notice.strategy.service.impl; import cn.gistack.alerts.notice.entity.Notice; import cn.gistack.alerts.notice.strategy.service.INoticeService; import org.springframework.stereotype.Component; /** * 电话通知 * @author zhongrj * @date 2023-05-29 */ @Component("tel") public class TelNoticeServiceImpl implements INoticeService { /** * 电话通知实现 * @param notice * @return */ @Override public Object toNotice(Notice notice) { return "tel"; } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/notice/util/FormatUtil.java
New file @@ -0,0 +1,56 @@ package cn.gistack.alerts.notice.util; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 格式化转换工具 * @author zhongrj * @date 2023-05-31 */ public class FormatUtil { /** * 取出{}中的内容 * @param content * @return */ public static String composeMessage(String content){ // 正则 ,匹配 {}及内所有内容 String regex = "\\{.+?\\}"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(content); List<String> list = new ArrayList<>(); list.add("手机号码"); while (matcher.find()) { // 键名 String key = matcher.group(); // 去除首尾大括号 String title = key.substring(1,key.length()-1).split(",")[0]; // 放入集合 list.add(title); } // 转换为以逗号分隔的字符串 return String.join(",",list); } // public static void main(String[] args) { // String data = "黄色预警:{日期,2}日{小时,2}时{分钟,2}分,{乡镇,10}乡镇{村,10}村{水库名称,25}水位{水库水位值,6}米过去一小时陡降{水位降值,6}米。过去24小时坝前点雨量{雨量值,6}毫米。请巡查责任人{姓名,4}做好巡查值守,发现险情及时上报;请技术责任人{姓名,4}密切关注。如为数据误报,请及时联系市县水利部门人员{姓名联系电话,16}(电话号码)。"; // String message = composeMessage(data); // System.out.println("message = " + message); // // String s = "黄色预警:{日期,2}{小时,2}{分钟,2}分数据误报,"; // String s1 = s.replaceAll("\\{.+?\\}", "%s"); // System.out.println(s1); // // String s2 = "1,2,3"; // // // String format = String.format(s1, Arrays.asList(s2.split(","))); // System.out.println("format = " + format); // } }