|
@@ -0,0 +1,238 @@
|
|
|
+package kd.cosmic.jkjt.tmc.bei.task;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import kd.bos.algo.DataSet;
|
|
|
+import kd.bos.context.RequestContext;
|
|
|
+import kd.bos.dataentity.entity.DynamicObject;
|
|
|
+import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
|
+import kd.bos.exception.KDException;
|
|
|
+import kd.bos.logging.BizLog;
|
|
|
+import kd.bos.orm.ORM;
|
|
|
+import kd.bos.orm.query.QCP;
|
|
|
+import kd.bos.orm.query.QFilter;
|
|
|
+import kd.bos.schedule.api.StopTask;
|
|
|
+import kd.bos.schedule.executor.AbstractTask;
|
|
|
+import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
|
+import kd.bos.servicehelper.QueryServiceHelper;
|
|
|
+import kd.bos.workflow.engine.msg.info.MessageInfo;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.CommonUtils;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.DateUtils;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.FeishuSendMessageUtils;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.constant.BeiBeTransDetailConstant;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.constant.LargeTransConfigConstant;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.constant.MsgWarnTemplateConstant;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.entity.MsgWarnMessageInfo;
|
|
|
+import kd.cosmic.jkjt.tmc.bei.common.enums.MsgWarnTypeEnum;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 大额交易预警任务
|
|
|
+ */
|
|
|
+public class LargeTransMsgWarnTask extends AbstractTask implements StopTask {
|
|
|
+
|
|
|
+ private String taskType ;
|
|
|
+
|
|
|
+ private static final MsgWarnTypeEnum WARTYPE = MsgWarnTypeEnum.LARGETRANS;
|
|
|
+ @Override
|
|
|
+ public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
|
|
|
+ // 查询生效的账户大额交易通知配置
|
|
|
+ Set<Long> largeTransIdConfig = getLargeTransConfig();
|
|
|
+
|
|
|
+ this.taskType = (String) map.get("taskType");
|
|
|
+
|
|
|
+ largeTransIdConfig.forEach(configId -> transConfigSendMessage(configId));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据账户大额交易通知配置,发送消息
|
|
|
+ * @param largeTransIdConfig
|
|
|
+ */
|
|
|
+ protected void transConfigSendMessage(Long largeTransIdConfig) {
|
|
|
+
|
|
|
+ DynamicObject configInfo = BusinessDataServiceHelper.loadSingle(largeTransIdConfig, LargeTransConfigConstant.ENTITYID);
|
|
|
+ DynamicObject company = configInfo.getDynamicObject(LargeTransConfigConstant.KEY_NCKD_COMPANY);
|
|
|
+ // 增加互斥锁,防止多个任务同时执行
|
|
|
+ DynamicObjectCollection ruleEntryCol = configInfo.getDynamicObjectCollection(LargeTransConfigConstant.RULEENTRY.ENTITYID);
|
|
|
+ ruleEntryCol.stream().forEach(ruleEntry -> sendMessageMatchRule(company, ruleEntry));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据规则匹配发送消息
|
|
|
+ * @param company
|
|
|
+ * @param ruleEntry
|
|
|
+ */
|
|
|
+ protected void sendMessageMatchRule(DynamicObject company , DynamicObject ruleEntry){
|
|
|
+ // 最小金额
|
|
|
+ BigDecimal lowerAmount = ruleEntry.getBigDecimal(LargeTransConfigConstant.RULEENTRY.KEY_NCKD_AMOUNT_LOWER);
|
|
|
+ // 最大金额
|
|
|
+ BigDecimal highAmount = ruleEntry.getBigDecimal(LargeTransConfigConstant.RULEENTRY.KEY_NCKD_AMOUNT_HIGH);
|
|
|
+ if(!ruleEntry.getBoolean("nckd_enable")){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String ruleName = ruleEntry.getString(LargeTransConfigConstant.RULEENTRY.KEY_NCKD_RULENAME);
|
|
|
+ DynamicObjectCollection receiverCol = ruleEntry.getDynamicObjectCollection(LargeTransConfigConstant.RULEENTRY.KEY_NCKD_RECEIVER);
|
|
|
+ if(receiverCol == null || receiverCol.isEmpty()){
|
|
|
+ BizLog.log("消息接收人为空,不进行消息发送。");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<Long> receiverIdList = receiverCol.stream().map(receiver -> (Long) receiver.getDynamicObject(LargeTransConfigConstant.KEY_FBASEDATAID).getPkValue()).collect(Collectors.toList());
|
|
|
+ // 查询公司下,时间范围内符合规则条件的数据
|
|
|
+ DynamicObjectCollection transDetailData = getTransDetailData(company, lowerAmount, highAmount);
|
|
|
+
|
|
|
+ if(transDetailData == null || transDetailData.isEmpty()){
|
|
|
+ BizLog.log("没有符合条件的数据,不进行消息发送。");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(DynamicObject transDetail : transDetailData){
|
|
|
+ String uniqueKey = String.join("-",WARTYPE.getValue(),transDetail.getString("billno"));
|
|
|
+// if(ORM.create().exists("nckd_msgwarnlog",new QFilter("nckd_unique_key", QCP.equals,uniqueKey).toArray())){
|
|
|
+// // 消息如果已发送,就不在执行
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+ String messageContent = getMcCenterMessage(transDetail);
|
|
|
+
|
|
|
+ MessageInfo messageInfo = new MessageInfo();
|
|
|
+ messageInfo.setTitle(String.join("-",WARTYPE.getName(),ruleName));
|
|
|
+ messageInfo.setUserIds(receiverIdList);
|
|
|
+ messageInfo.setContent(messageContent);
|
|
|
+ messageInfo.setTag(WARTYPE.getName());
|
|
|
+ messageInfo.setSenderId(RequestContext.get().getCurrUserId());
|
|
|
+ messageInfo.setEntityNumber(BeiBeTransDetailConstant.ENTITYID);
|
|
|
+ messageInfo.setBizDataId(transDetail.getLong("id"));
|
|
|
+
|
|
|
+ String feishuMessage = MsgWarnTemplateConstant.getFeishuTemplate(WARTYPE.getName() + "-" + ruleName,messageContent);
|
|
|
+ MsgWarnMessageInfo warnMessageInfo = new MsgWarnMessageInfo(WARTYPE.getValue(),
|
|
|
+ company.getString("name"),
|
|
|
+ uniqueKey,
|
|
|
+ feishuMessage,
|
|
|
+ messageInfo);
|
|
|
+ FeishuSendMessageUtils.sendFeishuMessage(warnMessageInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取飞书卡片消息
|
|
|
+ * @param transDetail
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected String getFeishuCardMessage(DynamicObject transDetail,String title){
|
|
|
+ BigDecimal debitAmount = transDetail.getBigDecimal(BeiBeTransDetailConstant.KEY_DEBITAMOUNT);
|
|
|
+ // 收款:我方账户是收款账户,对方账户是付款账户,付款则反之
|
|
|
+ if(debitAmount != null && debitAmount.compareTo(BigDecimal.ZERO) > 0){
|
|
|
+
|
|
|
+ return MsgWarnTemplateConstant.getFeishuTemplate("大额交易预警-" + title,getMcCenterMessage(transDetail));
|
|
|
+// JSONObject dataObj = new JSONObject();
|
|
|
+// dataObj.put("template_id",FeishuSendMessageUtils.getFeishuParams("LARGETRANS_MSGTEMPLATE_ID"));
|
|
|
+// JSONObject variableObj = new JSONObject();
|
|
|
+// // 为 variableObj 赋值
|
|
|
+// variableObj.put("payerAccount", transDetail.getString("company.name")); // 付方账户
|
|
|
+// variableObj.put("payerAccountNumber", transDetail.getString("accountbank.bankaccountnumber")); // 付方账号
|
|
|
+// variableObj.put("payerBank", transDetail.getString("bank.name")); // 付方开户行
|
|
|
+// variableObj.put("amount", CommonUtils.convertToTenThousandYuan(debitAmount)); // 支出金额
|
|
|
+// variableObj.put("receiver", transDetail.getString(BeiBeTransDetailConstant.KEY_OPPUNIT)); // 收方
|
|
|
+// variableObj.put("description", transDetail.getString(BeiBeTransDetailConstant.KEY_DESCRIPTION)); // 摘要
|
|
|
+// variableObj.put("time", DateUtils.formatDate(transDetail.getDate(BeiBeTransDetailConstant.KEY_BIZTIME))); // 时间,格式化为字符串
|
|
|
+//
|
|
|
+// dataObj.put("template_variable", variableObj);
|
|
|
+//
|
|
|
+// JSONObject contentObj = new JSONObject();
|
|
|
+// contentObj.put("type","template");
|
|
|
+// contentObj.put("data",dataObj);
|
|
|
+// return JSON.toJSONString(templateObj);
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取mc中心发送的消息信息
|
|
|
+ * @param transDetail
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected String getMcCenterMessage(DynamicObject transDetail){
|
|
|
+ BigDecimal debitAmount = transDetail.getBigDecimal(BeiBeTransDetailConstant.KEY_DEBITAMOUNT);
|
|
|
+ // 收款:我方账户是收款账户,对方账户是付款账户,付款则反之
|
|
|
+ if(debitAmount != null && debitAmount.compareTo(BigDecimal.ZERO) > 0){
|
|
|
+ return MsgWarnTemplateConstant.formatLargeTransMessage(
|
|
|
+ transDetail.getString("company.name"),
|
|
|
+ transDetail.getString("accountbank.bankaccountnumber"),
|
|
|
+ transDetail.getString("bank.name"),
|
|
|
+ CommonUtils.convertToTenThousandYuan(debitAmount),
|
|
|
+ transDetail.getString(BeiBeTransDetailConstant.KEY_OPPUNIT),
|
|
|
+ transDetail.getString(BeiBeTransDetailConstant.KEY_DESCRIPTION),
|
|
|
+ DateUtils.formatDate(transDetail.getDate(BeiBeTransDetailConstant.KEY_BIZTIME)));
|
|
|
+
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取公司下,时间范围内符合规则条件数据
|
|
|
+ * @param company
|
|
|
+ * @param lowerAmount
|
|
|
+ * @param highAmount
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected DynamicObjectCollection getTransDetailData(DynamicObject company , BigDecimal lowerAmount , BigDecimal highAmount){
|
|
|
+ if("daytime".equals(taskType)){
|
|
|
+ // 查询当前7:00-17:00的数据
|
|
|
+ Date beginDate = DateUtils.getDateByDayAndHour(0, 7);
|
|
|
+ Date endDate = DateUtils.getDateByDayAndHour(0, 17);
|
|
|
+ return getTransDetailData(company, beginDate, endDate, lowerAmount, highAmount);
|
|
|
+ }else{
|
|
|
+ // 查询昨天17:00至次日7:00
|
|
|
+ Date beginDate = DateUtils.getDateByDayAndHour(-1, 17);
|
|
|
+ Date endDate = DateUtils.getDateByDayAndHour(0, 7);
|
|
|
+ return getTransDetailData(company, beginDate, endDate, lowerAmount, highAmount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected DynamicObjectCollection getTransDetailData(DynamicObject company , Date beginDate , Date endDate,
|
|
|
+ BigDecimal lowerAmount , BigDecimal highAmount){
|
|
|
+ DataSet transDetailDataSet = getTransDetailDataSet(company, beginDate, endDate, lowerAmount, highAmount);
|
|
|
+ // 看报表与消息的兼容程度,再看怎么处理,暂时转成动态对象集合
|
|
|
+ return ORM.create().toPlainDynamicObjectCollection(transDetailDataSet.copy());
|
|
|
+ }
|
|
|
+
|
|
|
+ protected DataSet getTransDetailDataSet(DynamicObject company , Date beginDate , Date endDate ,
|
|
|
+ BigDecimal lowerAmount , BigDecimal highAmount){
|
|
|
+ List<QFilter> filterList = new ArrayList<>();
|
|
|
+ filterList.add(new QFilter(BeiBeTransDetailConstant.KEY_COMPANY, QFilter.equals, company.getPkValue()));
|
|
|
+ if(beginDate != null){
|
|
|
+ filterList.add(new QFilter(BeiBeTransDetailConstant.KEY_BIZTIME, QFilter.large_equals, beginDate));
|
|
|
+ }
|
|
|
+ if(endDate != null){
|
|
|
+ filterList.add(new QFilter(BeiBeTransDetailConstant.KEY_BIZTIME, QFilter.less_than, endDate));
|
|
|
+ }
|
|
|
+ if(lowerAmount != null && lowerAmount.compareTo(BigDecimal.ZERO) > 0){
|
|
|
+ filterList.add(new QFilter(BeiBeTransDetailConstant.KEY_DEBITAMOUNT, QFilter.large_equals, lowerAmount));
|
|
|
+ }
|
|
|
+ if (highAmount != null && highAmount.compareTo(BigDecimal.ZERO) > 0){
|
|
|
+ filterList.add(new QFilter(BeiBeTransDetailConstant.KEY_DEBITAMOUNT, QFilter.less_than, highAmount));
|
|
|
+ }
|
|
|
+
|
|
|
+ return QueryServiceHelper.queryDataSet(this.getClass().getName() ,BeiBeTransDetailConstant.ENTITYID,
|
|
|
+ "id,billno,company.name,accountbank.name,accountbank.bankaccountnumber,bank.name,debitamount,oppunit,description,bizdate,biztime",
|
|
|
+ filterList.toArray(new QFilter[0]),"bizdate desc");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取大额交易配置,通过配置来执行调度
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected Set<Long> getLargeTransConfig() {
|
|
|
+ DynamicObjectCollection configCol = QueryServiceHelper.query(LargeTransConfigConstant.ENTITYID, "id,nckd_company.id", new QFilter[]{
|
|
|
+ new QFilter(LargeTransConfigConstant.KEY_STATUS, QFilter.equals, "C"),
|
|
|
+ new QFilter(LargeTransConfigConstant.KEY_ENABLE, QFilter.equals, "1")
|
|
|
+ });
|
|
|
+ Map<Long, Long> companyIdMap = configCol.stream()
|
|
|
+ .collect(Collectors.toMap(r -> r.getLong("nckd_company.id"), r -> r.getLong("id"), (a, b) -> a));
|
|
|
+ return companyIdMap.values().stream().collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+}
|