浏览代码

邮件签名,消息类型拆分

1811872455@163.com 1 月之前
父节点
当前提交
26352f68c6
共有 19 个文件被更改,包括 1051 次插入1 次删除
  1. 92 0
      java/storlead-message/sql/arg_template/_gen_arg_templates.py
  2. 26 0
      java/storlead-message/sql/arg_template/arg_template_json_seed.sql
  3. 66 0
      java/storlead-message/sql/arg_template/broadcast_total_message_arg_template.json
  4. 30 0
      java/storlead-message/sql/arg_template/bulletin_message_arg_template.json
  5. 106 0
      java/storlead-message/sql/arg_template/business_message_arg_template.json
  6. 130 0
      java/storlead-message/sql/arg_template/customer_message_arg_template.json
  7. 26 0
      java/storlead-message/sql/arg_template/follow_message_arg_template.json
  8. 126 0
      java/storlead-message/sql/arg_template/liaison_message_arg_template.json
  9. 114 0
      java/storlead-message/sql/arg_template/order_message_arg_template.json
  10. 10 0
      java/storlead-message/sql/arg_template/other_extend_message_arg_template.json
  11. 30 0
      java/storlead-message/sql/arg_template/performance_goal_message_arg_template.json
  12. 10 0
      java/storlead-message/sql/arg_template/task_message_arg_template.json
  13. 1 1
      java/storlead-message/storlead-message-api/src/main/java/com/storlead/message/controller/MessageApiController.java
  14. 66 0
      java/storlead-message/storlead-message-api/src/main/java/com/storlead/message/controller/MessageTemplateApiController.java
  15. 11 0
      java/storlead-message/storlead-message-biz/src/main/java/com/storlead/message/service/impl/MessageService.java
  16. 67 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/enums/TradeMessageTypeEnum.java
  17. 25 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/message/TradeMessageTypeCatalog.java
  18. 44 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/TradeMessageAssembleService.java
  19. 71 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/TradeMessageAssembleServiceImpl.java

+ 92 - 0
java/storlead-message/sql/arg_template/_gen_arg_templates.py

