From a66f7d6aaef3895d10da42e54ab5054ec6464bdc Mon Sep 17 00:00:00 2001 From: 3y Date: Wed, 30 Nov 2022 19:33:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E5=BE=AE=E4=BF=A1=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=8F=B7=E6=B6=88=E6=81=AF=E5=AE=8C=E6=88=90=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/account/WeChatOfficialAccount.java | 19 +- .../model/OfficialAccountsContentModel.java | 19 +- .../domain/wechat/WeChatOfficialParam.java | 37 --- .../handler/impl/OfficialAccountHandler.java | 68 +++-- .../wechat/OfficialAccountService.java | 22 -- .../impl/OfficialAccountServiceImpl.java | 90 ------ .../controller/MessageTemplateController.java | 22 +- .../controller/OfficialAccountController.java | 42 +-- .../java3y/austin/web/utils/Convert4Amis.java | 263 ++++++++++++++++++ .../java3y/austin/web/utils/ConvertMap.java | 102 ------- 10 files changed, 350 insertions(+), 334 deletions(-) delete mode 100644 austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java delete mode 100644 austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java delete mode 100644 austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java create mode 100644 austin-web/src/main/java/com/java3y/austin/web/utils/Convert4Amis.java delete mode 100644 austin-web/src/main/java/com/java3y/austin/web/utils/ConvertMap.java diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java index 3f1a1c6..59ab5a6 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java @@ -5,8 +5,6 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.Map; - /** * * 模板消息参数 @@ -21,25 +19,10 @@ import java.util.Map; @NoArgsConstructor public class WeChatOfficialAccount { - /** - * 模板消息跳转的url - */ - private String url; - - /** - * 模板消息跳转小程序的appid - */ - private String miniProgramId; - - /** - * 模板消息跳转小程序的页面路径 - */ - private String path; - /** * 账号相关 */ private String appId; private String secret; - private String templateId; + } diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/model/OfficialAccountsContentModel.java b/austin-common/src/main/java/com/java3y/austin/common/dto/model/OfficialAccountsContentModel.java index f30fd41..2f519fd 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/dto/model/OfficialAccountsContentModel.java +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/model/OfficialAccountsContentModel.java @@ -19,11 +19,26 @@ public class OfficialAccountsContentModel extends ContentModel { /** * 模板消息发送的数据 */ - Map map; + private Map officialAccountParam; /** * 模板消息跳转的url */ - String url; + private String url; + + /** + * 模板Id + */ + private String templateId; + + /** + * 模板消息跳转小程序的appid + */ + private String miniProgramId; + + /** + * 模板消息跳转小程序的页面路径 + */ + private String path; } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java deleted file mode 100644 index ecd134c..0000000 --- a/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.java3y.austin.handler.domain.wechat; - -import lombok.Builder; -import lombok.Data; - -import java.util.Map; -import java.util.Set; - -/** - * @author sunql - * @date 2022年05月06日 9:56 - * - * 服务号参数 - */ -@Data -@Builder -public class WeChatOfficialParam { - /** - * 业务Id - */ - private Long messageTemplateId; - - /** - * 关注服务号得用户 - */ - private Set openIds; - - /** - * 模板消息的信息载体 - */ - private Map data; - - /** - * 发送账号 - */ - private Integer sendAccount; -} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java index 59f8b90..e4984ea 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java @@ -5,16 +5,20 @@ import com.google.common.base.Throwables; import com.java3y.austin.common.domain.TaskInfo; import com.java3y.austin.common.dto.model.OfficialAccountsContentModel; import com.java3y.austin.common.enums.ChannelType; -import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import com.java3y.austin.handler.handler.BaseHandler; import com.java3y.austin.handler.handler.Handler; -import com.java3y.austin.handler.wechat.OfficialAccountService; import com.java3y.austin.support.domain.MessageTemplate; +import com.java3y.austin.support.utils.WxServiceUtils; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; /** * @author zyg @@ -24,36 +28,60 @@ import java.util.List; @Slf4j public class OfficialAccountHandler extends BaseHandler implements Handler { - @Autowired - private OfficialAccountService officialAccountService; - public OfficialAccountHandler() { channelCode = ChannelType.OFFICIAL_ACCOUNT.getCode(); } @Override public boolean handler(TaskInfo taskInfo) { - // 构建微信模板消息 - OfficialAccountsContentModel contentModel = (OfficialAccountsContentModel) taskInfo.getContentModel(); - WeChatOfficialParam officialParam = WeChatOfficialParam.builder() - .openIds(taskInfo.getReceiver()) - .messageTemplateId(taskInfo.getMessageTemplateId()) - .sendAccount(taskInfo.getSendAccount()) - .data(contentModel.getMap()) - .build(); - - // 微信模板消息需要记录响应结果 try { - List messageIds = officialAccountService.send(officialParam); - log.info("OfficialAccountHandler#handler successfully messageIds:{}", messageIds); + OfficialAccountsContentModel contentModel = (OfficialAccountsContentModel) taskInfo.getContentModel(); + WxMpService wxMpService = WxServiceUtils.wxMpServiceMap.get(taskInfo.getSendAccount().longValue()); + List messages = assembleReq(taskInfo.getReceiver(), contentModel); + for (WxMpTemplateMessage message : messages) { + try { + wxMpService.getTemplateMsgService().sendTemplateMsg(message); + } catch (Exception e) { + log.info("OfficialAccountHandler#handler fail! param:{},e:{}", JSON.toJSONString(taskInfo), Throwables.getStackTraceAsString(e)); + } + } return true; } catch (Exception e) { - log.error("OfficialAccountHandler#handler fail:{},params:{}", - Throwables.getStackTraceAsString(e), JSON.toJSONString(taskInfo)); + log.error("OfficialAccountHandler#handler fail:{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(taskInfo)); } return false; } + + /** + * 组装发送模板信息参数 + */ + private List assembleReq(Set receiver, OfficialAccountsContentModel contentModel) { + List wxMpTemplateMessages = new ArrayList<>(receiver.size()); + for (String openId : receiver) { + WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() + .toUser(openId) + .templateId(contentModel.getTemplateId()) + .url(contentModel.getUrl()) + .data(getWxMpTemplateData(contentModel.getOfficialAccountParam())) + .miniProgram(new WxMpTemplateMessage.MiniProgram(contentModel.getMiniProgramId(), contentModel.getPath(), false)) + .build(); + wxMpTemplateMessages.add(templateMessage); + } + return wxMpTemplateMessages; + } + + /** + * 构建模板消息参数 + * + * @return + */ + private List getWxMpTemplateData(Map data) { + List templateDataList = new ArrayList<>(data.size()); + data.forEach((k, v) -> templateDataList.add(new WxMpTemplateData(k, v))); + return templateDataList; + } + @Override public void recall(MessageTemplate messageTemplate) { diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java deleted file mode 100644 index 4014db2..0000000 --- a/austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.java3y.austin.handler.wechat; - -import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; - -import java.util.List; - -/** - * @author zyg - */ -public interface OfficialAccountService { - - /** - * 发送模板消息 - * - * @param weChatOfficialParam 模板消息参数 - * @return - * @throws Exception - */ - List send(WeChatOfficialParam weChatOfficialParam) throws Exception; - -} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java deleted file mode 100644 index 6ce3703..0000000 --- a/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.java3y.austin.handler.wechat.impl; - -import com.java3y.austin.common.dto.account.WeChatOfficialAccount; -import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; -import com.java3y.austin.handler.wechat.OfficialAccountService; -import com.java3y.austin.support.utils.AccountUtils; -import com.java3y.austin.support.utils.WxServiceUtils; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; -import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * @author zyg - */ -@Service -@Slf4j -public class OfficialAccountServiceImpl implements OfficialAccountService { - - @Autowired - private AccountUtils accountUtils; - - @Override - public List send(WeChatOfficialParam officialParam) throws Exception { - WxMpService wxMpService = WxServiceUtils.wxMpServiceMap.get(officialParam.getSendAccount()); - WeChatOfficialAccount officialAccount = WxServiceUtils.accountHashMap.get(officialParam.getSendAccount()); - List messages = assembleReq(officialParam, officialAccount); - List messageIds = new ArrayList<>(messages.size()); - for (WxMpTemplateMessage wxMpTemplateMessage : messages) { - String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage); - messageIds.add(msgId); - } - return messageIds; - } - - /** - * 组装发送模板信息参数 - */ - private List assembleReq(WeChatOfficialParam officialParam, WeChatOfficialAccount officialAccount) { - Set receiver = officialParam.getOpenIds(); - List wxMpTemplateMessages = new ArrayList<>(receiver.size()); - - // 构建微信模板消息 - for (String openId : receiver) { - WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() - .toUser(openId) - .templateId(officialAccount.getTemplateId()) - .url(officialAccount.getUrl()) - .data(getWxMpTemplateData(officialParam.getData())) - .miniProgram(new WxMpTemplateMessage.MiniProgram(officialAccount.getMiniProgramId(), officialAccount.getPath(), false)) - .build(); - wxMpTemplateMessages.add(templateMessage); - } - return wxMpTemplateMessages; - } - - /** - * 构建模板消息参数 - * - * @return - */ - private List getWxMpTemplateData(Map data) { - List templateDataList = new ArrayList<>(data.size()); - data.forEach((k, v) -> templateDataList.add(new WxMpTemplateData(k, v))); - return templateDataList; - } - - /** - * 初始化微信服务号 - * - * @return - */ - public WxMpService initService(WeChatOfficialAccount officialAccount) { - WxMpService wxMpService = new WxMpServiceImpl(); - WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); - config.setAppId(officialAccount.getAppId()); - config.setSecret(officialAccount.getSecret()); - wxMpService.setWxMpConfigStorage(config); - return wxMpService; - } -} diff --git a/austin-web/src/main/java/com/java3y/austin/web/controller/MessageTemplateController.java b/austin-web/src/main/java/com/java3y/austin/web/controller/MessageTemplateController.java index f16b51d..4d9776a 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/controller/MessageTemplateController.java +++ b/austin-web/src/main/java/com/java3y/austin/web/controller/MessageTemplateController.java @@ -16,9 +16,10 @@ import com.java3y.austin.service.api.service.RecallService; import com.java3y.austin.service.api.service.SendService; import com.java3y.austin.support.domain.MessageTemplate; import com.java3y.austin.web.service.MessageTemplateService; -import com.java3y.austin.web.utils.ConvertMap; +import com.java3y.austin.web.utils.Convert4Amis; import com.java3y.austin.web.vo.MessageTemplateParam; import com.java3y.austin.web.vo.MessageTemplateVo; +import com.java3y.austin.web.vo.amis.CommonAmisVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -76,7 +77,7 @@ public class MessageTemplateController { @GetMapping("/list") @ApiOperation("/列表页") public BasicResultVO queryList(@Validated MessageTemplateParam messageTemplateParam) { - List> result = ConvertMap.flatList(messageTemplateService.queryList(messageTemplateParam)); + List> result = Convert4Amis.flatListMap(messageTemplateService.queryList(messageTemplateParam)); long count = messageTemplateService.count(); MessageTemplateVo messageTemplateVo = MessageTemplateVo.builder().count(count).rows(result).build(); @@ -89,7 +90,7 @@ public class MessageTemplateController { @GetMapping("query/{id}") @ApiOperation("/根据Id查找") public BasicResultVO queryById(@PathVariable("id") Long id) { - Map result = ConvertMap.flatSingle(messageTemplateService.queryById(id)); + Map result = Convert4Amis.flatSingleMap(messageTemplateService.queryById(id)); return BasicResultVO.success(result); } @@ -137,6 +138,21 @@ public class MessageTemplateController { return BasicResultVO.success(response); } + /** + * 获取需要测试的模板占位符,透出给Amis + */ + @PostMapping("test/content") + @ApiOperation("/测试发送接口") + public BasicResultVO test(Long id) { + MessageTemplate messageTemplate = messageTemplateService.queryById(id); + CommonAmisVo commonAmisVo = Convert4Amis.getTestContent(messageTemplate.getMsgContent()); + if (commonAmisVo != null) { + return BasicResultVO.success(commonAmisVo); + } + return BasicResultVO.success(); + } + + /** * 撤回接口 */ diff --git a/austin-web/src/main/java/com/java3y/austin/web/controller/OfficialAccountController.java b/austin-web/src/main/java/com/java3y/austin/web/controller/OfficialAccountController.java index 512b442..751ec09 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/controller/OfficialAccountController.java +++ b/austin-web/src/main/java/com/java3y/austin/web/controller/OfficialAccountController.java @@ -1,12 +1,12 @@ package com.java3y.austin.web.controller; -import cn.hutool.core.util.StrUtil; import com.google.common.base.Throwables; import com.java3y.austin.common.constant.AustinConstant; import com.java3y.austin.common.enums.RespStatusEnum; import com.java3y.austin.common.vo.BasicResultVO; import com.java3y.austin.support.utils.WxServiceUtils; +import com.java3y.austin.web.utils.Convert4Amis; import com.java3y.austin.web.vo.amis.CommonAmisVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -71,7 +71,7 @@ public class OfficialAccountController { try { WxMpService wxMpService = WxServiceUtils.wxMpServiceMap.get(id); List allPrivateTemplate = wxMpService.getTemplateMsgService().getAllPrivateTemplate(); - CommonAmisVo wxMpTemplateParam = getWxMpTemplateParam(wxTemplateId, allPrivateTemplate); + CommonAmisVo wxMpTemplateParam = Convert4Amis.getWxMpTemplateParam(wxTemplateId, allPrivateTemplate); return BasicResultVO.success(wxMpTemplateParam); } catch (Exception e) { log.error("OfficialAccountController#queryList fail:{}", Throwables.getStackTraceAsString(e)); @@ -80,43 +80,5 @@ public class OfficialAccountController { } - /** - * 这个方法不用看,纯粹为了适配amis前端 - * - * @param wxTemplateId - * @param allPrivateTemplate - * @return - */ - private CommonAmisVo getWxMpTemplateParam(String wxTemplateId, List allPrivateTemplate) { - CommonAmisVo officialAccountParam = null; - for (WxMpTemplate wxMpTemplate : allPrivateTemplate) { - if (wxTemplateId.equals(wxMpTemplate.getTemplateId())) { - String[] data = wxMpTemplate.getContent().split(StrUtil.LF); - officialAccountParam = CommonAmisVo.builder() - .type("input-table") - .name("officialAccountParam") - .label("新增一行,输入模板对应的文案") - .addable(true) - .editable(true) - .needConfirm(false) - .build(); - List columnsDTOS = new ArrayList<>(); - for (String datum : data) { - String name = datum.substring(datum.indexOf("{{") + 2, datum.indexOf(".")); - CommonAmisVo.ColumnsDTO.ColumnsDTOBuilder dtoBuilder = CommonAmisVo.ColumnsDTO.builder().name(name).type("input-text").required(true).quickEdit(true); - if (datum.contains("first")) { - dtoBuilder.label("名字"); - } else if (datum.contains("remark")) { - dtoBuilder.label("备注"); - } else { - dtoBuilder.label(datum.split(":")[0]); - } - columnsDTOS.add(dtoBuilder.build()); - } - officialAccountParam.setColumns(columnsDTOS); - } - } - return officialAccountParam; - } } diff --git a/austin-web/src/main/java/com/java3y/austin/web/utils/Convert4Amis.java b/austin-web/src/main/java/com/java3y/austin/web/utils/Convert4Amis.java new file mode 100644 index 0000000..fa1a0b8 --- /dev/null +++ b/austin-web/src/main/java/com/java3y/austin/web/utils/Convert4Amis.java @@ -0,0 +1,263 @@ +package com.java3y.austin.web.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.java3y.austin.web.vo.amis.CommonAmisVo; +import me.chanjar.weixin.mp.bean.template.WxMpTemplate; + +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 【该类的逻辑不用看,没有什么意义】 + * for Amis!!! amis框架在【表单】回显的时候,不支持嵌套动态语法!! + * 编写工具类将 List/Object 铺平成 Map 以及相关的格式 + * https://baidu.gitee.io/amis/zh-CN/components/form/index#%E8%A1%A8%E5%8D%95%E9%A1%B9%E6%95%B0%E6%8D%AE%E5%88%9D%E5%A7%8B%E5%8C%96 + * + * @author 3y + * @date 2022/1/23 + */ +public class Convert4Amis { + + // 标识忽略 + public static final int ignoreTg = 0; + // 标识已读取到'$'字符 + public static final int startTg = 1; + // 标识已读取到'{'字符 + public static final int readTg = 2; + /** + * 需要打散的字段(将json字符串打散为一个一个字段返回) + * (主要是用于回显数据) + */ + private static final List FLAT_FIELD_NAME = Arrays.asList("msgContent"); + + /** + * 需要格式化为jsonArray返回的字段 + * (前端是一个JSONArray传递进来) + */ + private static final List PARSE_JSON_ARRAY = Arrays.asList("feedCards", "btns"); + + /** + * (前端是一个JSONObject传递进来,返回一个JSONArray回去) + */ + private static final List PARSE_JSON_OBJ_TO_ARRAY = Arrays.asList("officialAccountParam"); + + /** + * 钉钉工作消息OA实际的映射 + */ + private static final List DING_DING_OA_FIELD = Arrays.asList("dingDingOaHead", "dingDingOaBody"); + /** + * 钉钉OA字段名实际的映射 + */ + private static final Map DING_DING_OA_NAME_MAPPING = new HashMap<>(); + + static { + DING_DING_OA_NAME_MAPPING.put("bgcolor", "dingDingOaHeadBgColor"); + DING_DING_OA_NAME_MAPPING.put("text", "dingDingOaHeadTitle"); + DING_DING_OA_NAME_MAPPING.put("title", "dingDingOaTitle"); + DING_DING_OA_NAME_MAPPING.put("image", "media_id"); + DING_DING_OA_NAME_MAPPING.put("author", "dingDingOaAuthor"); + DING_DING_OA_NAME_MAPPING.put("content", "dingDingOaContent"); + } + + /** + * 将List对象转换成Map(无嵌套) + * + * @param param + * @return + */ + public static List> flatListMap(List param) { + List> result = new ArrayList<>(); + for (T t : param) { + Map map = flatSingleMap(t); + result.add(map); + } + return result; + } + + /** + * 将单个对象转换成Map(无嵌套) + *

+ * 主要兼容amis的回显(前端不用amis可忽略) + * + * @param obj + * @return + */ + public static Map flatSingleMap(Object obj) { + Map result = MapUtil.newHashMap(32); + Field[] fields = ReflectUtil.getFields(obj.getClass()); + for (Field field : fields) { + if (FLAT_FIELD_NAME.contains(field.getName())) { + String fieldValue = (String) ReflectUtil.getFieldValue(obj, field); + JSONObject jsonObject = JSONObject.parseObject(fieldValue); + for (String key : jsonObject.keySet()) { + /** + * 钉钉OA消息回显 + */ + if (DING_DING_OA_FIELD.contains(key)) { + JSONObject object = jsonObject.getJSONObject(key); + for (String objKey : object.keySet()) { + result.put(DING_DING_OA_NAME_MAPPING.get(objKey), object.getString(objKey)); + } + } else if (PARSE_JSON_ARRAY.contains(key)) { + /** + * 部分字段是直接传入数组,把数组直接返回(用于回显) + */ + result.put(key, JSON.parseArray(jsonObject.getString(key))); + } else if (PARSE_JSON_OBJ_TO_ARRAY.contains(key)) { + /** + * 部分字段是直接传入Obj,把数组直接返回(用于回显) + */ + String value = "[" + jsonObject.getString(key) + "]"; + result.put(key, JSON.parseArray(value)); + } else { + result.put(key, jsonObject.getString(key)); + } + } + } + result.put(field.getName(), ReflectUtil.getFieldValue(obj, field)); + } + return result; + } + + /** + * 【这个方法不用看】,纯粹为了适配amis前端 + * + * @param wxTemplateId + * @param allPrivateTemplate + * @return + */ + public static CommonAmisVo getWxMpTemplateParam(String wxTemplateId, List allPrivateTemplate) { + CommonAmisVo officialAccountParam = null; + for (WxMpTemplate wxMpTemplate : allPrivateTemplate) { + if (wxTemplateId.equals(wxMpTemplate.getTemplateId())) { + String[] data = wxMpTemplate.getContent().split(StrUtil.LF); + officialAccountParam = CommonAmisVo.builder() + .type("input-table") + .name("officialAccountParam") + .addable(true) + .editable(true) + .needConfirm(false) + .build(); + List columnsDTOS = new ArrayList<>(); + for (String datum : data) { + String name = datum.substring(datum.indexOf("{{") + 2, datum.indexOf(".")); + CommonAmisVo.ColumnsDTO.ColumnsDTOBuilder dtoBuilder = CommonAmisVo.ColumnsDTO.builder().name(name).type("input-text").required(true).quickEdit(true); + if (datum.contains("first")) { + dtoBuilder.label("名字"); + } else if (datum.contains("remark")) { + dtoBuilder.label("备注"); + } else { + dtoBuilder.label(datum.split(":")[0]); + } + columnsDTOS.add(dtoBuilder.build()); + } + officialAccountParam.setColumns(columnsDTOS); + + } + } + return officialAccountParam; + } + + + /** + * 【这个方法不用看】,纯粹为了适配amis前端 + *

+ * 获取占位符的参数 + * + * @param msgContent + * @return + */ + public static CommonAmisVo getTestContent(String msgContent) { + Set placeholderList = getPlaceholderList(msgContent); + if (CollUtil.isEmpty(placeholderList)) { + return null; + } + + // placeholderList!=null 说明有占位符 + CommonAmisVo testParam = CommonAmisVo.builder() + .type("input-table") + .name("testParam") + .addable(true) + .editable(true) + .needConfirm(false) + .build(); + List columnsDTOS = new ArrayList<>(); + for (String param : placeholderList) { + CommonAmisVo.ColumnsDTO dto = CommonAmisVo.ColumnsDTO.builder().name(param).label(param).type("input-text").required(true).quickEdit(true).build(); + columnsDTOS.add(dto); + } + testParam.setColumns(columnsDTOS); + return testParam; + } + + /** + * 获取占位符的参数 + * + * @param content + * @return + */ + public static Set getPlaceholderList(String content) { + char[] textChars = content.toCharArray(); + StringBuilder textSofar = new StringBuilder(); + StringBuilder sb = new StringBuilder(); + // 存储占位符 位置信息集合 + List placeholderList = new ArrayList<>(); + // 当前标识 + int modeTg = ignoreTg; + for (int m = 0; m < textChars.length; m++) { + char c = textChars[m]; + textSofar.append(c); + switch (c) { + case '{': { + modeTg = startTg; + sb.append(c); + } + break; + case '$': { + if (modeTg == startTg) { + sb.append(c); + modeTg = readTg; + } else { + if (modeTg == readTg) { + sb = new StringBuilder(); + modeTg = ignoreTg; + } + } + } + break; + case '}': { + if (modeTg == readTg) { + modeTg = ignoreTg; + sb.append(c); + String str = sb.toString(); + if (StrUtil.isNotEmpty(str)) { + placeholderList.add(str); + textSofar = new StringBuilder(); + } + sb = new StringBuilder(); + } else if (modeTg == startTg) { + modeTg = ignoreTg; + sb = new StringBuilder(); + } + } + default: { + if (modeTg == readTg) { + sb.append(c); + } else if (modeTg == startTg) { + modeTg = ignoreTg; + sb = new StringBuilder(); + } + } + } + } + Set result = placeholderList.stream().map(s -> s.replaceAll("\\{", "").replaceAll("\\$", "").replaceAll("\\}", "")).collect(Collectors.toSet()); + return result; + } + +} diff --git a/austin-web/src/main/java/com/java3y/austin/web/utils/ConvertMap.java b/austin-web/src/main/java/com/java3y/austin/web/utils/ConvertMap.java deleted file mode 100644 index 883027f..0000000 --- a/austin-web/src/main/java/com/java3y/austin/web/utils/ConvertMap.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.java3y.austin.web.utils; - -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ReflectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; - -import java.lang.reflect.Field; -import java.util.*; - -/** - * for Amis!!! amis框架在【表单】回显的时候,不支持嵌套动态语法!! - * 编写工具类将 List/Object 铺平成 Map - * https://baidu.gitee.io/amis/zh-CN/components/form/index#%E8%A1%A8%E5%8D%95%E9%A1%B9%E6%95%B0%E6%8D%AE%E5%88%9D%E5%A7%8B%E5%8C%96 - * - * @author 3y - * @date 2022/1/23 - */ -public class ConvertMap { - /** - * 需要打散的字段(将json字符串打散为一个一个字段返回) - * (主要是用于回显数据) - */ - private static final List FLAT_FIELD_NAME = Arrays.asList("msgContent"); - - /** - * 需要格式化为jsonArray返回的字段 - * (前端是一个JSONArray传递进来) - */ - private static final List PARSE_JSON_ARRAY = Arrays.asList("feedCards", "btns"); - - /** - * 钉钉工作消息OA实际的映射 - */ - private static final List DING_DING_OA_FIELD = Arrays.asList("dingDingOaHead", "dingDingOaBody"); - /** - * 钉钉OA字段名实际的映射 - */ - private static final Map DING_DING_OA_NAME_MAPPING = new HashMap<>(); - static { - DING_DING_OA_NAME_MAPPING.put("bgcolor", "dingDingOaHeadBgColor"); - DING_DING_OA_NAME_MAPPING.put("text", "dingDingOaHeadTitle"); - DING_DING_OA_NAME_MAPPING.put("title", "dingDingOaTitle"); - DING_DING_OA_NAME_MAPPING.put("image", "media_id"); - DING_DING_OA_NAME_MAPPING.put("author", "dingDingOaAuthor"); - DING_DING_OA_NAME_MAPPING.put("content", "dingDingOaContent"); - } - - /** - * 将List对象转换成Map(无嵌套) - * - * @param param - * @return - */ - public static List> flatList(List param) { - List> result = new ArrayList<>(); - for (T t : param) { - Map map = flatSingle(t); - result.add(map); - } - return result; - } - - /** - * 将单个对象转换成Map(无嵌套) - *

- * 主要兼容amis的回显(前端不用amis可忽略) - * - * @param obj - * @return - */ - public static Map flatSingle(Object obj) { - Map result = MapUtil.newHashMap(32); - Field[] fields = ReflectUtil.getFields(obj.getClass()); - for (Field field : fields) { - if (FLAT_FIELD_NAME.contains(field.getName())) { - String fieldValue = (String) ReflectUtil.getFieldValue(obj, field); - JSONObject jsonObject = JSONObject.parseObject(fieldValue); - for (String key : jsonObject.keySet()) { - /** - * 钉钉OA消息回显 - */ - if (DING_DING_OA_FIELD.contains(key)) { - JSONObject object = jsonObject.getJSONObject(key); - for (String objKey : object.keySet()) { - result.put(DING_DING_OA_NAME_MAPPING.get(objKey), object.getString(objKey)); - } - } else if (PARSE_JSON_ARRAY.contains(key)) { - /** - * 部分字段是直接传入数组,把数组直接返回(也是用于回显) - */ - result.put(key, JSON.parseArray(jsonObject.getString(key))); - } else{ - result.put(key, jsonObject.getString(key)); - } - } - } - result.put(field.getName(), ReflectUtil.getFieldValue(obj, field)); - } - return result; - } -}