@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+"""Generate arg_template JSON samples + consolidated seed SQL."""
+import json
+import re
+from pathlib import Path
+
+base = Path(r"java/storlead-sasa/storlead-sales/src/main/java")
+out = Path(r"java/storlead-message/sql/arg_template")
+out.mkdir(parents=True, exist_ok=True)
+
+vos = [
+    ("customer_message_arg_template.json", [10, 11], "CustomerMessageVO", "客户/线索",
+     base / "com/storlead/sales/pojo/vo/customer/CustomerMessageVO.java"),
+    ("liaison_message_arg_template.json", 20, "LiaisonMessageVO", "联系人",
+     base / "com/storlead/sales/pojo/vo/customer/LiaisonMessageVO.java"),
+    ("business_message_arg_template.json", 30, "BusinessMessageVO", "商机",
+     base / "com/storlead/sales/pojo/vo/customer/BusinessMessageVO.java"),
+    ("order_message_arg_template.json", 40, "OrderMessageVO", "订单",
+     base / "com/storlead/sales/pojo/vo/customer/OrderMessageVO.java"),
+    ("task_message_arg_template.json", 80, "TaskMessageVO", "任务",
+     base / "com/storlead/sales/pojo/vo/customer/TaskMessageVO.java"),
+    ("follow_message_arg_template.json", 90, "FollowMessageVO", "跟进",
+     base / "com/storlead/sales/pojo/vo/customer/FollowMessageVO.java"),
+    ("bulletin_message_arg_template.json", 120, "BulletinMessageVO", "公告",
+     base / "com/storlead/sales/pojo/vo/customer/BulletinMessageVO.java"),
+    ("performance_goal_message_arg_template.json", 130, "PerformanceGoalMessgeVO", "业绩目标",
+     base / "com/storlead/sales/pojo/vo/customer/PerformanceGoalMessgeVO.java"),
+    ("broadcast_total_message_arg_template.json", 200, "BroadcastTotalMessageVO", "播报汇总",
+     base / "com/storlead/sales/pojo/vo/report/BroadcastTotalMessageVO.java"),
+    ("other_extend_message_arg_template.json", 999, "OtherExtendMessageVO", "其他扩展",
+     base / "com/storlead/sales/pojo/vo/customer/OtherExtendMessageVO.java"),
+]
+
+field_pat = re.compile(
+    r'@ApiModelProperty\s*\(\s*value\s*=\s*"([^"]*)"\s*\)\s*(?:@[^\n]+\s*)*private\s+[\w.<>,\s?]+\s+(\w+)\s*;',
+    re.M,
+)
+
+all_sql = [
+    "-- =============================================================================",
+    "-- message_template_event_group.arg_template_json 回填脚本(汇总)",
+    "-- =============================================================================",
+    "-- 说明:",
+    "--   1. 由各 MessageVO 中带 @ApiModelProperty 的本类字段生成",
+    "--   2. JSON 格式:[{propertyName, propertyKey}],propertyKey 形如 ${fieldName}$",
+    "--   3. 仅更新 arg_template_json 为空的记录;需要按应用隔离时取消注释 AND app_id = 20",
+    "--   4. 可读 JSON 样例见同目录 *.json;VO 变更后可运行本脚本重新生成",
+    "--",
+    "-- 类型对照(SalesMessageTypeEnum):",
+    "--   10/11  CustomerMessageVO          客户/线索",
+    "--   20     LiaisonMessageVO           联系人",
+    "--   30     BusinessMessageVO          商机",
+    "--   40     OrderMessageVO             订单",
+    "--   80     TaskMessageVO              任务",
+    "--   90     FollowMessageVO            跟进",
+    "--   120    BulletinMessageVO          公告",
+    "--   130    PerformanceGoalMessgeVO    业绩目标",
+    "--   200    BroadcastTotalMessageVO    播报汇总",
+    "--   999    OtherExtendMessageVO       其他扩展",
+    "-- =============================================================================",
+    "",
+]
+
+for fname, types, cls, label, path in vos:
+    text = path.read_text(encoding="utf-8")
+    items = []
+    for m in field_pat.finditer(text):
+        items.append({"propertyName": m.group(1), "propertyKey": "${%s}$" % m.group(2)})
+    (out / fname).write_text(json.dumps(items, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
+    print("%s: %d fields -> %s" % (cls, len(items), fname))
+
+    json_one_line = json.dumps(items, ensure_ascii=False, separators=(",", ":"))
+    json_sql = json_one_line.replace("'", "''")
+    if isinstance(types, list):
+        type_cond = "`template_service_type` IN (%s)" % ", ".join(str(t) for t in types)
+        type_desc = "/".join(str(t) for t in types)
+    else:
+        type_cond = "`template_service_type` = %s" % types
+        type_desc = str(types)
+
+    all_sql.append("-- -----------------------------------------------------------------------------")
+    all_sql.append("-- type=%s  %s  %s(%d 个变量)" % (type_desc, cls, label, len(items)))
+    all_sql.append("-- -----------------------------------------------------------------------------")
+    all_sql.append("UPDATE `message_template_event_group`")
+    all_sql.append("SET `arg_template_json` = '%s'" % json_sql)
+    all_sql.append("WHERE %s" % type_cond)
+    all_sql.append("  AND (`arg_template_json` IS NULL OR `arg_template_json` = '');")
+    all_sql.append("-- AND `app_id` = 20;")
+    all_sql.append("")
+
+(out / "arg_template_json_seed.sql").write_text("\n".join(all_sql), encoding="utf-8")
+print("wrote arg_template_json_seed.sql")

文件差异内容过多而无法显示
+ 26 - 0
java/storlead-message/sql/arg_template/arg_template_json_seed.sql


+ 66 - 0
java/storlead-message/sql/arg_template/broadcast_total_message_arg_template.json

@@ -0,0 +1,66 @@
+[
+  {
+    "propertyName": "周期类型名称:周/月/季度/半年度/年度",
+    "propertyKey": "${type}$"
+  },
+  {
+    "propertyName": "分公司名称",
+    "propertyKey": "${companyName}$"
+  },
+  {
+    "propertyName": "部门名称",
+    "propertyKey": "${deptName}$"
+  },
+  {
+    "propertyName": "客户记录",
+    "propertyKey": "${broadcastCustomerDates}$"
+  },
+  {
+    "propertyName": "商机记录",
+    "propertyKey": "${broadcastBusinessDates}$"
+  },
+  {
+    "propertyName": "订单数量记录",
+    "propertyKey": "${broadcastOrderDates}$"
+  },
+  {
+    "propertyName": "订单金额记录",
+    "propertyKey": "${broadcastOrderAmountDates}$"
+  },
+  {
+    "propertyName": "客户总额",
+    "propertyKey": "${totalCustomerNum}$"
+  },
+  {
+    "propertyName": "订单金额总额",
+    "propertyKey": "${totalOrderAmount}$"
+  },
+  {
+    "propertyName": "商机总额",
+    "propertyKey": "${totalBusinessNum}$"
+  },
+  {
+    "propertyName": "订单数量总额",
+    "propertyKey": "${totalOrderNum}$"
+  },
+  {
+    "propertyName": "线索总额",
+    "propertyKey": "${totalClueNum}$"
+  },
+  {
+    "propertyName": "跟进总额",
+    "propertyKey": "${totalFollowNum}$"
+  },
+  {
+    "propertyName": "邮件总额",
+    "propertyKey": "${totalEmailNum}$"
+  },
+  {
+    "propertyName": "记录产生时间(yyyy年MM月dd日)",
+    "propertyKey": "${recordTime}$"
+  },
+  {
+    "propertyName": "记录范围时间(yyyyMMdd-yyyyMMdd)",
+    "propertyKey": "${recordRangeTime}$"
+  }
+]

+ 30 - 0
java/storlead-message/sql/arg_template/bulletin_message_arg_template.json

@@ -0,0 +1,30 @@
+[
+  {
+    "propertyName": "消息ID",
+    "propertyKey": "${id}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  },
+  {
+    "propertyName": "用户名",
+    "propertyKey": "${publisher}$"
+  },
+  {
+    "propertyName": "业务类型关联ID",
+    "propertyKey": "${resourceTypeId}$"
+  },
+  {
+    "propertyName": "业务名称",
+    "propertyKey": "${resourceName}$"
+  },
+  {
+    "propertyName": "业务类型名称",
+    "propertyKey": "${resourceTypeName}$"
+  },
+  {
+    "propertyName": "标题",
+    "propertyKey": "${title}$"
+  }
+]

+ 106 - 0
java/storlead-message/sql/arg_template/business_message_arg_template.json

@@ -0,0 +1,106 @@
+[
+  {
+    "propertyName": "商机标题",
+    "propertyKey": "${title}$"
+  },
+  {
+    "propertyName": "创建人员",
+    "propertyKey": "${createByName}$"
+  },
+  {
+    "propertyName": "归属人员",
+    "propertyKey": "${ownerByName}$"
+  },
+  {
+    "propertyName": "关联客户",
+    "propertyKey": "${customerName}$"
+  },
+  {
+    "propertyName": "主联系人",
+    "propertyKey": "${liaisonName}$"
+  },
+  {
+    "propertyName": "预计销售金额",
+    "propertyKey": "${estimatedSalesAmount}$"
+  },
+  {
+    "propertyName": "预计签单日期",
+    "propertyKey": "${expectedSigningDate}$"
+  },
+  {
+    "propertyName": "销售阶段",
+    "propertyKey": "${salesPhaseName}$"
+  },
+  {
+    "propertyName": "商机类型",
+    "propertyKey": "${businessTypeName}$"
+  },
+  {
+    "propertyName": "成交几率",
+    "propertyKey": "${stransactionProbabilityName}$"
+  },
+  {
+    "propertyName": "商机来源",
+    "propertyKey": "${sourcesOfBusinessName}$"
+  },
+  {
+    "propertyName": "获取日期",
+    "propertyKey": "${getedDate}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  },
+  {
+    "propertyName": "操作时间",
+    "propertyKey": "${operateTime}$"
+  },
+  {
+    "propertyName": "跟进时间",
+    "propertyKey": "${followUpTime}$"
+  },
+  {
+    "propertyName": "跟进内容",
+    "propertyKey": "${followUpContent}$"
+  },
+  {
+    "propertyName": "紧要程度",
+    "propertyKey": "${urgentLevelName}$"
+  },
+  {
+    "propertyName": "变更时间",
+    "propertyKey": "${changeTime}$"
+  },
+  {
+    "propertyName": "变更字段",
+    "propertyKey": "${changeField}$"
+  },
+  {
+    "propertyName": "变更字段值",
+    "propertyKey": "${changeFieldValue}$"
+  },
+  {
+    "propertyName": "变更字段原值",
+    "propertyKey": "${changeFieldOriginalValue}$"
+  },
+  {
+    "propertyName": "评论时间",
+    "propertyKey": "${commentTime}$"
+  },
+  {
+    "propertyName": "评论内容",
+    "propertyKey": "${commentContent}$"
+  },
+  {
+    "propertyName": "删除时间",
+    "propertyKey": "${deleteTime}$"
+  },
+  {
+    "propertyName": "删除人",
+    "propertyKey": "${deleteByName}$"
+  },
+  {
+    "propertyName": "商机状态",
+    "propertyKey": "${businessStatusName}$"
+  }
+]

+ 130 - 0
java/storlead-message/sql/arg_template/customer_message_arg_template.json

@@ -0,0 +1,130 @@
+[
+  {
+    "propertyName": "客户名称",
+    "propertyKey": "${customerName}$"
+  },
+  {
+    "propertyName": "区域名称",
+    "propertyKey": "${areaName}$"
+  },
+  {
+    "propertyName": "归属人员",
+    "propertyKey": "${ownerByName}$"
+  },
+  {
+    "propertyName": "创建人员",
+    "propertyKey": "${createByName}$"
+  },
+  {
+    "propertyName": "客户状态",
+    "propertyKey": "${customerStatusName}$"
+  },
+  {
+    "propertyName": "客户来源",
+    "propertyKey": "${customerSourceName}$"
+  },
+  {
+    "propertyName": "客户类型",
+    "propertyKey": "${customerTypeName}$"
+  },
+  {
+    "propertyName": "首联系人姓名",
+    "propertyKey": "${liaisonName}$"
+  },
+  {
+    "propertyName": "客户等级",
+    "propertyKey": "${customerLevelName}$"
+  },
+  {
+    "propertyName": "信用等级",
+    "propertyKey": "${customerCreditLevelName}$"
+  },
+  {
+    "propertyName": "企业名称",
+    "propertyKey": "${companyName}$"
+  },
+  {
+    "propertyName": "企业网址",
+    "propertyKey": "${companyUrl}$"
+  },
+  {
+    "propertyName": "新增类型",
+    "propertyKey": "${addType}$"
+  },
+  {
+    "propertyName": "移入人员",
+    "propertyKey": "${moveByName}$"
+  },
+  {
+    "propertyName": "移入时间",
+    "propertyKey": "${moveTime}$"
+  },
+  {
+    "propertyName": "转移人",
+    "propertyKey": "${transferByName}$"
+  },
+  {
+    "propertyName": "转移类型",
+    "propertyKey": "${transferType}$"
+  },
+  {
+    "propertyName": "删除人员",
+    "propertyKey": "${deleteByName}$"
+  },
+  {
+    "propertyName": "删除时间",
+    "propertyKey": "${deleteTime}$"
+  },
+  {
+    "propertyName": "置垃圾时间",
+    "propertyKey": "${setPublicTime}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  },
+  {
+    "propertyName": "合并时间",
+    "propertyKey": "${mergeTime}$"
+  },
+  {
+    "propertyName": "邮件标题",
+    "propertyKey": "${emailTitle}$"
+  },
+  {
+    "propertyName": "接收时间",
+    "propertyKey": "${receiveTime}$"
+  },
+  {
+    "propertyName": "邮箱",
+    "propertyKey": "${email}$"
+  },
+  {
+    "propertyName": "跟进时间",
+    "propertyKey": "${followUpTime}$"
+  },
+  {
+    "propertyName": "跟进内容",
+    "propertyKey": "${followUpContent}$"
+  },
+  {
+    "propertyName": "紧要程度",
+    "propertyKey": "${urgentLevel}$"
+  },
+  {
+    "propertyName": "逾期时长",
+    "propertyKey": "${overdueDuration}$"
+  },
+  {
+    "propertyName": "评论时间",
+    "propertyKey": "${commentTime}$"
+  },
+  {
+    "propertyName": "评论内容",
+    "propertyKey": "${commentContent}$"
+  },
+  {
+    "propertyName": "消息内容",
+    "propertyKey": "${messageContent}$"
+  }
+]

+ 26 - 0
java/storlead-message/sql/arg_template/follow_message_arg_template.json

@@ -0,0 +1,26 @@
+[
+  {
+    "propertyName": "消息ID",
+    "propertyKey": "${id}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  },
+  {
+    "propertyName": "业务类型关联ID",
+    "propertyKey": "${resourceTypeId}$"
+  },
+  {
+    "propertyName": "业务名称",
+    "propertyKey": "${resourceName}$"
+  },
+  {
+    "propertyName": "业务类型名称",
+    "propertyKey": "${resourceTypeName}$"
+  },
+  {
+    "propertyName": "客户名称",
+    "propertyKey": "${customerName}$"
+  }
+]

+ 126 - 0
java/storlead-message/sql/arg_template/liaison_message_arg_template.json

@@ -0,0 +1,126 @@
+[
+  {
+    "propertyName": "联系人id",
+    "propertyKey": "${id}$"
+  },
+  {
+    "propertyName": "关联客户id",
+    "propertyKey": "${customerId}$"
+  },
+  {
+    "propertyName": "是否是首要联系人(0不是,1是)",
+    "propertyKey": "${hasPrimaryLialison}$"
+  },
+  {
+    "propertyName": "联系人姓名",
+    "propertyKey": "${name}$"
+  },
+  {
+    "propertyName": "尊称(0未知,1先生,2女士)",
+    "propertyKey": "${call}$"
+  },
+  {
+    "propertyName": "尊称(0未知,1先生,2女士)",
+    "propertyKey": "${callName}$"
+  },
+  {
+    "propertyName": "联系人角色value(对应字典联系人角色value)",
+    "propertyKey": "${liaisonRoleDictValue}$"
+  },
+  {
+    "propertyName": "生日",
+    "propertyKey": "${birthday}$"
+  },
+  {
+    "propertyName": "部门职务",
+    "propertyKey": "${departmentPosition}$"
+  },
+  {
+    "propertyName": "手机号码",
+    "propertyKey": "${telephone}$"
+  },
+  {
+    "propertyName": "电子邮箱",
+    "propertyKey": "${email}$"
+  },
+  {
+    "propertyName": "资源类型",
+    "propertyKey": "${resourceType}$"
+  },
+  {
+    "propertyName": "资源类型关联ID",
+    "propertyKey": "${resourceTypeId}$"
+  },
+  {
+    "propertyName": "传真号码",
+    "propertyKey": "${faxNumber}$"
+  },
+  {
+    "propertyName": "邮政编码",
+    "propertyKey": "${postcode}$"
+  },
+  {
+    "propertyName": "联系方式",
+    "propertyKey": "${contactInformation}$"
+  },
+  {
+    "propertyName": "备注信息",
+    "propertyKey": "${remark}$"
+  },
+  {
+    "propertyName": "qq",
+    "propertyKey": "${qq}$"
+  },
+  {
+    "propertyName": "skype",
+    "propertyKey": "${skype}$"
+  },
+  {
+    "propertyName": "旺旺",
+    "propertyKey": "${wangwang}$"
+  },
+  {
+    "propertyName": "微信",
+    "propertyKey": "${wechat}$"
+  },
+  {
+    "propertyName": "Twitter",
+    "propertyKey": "${twitter}$"
+  },
+  {
+    "propertyName": "Linkedin",
+    "propertyKey": "${linkedin}$"
+  },
+  {
+    "propertyName": "Facebook",
+    "propertyKey": "${facebook}$"
+  },
+  {
+    "propertyName": "Whatsapp",
+    "propertyKey": "${whatsapp}$"
+  },
+  {
+    "propertyName": "区域",
+    "propertyKey": "${internationalArea}$"
+  },
+  {
+    "propertyName": "详细地址",
+    "propertyKey": "${address}$"
+  },
+  {
+    "propertyName": "固定电话",
+    "propertyKey": "${fixedLineTelephone}$"
+  },
+  {
+    "propertyName": "宅电",
+    "propertyKey": "${homeElectricity}$"
+  },
+  {
+    "propertyName": "归属人姓名",
+    "propertyKey": "${ownerByName}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  }
+]

+ 114 - 0
java/storlead-message/sql/arg_template/order_message_arg_template.json

@@ -0,0 +1,114 @@
+[
+  {
+    "propertyName": "订单标题",
+    "propertyKey": "${title}$"
+  },
+  {
+    "propertyName": "关联客户",
+    "propertyKey": "${customerName}$"
+  },
+  {
+    "propertyName": "关联商机",
+    "propertyKey": "${businessName}$"
+  },
+  {
+    "propertyName": "关联报价",
+    "propertyKey": "${quoteName}$"
+  },
+  {
+    "propertyName": "订单总金额",
+    "propertyKey": "${totalOrderAmt}$"
+  },
+  {
+    "propertyName": "付款币种",
+    "propertyKey": "${currencyName}$"
+  },
+  {
+    "propertyName": "订单类型",
+    "propertyKey": "${orderTypeName}$"
+  },
+  {
+    "propertyName": "签单日期",
+    "propertyKey": "${signedDate}$"
+  },
+  {
+    "propertyName": "预计生产日期",
+    "propertyKey": "${expectedProductionDate}$"
+  },
+  {
+    "propertyName": "预计发货日期",
+    "propertyKey": "${expectedDeliveryDate}$"
+  },
+  {
+    "propertyName": "归属人员",
+    "propertyKey": "${ownerByName}$"
+  },
+  {
+    "propertyName": "创建人员",
+    "propertyKey": "${createByName}$"
+  },
+  {
+    "propertyName": "删除时间",
+    "propertyKey": "${deleteTime}$"
+  },
+  {
+    "propertyName": "删除人员",
+    "propertyKey": "${deleteByName}$"
+  },
+  {
+    "propertyName": "变更时间",
+    "propertyKey": "${changeTime}$"
+  },
+  {
+    "propertyName": "变更字段",
+    "propertyKey": "${changeField}$"
+  },
+  {
+    "propertyName": "变更字段值",
+    "propertyKey": "${changeFieldValue}$"
+  },
+  {
+    "propertyName": "变更字段原值",
+    "propertyKey": "${changeFieldOriginalValue}$"
+  },
+  {
+    "propertyName": "操作时间",
+    "propertyKey": "${operateTime}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  },
+  {
+    "propertyName": "评论时间",
+    "propertyKey": "${commentTime}$"
+  },
+  {
+    "propertyName": "评论内容",
+    "propertyKey": "${commentContent}$"
+  },
+  {
+    "propertyName": "订单状态",
+    "propertyKey": "${orderStatusName}$"
+  },
+  {
+    "propertyName": "转移时间",
+    "propertyKey": "${transferTime}$"
+  },
+  {
+    "propertyName": "转移类型",
+    "propertyKey": "${transferType}$"
+  },
+  {
+    "propertyName": "转移人",
+    "propertyKey": "${transferByName}$"
+  },
+  {
+    "propertyName": "紧要程度",
+    "propertyKey": "${urgentLevelName}$"
+  },
+  {
+    "propertyName": "逾期时长",
+    "propertyKey": "${overdueDuration}$"
+  }
+]

+ 10 - 0
java/storlead-message/sql/arg_template/other_extend_message_arg_template.json

@@ -0,0 +1,10 @@
+[
+  {
+    "propertyName": "消息ID",
+    "propertyKey": "${id}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  }
+]

+ 30 - 0
java/storlead-message/sql/arg_template/performance_goal_message_arg_template.json

@@ -0,0 +1,30 @@
+[
+  {
+    "propertyName": "所属年份",
+    "propertyKey": "${year}$"
+  },
+  {
+    "propertyName": "方式",
+    "propertyKey": "${method}$"
+  },
+  {
+    "propertyName": "方式(实际使用)",
+    "propertyKey": "${methodName}$"
+  },
+  {
+    "propertyName": "指标类型",
+    "propertyKey": "${type}$"
+  },
+  {
+    "propertyName": "指标类型(实际使用)",
+    "propertyKey": "${typeName}$"
+  },
+  {
+    "propertyName": "跳转的页面",
+    "propertyKey": "${jump}$"
+  },
+  {
+    "propertyName": "操作人",
+    "propertyKey": "${operateByName}$"
+  }
+]

+ 10 - 0
java/storlead-message/sql/arg_template/task_message_arg_template.json

@@ -0,0 +1,10 @@
+[
+  {
+    "propertyName": "任务开始时间",
+    "propertyKey": "${taskBeginTime}$"
+  },
+  {
+    "propertyName": "任务内容",
+    "propertyKey": "${taskContent}$"
+  }
+]

+ 1 - 1
java/storlead-message/storlead-message-api/src/main/java/com/storlead/message/controller/MessageApiController.java

@@ -70,7 +70,7 @@ public class MessageApiController {
     }
 
     @PostMapping(value = "/read")
-    @ApiOperation(value = "更新为已读" )
+    @ApiOperation(value = "更新为已读")
     public Result<?> updateStatus(Long [] messageLogIds) {
         if (Objects.isNull(messageLogIds) || messageLogIds.length == 0) {
             return Result.error("参数错误");

+ 66 - 0
java/storlead-message/storlead-message-api/src/main/java/com/storlead/message/controller/MessageTemplateApiController.java

@@ -17,6 +17,7 @@ import com.storlead.message.service.MessageTemplateEventGroupService;
 import com.storlead.message.pojo.dto.MessageTemplateEventDTO;
 import com.storlead.message.util.MessageArgTemplateUtil;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -25,6 +26,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -116,6 +119,69 @@ public class MessageTemplateApiController {
         templateVO.setArgls(argTemplatels);
         return Result.result(templateVO);
     }
+
+//    @ApiOperation("获取消息模板详情")
+//    @PostMapping("getGroupDetailOld")
+//    public Result getGroupDetailOld(Long id,String templateDetailType) {
+//        MessageTemplateEventGroupEntity templateEventGroup =  templateEventGroupService.getById(id);
+//        if (Objects.isNull(templateEventGroup)) {
+//            return Result.ok();
+//        }
+//        MessageTemplateVO templateVO = new MessageTemplateVO();
+//        BeanUtils.copyProperties(templateEventGroup,templateVO);
+//        LambdaQueryWrapper<MessageTemplateEventDetailEntity> wrapper = new LambdaQueryWrapper<>();
+//        wrapper.eq(MessageTemplateEventDetailEntity::getTemplateEventId,templateEventGroup.getId());
+//        if (Objects.nonNull(templateDetailType)) {
+//            wrapper.eq(MessageTemplateEventDetailEntity::getTemplateDetailType,templateDetailType);
+//        }
+//        List<MessageTemplateEventDetailEntity>  detailEntities = templateEventDetailService.list(wrapper);
+//        templateVO.setDetailEntities(detailEntities);
+//        templateVO.dictFiled();
+//
+//        List<MessageArgTemplateVO> argTemplatels = new ArrayList<>();
+//        Class clazz = null;
+//        if (SalesMessageTypeEnum.CUSTOMER.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = CustomerMessageVO.class;
+//        } else if (MessageTypeEnum.CLUS.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = CustomerMessageVO.class;
+//        } else if (MessageTypeEnum.ORDER_FORM.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = OrderMessageVO.class;
+//        } else if (MessageTypeEnum.BUSINESS.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = BusinessMessageVO.class;
+//        } else if (MessageTypeEnum.TASK_CANCELED.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = TaskMessageVO.class;
+//        } else if (MessageTypeEnum.FOLLOW_UP.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = FollowMessageVO.class;
+//        } else if (MessageTypeEnum.LIAISON.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = LiaisonMessageVO.class;
+//        } else if (MessageTypeEnum.PERFORMANCE_GOAL.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = PerformanceGoalMessgeVO.class;
+//        } else if (MessageTypeEnum.BULLETIN.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = BulletinMessageVO.class;
+//        } else if (MessageTypeEnum.OTHER_EXTEND.getCode().equals(templateEventGroup.getTemplateServiceType().toString())) {
+//            clazz = OtherExtendMessageVO.class;
+//        } else if (MessageTypeEnum.BROADCAST.getCode().equals(templateEventGroup.getTemplateServiceType().toString())){
+//            clazz = BroadcastTotalMessageVO.class;
+//        }
+//
+//        if (clazz != null) {
+//            for (Field field : clazz.getDeclaredFields()) {
+//                MessageArgTemplateVO vo = new MessageArgTemplateVO();
+//                vo.setPropertyKey("${" + field.getName() + "}$");
+//                // 检查字段是否有 @Column 注解
+//                if (field.isAnnotationPresent(ApiModelProperty.class)) {
+//                    // 获取注解实例
+//                    ApiModelProperty property = field.getAnnotation(ApiModelProperty.class);
+//                    vo.setPropertyName(property.value());
+//                    // 输出字段名和注解的值
+//                }
+//                argTemplatels.add(vo);
+//            }
+//        }
+//        templateVO.setArgls(argTemplatels);
+//        return Result.result(templateVO);
+//    }
+
     @ApiOperation("获取消息模板详情")
     @PostMapping("getDetail")
     public Result getDetail(Long id) {

+ 11 - 0
java/storlead-message/storlead-message-biz/src/main/java/com/storlead/message/service/impl/MessageService.java

@@ -68,10 +68,21 @@ public class MessageService {
     }
 
     public void autoMatchEventSendMessage(Map<String,Object> messageMap, String templateServiceType, String eventCode, Set<Long> toUserIds, String... args) {
+        autoMatchEventSendMessage(messageMap, templateServiceType, eventCode, null, toUserIds, args);
+    }
+
+    /**
+     * 按消息类型 + 事件码匹配模板并发送;可按 appId 限定应用,避免跨应用同类型 code 串模板。
+     */
+    public void autoMatchEventSendMessage(Map<String,Object> messageMap, String templateServiceType, String eventCode,
+                                          Long appId, Set<Long> toUserIds, String... args) {
         try {
             LambdaQueryWrapper<MessageTemplateEventGroupEntity> templateEventWrapper = new LambdaQueryWrapper<>();
             templateEventWrapper.eq(MessageTemplateEventGroupEntity::getTemplateServiceType,templateServiceType);
             templateEventWrapper.eq(MessageTemplateEventGroupEntity::getEventCode,eventCode);
+            if (Objects.nonNull(appId)) {
+                templateEventWrapper.eq(MessageTemplateEventGroupEntity::getAppId, appId);
+            }
             templateEventWrapper.last(" limit 1");
             MessageTemplateEventGroupEntity  eventGroup = eventGroupService.getOne(templateEventWrapper);
             if (Objects.isNull(eventGroup)) {

+ 67 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/enums/TradeMessageTypeEnum.java

@@ -1,7 +1,74 @@
 package com.storlead.trade.enums;
 
+import com.storlead.message.pojo.vo.MessageTypeReadStateVO;
 import lombok.Getter;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Getter
 public enum  TradeMessageTypeEnum {
+
+    CUSTOMIZE_EXAMPLE("0", "业务自定义"),
+    OTHER_EXTEND("999", "其他"),
+    ;
+
+    /** 贸易应用 ID,对应 sys_app.id */
+    public static final Long APP_ID = 7L;
+
+    public static final TradeMessageTypeEnum[] messageSubTypes = TradeMessageTypeEnum.values();
+
+    private final String code;
+    private final String desc;
+
+    TradeMessageTypeEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static Map<String, Integer> getMessageTypeMap(List<String> types) {
+        Map<String, Integer> map = new HashMap<>();
+        for (TradeMessageTypeEnum subTypeEnum : messageSubTypes) {
+            if (CollectionUtils.isEmpty(types)) {
+                map.put(subTypeEnum.getCode(), 0);
+            } else if (types.contains(subTypeEnum.getCode())) {
+                map.put(subTypeEnum.getCode(), 0);
+            }
+        }
+        return map;
+    }
+
+    public static List<MessageTypeReadStateVO> getMessageTypeReadStatels(List<String> types) {
+        List<MessageTypeReadStateVO> arr = new ArrayList<>();
+        for (TradeMessageTypeEnum subTypeEnum : messageSubTypes) {
+            MessageTypeReadStateVO vo = new MessageTypeReadStateVO();
+            vo.setAppId(APP_ID);
+            vo.setMessageType(Integer.valueOf(subTypeEnum.getCode()));
+            vo.setMessageTypeName(subTypeEnum.getDesc());
+            if (CollectionUtils.isEmpty(types)) {
+                vo.setStateNumber(0);
+                arr.add(vo);
+            } else if (types.contains(subTypeEnum.getCode())) {
+                vo.setStateNumber(0);
+                arr.add(vo);
+            }
+        }
+        return arr;
+    }
+
+    public static TradeMessageTypeEnum getByCode(Integer code) {
+        if (code == null) {
+            return null;
+        }
+        String codeStr = String.valueOf(code);
+        for (TradeMessageTypeEnum tag : values()) {
+            if (tag.code.equals(codeStr)) {
+                return tag;
+            }
+        }
+        return null;
+    }
 }

+ 25 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/message/TradeMessageTypeCatalog.java

@@ -0,0 +1,25 @@
+package com.storlead.trade.message;
+
+import com.storlead.message.catalog.MessageTypeCatalog;
+import com.storlead.message.pojo.vo.MessageTypeReadStateVO;
+import com.storlead.trade.enums.TradeMessageTypeEnum;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 贸易应用消息类型目录(appId = {@link TradeMessageTypeEnum#APP_ID})。
+ */
+@Component
+public class TradeMessageTypeCatalog implements MessageTypeCatalog {
+
+    @Override
+    public Long getAppId() {
+        return TradeMessageTypeEnum.APP_ID;
+    }
+
+    @Override
+    public List<MessageTypeReadStateVO> buildReadStateTemplates(List<String> types) {
+        return TradeMessageTypeEnum.getMessageTypeReadStatels(types);
+    }
+}

+ 44 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/TradeMessageAssembleService.java

@@ -0,0 +1,44 @@
+package com.storlead.trade.service;
+
+import com.storlead.trade.enums.TradeMessageTypeEnum;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 贸易模块消息组装与发送(对齐 sales {@code MessageAssembleService})。
+ * <p>
+ * 统一带上 {@link TradeMessageTypeEnum#APP_ID},按应用隔离模板与站内消息。
+ */
+public interface TradeMessageAssembleService {
+
+    /**
+     * 按类型枚举 + 事件码发送。
+     *
+     * @param messageType 贸易消息类型
+     * @param eventCode   模板事件码(message_template_event_group.event_code)
+     * @param payload     模板变量
+     * @param toUserIds   接收人;空则走模板默认接收人逻辑
+     * @param channels    渠道,如 site / wecom / sms / mail;不传默认四渠道
+     */
+    void sendEventMessage(TradeMessageTypeEnum messageType, String eventCode,
+                          Map<String, Object> payload, Set<Long> toUserIds, String... channels);
+
+    /**
+     * 按类型 code + 事件码发送。
+     */
+    void sendEventMessage(String messageTypeCode, String eventCode,
+                          Map<String, Object> payload, Set<Long> toUserIds, String... channels);
+
+    /**
+     * 将任意 Bean 转为 Map 后发送。
+     */
+    void sendEventMessage(TradeMessageTypeEnum messageType, String eventCode,
+                          Object payloadBean, Set<Long> toUserIds, String... channels);
+
+    /**
+     * 业务自定义类型({@link TradeMessageTypeEnum#CUSTOMIZE_EXAMPLE})快捷发送。
+     */
+    void sendCustomizeMessage(String eventCode, Map<String, Object> payload,
+                              Set<Long> toUserIds, String... channels);
+}

+ 71 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/TradeMessageAssembleServiceImpl.java

@@ -0,0 +1,71 @@
+package com.storlead.trade.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.storlead.message.service.impl.MessageService;
+import com.storlead.trade.enums.TradeMessageTypeEnum;
+import com.storlead.trade.service.TradeMessageAssembleService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 贸易消息发送实现:组装变量后调用 message 域,并固定 appId。
+ */
+@Log4j2
+@Service
+public class TradeMessageAssembleServiceImpl implements TradeMessageAssembleService {
+
+    private static final String[] DEFAULT_CHANNELS = {"site", "wecom", "sms", "mail"};
+
+    @Resource
+    private MessageService messageService;
+
+    @Override
+    public void sendEventMessage(TradeMessageTypeEnum messageType, String eventCode,
+                                 Map<String, Object> payload, Set<Long> toUserIds, String... channels) {
+        if (messageType == null) {
+            log.warn("trade sendEventMessage skip: messageType is null, eventCode={}", eventCode);
+            return;
+        }
+        sendEventMessage(messageType.getCode(), eventCode, payload, toUserIds, channels);
+    }
+
+    @Override
+    public void sendEventMessage(String messageTypeCode, String eventCode,
+                                 Map<String, Object> payload, Set<Long> toUserIds, String... channels) {
+        if (StrUtil.isBlank(messageTypeCode) || StrUtil.isBlank(eventCode)) {
+            log.warn("trade sendEventMessage skip: blank type/event, type={}, event={}", messageTypeCode, eventCode);
+            return;
+        }
+        Map<String, Object> messageMap = payload == null ? new HashMap<>() : new HashMap<>(payload);
+        String[] sendChannels = (channels == null || channels.length == 0) ? DEFAULT_CHANNELS : channels;
+        messageService.autoMatchEventSendMessage(
+                messageMap,
+                messageTypeCode,
+                eventCode,
+                TradeMessageTypeEnum.APP_ID,
+                toUserIds,
+                sendChannels
+        );
+    }
+
+    @Override
+    public void sendEventMessage(TradeMessageTypeEnum messageType, String eventCode,
+                                 Object payloadBean, Set<Long> toUserIds, String... channels) {
+        Map<String, Object> payload = payloadBean == null
+                ? new HashMap<>()
+                : BeanUtil.beanToMap(payloadBean);
+        sendEventMessage(messageType, eventCode, payload, toUserIds, channels);
+    }
+
+    @Override
+    public void sendCustomizeMessage(String eventCode, Map<String, Object> payload,
+                                     Set<Long> toUserIds, String... channels) {
+        sendEventMessage(TradeMessageTypeEnum.CUSTOMIZE_EXAMPLE, eventCode, payload, toUserIds, channels);
+    }
+}

部分文件因为文件数量过多而无法显示