From e22366fdc5b20be7841522b800d5b4820fb7c909 Mon Sep 17 00:00:00 2001 From: "youHong.ai" <774495953@qq.com> Date: Thu, 23 Mar 2023 16:15:32 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=86=E9=83=A8?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E7=94=9F=E6=88=90=E7=99=BB=E5=BD=95=E5=90=8D?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- .../GenerateLoginIdAction.java | 51 +++++++++++++++++-- .../mapper/GenerateLoginIdMapper.java | 11 ++++ src/test/java/youhong/ai/pcn/UtilTest.java | 38 ++++++++++++++ 4 files changed, 100 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index a1f5db0..bfc3e78 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ DirectoryV2.xml /lib/classbeanLib/ecology-dev-lib.jar /lib/classbeanLib/web-inf-class-lib.jar /lib/weaverLib/ +/lib/jitulib/ *.groovy *.log *.iml @@ -46,5 +47,5 @@ src/test/resources/font src/main/resources/WEB-INF/vm/outFile target/ *.back -src/main/old_src/ - +src/main/aiyh_old_src/ +src/main/jitu_src/ \ No newline at end of file diff --git a/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/GenerateLoginIdAction.java b/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/GenerateLoginIdAction.java index 5732d89..8a0b35f 100644 --- a/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/GenerateLoginIdAction.java +++ b/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/GenerateLoginIdAction.java @@ -15,6 +15,7 @@ import weaver.soa.workflow.request.RequestInfo; import weaver.youhong.ai.pcn.actioin.generateloginid.mapper.GenerateLoginIdMapper; import java.text.NumberFormat; +import java.util.List; import java.util.Map; /** @@ -57,9 +58,11 @@ public class GenerateLoginIdAction extends SafeCusBaseAction { Map mainTableValue = super.getMainTableValue(requestInfo); String subCompanyName = mainTableValue.get(subCompanyTextField); String subCompanyId = mapper.selectSubCompanyIdBySubCompanyName(subCompanyName); - Map lastLoginIdInfo = mapper.selectLastLoginId(subCompanyName, subCompanyId, subCompanyName + "%"); - String loginIdNo = lastLoginIdInfo.get("loginIdNo"); - String loginId = prefixFill(loginIdNo, subCompanyName); + // Map lastLoginIdInfo = mapper.selectLastLoginId(subCompanyName, subCompanyId, subCompanyName + "%"); + // String loginIdNo = lastLoginIdInfo.get("loginIdNo"); + // String loginId = prefixFill(loginIdNo, subCompanyName); + List loginIdList = mapper.selectLoginIdList(subCompanyId); + String loginId = subCompanyName + formatList(loginIdList, Integer.parseInt(numberFillQuantity)); if (mapper.updateLoginId(billTable, requestId, loginId, loginIdField)) { try { Thread.sleep(500); @@ -74,6 +77,48 @@ public class GenerateLoginIdAction extends SafeCusBaseAction { } } + + /** + *

前缀补齐

+ * + * @param list 登录名编号 + * @param length 前缀 + * @return 登录名 + */ + public String formatList(List list, int length) { + NumberFormat format = NumberFormat.getInstance(); + format.setMinimumIntegerDigits(length); + format.setGroupingUsed(false); + if (list == null || list.isEmpty()) { + return format.format(0); + } + int maxNum = 0; + for (String s : list) { + if (s != null && !s.isEmpty()) { + int num = 0; + boolean foundNum = false; + // 从末尾向前读取 + for (int i = s.length() - 1; i >= 0; i--) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + foundNum = true; + int digit = c - '0'; + // 根据数字位数计算数字大小 + num += digit * Math.pow(10, s.length() - i - 1); + } else if (foundNum) { + // 遇到非数字字符,停止读取 + break; + } + } + if (num > maxNum) { + maxNum = num; + } + } + } + + return format.format(maxNum + 1); + } + /** *

前缀补齐

* diff --git a/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/mapper/GenerateLoginIdMapper.java b/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/mapper/GenerateLoginIdMapper.java index a12019d..3041419 100644 --- a/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/mapper/GenerateLoginIdMapper.java +++ b/src/main/java/weaver/youhong/ai/pcn/actioin/generateloginid/mapper/GenerateLoginIdMapper.java @@ -5,6 +5,7 @@ import aiyh.utils.annotation.recordset.Select; import aiyh.utils.annotation.recordset.SqlMapper; import aiyh.utils.annotation.recordset.Update; +import java.util.List; import java.util.Map; /** @@ -47,6 +48,16 @@ public interface GenerateLoginIdMapper { ); + /** + *

查询分部下的所有人员登录账号

+ * + * @param subCompanyId 分部id + * @return 所有人员登录账号 + */ + @Select("select LOGINID from hrmresource where SUBCOMPANYID1 = #{subCompanyId}") + List selectLoginIdList(@ParamMapper("subCompanyId") String subCompanyId); + + /** *

更新流程中的loginId字段

* diff --git a/src/test/java/youhong/ai/pcn/UtilTest.java b/src/test/java/youhong/ai/pcn/UtilTest.java index f7af5c0..1c1a056 100644 --- a/src/test/java/youhong/ai/pcn/UtilTest.java +++ b/src/test/java/youhong/ai/pcn/UtilTest.java @@ -27,6 +27,7 @@ import youhong.ai.pcn.pojo.Student; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.text.NumberFormat; import java.util.*; import static com.alibaba.fastjson.JSON.parseObject; @@ -257,5 +258,42 @@ public class UtilTest extends BaseTest { @Test public void testOaNum() { + out.println(formatList(Arrays.asList("PCN2P000001", "PCNS0000002", "PDJA000003", "PDC0000405"), 10)); } + + public static String formatList(List list, int length) { + NumberFormat format = NumberFormat.getInstance(); + format.setMinimumIntegerDigits(length); + format.setGroupingUsed(false); + if (list == null || list.isEmpty()) { + return format.format(0); + } + int maxNum = 0; + for (String s : list) { + if (s != null && !s.isEmpty()) { + int num = 0; + boolean foundNum = false; + // 从末尾向前读取 + for (int i = s.length() - 1; i >= 0; i--) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + foundNum = true; + int digit = c - '0'; + // 根据数字位数计算数字大小 + num += digit * Math.pow(10, s.length() - i - 1); + } else if (foundNum) { + // 遇到非数字字符,停止读取 + break; + } + } + if (num > maxNum) { + maxNum = num; + } + } + } + + return format.format(maxNum + 1); + } + + } From 4615e23317d81587f18ff51014674b724767a6f6 Mon Sep 17 00:00:00 2001 From: "yushun.ding" <2437588377@qq.com> Date: Sat, 25 Mar 2023 00:26:00 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E5=A4=84=E7=90=86=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/aiyh/utils/Util.java | 66 ++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index cc5f158..62322df 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -3870,4 +3870,70 @@ public class Util extends weaver.general.Util { } return ip; } + + /** + * 多语言处理 + * + * @param oldName 老名字 + * @param newName 新名字 + * @param lanuage 要替换的语言 以 7 8 9 举例 + */ + public String moreLanugageHandler(String oldName, String newName, String lanuage) { + List languageIds = weaver.general.Util.getActiveLanguageIds();//获取系统支持的多语言 + String newMoreLanuage = ""; + //要按照当前系统支持的多语言id进行拼接处理 + if (oldName.startsWith("~`~`") && oldName.endsWith("`~`~")) { + // 获取当前系统存在的多语言id + // 思路:先按照系统存在的语言进行拼接,之后判断oldname包含那些语言进行过滤,将除了lanuage的其他语言都替换成之前的 + //多语言的中间处理 + String tempLanuage = joinLanuage(newName, languageIds); + //中间处理转成map + Map splitMultilangData = weaver.general.Util.splitMultilangData(tempLanuage); + Map lanuageMap = new HashMap<>(); + for (Object id : languageIds) { + String labelLanuage = "`~`" + id; + if (oldName.contains(labelLanuage)) { + //获取过滤的语言name + String formatLanuageName = weaver.general.Util.formatMultiLang(oldName, String.valueOf(id)); + if (!weaver.general.StringUtil.isEmpty(formatLanuageName)) { + lanuageMap.put(String.valueOf(id), formatLanuageName); + } + } + } + String s = lanuageMap.get(lanuage); + if (weaver.general.StringUtil.isEmpty(s)) { + for (Map.Entry entry : lanuageMap.entrySet()) { + splitMultilangData.put(entry.getKey(), entry.getValue()); + } + } else { + lanuageMap.remove(lanuage); + for (Map.Entry entry : lanuageMap.entrySet()) { + splitMultilangData.put(entry.getKey(), entry.getValue()); + } + } + newMoreLanuage = weaver.general.Util.stitchMultilangData(splitMultilangData); + } else { + //要根据系统支持的语言进行拼接 + newMoreLanuage = joinLanuage(newName, languageIds); + } + return newMoreLanuage; + } + + /** + * 多语言拼接 + * + * @param newName 新的名字 + * @param languageIds 系统支持的语言集合 + * @return 拼接后的字符串 + */ + public String joinLanuage(String newName, List languageIds) { + StringBuilder supportLanuage = new StringBuilder(); + supportLanuage.append("~`~`"); + languageIds.forEach(id -> { + supportLanuage.append(id).append(" ").append(newName).append("`~`"); + }); + supportLanuage.delete(supportLanuage.lastIndexOf("`~`"), supportLanuage.length()); + supportLanuage.append("`~`~"); + return supportLanuage.toString(); + } } From 3c49ade7b4abc220f9a7345b367126fd5b403c2a Mon Sep 17 00:00:00 2001 From: "yushun.ding" <2437588377@qq.com> Date: Sat, 25 Mar 2023 21:12:22 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=A1=A5=E5=85=85static?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/aiyh/utils/Util.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index 62322df..12ad673 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -3878,8 +3878,8 @@ public class Util extends weaver.general.Util { * @param newName 新名字 * @param lanuage 要替换的语言 以 7 8 9 举例 */ - public String moreLanugageHandler(String oldName, String newName, String lanuage) { - List languageIds = weaver.general.Util.getActiveLanguageIds();//获取系统支持的多语言 + public static String moreLanugageHandler(String oldName, String newName, String lanuage) { + List languageIds = getActiveLanguageIds();//获取系统支持的多语言 String newMoreLanuage = ""; //要按照当前系统支持的多语言id进行拼接处理 if (oldName.startsWith("~`~`") && oldName.endsWith("`~`~")) { @@ -3888,13 +3888,13 @@ public class Util extends weaver.general.Util { //多语言的中间处理 String tempLanuage = joinLanuage(newName, languageIds); //中间处理转成map - Map splitMultilangData = weaver.general.Util.splitMultilangData(tempLanuage); + Map splitMultilangData = splitMultilangData(tempLanuage); Map lanuageMap = new HashMap<>(); for (Object id : languageIds) { String labelLanuage = "`~`" + id; if (oldName.contains(labelLanuage)) { //获取过滤的语言name - String formatLanuageName = weaver.general.Util.formatMultiLang(oldName, String.valueOf(id)); + String formatLanuageName = formatMultiLang(oldName, String.valueOf(id)); if (!weaver.general.StringUtil.isEmpty(formatLanuageName)) { lanuageMap.put(String.valueOf(id), formatLanuageName); } @@ -3911,7 +3911,7 @@ public class Util extends weaver.general.Util { splitMultilangData.put(entry.getKey(), entry.getValue()); } } - newMoreLanuage = weaver.general.Util.stitchMultilangData(splitMultilangData); + newMoreLanuage = stitchMultilangData(splitMultilangData); } else { //要根据系统支持的语言进行拼接 newMoreLanuage = joinLanuage(newName, languageIds); @@ -3926,7 +3926,7 @@ public class Util extends weaver.general.Util { * @param languageIds 系统支持的语言集合 * @return 拼接后的字符串 */ - public String joinLanuage(String newName, List languageIds) { + public static String joinLanuage(String newName, List languageIds) { StringBuilder supportLanuage = new StringBuilder(); supportLanuage.append("~`~`"); languageIds.forEach(id -> { From ee64140219bac1b2ce7115bfaa2d0a0b44694af8 Mon Sep 17 00:00:00 2001 From: "yushun.ding" <2437588377@qq.com> Date: Mon, 27 Mar 2023 13:03:45 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E9=87=91=E9=A2=9D=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=20+=20-=20*=20/=20=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/aiyh/utils/AmountHandler.java | 178 ++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/main/java/aiyh/utils/AmountHandler.java diff --git a/src/main/java/aiyh/utils/AmountHandler.java b/src/main/java/aiyh/utils/AmountHandler.java new file mode 100644 index 0000000..0ccdab0 --- /dev/null +++ b/src/main/java/aiyh/utils/AmountHandler.java @@ -0,0 +1,178 @@ +package aiyh.utils; + +/** + * @Author DYS + * @Date 2023/3/25 18:08 + * @description create at weaver + */ + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 金额类型. 支持自身的四则运算,并将this返回. + */ +public class AmountHandler implements Serializable { + + private BigDecimal value; + + /** + * 提供默认精度10 + */ + private int scale = 10; + + public AmountHandler() { + + } + + /** + * double类型构造函数 + * + * @param value + */ + public AmountHandler(double value) { + this.value = new BigDecimal(Double.toString(value)); + } + + /** + * String类型构造函数 + * + * @param value + */ + public AmountHandler(String value) { + this.value = new BigDecimal(value); + } + + /** + * 取得BigDecimal的值 + * + * @return + */ + public BigDecimal getValue() { + return this.value; + } + + /** + * 两个double类型的数值相加 + * + * @param v1 + * @param v2 + * @return + */ + public double add(double v1, double v2) { + AmountHandler a1 = new AmountHandler(v1); + AmountHandler a2 = new AmountHandler(v2); + return add(a1, a2); + } + + /** + * 两数相除 + * + * @param v1 + * @param v2 + * @return + */ + public double div(double v1, double v2) { + AmountHandler a1 = new AmountHandler(v1); + AmountHandler a2 = new AmountHandler(v2); + return this.divide(a1, a2); + } + + /** + * 相减 + * + * @param v1 + * @param v2 + * @return + */ + public double sub(double v1, double v2) { + AmountHandler a1 = new AmountHandler(v1); + AmountHandler a2 = new AmountHandler(v2); + return this.subtract(a1, a2); + } + + /** + * 相乘 + * + * @param v1 + * @param v2 + * @return + */ + public double mul(double v1, double v2) { + AmountHandler a1 = new AmountHandler(v1); + AmountHandler a2 = new AmountHandler(v2); + return this.multiply(a1, a2); + } + + /** + * 两个Amount类型的数据进行相加 + * + * @param v1 + * @param v2 + * @return + */ + public double add(AmountHandler v1, AmountHandler v2) { + return v1.getValue().add(v2.getValue()).doubleValue(); + } + + /** + * 两个Amount类型变量相除 + * + * @param v1 + * @param v2 + * @return + */ + public double divide(AmountHandler v1, AmountHandler v2) { + if (scale < 0) { + throw new IllegalArgumentException("精度指定错误,请指定一个>=0的精度"); + } + return v1.getValue().divide(v2.getValue(), scale, + BigDecimal.ROUND_HALF_UP).doubleValue(); + } + + /** + * 两数相乘 + * + * @param v1 + * @param v2 + * @return + */ + public double multiply(AmountHandler v1, AmountHandler v2) { + return v1.getValue().multiply(v2.getValue()).doubleValue(); + } + + /** + * 两数相减 + * + * @param v1 + * @param v2 + * @return + */ + public double subtract(AmountHandler v1, AmountHandler v2) { + return v1.getValue().subtract(v2.getValue()).doubleValue(); + } + + /** + * 返回value的浮点数值 + * + * @return + */ + public double doubleValue() { + return this.getValue().doubleValue(); + } + + /** + * 设置精度 + * + * @param scale + */ + public void setScale(int scale) { + this.scale = scale; + } + + public static void main(String[] args) { + AmountHandler AmountHandler = new AmountHandler(5000.23); + AmountHandler AmountHandler1 = new AmountHandler(2033.37); + System.out.println(new AmountHandler().add(AmountHandler, AmountHandler1)); + } +} From 9275631cd829a3ba2031c14d13867c958750dfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=A3=E7=84=B6?= Date: Tue, 4 Apr 2023 17:15:00 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=A7=A3=E5=86=B3double=E8=B6=85=E5=87=BA?= =?UTF-8?q?=E7=B2=BE=E5=BA=A6=E8=BD=AC=E6=88=90=E7=A7=91=E5=AD=A6=E8=AE=B0?= =?UTF-8?q?=E6=95=B0=E6=B3=95=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/service/DealWithMapping.java | 16 +++- ...viceImpl.java => UserServiceImplBack.java} | 2 + .../http_test/annotations/CusPathQuery.java | 16 ---- ...{CusRequest.java => CusRequestClient.java} | 2 +- .../http_test/annotations/GetPathValue.java | 15 ---- .../wang/http_test/annotations/PostBody.java | 15 ---- ...ant.java => CusRequestClientConstant.java} | 2 +- ...andle.java => CusRequestBeforeHandle.java} | 0 .../wang/http_test/handle/PostTypeHandle.java | 35 -------- .../http_test/handle/RequestHeaderHandle.java | 81 ------------------- ...rseHandle.java => CusPathParseHandle.java} | 4 +- 11 files changed, 21 insertions(+), 167 deletions(-) rename src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/{UserServiceImpl.java => UserServiceImplBack.java} (98%) delete mode 100644 src/test/java/xuanran/wang/http_test/annotations/CusPathQuery.java rename src/test/java/xuanran/wang/http_test/annotations/{CusRequest.java => CusRequestClient.java} (86%) delete mode 100644 src/test/java/xuanran/wang/http_test/annotations/GetPathValue.java delete mode 100644 src/test/java/xuanran/wang/http_test/annotations/PostBody.java rename src/test/java/xuanran/wang/http_test/constant/{RequestUtilConstant.java => CusRequestClientConstant.java} (89%) rename src/test/java/xuanran/wang/http_test/handle/{RequestBeforeHandle.java => CusRequestBeforeHandle.java} (100%) delete mode 100644 src/test/java/xuanran/wang/http_test/handle/PostTypeHandle.java delete mode 100644 src/test/java/xuanran/wang/http_test/handle/RequestHeaderHandle.java rename src/test/java/xuanran/wang/http_test/handle/path_handle/{CusFieldKeyParseHandle.java => CusPathParseHandle.java} (89%) diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index 712fc01..1219d1e 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -21,6 +21,7 @@ import weaver.zwl.common.ToolUtil; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; import java.security.SecureRandom; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -115,7 +116,20 @@ public class DealWithMapping extends ToolUtil { continue; } if ("DECIMAL".equalsIgnoreCase(type) || "NUMERIC".equalsIgnoreCase(type)) { - map.put(key, rs.getDouble(i)); + /** + * @author xuanran.wang + * @data 2023-04-04 + * @desc 解决double超出精度转成科学记数法的问题 + */ + String val = Util.null2String(rs.getString(i)); + BigDecimal decimal; + if(StringUtils.isBlank(val)){ + decimal = new BigDecimal("0"); + }else { + decimal = new BigDecimal(val); + } + map.put(key, decimal); +// map.put(key, rs.getDouble(i)); continue; } map.put(key, rs.getString(i)); diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java similarity index 98% rename from src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java rename to src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java index 01d336e..759e1e2 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java @@ -68,6 +68,7 @@ public class UserServiceImpl extends CusInfoActionService { // 通过外键获取部门信息数据为空 throw new CustomerException("The department information data obtained by foreign key is empty!"); } + logger.info(Util.logStr("depInfoByOutKey : {}", JSONObject.toJSONString(depInfoByOutKey))); nextHrmId = getNextHrmId(); List params = initHrmParam(nextHrmId, userInfo, depInfoByOutKey); String departmentId = Util.null2DefaultStr(depInfoByOutKey.get("departmentId"), ""); @@ -177,6 +178,7 @@ public class UserServiceImpl extends CusInfoActionService { // 通过外键获取部门信息数据为空 throw new CustomerException("The department information data obtained by foreign key is empty!"); } + logger.info(Util.logStr("depInfoByOutKey : {}", JSONObject.toJSONString(depInfoByOutKey))); // oa人员id String hrmId = consumerMapper.getHrmIdByOutKey(userInfoId); if(StringUtils.isBlank(hrmId)){ diff --git a/src/test/java/xuanran/wang/http_test/annotations/CusPathQuery.java b/src/test/java/xuanran/wang/http_test/annotations/CusPathQuery.java deleted file mode 100644 index 3d43003..0000000 --- a/src/test/java/xuanran/wang/http_test/annotations/CusPathQuery.java +++ /dev/null @@ -1,16 +0,0 @@ -package xuanran.wang.http_test.annotations; - -import java.lang.annotation.*; - -/** - *

请求路径参数替换

- * - * @author xuanran.wang - * @date 2023/3/10 17:00 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.PARAMETER}) -@Documented -public @interface CusPathQuery { - String value(); -} diff --git a/src/test/java/xuanran/wang/http_test/annotations/CusRequest.java b/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java similarity index 86% rename from src/test/java/xuanran/wang/http_test/annotations/CusRequest.java rename to src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java index ef05213..c1ea590 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/CusRequest.java +++ b/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java @@ -11,5 +11,5 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented -public @interface CusRequest { +public @interface CusRequestClient { } diff --git a/src/test/java/xuanran/wang/http_test/annotations/GetPathValue.java b/src/test/java/xuanran/wang/http_test/annotations/GetPathValue.java deleted file mode 100644 index 65dd302..0000000 --- a/src/test/java/xuanran/wang/http_test/annotations/GetPathValue.java +++ /dev/null @@ -1,15 +0,0 @@ -package xuanran.wang.http_test.annotations; - -import java.lang.annotation.*; - -/** - *

路径参数 可以修饰map,字段 如果是字段那就会将

- * - * @author xuanran.wang - * @date 2023/3/10 13:06 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -@Documented -public @interface GetPathValue { -} diff --git a/src/test/java/xuanran/wang/http_test/annotations/PostBody.java b/src/test/java/xuanran/wang/http_test/annotations/PostBody.java deleted file mode 100644 index 2f704c8..0000000 --- a/src/test/java/xuanran/wang/http_test/annotations/PostBody.java +++ /dev/null @@ -1,15 +0,0 @@ -package xuanran.wang.http_test.annotations; - -import java.lang.annotation.*; - -/** - *

post请求体

- * - * @author xuanran.wang - * @date 2023/3/10 13:48 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -@Documented -public @interface PostBody { -} diff --git a/src/test/java/xuanran/wang/http_test/constant/RequestUtilConstant.java b/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java similarity index 89% rename from src/test/java/xuanran/wang/http_test/constant/RequestUtilConstant.java rename to src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java index d8f6c83..d368610 100644 --- a/src/test/java/xuanran/wang/http_test/constant/RequestUtilConstant.java +++ b/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java @@ -6,7 +6,7 @@ package xuanran.wang.http_test.constant; * @author xuanran.wang * @date 2023/3/10 14:01 */ -public class RequestUtilConstant { +public class CusRequestClientConstant { public static final int GET = 0; public static final int POST = 1; public static final int DELETE = 2; diff --git a/src/test/java/xuanran/wang/http_test/handle/RequestBeforeHandle.java b/src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java similarity index 100% rename from src/test/java/xuanran/wang/http_test/handle/RequestBeforeHandle.java rename to src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java diff --git a/src/test/java/xuanran/wang/http_test/handle/PostTypeHandle.java b/src/test/java/xuanran/wang/http_test/handle/PostTypeHandle.java deleted file mode 100644 index 7b75eeb..0000000 --- a/src/test/java/xuanran/wang/http_test/handle/PostTypeHandle.java +++ /dev/null @@ -1,35 +0,0 @@ -//package xuanran.wang.http_test.handle; -// -//import com.alibaba.fastjson.JSONObject; -//import xuanran.wang.http_test.annotations.PostBody; -// -//import java.lang.reflect.Method; -//import java.lang.reflect.Parameter; -//import java.util.HashMap; -//import java.util.Map; -// -///** -// *

post方法解析

-// * -// * @author xuanran.wang -// * @date 2023/3/10 13:54 -// */ -//public class PostTypeHandle implements RequestBeforeHandle { -// @Override -// public Map handle(String url, Method method, Object[] args) { -// Parameter[] parameters = method.getParameters(); -// for (int i = 0; i < parameters.length; i++) { -// PostBody postBody = parameters[i].getDeclaredAnnotation(PostBody.class); -// if(postBody != null){ -// Object arg = args[i]; -// if(arg instanceof Map){ -// return (Map) arg; -// }else if(arg instanceof String){ -// String json = JSONObject.toJSONString(arg); -// return JSONObject.parseObject(json, Map.class); -// } -// } -// } -// return new HashMap(); -// } -//} diff --git a/src/test/java/xuanran/wang/http_test/handle/RequestHeaderHandle.java b/src/test/java/xuanran/wang/http_test/handle/RequestHeaderHandle.java deleted file mode 100644 index 6d2d99b..0000000 --- a/src/test/java/xuanran/wang/http_test/handle/RequestHeaderHandle.java +++ /dev/null @@ -1,81 +0,0 @@ -//package xuanran.wang.http_test.handle; -// -//import aiyh.utils.Util; -//import aiyh.utils.excention.CustomerException; -//import org.apache.commons.collections.CollectionUtils; -//import org.apache.commons.collections.MapUtils; -//import org.apache.commons.lang3.StringUtils; -//import xuanran.wang.http_test.annotations.header.CusRequestHeader; -//import xuanran.wang.http_test.interfaces.CusCreateRequestHeader; -// -//import java.lang.reflect.Method; -//import java.lang.reflect.Parameter; -//import java.util.HashMap; -//import java.util.Map; -// -///** -// *

请求头处理

-// * -// * @author xuanran.wang -// * @date 2023/3/10 14:42 -// */ -//public class RequestHeaderHandle implements RequestBeforeHandle { -// @Override -// public Object handle(String url, Method method, Object[] args) { -// CusRequestHeader methodCusRequestHeader = method.getDeclaredAnnotation(CusRequestHeader.class); -// if(methodCusRequestHeader == null){ -// return new HashMap<>(); -// } -// // 数组形式 -// String[] headersArr = methodCusRequestHeader.cusHeaders(); -// HashMap headers = new HashMap<>(); -// if(headersArr != null){ -// for (String headerStr : headersArr) { -// String[] split = headerStr.split(":"); -// String key = Util.null2DefaultStr(split[0],"").trim(); -// String val = Util.null2DefaultStr(split[1],"").trim(); -// if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(val)){ -// headers.put(key, val); -// } -// } -// } -// -// // java代码自定义 -// String path = Util.null2DefaultStr(methodCusRequestHeader.cusHeadersClassPath(),""); -// if(StringUtils.isNotBlank(path)){ -// Class clazz; -// try { -// clazz = Class.forName(path); -// } catch (ClassNotFoundException e) { -// throw new CustomerException(Util.logStr("自定义请求头java类文件没找到!: {}", path)); -// } -// if(!clazz.isAssignableFrom(CusCreateRequestHeader.class)){ -// throw new CustomerException(Util.logStr("当前类路径:[{}] ,未实现CusCreateRequestHeader接口!", path)); -// } -// CusCreateRequestHeader o; -// try { -// o = (CusCreateRequestHeader) clazz.newInstance(); -// }catch (InstantiationException | IllegalAccessException e) { -// throw new CustomerException(Util.logStr("实例化 [{}] 对象失败! error:{}", path, e.getMessage())); -// } -// Map cusCreateHeader = o.createHeader(); -// if(MapUtils.isNotEmpty(cusCreateHeader)){ -// headers.putAll(cusCreateHeader); -// } -// } -// // 参数中 -// Parameter[] parameters = method.getParameters(); -// for (int i = 0; i < parameters.length; i++) { -// Parameter parameter = parameters[i]; -// CusRequestHeader requestHeader = parameter.getAnnotation(CusRequestHeader.class); -// if(requestHeader != null){ -// String val = Util.null2DefaultStr(args[i], "").trim(); -// String key = requestHeader.value().trim(); -// if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(val)){ -// headers.put(key, val); -// } -// } -// } -// return headers; -// } -//} diff --git a/src/test/java/xuanran/wang/http_test/handle/path_handle/CusFieldKeyParseHandle.java b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java similarity index 89% rename from src/test/java/xuanran/wang/http_test/handle/path_handle/CusFieldKeyParseHandle.java rename to src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java index 19ab94e..d9cf5b8 100644 --- a/src/test/java/xuanran/wang/http_test/handle/path_handle/CusFieldKeyParseHandle.java +++ b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java @@ -2,7 +2,7 @@ package xuanran.wang.http_test.handle.path_handle; import aiyh.utils.Util; import org.apache.commons.lang3.StringUtils; -import xuanran.wang.http_test.annotations.CusPathQuery; +import xuanran.wang.http_test.annotations.request_path.CusPathQuery; import xuanran.wang.http_test.entity.CusRequestEntity; import xuanran.wang.http_test.handle.RequestBeforeHandle; @@ -33,7 +33,7 @@ public class CusFieldKeyParseHandle implements RequestBeforeHandle { }else { Class clazz = parameter.getType(); if(clazz.isAssignableFrom(Map.class)){ - requestEntity.setPathParams((Map) arg); + requestEntity.getPathParams().putAll((Map) arg); } } } From 771778167605599fbbda0711350abcdd9c01495d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=A3=E7=84=B6?= Date: Sun, 9 Apr 2023 21:15:39 +0800 Subject: [PATCH 6/8] =?UTF-8?q?2023-04-09=20=E4=B8=8A=E6=B5=B7=E5=A4=A7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=AD=E5=BF=83=E7=BB=9F=E4=B8=80=E5=BE=85?= =?UTF-8?q?=E5=8A=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xuanran.wang/bme/js/BuildContractApply.js | 6 +- javascript/xuanran.wang/bme/js/Common.js | 24 +- javascript/xuanran.wang/bme/js/DiaoBo.js | 26 ++ javascript/xuanran.wang/bme/js/PayApply.js | 155 +++++++- .../bme/js/PurchaseContractApply.js | 6 +- .../xuanran.wang/bme/js/SaleContractApply.js | 9 +- javascript/xuanran.wang/shyl/MealOrder.js | 45 +++ pom.xml | 6 + .../BatchCreateWorkFlowController.java | 4 - .../controller/UserUpdateToMQController.java | 54 +++ .../wang/shyl/mapper/ProducerMapper.java | 26 +- .../xuanran/wang/shyl/service/CarService.java | 5 + .../shyl/service/UserUpdateToMQService.java | 57 +++ .../workflow/action/FileTypeFieldConvert.java | 70 ++++ .../bme/action/CheckConsumerNameAction.java | 49 +++ .../action/ContractApplyComDateAction.java | 17 +- .../wang/common/util/CusInfoToOAUtil.java | 24 +- .../xuanran/wang/immc/WorkFlowToVmsAndMQ.java | 64 +++ .../wang/immc/cusfieldvalue/CusListValue.java | 50 +++ .../wang/immc/entity/VmsResponseVoField.java | 23 ++ .../xuanran/wang/immc/mapper/ImMcMapper.java | 20 + .../service/WorkFlowToVmsAndMQService.java | 165 ++++++++ .../sh_bigdata/common/entity/CusSuccess.java | 26 ++ .../sh_bigdata/common/entity/CusToken.java | 25 ++ .../common/util/RequestMasterPlate.java | 74 ++++ .../common/util/SendTodoTaskUtil.java | 167 ++++++++ .../sh_bigdata/common/util/ShBigDataUtil.java | 120 ++++++ .../sh_bigdata/common/util/TokenUtil.java | 78 ++++ .../OrganizationHrmSyncFromOtherSys.java | 106 +++++ .../annotations/CusDbEntityMapping.java | 16 + .../entity/OtherSysDepartment.java | 53 +++ .../mapper/OrgHrmAsyncMapper.java | 25 ++ .../service/OrgHrmAsyncApiService.java | 32 ++ .../service/OrgHrmAsyncService.java | 31 ++ .../impl/OrgHrmAsyncApiServiceImpl.java | 49 +++ .../service/impl/OrgHrmAsyncServiceImpl.java | 163 ++++++++ .../task_async/SendTodoTaskImpl.java | 162 ++++++++ .../task_async/entity/CusDoneTask.java | 23 ++ .../task_async/entity/CusDoneTaskOA.java | 39 ++ .../task_async/entity/CusTodoTask.java | 29 ++ .../entity/CusTodoTaskToOADetail.java | 68 ++++ .../task_async/mapper/SendTodoTaskMapper.java | 30 ++ .../service/SendTodoTaskService.java | 16 + .../service/impl/SendTodoTaskServiceImpl.java | 152 ++++++++ .../wang/shyl_mq/entity/MQMessage.java | 10 +- .../wang/shyl_mq/mapper/ConsumerMapper.java | 6 +- .../wang/shyl_mq/service/ProducerService.java | 10 +- .../service/impl/PassWordServiceImpl.java | 16 +- .../shyl_mq/service/impl/UserServiceImpl.java | 124 ++++++ .../service/impl/UserServiceImplBack.java | 4 +- .../wang/shyl_mq/util/RocketConsumerUtil.java | 23 +- .../prop/prop2map/OACarTest.properties | 5 + .../prop/prop2map/ShBigdataConf.properties | 24 ++ .../WEB-INF/prop/prop2map/VmsKafka.properties | 5 + .../annotations/CusRequestClient.java | 9 + .../http_test/annotations/CusRequestUrl.java | 16 + .../annotations/body/CusRequestBody.java | 16 + .../annotations/handle/CusHandle.java | 16 + .../annotations/handle/CusPreLoadHandle.java | 23 ++ .../handle/CusReqAfterHandleRegister.java | 19 + .../handle/CusResponseSuccessHandle.java | 19 + .../request_path/CusPathQuery.java | 2 +- .../request_type/CusRequestDelete.java | 12 +- .../request_type/CusRequestGet.java | 14 +- .../request_type/CusRequestPost.java | 12 +- .../request_type/CusRequestPut.java | 12 +- .../request_type/CusRequestType.java | 16 + .../constant/CusRequestClientConstant.java | 59 ++- .../http_test/entity/CusHandleEntity.java | 16 + .../http_test/entity/CusRequestEntity.java | 21 +- .../http_test/entity/CusResponseSuccess.java | 21 + .../http_test/handle/CusHandleCenter.java | 129 +++++++ .../handle/CusRequestAfterHandle.java | 31 ++ .../handle/CusRequestBeforeHandle.java | 4 +- .../http_test/handle/CusRequestHandle.java | 42 ++ .../header_handle/RequestHeaderHandle.java | 84 ++++ .../path_handle/CusBodyParseHandle.java | 39 ++ .../path_handle/CusPathParseHandle.java | 14 +- .../handle/path_handle/TestHandle.java | 22 ++ .../CusDefaultRequestAfterHandle.java | 47 +++ .../request_handle/CusRequestGetHandle.java | 21 + .../request_handle/CusRequestPostHandle.java | 21 + .../handle/request_handle/CusUrlHandle.java | 29 ++ .../http_test/handle/util/HandleUtil.java | 179 +++++++++ .../wang/http_test/proxy/RequestUtil.java | 93 +++-- .../wang/http_test/service/TestService.java | 33 +- .../wang/http_test/test/RequestTest.java | 33 +- .../test/TestRequestAfterHandle.java | 20 + .../java/xuanran/wang/immc/Kafka/MQTest.java | 363 ++++++++++++++++++ src/test/java/xuanran/wang/mq/CusMQType.java | 17 + .../wang/mq/consumer/DefaultConsumer.java | 21 + .../xuanran/wang/mq/infaces/CusBaseMQ.java | 27 ++ .../xuanran/wang/mq/infaces/CusConsumer.java | 16 + .../xuanran/wang/mq/infaces/CusMQClient.java | 11 + .../xuanran/wang/mq/infaces/CusProducer.java | 16 + .../xuanran/wang/mq/infaces/aop/CusMQAop.java | 18 + .../mq/infaces/callback/CusMQCallBack.java | 35 ++ .../java/xuanran/wang/mq/mq/CusKafkaMQ.java | 86 +++++ .../java/xuanran/wang/mq/mq/CusMQFactory.java | 45 +++ .../java/xuanran/wang/mq/mq/CusRocketMQ.java | 146 +++++++ .../xuanran/wang/mq/mq/DefaultCusMQAop.java | 41 ++ .../java/xuanran/wang/mq/test/MQTest.java | 58 +++ .../java/xuanran/wang/mq/util/CusMQUtil.java | 53 +++ .../wang/shyl/dataasync/AsyncTest.java | 22 +- .../wang/shyl/dataasync/MapperTest.java | 40 +- 105 files changed, 4585 insertions(+), 190 deletions(-) create mode 100644 javascript/xuanran.wang/bme/js/DiaoBo.js create mode 100644 javascript/xuanran.wang/shyl/MealOrder.js create mode 100644 src/main/java/com/api/xuanran/wang/shyl/controller/UserUpdateToMQController.java create mode 100644 src/main/java/com/api/xuanran/wang/shyl/service/UserUpdateToMQService.java create mode 100644 src/main/java/weaver/shyl/workflow/action/FileTypeFieldConvert.java create mode 100644 src/main/java/weaver/xuanran/wang/bme/action/CheckConsumerNameAction.java create mode 100644 src/main/java/weaver/xuanran/wang/immc/WorkFlowToVmsAndMQ.java create mode 100644 src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java create mode 100644 src/main/java/weaver/xuanran/wang/immc/entity/VmsResponseVoField.java create mode 100644 src/main/java/weaver/xuanran/wang/immc/mapper/ImMcMapper.java create mode 100644 src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusSuccess.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusToken.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/RequestMasterPlate.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/TokenUtil.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/OrganizationHrmSyncFromOtherSys.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/annotations/CusDbEntityMapping.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/entity/OtherSysDepartment.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/mapper/OrgHrmAsyncMapper.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncApiService.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncService.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncApiServiceImpl.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncServiceImpl.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/SendTodoTaskImpl.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTask.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTaskOA.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTaskToOADetail.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/mapper/SendTodoTaskMapper.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/SendTodoTaskService.java create mode 100644 src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/impl/SendTodoTaskServiceImpl.java create mode 100644 src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java create mode 100644 src/main/resources/WEB-INF/prop/prop2map/OACarTest.properties create mode 100644 src/main/resources/WEB-INF/prop/prop2map/ShBigdataConf.properties create mode 100644 src/main/resources/WEB-INF/prop/prop2map/VmsKafka.properties create mode 100644 src/test/java/xuanran/wang/http_test/annotations/CusRequestUrl.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/body/CusRequestBody.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/handle/CusHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/handle/CusPreLoadHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/handle/CusReqAfterHandleRegister.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/handle/CusResponseSuccessHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestType.java create mode 100644 src/test/java/xuanran/wang/http_test/entity/CusHandleEntity.java create mode 100644 src/test/java/xuanran/wang/http_test/entity/CusResponseSuccess.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/CusHandleCenter.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/CusRequestAfterHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/CusRequestHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/header_handle/RequestHeaderHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/path_handle/CusBodyParseHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/path_handle/TestHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/request_handle/CusDefaultRequestAfterHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestGetHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestPostHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/request_handle/CusUrlHandle.java create mode 100644 src/test/java/xuanran/wang/http_test/handle/util/HandleUtil.java create mode 100644 src/test/java/xuanran/wang/http_test/test/TestRequestAfterHandle.java create mode 100644 src/test/java/xuanran/wang/immc/Kafka/MQTest.java create mode 100644 src/test/java/xuanran/wang/mq/CusMQType.java create mode 100644 src/test/java/xuanran/wang/mq/consumer/DefaultConsumer.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/CusBaseMQ.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/CusConsumer.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/CusMQClient.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/CusProducer.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/aop/CusMQAop.java create mode 100644 src/test/java/xuanran/wang/mq/infaces/callback/CusMQCallBack.java create mode 100644 src/test/java/xuanran/wang/mq/mq/CusKafkaMQ.java create mode 100644 src/test/java/xuanran/wang/mq/mq/CusMQFactory.java create mode 100644 src/test/java/xuanran/wang/mq/mq/CusRocketMQ.java create mode 100644 src/test/java/xuanran/wang/mq/mq/DefaultCusMQAop.java create mode 100644 src/test/java/xuanran/wang/mq/test/MQTest.java create mode 100644 src/test/java/xuanran/wang/mq/util/CusMQUtil.java diff --git a/javascript/xuanran.wang/bme/js/BuildContractApply.js b/javascript/xuanran.wang/bme/js/BuildContractApply.js index c8df318..f328f1b 100644 --- a/javascript/xuanran.wang/bme/js/BuildContractApply.js +++ b/javascript/xuanran.wang/bme/js/BuildContractApply.js @@ -22,6 +22,7 @@ const detail2TempDateField = WfForm.convertFieldNameToId("dyrq", detailTable); // 需要计算的款项类型集合 const computeDatePayType = ['0']; const DETAIL_MAX_SIZE = 5; +const readOnlyArr = ['0']; // 款项类型预计对应日期取值 const paymentTypeGetValue = { 0: (index)=>{ @@ -36,7 +37,8 @@ jQuery().ready(function(){ 'detailComPayDateId': detail2ComPayDateId, 'dayId': detail2DayId, 'computeDatePayType': computeDatePayType, - 'paymentTypeGetValue': paymentTypeGetValue + 'paymentTypeGetValue': paymentTypeGetValue, + 'readOnlyArr': readOnlyArr } let rowArr = WfForm.getDetailAllRowIndexStr(detailTable).split(","); @@ -49,7 +51,7 @@ jQuery().ready(function(){ addRowBack(2, configObj); - changeDetailFieldReadOnly(detailTable, detail2ComPayDateId, detail2PaymentTypeId, computeDatePayType) + changeDetailFieldReadOnly(detailTable, detail2ComPayDateId, detail2PaymentTypeId, readOnlyArr) // 主表字段发生变化 mainFieldChangeDetailCom(contractSignDateId, detailTable, configObj); diff --git a/javascript/xuanran.wang/bme/js/Common.js b/javascript/xuanran.wang/bme/js/Common.js index 5c432b3..583099e 100644 --- a/javascript/xuanran.wang/bme/js/Common.js +++ b/javascript/xuanran.wang/bme/js/Common.js @@ -60,6 +60,7 @@ function submitCallback(detailTable, detail2PayProportionId){ sum += parseFloat(WfForm.getFieldValue(field));//遍历明细行字段 } } + console.log('sum => ', sum) sum === 100.00 ? callback() : WfForm.showMessage("明细付款比例总和不等于100,请修改后提交!"); }); } @@ -118,11 +119,18 @@ function changeDetailPayDate(obj){ let computeDatePayType = obj['computeDatePayType']; // 获取主表的字符值转换函数 let paymentTypeGetValue = obj['paymentTypeGetValue']; + // 只读 + let readOnlyArr = obj['readOnlyArr']; // 款项类型 let paymentType = WfForm.getFieldValue(`${detailPaymentTypeId}_${index}`); + if(readOnlyArr.includes(paymentType)){ + WfForm.changeFieldAttr(`${detailComPayDateId}_${index}`, READ_ONLY); + }else{ + // 如果款项类型不需要计算就把预计付款日期属性改成可编辑 + WfForm.changeFieldAttr(`${detailComPayDateId}_${index}`, EDIT); + } // 先进行赋值 if(computeDatePayType.includes(paymentType)){ - WfForm.changeFieldAttr(`${detailComPayDateId}_${index}`, READ_ONLY); // 存在字段联动延时处理 setTimeout(()=>{ if(paymentTypeGetValue){ @@ -142,16 +150,14 @@ function changeDetailPayDate(obj){ value: comDate }); } - }else { - // 如果对应日期为空就给预计付款赋空值 - WfForm.changeFieldValue(`${detailComPayDateId}_${index}`,{ - value: '' - }); } + // else { + // // 如果对应日期为空就给预计付款赋空值 + // WfForm.changeFieldValue(`${detailComPayDateId}_${index}`,{ + // value: '' + // }); + // } },100); - }else{ - // 如果款项类型不需要计算就把预计付款日期属性改成可编辑 - WfForm.changeFieldAttr(`${detailComPayDateId}_${index}`, EDIT); } } diff --git a/javascript/xuanran.wang/bme/js/DiaoBo.js b/javascript/xuanran.wang/bme/js/DiaoBo.js new file mode 100644 index 0000000..a742e50 --- /dev/null +++ b/javascript/xuanran.wang/bme/js/DiaoBo.js @@ -0,0 +1,26 @@ +const zrckField = WfForm.convertFieldNameToId('zrck'); +const zcckField = WfForm.convertFieldNameToId('zcck'); +// 主表存货编码 +const mainStockSetField = WfForm.convertFieldNameToId('chbmjh'); +// 明细1存货编码字段 +const deail1StockSetField = WfForm.convertFieldNameToId('chbm','detail_1'); +jQuery(document).ready(function(){ + WfForm.triggerFieldAllLinkage(zrckField); + WfForm.triggerFieldAllLinkage(zcckField); + initStockNo(); +}); +function initStockNo(){ + var rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(","); + let arr = []; + for(var i=0; i{ + WfForm.triggerFieldAllLinkage(mainStockSetField); + },500); +} \ No newline at end of file diff --git a/javascript/xuanran.wang/bme/js/PayApply.js b/javascript/xuanran.wang/bme/js/PayApply.js index fbe6238..3923e3f 100644 --- a/javascript/xuanran.wang/bme/js/PayApply.js +++ b/javascript/xuanran.wang/bme/js/PayApply.js @@ -3,30 +3,157 @@ const yjfksj = WfForm.convertFieldNameToId('yjfksj'); // 主表比例 const bl = WfForm.convertFieldNameToId('bcfkbl'); // 明细要求付款日期 -const detail3Yqfkrq = WfForm.convertFieldNameToId('yqfkrq',"detail_3"); +const detail3Yqfkrq = WfForm.convertFieldNameToId('yqfkrq', "detail_3"); // 明细本次付款比例 -const detailBl = WfForm.convertFieldNameToId('bcfkbl',"detail_3"); +const detailBl = WfForm.convertFieldNameToId('bcfkbl', "detail_3"); +// 关联订单 +const relationOrder = WfForm.convertFieldNameToId("gldd"); +// 明细4施工合同字段 +const detail4SgField = WfForm.convertFieldNameToId("sght", "detail_4"); +// 明细4采购合同字段 +const detail4CgField = WfForm.convertFieldNameToId("cght", "detail_4"); +// 明细4发票字段 +const detail4FpField = WfForm.convertFieldNameToId("fpje", "detail_4"); +// 明细4合同发票金额和 +let detail4Map = new Map(); +// 明细3施工合同字段 +const detail3SgField = WfForm.convertFieldNameToId("sght", "detail_3"); +// 明细3采购合同字段 +const detail3CgField = WfForm.convertFieldNameToId("cght", "detail_3"); +// 明细3 含税金额 +const detail3TaxField = WfForm.convertFieldNameToId("ddhsje", "detail_3"); +// 明细3以收票金额 +const detail3YspField = WfForm.convertFieldNameToId("yspje", "detail_3"); WfForm.registerCheckEvent(WfForm.OPER_ADDROW + "3", function (callback) { callback(); + setTimeout(() => { + initDeatail3Date(); + }, 5) +}); +// 关联订单变化时将明细四的合同-金额map进行初始化 +WfForm.bindFieldChangeEvent(relationOrder, function (obj, id, value) { + setTimeout(() => { + initDetail4Map(); + changeDetail3SpMoney(); + }, 2000); +}); + + +WfForm.bindFieldChangeEvent(`${yjfksj},${bl}`, function (obj, id, value) { initDeatail3Date(); }); -WfForm.bindFieldChangeEvent(`${yjfksj},${bl}`, function(obj,id,value){ - initDeatail3Date(); -}); - -function initDeatail3Date(){ - let dateVal = WfForm.getFieldValue(yjfksj); - let blVal = WfForm.getFieldValue(bl); - console.log('dateVal ', dateVal); - console.log('blVal ', blVal); +// 计算明细三开票金额 +function changeDetail3SpMoney() { let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); for (let i = 0; i < detail3RowArr.length; i++) { let rowIndex = detail3RowArr[i]; if (rowIndex !== "") { - WfForm.changeFieldValue(`${detail3Yqfkrq}_${rowIndex}`,{value: dateVal}); - WfForm.changeFieldValue(`${detailBl}_${rowIndex}`,{value: blVal}); + let detail3SgFieldVal = WfForm.getFieldValue(`${detail3SgField}_${rowIndex}`); + let detail3CgFieldVal = WfForm.getFieldValue(`${detail3CgField}_${rowIndex}`); + let fpje = detail4Map.get(detail3SgFieldVal) ?? detail4Map.get(detail3CgFieldVal); + let mapVal = detail4Map.get(detail3SgFieldVal); + let key = detail3SgFieldVal; + if (!mapVal) { + key = detail3CgFieldVal; + } + console.log('key ', key); + if (fpje) { + console.log('fpje => ', fpje); +// 0.1 0.3 + let detail3TaxVal = WfForm.getFieldValue(`${detail3TaxField}_${rowIndex}`); + console.log('detail3TaxVal => ', detail3TaxVal); + let tempJe = fpje - detail3TaxVal; + console.log('tempJe => ', tempJe); + if (fpje > detail3TaxVal) { + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: detail3TaxVal}); + } else if (tempJe <= 0 && fpje == 0) { + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: 0}); + } else if (tempJe < 0) { + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: fpje}); + tempJe = 0; + } + detail4Map.set(key, tempJe); + console.log('detail4Map ', detail4Map) + } else { + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: 0}); + } } } -} \ No newline at end of file +} + + +function initDeatail3Date() { + let dateVal = WfForm.getFieldValue(yjfksj); + let blVal = WfForm.getFieldValue(bl); + let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); + for (let i = 0; i < detail3RowArr.length; i++) { + let rowIndex = detail3RowArr[i]; + if (rowIndex !== "") { + WfForm.changeFieldValue(`${detail3Yqfkrq}_${rowIndex}`, {value: dateVal}); + WfForm.changeFieldValue(`${detailBl}_${rowIndex}`, {value: blVal}); + } + } +} + +function initDetail4Map() { + let detail4RowArr = WfForm.getDetailAllRowIndexStr('detail_4').split(","); + console.log('detail4RowArr ', detail4RowArr); + for (let i = 0; i < detail4RowArr.length; i++) { + let rowIndex = detail4RowArr[i]; + if (rowIndex !== "") { + let detail4SgFieldVal = WfForm.getFieldValue(`${detail4SgField}_${rowIndex}`); + let detail4CgFieldVal = WfForm.getFieldValue(`${detail4CgField}_${rowIndex}`); + let detail4FpFieldVal = WfForm.getFieldValue(`${detail4FpField}_${rowIndex}`); + let key = -1; + console.log('detail4SgFieldVal ', detail4SgFieldVal); + console.log('detail4CgFieldVal ', detail4CgFieldVal); + console.log('detail4FpFieldVal ', detail4FpFieldVal); + if (!detail4FpFieldVal) { + continue; + } + key = detail4CgFieldVal ?? detail4SgFieldVal; + console.log('key ', key); + let tempVal = parseFloat(detail4Map.get(key) ?? 0); + tempVal += parseFloat(detail4FpFieldVal); + detail4Map.set(key, tempVal); + } + } + console.log('detail4Map ', detail4Map) +} + +const detail3ApplyMoneyField = WfForm.convertFieldNameToId("bcfkje", "detail_3"); +const detail3CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_3"); +const detail3Bl = WfForm.convertFieldNameToId('bcfkbl', "detail_3"); +let detailBlMap = new Map(); +const detail1Bl = WfForm.convertFieldNameToId('fkbl', "detail_1"); +const detail1CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_1"); +WfForm.bindDetailFieldChangeEvent(detail3ApplyMoneyField, (id, rowIndex, value) => { + let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); + detailBlMap = new Map(); + for (let i = 0; i < detail3RowArr.length; i++) { + let rowIndex = detail3RowArr[i]; + if (rowIndex !== "") { + let bl = parseFloat(WfForm.getFieldValue(`${detail3Bl}_${rowIndex}`)); + let cg = WfForm.getFieldValue(`${detail3CgId}_${rowIndex}`); + let mapVal = parseFloat(detailBlMap.get(cg) ?? 0) + bl; + detailBlMap.set(cg, mapVal); + } + } + console.log('detailBlMap ', detailBlMap) + let detail1RowArr = WfForm.getDetailAllRowIndexStr('detail_1').split(","); + for (let i = 0; i < detail1RowArr.length; i++) { + let rowIndex = detail1RowArr[i]; + if (rowIndex !== "") { + let cg = WfForm.getFieldValue(`${detail1CgId}_${rowIndex}`); + let val = detailBlMap.get(cg) === '' ? 0 : detailBlMap.get(cg); + WfForm.changeFieldValue(`${detail1Bl}_${rowIndex}`, {value: val}) + } + } +}); + + + + + diff --git a/javascript/xuanran.wang/bme/js/PurchaseContractApply.js b/javascript/xuanran.wang/bme/js/PurchaseContractApply.js index 705e114..1e2722f 100644 --- a/javascript/xuanran.wang/bme/js/PurchaseContractApply.js +++ b/javascript/xuanran.wang/bme/js/PurchaseContractApply.js @@ -23,6 +23,7 @@ const detailComPayDateId = WfForm.convertFieldNameToId("yjfkrq",detailTable); // 对应日期 const detailTempDateField = WfForm.convertFieldNameToId("dyrq", detailTable); // 需要计算的款项类型集合 +const readOnlyArr = ['0']; const computeDatePayType = ['0','2','4']; // 款项类型预计对应日期取值 const paymentTypeGetValue = { @@ -49,12 +50,13 @@ function init(){ 'detailComPayDateId': detailComPayDateId, 'dayId': detailDayId, 'computeDatePayType': computeDatePayType, - 'paymentTypeGetValue': paymentTypeGetValue + 'paymentTypeGetValue': paymentTypeGetValue, + 'readOnlyArr': readOnlyArr } addRowBack(3, obj); - changeDetailFieldReadOnly(detailTable, detailComPayDateId, detailPaymentTypeId, computeDatePayType) + changeDetailFieldReadOnly(detailTable, detailComPayDateId, detailPaymentTypeId, readOnlyArr) // 主表字段发生变化 mainFieldChangeDetailCom(`${mainProjectId},${contractSignDateId}`, detailTable, obj); // 明细的款项类型字段变化绑定 diff --git a/javascript/xuanran.wang/bme/js/SaleContractApply.js b/javascript/xuanran.wang/bme/js/SaleContractApply.js index eff8107..6fb1ba7 100644 --- a/javascript/xuanran.wang/bme/js/SaleContractApply.js +++ b/javascript/xuanran.wang/bme/js/SaleContractApply.js @@ -11,7 +11,7 @@ const mainWorkFlowEndId = WfForm.convertFieldNameToId("fhdgdrq"); // 主表实际验收 const mainActualCheckId = WfForm.convertFieldNameToId("sjysrq"); // 明细2付款比例字段 -const detail2PayProportionId = WfForm.convertFieldNameToId("fkbl",detailTable); +const detail2PayProportionId = WfForm.convertFieldNameToId("skbl",detailTable); // 明细2款项类型 const detail2PaymentTypeId = WfForm.convertFieldNameToId("kxlx",detailTable); // 明细2前后字段 @@ -24,6 +24,8 @@ const detail2ComPayDateId = WfForm.convertFieldNameToId("yjfkrq",detailTable); const detail2TempDateField = WfForm.convertFieldNameToId("dyrq", detailTable); // 需要计算的款项类型集合 const computeDatePayType = ['2', '4', '5']; +// 只读 明细款项类型 +const readOnlyArr = []; // 款项类型预计对应日期取值 const paymentTypeGetValue = { 2: (index)=>{ @@ -50,10 +52,11 @@ function init(){ 'detailComPayDateId': detail2ComPayDateId, 'dayId': detail2DayId, 'computeDatePayType': computeDatePayType, - 'paymentTypeGetValue': paymentTypeGetValue + 'paymentTypeGetValue': paymentTypeGetValue, + 'readOnlyArr': readOnlyArr } addRowBack(2, obj); - changeDetailFieldReadOnly(detailTable, detail2ComPayDateId, detail2PaymentTypeId, computeDatePayType) + changeDetailFieldReadOnly(detailTable, detail2ComPayDateId, detail2PaymentTypeId, readOnlyArr); // 主表字段发生变化 mainFieldChangeDetailCom(mainProjectId, detailTable, obj); // 明细的款项类型字段变化绑定 diff --git a/javascript/xuanran.wang/shyl/MealOrder.js b/javascript/xuanran.wang/shyl/MealOrder.js new file mode 100644 index 0000000..aca382b --- /dev/null +++ b/javascript/xuanran.wang/shyl/MealOrder.js @@ -0,0 +1,45 @@ +const enable = 0; +// 班级浏览按钮表单字段id +const classFieldId = WfForm.convertFieldNameToId("bjmc"); +// 明细1学员id +const detail1StuId = WfForm.convertFieldNameToId("studentId","detail_1");; +// 明细1学员编号 +const detail1StuNo = WfForm.convertFieldNameToId("studentNo","detail_1");; +// 明细1学员姓名 +const detail1StuName = WfForm.convertFieldNameToId("studentName","detail_1");; +// 明细1班级id +const detail1ClassId = WfForm.convertFieldNameToId("classId","detail_1"); +// 主表学员汇总字段 +const stuAllField = WfForm.convertFieldNameToId("mxxybhhzfz"); +WfForm.bindFieldChangeEvent(classFieldId, function(obj,id,value){ + let classId = WfForm.getBrowserShowName(classFieldId); + WfForm.delDetailRow("detail_1", "all"); + $.get('/api/wxr/students/getStudentsByClassId',{id:classId},(res)=>{ + let obj = JSON.parse(res); + if(obj.code != 200){ + WfForm.showMessage(obj.msg); + return; + } + console.log('obj ', obj); + let objData = obj.data; + let responseObj = JSON.parse(objData); + if(!responseObj || !responseObj.data){ + WfForm.showMessage(responseObj.msg); + return; + } + objData = responseObj.data; + WfForm.changeFieldValue(stuAllField, {value: ''}); + let stuArr = []; + objData.forEach((item)=>{ + let detailObj = {}; + detailObj[detail1StuId] = { value: item.id }; + detailObj[detail1StuNo] = { value: item.studentNo }; + detailObj[detail1StuName] = { value: item.studentName }; + detailObj[detail1ClassId] = { value: item.classId }; + // console.log('detailObj ', detailObj) + WfForm.addDetailRow("detail_1",detailObj); + stuArr.push(item.studentNo); + }) + WfForm.changeFieldValue(stuAllField, {value: stuArr.join(',')}); + }) +}); \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5b8411e..7267c9b 100644 --- a/pom.xml +++ b/pom.xml @@ -103,6 +103,12 @@ 4.4.0 + + org.apache.kafka + kafka-clients + 2.3.1 + + cn.afterturn easypoi-base diff --git a/src/main/java/com/api/xuanran/wang/shyl/controller/BatchCreateWorkFlowController.java b/src/main/java/com/api/xuanran/wang/shyl/controller/BatchCreateWorkFlowController.java index 3c0791d..94abd03 100644 --- a/src/main/java/com/api/xuanran/wang/shyl/controller/BatchCreateWorkFlowController.java +++ b/src/main/java/com/api/xuanran/wang/shyl/controller/BatchCreateWorkFlowController.java @@ -6,8 +6,6 @@ import aiyh.utils.excention.CustomerException; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.api.xuanran.wang.shyl.service.BatchCreateWorkflowService; -import com.api.xuanran.wang.shyl.service.MeetingService; -import com.api.xuanran.wang.shyl.vo.CreateWfVO; import com.engine.common.util.ServiceUtil; import com.engine.workflow.publicApi.WorkflowRequestOperatePA; import com.engine.workflow.publicApi.impl.WorkflowRequestOperatePAImpl; @@ -16,7 +14,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import weaver.hrm.User; -import weaver.xuanran.wang.common.mapper.CommonMapper; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -26,7 +23,6 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import java.util.List; /** *

上海团校-批量创建流程接口

diff --git a/src/main/java/com/api/xuanran/wang/shyl/controller/UserUpdateToMQController.java b/src/main/java/com/api/xuanran/wang/shyl/controller/UserUpdateToMQController.java new file mode 100644 index 0000000..a0b5f89 --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/shyl/controller/UserUpdateToMQController.java @@ -0,0 +1,54 @@ +package com.api.xuanran.wang.shyl.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.api.xuanran.wang.shyl.service.UserUpdateToMQService; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +/** + *

用户信息更新将数据发送到队列中

+ * + * @author xuanran.wang + * @date 2023/3/20 17:15 + */ +@Path("/wxr/user_mq") +public class UserUpdateToMQController { + private final Logger log = Util.getLogger(); + private final UserUpdateToMQService userUpdateToMQService = new UserUpdateToMQService(); + /** + *

用户信息更新

+ * @author xuanran.wang + * @dateTime 2023/3/1 15:24 + **/ + @Path("/update") + @POST + @Produces(MediaType.TEXT_PLAIN) + public String updateUserInfoToMQ(@Context HttpServletRequest request, + @Context HttpServletResponse response){ + try { + String id = Util.null2DefaultStr(request.getParameter("id"),""); + String onlyMark = Util.null2DefaultStr(request.getParameter("onlyMark"),""); + String configName = Util.null2DefaultStr(request.getParameter("configName"),""); + String debug = Util.null2DefaultStr(request.getParameter("debug"),""); + if(StringUtils.isBlank(id) || StringUtils.isBlank(onlyMark) || StringUtils.isBlank(configName)){ + throw new CustomerException("update user to mq id or onlyMark or configName can not null!"); + } + userUpdateToMQService.toMQ(id, onlyMark, configName, debug); + return ApiResult.success(null); + }catch (Exception e){ + log.error(Util.logStr("MeetingController error ! {}", e.getMessage())); + return ApiResult.error(500,"会议取消接口发生异常! 异常信息 :[ " + e.getMessage() + " ]"); + } + + } +} diff --git a/src/main/java/com/api/xuanran/wang/shyl/mapper/ProducerMapper.java b/src/main/java/com/api/xuanran/wang/shyl/mapper/ProducerMapper.java index 3b7da0c..7d0715b 100644 --- a/src/main/java/com/api/xuanran/wang/shyl/mapper/ProducerMapper.java +++ b/src/main/java/com/api/xuanran/wang/shyl/mapper/ProducerMapper.java @@ -5,7 +5,7 @@ import aiyh.utils.annotation.recordset.Select; import aiyh.utils.annotation.recordset.SqlMapper; import com.api.xuanran.wang.shyl.entity.ProducerCarInfo; -import java.util.HashMap; +import java.util.Map; /** *

生产者mapper

@@ -15,6 +15,13 @@ import java.util.HashMap; */ @SqlMapper public interface ProducerMapper { + /** + *

通过车辆ID查信息

+ * @author xuanran.wang + * @dateTime 2023/3/20 17:26 + * @param id 车辆id + * @return 车辆实体 + **/ @Select("select a.id carCode, Deposit status,b.outkey driver, b.lastname userName, " + "b.telephone userPhone, carNo plateList, remark " + "from carinfo a " + @@ -23,6 +30,13 @@ public interface ProducerMapper { "where a.id = #{id}") ProducerCarInfo queryCarInfo(@ParamMapper("id") String id); + /** + *

通过车排号查信息

+ * @author xuanran.wang + * @dateTime 2023/3/20 17:27 + * @param carNo 车牌号 + * @return 车辆实体 + **/ @Select("select a.id carCode, Deposit status,b.outkey driver, b.lastname userName, " + "b.telephone userPhone, carNo plateList, remark " + "from carinfo a " + @@ -30,4 +44,14 @@ public interface ProducerMapper { "on a.driver = b.id " + "where a.carNo = #{carNo}") ProducerCarInfo queryCarNo(@ParamMapper("carNo") String carNo); + + /** + *

根据人员ID查询信息

+ * @author xuanran.wang + * @dateTime 2023/3/20 17:27 + * @param id 人员ID + * @return 人员信息 + **/ + @Select("select * from hrmresource where id = #{id}") + Map queryUserInfo(@ParamMapper("id") String id); } diff --git a/src/main/java/com/api/xuanran/wang/shyl/service/CarService.java b/src/main/java/com/api/xuanran/wang/shyl/service/CarService.java index c4205ec..fd73005 100644 --- a/src/main/java/com/api/xuanran/wang/shyl/service/CarService.java +++ b/src/main/java/com/api/xuanran/wang/shyl/service/CarService.java @@ -81,6 +81,10 @@ public class CarService { carNo = Util.null2DefaultStr(request.getParameter("carNo"),""); info = producerMapper.queryCarNo(carNo); } + + //add by taojw +// String plateList = info.getPlateList(); + // 如果能找到就说明是更新或者新增 if("del".equals(operation)){ //删除状态下 info = new ProducerCarInfo(); @@ -88,6 +92,7 @@ public class CarService { info.setStatus("1"); info.setRemark(""); info.setDriver(""); + //edit by taojw info.setPlateList(""); info.setUserName(""); info.setUserPhone(""); diff --git a/src/main/java/com/api/xuanran/wang/shyl/service/UserUpdateToMQService.java b/src/main/java/com/api/xuanran/wang/shyl/service/UserUpdateToMQService.java new file mode 100644 index 0000000..c19c2dc --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/shyl/service/UserUpdateToMQService.java @@ -0,0 +1,57 @@ +package com.api.xuanran.wang.shyl.service; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSONObject; +import com.api.xuanran.wang.shyl.mapper.ProducerMapper; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.service.DealWithMapping; +import weaver.xuanran.wang.shyl_mq.util.RocketConsumerUtil; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + *

用户信息更新将数据发送到队列业务方法

+ * + * @author xuanran.wang + * @date 2023/3/20 17:18 + */ +public class UserUpdateToMQService { + + private final Logger logger = Util.getLogger(); + + private final DealWithMapping dealWithMapping = new DealWithMapping(); + + private final ProducerMapper producerMapper = Util.getMapper(ProducerMapper.class); + + private static final String HRM_TABLE = "hrmresource"; + + + public void toMQ(String id, + String onlyMark, + String configName, + String debug){ + Map userMap = producerMapper.queryUserInfo(id); + if(MapUtils.isEmpty(userMap)){ + logger.error(Util.logStr("userId: {}, userInfo is empty!")); + return; + } + RequestMappingConfig config = dealWithMapping.treeDealWithUniqueCode(onlyMark); + dealWithMapping.setMainTable(HRM_TABLE); + Map param = dealWithMapping.getRequestParam(userMap, config); + if(MapUtils.isEmpty(param)){ + logger.error(Util.logStr("userId:{}, 生成json为空!",id)); + return; + } + if(StringUtils.isNotBlank(debug)){ + logger.info("update user json : \n" + JSONObject.toJSONString(param)); + return; + } + RocketConsumerUtil.producerSendMsg(configName, JSONObject.toJSONString(param), id); + } +} diff --git a/src/main/java/weaver/shyl/workflow/action/FileTypeFieldConvert.java b/src/main/java/weaver/shyl/workflow/action/FileTypeFieldConvert.java new file mode 100644 index 0000000..5e3a293 --- /dev/null +++ b/src/main/java/weaver/shyl/workflow/action/FileTypeFieldConvert.java @@ -0,0 +1,70 @@ +package weaver.shyl.workflow.action; + +import aiyh.utils.Util; +import aiyh.utils.entity.DocImageInfo; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.file.ImageFileManager; +import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Base64; +import java.util.Map; +/** + *

团校-流程中字段图片附件转成base64

+ * + * @author xuanran.wang + * @date 2023/3/27 22:41 + */ +public class FileTypeFieldConvert implements CusInterfaceGetValue { + + private final Logger log = Util.getLogger(); + + /** + * 获取参数值 + * + * @param mainMap 主表数据 + * @param detailMap 明细表数据 + * @param currentValue 当前字段值 + * @param pathParam 路径参数 + * @return 最终返回参数 + */ + @Override + public Object execute(Map mainMap, Map detailMap, String currentValue, Map pathParam) { + try { + log.info("原文件图片ID:[" + currentValue + "]"); + log.info("pathParam : " + JSONObject.toJSONString(pathParam)); + int tempId = Util.getIntValue(currentValue, -1); + if(!"".equals(currentValue) && tempId > 0 && !currentValue.contains(",")) { + String imageFileId = Util.null2DefaultStr(pathParam.get("imageFileId"),""); + InputStream inputStream; + if (StringUtils.isBlank(imageFileId)) { + DocImageInfo docImageInfo = Util.selectImageInfoByDocId(currentValue); + inputStream = ImageFileManager.getInputStreamById(docImageInfo.getImageFileId()); + }else { + int fileId = Util.getIntValue(currentValue, -1); + if(fileId < 0){ + throw new CustomerException("image file id < 0"); + } + inputStream = ImageFileManager.getInputStreamById(fileId); + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] bytes = outputStream.toByteArray(); + return Base64.getEncoder().encodeToString(bytes); + } + } catch (Exception e) { + log.error("convert file to base64 fail!" + e.getMessage() + "\n" + Util.getErrString(e)); + throw new CustomerException("convert file to base64 fail!"); + } + return null; + } +} + diff --git a/src/main/java/weaver/xuanran/wang/bme/action/CheckConsumerNameAction.java b/src/main/java/weaver/xuanran/wang/bme/action/CheckConsumerNameAction.java new file mode 100644 index 0000000..9adc14c --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/bme/action/CheckConsumerNameAction.java @@ -0,0 +1,49 @@ +package weaver.xuanran.wang.bme.action; + +import aiyh.utils.Util; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; +import weaver.workflow.request.RequestManager; + +/** + *

校验客户名称

+ * + * @author xuanran.wang + * @date 2023/4/6 09:51 + */ +public class CheckConsumerNameAction implements Action { + private final Logger log = Util.getLogger(); + private String wfConsumerField; + private String modelConsumerField; + private String modelName; + + @Override + public String execute(RequestInfo request) { + String requestId = request.getRequestid(); + String tableName = request.getRequestManager().getBillTableName(); + RecordSet rs = new RecordSet(); + + wfConsumerField = Util.null2DefaultStr(wfConsumerField, "khmc"); + modelConsumerField = Util.null2DefaultStr(modelConsumerField, "khmc"); + modelName = Util.null2DefaultStr(modelName, "uf_kh"); + + RequestManager requestManager = request.getRequestManager(); + rs.executeQuery("select * from " + tableName + " where requestid = ?", requestId); + rs.next(); + String wfConsumer = rs.getString(wfConsumerField); + log.info("wfConsumer : [ " + wfConsumer + " ]"); + if(StringUtils.isNotBlank(wfConsumer)){ + String sql = "select id from " + modelName + " where " + modelConsumerField + " = ?"; + log.info("sql : " + sql + " ,参数: " + wfConsumer); + if (rs.executeQuery(sql, wfConsumer) && rs.next()) { + requestManager.setMessageid(System.currentTimeMillis() + ""); + requestManager.setMessagecontent("当前客户名称: " + wfConsumer + " ,在客户表中已经存在请修改后提交!"); + return Action.FAILURE_AND_CONTINUE; + } + } + return Action.SUCCESS; + } +} diff --git a/src/main/java/weaver/xuanran/wang/bme/action/ContractApplyComDateAction.java b/src/main/java/weaver/xuanran/wang/bme/action/ContractApplyComDateAction.java index 55478d3..a58c672 100644 --- a/src/main/java/weaver/xuanran/wang/bme/action/ContractApplyComDateAction.java +++ b/src/main/java/weaver/xuanran/wang/bme/action/ContractApplyComDateAction.java @@ -68,6 +68,7 @@ public class ContractApplyComDateAction implements Action { *

明细前后字段

**/ @RequiredMark + @PrintParamMark private String beforeBackField; /** @@ -124,6 +125,7 @@ public class ContractApplyComDateAction implements Action { log.error(Util.logStr("checkDate:{}, project:{}", checkDate, project)); throw new CustomerException("实际验收日期或项目字段字段为空!"); } + // select a.id,a.requestid from formtable_main_58 a right join uf_cgdd b on a.htbh = b.lcbh where b.id = String selectSql = "select id,requestid from " + buildContractTable + " where " + buildContractProjectField + " = ?"; if(StringUtils.isNotBlank(relationSql)){ selectSql = relationSql; @@ -159,16 +161,15 @@ public class ContractApplyComDateAction implements Action { params.add(param); log.info(Util.logStr("关联流程requestId: {}, 流程明细前后字段: {}, 天数: {}, 计算后的日期: {}",tempRequestId, beforeBack, day, computeDate)); } - } - if(CollectionUtils.isNotEmpty(params)){ - if(!rs.executeBatchSql(updateSql,params)){ - log.error(Util.logStr("更新sql : {}, 参数 : {}", updateSql, params)); - throw new CustomerException("更新合同sql错误!"); + if(CollectionUtils.isNotEmpty(params)){ + if(!rs.executeBatchSql(updateSql,params)){ + log.error(Util.logStr("更新sql : {}, 参数 : {}", updateSql, params)); + throw new CustomerException("更新合同sql错误!"); + } + }else { + log.error(Util.logStr("明细表: {}不存在数据!", detailContractTable)); } - }else { - log.error(Util.logStr("明细表: {}不存在数据!", detailContractTable)); } - }else{ log.error(Util.logStr("查询关联项目sql暂未查到数据! sql {} ,{}", selectSql, requestId)); } diff --git a/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java b/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java index 0496f10..53df958 100644 --- a/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java +++ b/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java @@ -150,13 +150,15 @@ public class CusInfoToOAUtil { * @dateTime 2023/2/9 11:51 * @param modelId 模块id * @param list 插入参数集合 - * @param whereSql 更新条件 + * @param whereSql 更新条件sql * @return 建模数据id **/ public static List executeBatchByEntity(int modelId, List list, String whereSql){ String tableName = checkModelId(modelId); List> params = new ArrayList<>(); List> whereParams = new ArrayList<>(); + StringBuilder whereSqlSb; + LinkedHashSet whereFields = new LinkedHashSet<>(); for (Object o : list) { if(Objects.isNull(o)){ continue; @@ -165,7 +167,14 @@ public class CusInfoToOAUtil { Field[] fields = clazz.getDeclaredFields(); LinkedHashMap linkedHashMap = new LinkedHashMap<>(); ArrayList whereParam = new ArrayList<>(); - for (Field field : fields) { + List fieldArr = Arrays.stream(fields).collect(Collectors.toList()); + Class superclass = clazz.getSuperclass(); + // 找出父类所有的字段 + while (superclass != null){ + fieldArr.addAll(Arrays.stream(superclass.getDeclaredFields()).collect(Collectors.toList())); + superclass = superclass.getSuperclass(); + } + for (Field field : fieldArr) { field.setAccessible(true); String fieldName = field.getName(); Object fieldValue; @@ -194,14 +203,25 @@ public class CusInfoToOAUtil { if(null == sqlUpdateWhereField || !sqlUpdateWhereField.value()){ continue; } + if(StringUtils.isBlank(whereSql)){ + whereFields.add(fieldName + " = ?"); + } whereParam.add(fieldValue.toString()); } params.add(linkedHashMap); whereParams.add(whereParam); } + if(!whereFields.isEmpty()){ + whereSqlSb = new StringBuilder("select id from #{tableName} where "); + for (String field : whereFields) { + whereSqlSb.append(field).append(" and "); + } + whereSql = whereSqlSb.substring(0, whereSqlSb.length() - 4); + } return executeBatch(modelId, tableName, params, whereSql, whereParams, true, new ArrayList<>()); } + /** *

将自定义信息写入建模

* @author xuanran.wang diff --git a/src/main/java/weaver/xuanran/wang/immc/WorkFlowToVmsAndMQ.java b/src/main/java/weaver/xuanran/wang/immc/WorkFlowToVmsAndMQ.java new file mode 100644 index 0000000..0246fb8 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/immc/WorkFlowToVmsAndMQ.java @@ -0,0 +1,64 @@ +package weaver.xuanran.wang.immc; + +import aiyh.utils.Util; +import aiyh.utils.action.SafeCusBaseAction; +import aiyh.utils.annotation.ActionDesc; +import aiyh.utils.annotation.ActionOptionalParam; +import aiyh.utils.annotation.PrintParamMark; +import aiyh.utils.annotation.RequiredMark; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; +import weaver.xuanran.wang.immc.entity.VmsResponseVoField; +import weaver.xuanran.wang.immc.service.WorkFlowToVmsAndMQService; + +/** + *

智己 将流程数据推送到接口/kafka队列中

+ * + * @author xuanran.wang + * @date 2023/3/30 11:21 + */ +@ActionDesc(value = "智己 将流程数据推送到接口/kafka队列中", author = "xuanran.wang") +public class WorkFlowToVmsAndMQ extends SafeCusBaseAction { + + private final WorkFlowToVmsAndMQService workFlowToVmsAndMQService = new WorkFlowToVmsAndMQService(); + /** + *

+ * OA-uat + * 用户密码 + * oa_uat_user/los0cp6aiV1iO1e2 + * Topic + * oa_service_immc_topic_uat + * 接入点 + * 10.184.42.41:9094,10.184.42.42:9094,10.184.42.40:9094 + *

+ **/ + @PrintParamMark + @ActionOptionalParam(value = "", desc = "kafka配置文件名称") + private String kafkaConfig; + + @PrintParamMark + @RequiredMark("建模配置文件唯一标识") + private String onlyMark; + + @PrintParamMark + @ActionOptionalParam(value = "code", desc = "接口成功标识字段") + private String successField; + @PrintParamMark + @ActionOptionalParam(value = "200", desc = "接口成功标识默认200") + private String successVal; + @PrintParamMark + @ActionOptionalParam(value = "message", desc = "报错返回信息字段") + private String msg; + + @Override + public void doSubmit(String requestId, String billTable, int workflowId, User user, RequestInfo requestInfo) { + log.info("-------------- " + requestId + " begin --------------"); + VmsResponseVoField vmsResponseVoField = VmsResponseVoField + .builder() + .successField(Util.null2DefaultStr(successField, "code")) + .successVal(Util.null2DefaultStr(successVal, "200")) + .message(Util.null2DefaultStr(msg, "message")) + .build(); + workFlowToVmsAndMQService.workFlowToVmsAndMQ(onlyMark, billTable, requestId, vmsResponseVoField, kafkaConfig); + } +} diff --git a/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java b/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java new file mode 100644 index 0000000..44faeeb --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/immc/cusfieldvalue/CusListValue.java @@ -0,0 +1,50 @@ +package weaver.xuanran.wang.immc.cusfieldvalue; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; +import weaver.xiao.commons.config.interfacies.CusInterfaceListValue; +import weaver.xuanran.wang.immc.mapper.ImMcMapper; + +import java.util.*; + +/** + *

附件集合

+ * + * @author xuanran.wang + * @date 2023/3/30 15:11 + */ +public class CusListValue implements CusInterfaceGetValue { + + private final Logger log = Util.getLogger(); + private final ImMcMapper mapper = Util.getMapper(ImMcMapper.class); + + @Override + public Object execute(Map mainMap, Map detailMap, String currentValue, Map pathParam) { + List list = new ArrayList<>(); + log.info("pathParam : \n" + JSONObject.toJSONString(pathParam)); + String attachmentField = Util.null2DefaultStr(pathParam.get("attachmentField"), ""); + String cusSql = Util.null2DefaultStr(pathParam.get("cusSql"), ""); + if(StringUtils.isNotBlank(cusSql)){ + String docIds = ""; + if (StringUtils.isNotBlank(attachmentField)) { + List attachment = new ArrayList<>(); + for (String item : attachmentField.split(",")) { + String filedValue = Util.null2DefaultStr(mainMap.get(item),""); + if(StringUtils.isNotBlank(Util.null2DefaultStr(mainMap.get(item),""))){ + attachment.add(filedValue); + } + } + docIds = StringUtils.join(attachment, ","); + } + cusSql = cusSql + .replace("{?docIds}", "( " + docIds + " )") + .replace("{?requestid}",Util.null2DefaultStr(mainMap.get("requestid"),"")); + List> attachmentInfo = mapper.getAttachmentInfo(cusSql); + list.addAll(attachmentInfo); + } + return list; + } +} diff --git a/src/main/java/weaver/xuanran/wang/immc/entity/VmsResponseVoField.java b/src/main/java/weaver/xuanran/wang/immc/entity/VmsResponseVoField.java new file mode 100644 index 0000000..7ccab43 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/immc/entity/VmsResponseVoField.java @@ -0,0 +1,23 @@ +package weaver.xuanran.wang.immc.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.kie.api.definition.rule.All; + +/** + *

vms响应对象

+ * + * @author xuanran.wang + * @date 2023/3/30 14:23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class VmsResponseVoField { + private String successField; + private String successVal; + private String message; +} diff --git a/src/main/java/weaver/xuanran/wang/immc/mapper/ImMcMapper.java b/src/main/java/weaver/xuanran/wang/immc/mapper/ImMcMapper.java new file mode 100644 index 0000000..12b3bfc --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/immc/mapper/ImMcMapper.java @@ -0,0 +1,20 @@ +package weaver.xuanran.wang.immc.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.SqlString; + +import java.util.List; +import java.util.Map; + +/** + *

dao

+ * + * @author xuanran.wang + * @date 2023/3/30 15:27 + */ +@SqlMapper +public interface ImMcMapper { + @Select(custom = true) + List> getAttachmentInfo(@SqlString String sql); +} diff --git a/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java b/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java new file mode 100644 index 0000000..84d08ef --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/immc/service/WorkFlowToVmsAndMQService.java @@ -0,0 +1,165 @@ +package weaver.xuanran.wang.immc.service; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.service.DealWithMapping; +import weaver.xuanran.wang.common.util.CommonUtil; +import weaver.xuanran.wang.immc.entity.VmsResponseVoField; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.Map; + +/** + *

vms业务方法

+ * + * @Author xuanran.wang + * @Date 2022/12/1 10:58 + */ +public class WorkFlowToVmsAndMQService { + private static final int SUCCESS_CODE = 200; + private final DealWithMapping dealWithMapping = new DealWithMapping(); + private final Logger log = Util.getLogger(); // 获取日志对象 + private final HttpUtils httpUtils = new HttpUtils(); + // 表单字段 + private static final String MQ_SUCCESS = "mq_success"; + // 表单字段 + private static final String VMS_SUCCESS = "vms_success"; + private static final String SUCCESS = "0"; + { + httpUtils.getGlobalCache().header.put("Content-Type", MediaType.APPLICATION_JSON); // 全局请求头 + } + + + /** + *

推送数据

+ * + * @param onlyMark 唯一编码 + * @param billTable 表名 + * @param requestId 请求id + * @param vmsResponseVoField vms成功标识 + * @param config kafka配置文件名称 + * @author xuanran.wang + * @dateTime 2022/12/5 17:05 + **/ + public void workFlowToVmsAndMQ(String onlyMark, String billTable, String requestId, VmsResponseVoField vmsResponseVoField, String config) { + RequestMappingConfig requestMappingConfig = dealWithMapping.treeDealWithUniqueCode(onlyMark); // 将配置参数通过唯一标识查询处理成树形结构 + String selectMainSql = CommonUtil.getSelectSql(requestMappingConfig, billTable); + log.info(Util.logStr("查询主表数据sql : {}, requestId : {}", selectMainSql, requestId)); + RecordSet recordSet = new RecordSet(); + recordSet.executeQuery(selectMainSql, requestId); + recordSet.next(); + String url = requestMappingConfig.getRequestUrl(); + dealWithMapping.setMainTable(billTable); + Map param = dealWithMapping.getRequestParam(recordSet, requestMappingConfig); + String vmsSuccess = Util.null2DefaultStr(recordSet.getString(VMS_SUCCESS),""); + String mqSuccess = Util.null2DefaultStr(recordSet.getString(MQ_SUCCESS),""); + if(!SUCCESS.equals(vmsSuccess)){ + ResponeVo responeVo; + try { + responeVo = httpUtils.apiPost(url, param); + } catch (IOException e) { + throw new CustomerException(Util.logStr("发送请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + parseResponseVo(responeVo, url, param, vmsResponseVoField); + updateWorkFlow(VMS_SUCCESS, billTable, requestId); + } + if(!SUCCESS.equals(mqSuccess) && StringUtils.isNotBlank(config)){ + sendToMQ(config, param); + updateWorkFlow(MQ_SUCCESS, billTable, requestId); + } + } + + /** + *

解析响应对象

+ * @author xuanran.wang + * @dateTime 2022/12/23 11:25 + * @param responseVo 响应对象 + * @param url 地址 + * @param requestParam 请求 + **/ + private void parseResponseVo(ResponeVo responseVo, String url, Map requestParam, VmsResponseVoField vmsResponseVoField){ + if (responseVo.getCode() != SUCCESS_CODE) { // 相应状态码 + log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 + "this request heard is [{}],but response status code is [{}]," + + "this response is [{}]", url, JSON.toJSON(requestParam), JSON.toJSONString(httpUtils.getGlobalCache().header), responseVo.getCode(), // 相应状态码 + responseVo.getEntityString())); // 相应内容 + throw new CustomerException(Util.logStr("can not fetch [{}]", url)); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + log.info(Util.logStr("vmsResponseVoField: {}", JSONObject.toJSONString(vmsResponseVoField))); + Map response = responseVo.getResponseMap(); // 根据相应结果转化为map集合 + String successCode = Util.null2DefaultStr(response.get(vmsResponseVoField.getSuccessField()), ""); + if (!vmsResponseVoField.getSuccessVal().equals(successCode)) { + throw new CustomerException(Util.logStr("接口响应码不为 : [{}],接口响应信息: {}", successCode, Util.null2DefaultStr(response.get(vmsResponseVoField.getMessage()), ""))); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + } + + /** + *

将流程信息发送到kafka

+ * @author xuanran.wang + * @dateTime 2023/3/30 14:56 + * @param kafkaConfig kafka配置文件名称 + * @param message 消息对象 + **/ + public void sendToMQ(String kafkaConfig, Map message){ + KafkaProducer producer = null; + try { + Map configMap = Util.getProperties2Map(kafkaConfig); + if(MapUtils.isEmpty(configMap)){ + throw new CustomerException("please check /web-inf/prop2map has " + kafkaConfig + ".properties"); + } + log.info("kafkaConfig : " + JSONObject.toJSONString(configMap)); + String topic = Util.null2DefaultStr(configMap.get("topic"),""); + if(StringUtils.isBlank(topic)){ + throw new CustomerException("kafka properties topic can not null!"); + } + producer = new KafkaProducer<>(configMap); + // 发送消息到指定主题 + ProducerRecord record = new ProducerRecord<>(topic, JSONObject.toJSONString(message)); + try { + RecordMetadata recordMetadata = producer.send(record).get(); + log.info(Util.logStr("send mq recordMetadata: {}", JSONObject.toJSONString(recordMetadata))); + }catch (Exception e){ + throw new CustomerException(Util.logStr("producer send error: {}!", e.getMessage())); + } + }catch (Exception e){ + throw new CustomerException(Util.logStr("send to kafka error!: {}", e.getMessage())); + }finally { + // 关闭Kafka生产者实例 + if(producer != null){ + producer.close(); + } + } + } + + /** + *

更新流程sql

+ * @author xuanran.wang + * @dateTime 2023/3/30 19:18 + * @param field 主表字段 + * @param tableName 表名 + * @param requestId 请求id + **/ + public void updateWorkFlow(String field, String tableName, String requestId){ + String updateSQL = "update " + tableName + " set " + field + " = " + SUCCESS + " where requestid = ?"; + RecordSet recordSet = new RecordSet(); + if(!recordSet.executeUpdate(updateSQL, requestId)){ + log.error(Util.logStr("update field error! sql: {}, requestId: {}", updateSQL, requestId)); + throw new CustomerException("更新表单字段失败!"); + } + } +} + + diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusSuccess.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusSuccess.java new file mode 100644 index 0000000..75622c5 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusSuccess.java @@ -0,0 +1,26 @@ +package weaver.xuanran.wang.sh_bigdata.common.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.function.Consumer; + +/** + *

自定义请求条件

+ * + * @author xuanran.wang + * @date 2023/4/6 19:34 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CusSuccess { + private String successField; + private int successValue; + private String errorMsg; + private String dataKey; + private Object response; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusToken.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusToken.java new file mode 100644 index 0000000..1c13a1d --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/entity/CusToken.java @@ -0,0 +1,25 @@ +package weaver.xuanran.wang.sh_bigdata.common.entity; + +import lombok.Data; + +/** + *

token实体类

+ * + * @author xuanran.wang + * @date 2023/4/7 23:29 + */ +@Data +public class CusToken { + /** + *

token

+ **/ + private String access_token; + /** + *

有效时间(s)

+ **/ + private long expires_in; + /** + *

过期时间戳

+ **/ + private long expiryTime; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/RequestMasterPlate.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/RequestMasterPlate.java new file mode 100644 index 0000000..b638132 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/RequestMasterPlate.java @@ -0,0 +1,74 @@ +package weaver.xuanran.wang.sh_bigdata.common.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusSuccess; + +import java.io.IOException; +import java.util.Map; + +/** + *

请求模版方法

+ * + * @author xuanran.wang + * @date 2023/4/4 11:51 + */ +public class RequestMasterPlate{ + private final Logger log = Util.getLogger(); + private final HttpUtils httpUtils = new HttpUtils(); + private static final int HTTP_SUCCESS_CODE = 200; + + public T apiGet(String url, Map params, Map headers, CusSuccess cusSuccess){ + ResponeVo responeVo; + try { + responeVo = httpUtils.apiGet(url, params, headers); + } catch (IOException e) { + throw new CustomerException(Util.logStr("发送请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + return parseResponse(url, responeVo, params, cusSuccess); + } + + public T apiPost(String url, Object o, Map headers, CusSuccess cusSuccess){ + ResponeVo responeVo; + try { + responeVo = httpUtils.apiPostObject(url, o, headers); + } catch (IOException e) { + throw new CustomerException(Util.logStr("发送请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + return parseResponse(url, responeVo, o, cusSuccess); + } + + public T parseResponse(String url, ResponeVo responseVo, Object o, CusSuccess cusSuccess){ + if (responseVo.getCode() != HTTP_SUCCESS_CODE) { // 相应状态码 + log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 + "this request heard is [{}],but response status code is [{}]," + + "this response is [{}]", url, JSON.toJSON(o), JSON.toJSONString(httpUtils.getGlobalCache().header), responseVo.getCode(), // 相应状态码 + responseVo.getEntityString())); // 相应内容 + throw new CustomerException(Util.logStr("can not fetch [{}]", url)); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + Map response = responseVo.getResponseMap(); // 根据相应结果转化为map集合 + cusSuccess.setResponse(response); + int responseValue = Util.getIntValue(Util.null2DefaultStr(response.get(cusSuccess.getSuccessField()), ""),-1); + if (cusSuccess.getSuccessValue() != responseValue) { + throw new CustomerException(Util.logStr("接口响应码不为: [{}], 接口响应信息: {}", cusSuccess.getSuccessValue(), Util.null2DefaultStr(response.get(cusSuccess.getErrorMsg()), ""))); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 + } + String[] split = Util.null2DefaultStr(cusSuccess.getDataKey(),"").split("\\."); + int len = split.length; + if(len == 0 || StringUtils.isBlank(cusSuccess.getDataKey())){ + return (T)response; + } + for (int i = 0; i < len - 1; i++) { + response = (Map) response.get(split[i]); + } + return (T) response.get(split[len - 1]); + } + + + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java new file mode 100644 index 0000000..6810040 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/SendTodoTaskUtil.java @@ -0,0 +1,167 @@ +package weaver.xuanran.wang.sh_bigdata.common.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.workflow.request.todo.RequestStatusObj; +import weaver.xuanran.wang.common.mapper.CommonMapper; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusDoneTask; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusTodoTask; +import weaver.xuanran.wang.sh_bigdata.task_async.mapper.SendTodoTaskMapper; + +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/4/6 16:47 + */ +@Data +public class SendTodoTaskUtil { + private final SendTodoTaskMapper mapper = Util.getMapper(SendTodoTaskMapper.class); + private final CommonMapper commonMapper = Util.getMapper(CommonMapper.class); + private String appId; + private String oaAddress; + private Logger log = Util.getLogger(); + + { + oaAddress = getOAAddress(); + } + + /** + *

将待办/已办集合进行去重

+ * @author xuanran.wang + * @dateTime 2023/4/6 17:01 + * @param list 待办/已办集合 + * @return 去重后的数据 + **/ + public List distantList(List list){ + if(CollectionUtils.isEmpty(list)){ + return new ArrayList<>(); + } + HashMap obj = new HashMap<>(); + for (RequestStatusObj statusObj : list) { + String str = statusObj.getRequestid() + "" + statusObj.getUser().getUID(); + if(obj.containsKey(str)){ + continue; + } + obj.put(str, statusObj); + } + return new ArrayList<>(obj.values()); + } + + /** + *

将oa任务对象转换成三方系统任务对象

+ * @author xuanran.wang + * @dateTime 2023/4/6 17:29 + * @param objs 任务对象 + * @return 三方系统任务接收对象 + **/ + public List getTodoTaskInfo(List objs){ + ArrayList res = new ArrayList<>(); + for (RequestStatusObj obj : objs) { + String taskId = getTaskId(0, obj); + CusTodoTask todoTask = new CusTodoTask(); + int requestId = obj.getRequestid(); + int userId = obj.getUser().getUID(); + todoTask.setTaskNum(taskId); + todoTask.setAppId(appId); + todoTask.setTaskName(obj.getRequestnamenew()); + todoTask.setTaskDesc(obj.getRequestnamenew()); + todoTask.setLinkUrl(oaAddress + "/spa/workflow/static4form/index.html?#/main/workflow/req?requestid="+requestId); + todoTask.setMobileLinkUrl(oaAddress + "/spa/workflow/static4mobileform/index.html?#/req?requestid="+requestId); + todoTask.setSender(getConvertHrm(0, obj, obj.getCreator().getUID() + "")); + todoTask.setReceiver(getConvertHrm(1, obj,userId + "")); + res.add(todoTask); + } + return res; + } + + /** + *

将oa任务对象转换成三方系统任务对象

+ * @author xuanran.wang + * @dateTime 2023/4/6 17:29 + * @param objs 任务对象 + * @return 三方系统任务接收对象 + **/ + public List getDoneTaskInfo(List objs){ + ArrayList res = new ArrayList<>(); + for (RequestStatusObj obj : objs) { + String taskId = getTaskId(1, obj); + List list = mapper.queryUnSendTodoTaskList(taskId); + for (String num : list) { + CusDoneTask doneTask = new CusDoneTask(); + doneTask.setTaskNum(num); + doneTask.setStatus(1); + doneTask.setAppId(appId); + res.add(doneTask); + } + } + return res; + } + + /** + *

获取任务id

+ * @author xuanran.wang + * @dateTime 2023/4/9 17:25 + * @param type 任务类型 0:待办 1:已办 + * @param obj 任务对象 + * @return 任务ID + **/ + public String getTaskId(int type, RequestStatusObj obj){ + String taskId = obj.getRequestid() + "" + obj.getUser().getUID(); + if(type == 0){ + taskId += (System.currentTimeMillis() / 1000); + } + return taskId; + } + + /** + *

获取转换后的人员id

+ * @author xuanran.wang + * @dateTime 2023/4/6 16:55 + * @param type 类型 0:发送人 1:接收人 + * @param obj 任务对象 + * @param hrmId 人力资源ID + * @return 转换后的人员id + **/ + public String getConvertHrm(int type, RequestStatusObj obj, String hrmId){ + String convertSql; + if(type == 0){ + convertSql = Util.null2DefaultStr(ShBigDataUtil.getPropertiesValByKey("hrmSenderConvertRuleSql"),""); + }else { + convertSql = Util.null2DefaultStr(ShBigDataUtil.getPropertiesValByKey("hrmReceiveConvertRuleSql"),""); + } + if(StringUtils.isNotBlank(convertSql) && StringUtils.isNotBlank(hrmId)){ + List ids = Arrays.stream(hrmId.split(",")).collect(Collectors.toList()); + int requestId = obj.getRequestid(); + convertSql = convertSql + .replace("{?.requestId}", requestId + "") + .replace("{?.nodeId}",obj.getNodeid() + ""); + return Util.null2DefaultStr(StringUtils.join(mapper.selectHrmConvertId(convertSql, ids), ","),hrmId + ""); + } + return hrmId + ""; + } + + /** + *

获取oa地址

+ * @author xuanran.wang + * @dateTime 2022/12/22 13:51 + * @return OA地址 + **/ + public String getOAAddress(){ + String address = mapper.queryOAAddress(); + if(StringUtils.isBlank(address)){ + throw new CustomerException("OAAddress can not null!"); + } + return address; + } + + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java new file mode 100644 index 0000000..5688afc --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/ShBigDataUtil.java @@ -0,0 +1,120 @@ +package weaver.xuanran.wang.sh_bigdata.common.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusSuccess; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusToken; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.annotations.CusDbEntityMapping; + +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

上海大数据中心工具方法

+ * + * @author xuanran.wang + * @date 2023/4/4 11:34 + */ +public class ShBigDataUtil { + + private static final String CONFIG_NAME = "ShBigdataConf"; + + private static final List WHILTE_LIST = new ArrayList<>(); + + static { + WHILTE_LIST.add("hrmSenderConvertRuleSql"); + WHILTE_LIST.add("hrmReceiveConvertRuleSql"); + } + + /** + *

获取token

+ * @author xuanran.wang + * @dateTime 2023/4/6 19:59 + * @return token + **/ + public static String getToken(){ + return TokenUtil.getToken(); + } + + /** + *

给post请求的url添加token

+ * @author xuanran.wang + * @dateTime 2023/4/6 20:11 + * @param url 路径 + * @return 添加完token的路径url + **/ + public static String addToken2Url(String url){ + return url + "?access_token=" + getToken(); + } + + /** + *

获取配置文件

+ * @author xuanran.wang + * @dateTime 2023/4/4 11:47 + * @return 配置文件map + **/ + public static Map getConfFromProperties(){ + Map configMap = Util.getProperties2Map(CONFIG_NAME); + if(MapUtils.isEmpty(configMap)){ + throw new CustomerException(Util.logStr("/web-inf/prop/prop2map/{}.properties can not empty!", CONFIG_NAME)); + } + return configMap; + } + + /** + *

从配置文件中获取指定key的value并进行校验

+ * @author xuanran.wang + * @dateTime 2023/4/6 10:45 + * @param key 指定的key + * @return value + **/ + public static String getPropertiesValByKey(String key){ + Map conf = getConfFromProperties(); + String value = Util.null2DefaultStr(conf.get(key), ""); + if(StringUtils.isBlank(value) && !WHILTE_LIST.contains(key)){ + throw new CustomerException(Util.logStr("/web-inf/prop/prop2map/{}.properties the key = {} can not empty!",CONFIG_NAME, key)); + } + return value; + } + + /** + *

解析注解并将实体类转换成map

+ * @author xuanran.wang + * @dateTime 2023/4/6 12:27 + * @param type 表类型 0: 分部, 1: 部门 + * @param o 对象 + * @return 参数 + **/ + public static LinkedHashMap parseCusDbEntityMapping(int type, Object o) throws IllegalAccessException { + Class clazz = o.getClass(); + LinkedHashMap params = new LinkedHashMap<>(); + Field[] fields = clazz.getDeclaredFields(); + Field[] superFields = clazz.getSuperclass().getDeclaredFields(); + List collect = Arrays.stream(fields).collect(Collectors.toList()); + if(superFields.length > 0){ + collect.addAll(Arrays.stream(superFields).collect(Collectors.toList())); + } + for (Field field : collect) { + CusDbEntityMapping cusDbEntityMapping = field.getDeclaredAnnotation(CusDbEntityMapping.class); + if(cusDbEntityMapping != null){ + String[] dbFields = cusDbEntityMapping.dbFiled(); + String dbField; + if(dbFields.length == 0 || type == -1){ + dbField = field.getName(); + }else { + int index = Math.min(dbFields.length, type); + dbField = dbFields[index - 1]; + } + field.setAccessible(true); + params.put(dbField, field.get(o)); + } + } + return params; + } + + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/TokenUtil.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/TokenUtil.java new file mode 100644 index 0000000..706bf4c --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/common/util/TokenUtil.java @@ -0,0 +1,78 @@ +package weaver.xuanran.wang.sh_bigdata.common.util; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSONObject; +import org.apache.dubbo.common.serialize.fastjson.FastJsonObjectOutput; +import org.apache.log4j.Logger; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusSuccess; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusToken; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + *

token 工具类

+ * + * @author xuanran.wang + * @date 2023/4/7 23:27 + */ +public class TokenUtil { + private static final Logger log = Util.getLogger(); + private static volatile CusToken cusToken = null; + private static final CusSuccess tokenCusSuccess = CusSuccess.builder() + .successField("errcode") + .successValue(0) + .errorMsg("msg") + .dataKey("") + .build(); + private static final RequestMasterPlate requestMasterPlate = new RequestMasterPlate(); + + /** + *

获取token

+ * @author xuanran.wang + * @dateTime 2023/4/6 19:59 + * @return token + **/ + public static String getToken() { + if(cusToken == null){ + synchronized (TokenUtil.class){ + if(cusToken == null){ + return getTokenByHTTP(); + } + } + } + long expiryTime = cusToken.getExpiryTime(); + if(new Date().getTime() >= expiryTime){ + synchronized (TokenUtil.class){ + expiryTime = cusToken.getExpiryTime(); + if(new Date().getTime() >= expiryTime){ + return getTokenByHTTP(); + } + } + } + return cusToken.getAccess_token(); + } + + /** + *

从接口获取token

+ * @author xuanran.wang + * @dateTime 2023/4/7 23:49 + * @return token + **/ + private static String getTokenByHTTP(){ + HashMap params = new HashMap<>(); + // 接口调用地址 + String tokenUrl = ShBigDataUtil.getPropertiesValByKey("tokenUrl"); + // 密钥 + String corpSecret = ShBigDataUtil.getPropertiesValByKey("corpSecret"); + params.put("corpsecret", corpSecret); + Map tokenMap = requestMasterPlate.apiGet(tokenUrl, params, new HashMap<>(), tokenCusSuccess); + cusToken = JSONObject.parseObject(JSONObject.toJSONString(tokenMap), CusToken.class); + long expiryBeforeTime = Util.getIntValue(ShBigDataUtil.getPropertiesValByKey("expiryBeforeTime"), 5); + // 默认少5分钟过期 + cusToken.setExpiryTime(new Date().getTime() + (cusToken.getExpires_in() * 1000) - (60 * expiryBeforeTime * 1000)); + log.info("http token => " + JSONObject.toJSONString(cusToken)); + return cusToken.getAccess_token(); + } +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/OrganizationHrmSyncFromOtherSys.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/OrganizationHrmSyncFromOtherSys.java new file mode 100644 index 0000000..7e2b8d2 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/OrganizationHrmSyncFromOtherSys.java @@ -0,0 +1,106 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async; + +import weaver.hrm.resource.HrmSynDAO; +import weaver.interfaces.hrm.*; + +import java.util.HashMap; +import java.util.Map; + +/** + *

上海大数据中心人员/组织架构同步

+ * + * @author xuanran.wang + * @date 2023/4/4 10:21 + */ +public class OrganizationHrmSyncFromOtherSys implements HrmSynService { + private HashMap synResult; + + public OrganizationHrmSyncFromOtherSys(){ + this.removeSynResult(); + } + + @Override + public String SynTimingToOASubCompany() { + return null; + } + + @Override + public String SynTimingToOADepartment() { + return null; + } + + @Override + public String SynTimingToOAJobtitle() { + return null; + } + + @Override + public String SynTimingToOAHrmResource() { + return null; + } + + @Override + public void SynTimingFromOASubCompany(SubCompanyBean[] subCompanyBeans) { + } + + @Override + public void SynTimingFromOADepartment(DepartmentBean[] departmentBeans) { + + } + + @Override + public void SynTimingFromOAJobtitle(JobTitleBean[] jobTitleBeans) { + + } + + @Override + public void SynTimingFromOAHrmResource(UserBean[] userBeans) { + + } + + @Override + public void SynInstantSubCompany(SubCompanyBean subCompanyBean) { + + } + + @Override + public void SynInstantDepartment(DepartmentBean departmentBean) { + + } + + @Override + public void SynInstantJobtitle(JobTitleBean jobTitleBean) { + + } + + @Override + public void SynInstantHrmResource(UserBean userBean) { + + } + + @Override + public boolean SynSendMessage(String s, String s1, String s2, String s3, String s4) { + return false; + } + + @Override + public HashMap getSynResult() { + return this.synResult; + } + + @Override + public void removeSynResult() { + this.synResult = new HashMap<>(); + } + + private Map buildItemMap(String pkCode, String pk, String memo, String success, String error) { + //保存结果 + Map res = new HashMap<>(); + res.put(weaver.hrm.resource.HrmSynDAO.OUTPK, pkCode); + res.put(weaver.hrm.resource.HrmSynDAO.PK, pk); + res.put(weaver.hrm.resource.HrmSynDAO.Memo, memo); + res.put(weaver.hrm.resource.HrmSynDAO.Success, success); + res.put(HrmSynDAO.ErrorMessage, error); + return res; + } +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/annotations/CusDbEntityMapping.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/annotations/CusDbEntityMapping.java new file mode 100644 index 0000000..a377187 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/annotations/CusDbEntityMapping.java @@ -0,0 +1,16 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.annotations; + +import java.lang.annotation.*; + +/** + *

自定义实体类与数据库映射

+ * + * @author xuanran.wang + * @date 2023/4/6 11:55 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface CusDbEntityMapping { + String[] dbFiled() default {}; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/entity/OtherSysDepartment.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/entity/OtherSysDepartment.java new file mode 100644 index 0000000..aacf42a --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/entity/OtherSysDepartment.java @@ -0,0 +1,53 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity; + +import aiyh.utils.annotation.recordset.SqlDbFieldAnn; +import lombok.Data; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.annotations.CusDbEntityMapping; + +import java.util.List; + + +/** + *

上海大数据中心人员/组织架构同步 部门实体类

+ * + * @author xuanran.wang + * @date 2023/4/4 11:03 + */ +@Data +public class OtherSysDepartment { + /** + *

创建的部门id

+ **/ + @CusDbEntityMapping(dbFiled ={"outkey"}) + private int id; + /** + *

部门名称

+ **/ + @CusDbEntityMapping(dbFiled = {"subcompanyname", "departmentname"}) + private String name; + /** + *

父部门id。根部门为1

+ **/ + @CusDbEntityMapping(dbFiled = {"supsubcomid", "supdepid"}) + private int parentid; + /** + *

+ * 在父部门中的次序值。order值大的排序靠前,order值相等的情况下,按照部门id排,id越小排序越靠前。有效的值范围是[0, 2^32) + *

+ **/ + @CusDbEntityMapping(dbFiled = {"showorder"}) + private int order; + /** + *

所属分部id

+ **/ + @CusDbEntityMapping(dbFiled = {"supsubcomid","supsubcomid1"}) + private int subCompanyId; + /** + *

+ * 是否有子部门,0:否,1:是 + *

+ **/ + private int hasChild; + + private List childList; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/mapper/OrgHrmAsyncMapper.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/mapper/OrgHrmAsyncMapper.java new file mode 100644 index 0000000..769ae6f --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/mapper/OrgHrmAsyncMapper.java @@ -0,0 +1,25 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.SqlString; +import aiyh.utils.annotation.recordset.Update; +import io.swagger.models.auth.In; + +import java.util.Map; + +/** + *

组织架构同步 mapper

+ * + * @author xuanran.wang + * @date 2023/4/6 11:05 + */ +@SqlMapper +public interface OrgHrmAsyncMapper { + + @Select("select outkey, id from HrmSubCompany where outkey != '' and outkey is not null") + Map selectSubCompany(); + + @Update(custom = true) + boolean updateSubInfo(@SqlString String sql, Map params); +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncApiService.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncApiService.java new file mode 100644 index 0000000..8d23e7c --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncApiService.java @@ -0,0 +1,32 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.service; + +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OtherSysDepartment; + +import java.util.List; + +/** + *

上海大数据中心人员/组织架构同步 接口调用

+ * + * @author xuanran.wang + * @date 2023/4/4 11:09 + */ +public interface OrgHrmAsyncApiService { + + + /** + *

获取用户信息

+ * @author xuanran.wang + * @dateTime 2023/4/4 11:13 + * @return 响应对象 + **/ + List getUserInfo(); + + /** + *

获取部门信息

+ * @author xuanran.wang + * @dateTime 2023/4/4 11:13 + * @return 响应对象 + **/ + List getDepartmentInfo(); + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncService.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncService.java new file mode 100644 index 0000000..c7d1cf7 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/OrgHrmAsyncService.java @@ -0,0 +1,31 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.service; + +import io.swagger.models.auth.In; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OtherSysDepartment; + +import java.util.List; +import java.util.Map; + +/** + *

<上海大数据中心人员/组织架构同步 业务方法/h1> + * + * @author xuanran.wang + * @date 2023/4/4 11:07 + */ +public interface OrgHrmAsyncService { + + /** + *

获取分部表中 outKey 与 id对应到map集合

+ * @author xuanran.wang + * @dateTime 2023/4/6 13:44 + * @return 分部表中 outKey 与 id对应到map集合 + **/ + Map initSubCompany(); + /** + *

部门数据同步

+ * @author xuanran.wang + * @dateTime 2023/4/6 13:44 + **/ + List asyncDepartment(); + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncApiServiceImpl.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncApiServiceImpl.java new file mode 100644 index 0000000..d4ba595 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncApiServiceImpl.java @@ -0,0 +1,49 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.impl; + +import com.alibaba.fastjson.JSONObject; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusSuccess; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OtherSysDepartment; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.OrgHrmAsyncApiService; +import weaver.xuanran.wang.sh_bigdata.common.util.RequestMasterPlate; +import weaver.xuanran.wang.sh_bigdata.common.util.ShBigDataUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

+ * 上海大数据中心人员/组织架构同步 接口调用 具体业务方法 + *

+ * + * @author xuanran.wang + * @date 2023/4/4 11:24 + */ +public class OrgHrmAsyncApiServiceImpl implements OrgHrmAsyncApiService { + private final RequestMasterPlate requestMasterPlate = new RequestMasterPlate(); + @Override + public List getUserInfo() { + return null; + } + + @Override + public List getDepartmentInfo() { + String departmentInfoUrl = ShBigDataUtil.getPropertiesValByKey("departmentInfoUrl"); + HashMap params = new HashMap<>(); + params.put("access_token", ShBigDataUtil.getToken()); + CusSuccess cusSuccess = CusSuccess.builder() + .successField("code") + .successValue(0) + .errorMsg("msg") + .dataKey("data.department") + .build(); + List> list = requestMasterPlate.apiGet(departmentInfoUrl, params, new HashMap<>(), cusSuccess); + List res = new ArrayList<>(); + for (Object o : list) { + res.add(JSONObject.parseObject(JSONObject.toJSONString(o), OtherSysDepartment.class)); + } + return res; + } + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncServiceImpl.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncServiceImpl.java new file mode 100644 index 0000000..b3500d8 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/org_hrm_async/service/impl/OrgHrmAsyncServiceImpl.java @@ -0,0 +1,163 @@ +package weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.impl; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import org.apache.commons.collections.CollectionUtils; +import weaver.conn.RecordSet; +import weaver.hrm.company.SubCompanyComInfo; +import weaver.matrix.MatrixUtil; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OtherSysDepartment; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.mapper.OrgHrmAsyncMapper; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.OrgHrmAsyncApiService; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.OrgHrmAsyncService; +import weaver.xuanran.wang.sh_bigdata.common.util.ShBigDataUtil; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

组织架构同步

+ * + * @author xuanran.wang + * @date 2023/4/6 10:10 + */ +public class OrgHrmAsyncServiceImpl implements OrgHrmAsyncService { + private final OrgHrmAsyncApiService orgHrmAsyncApiService = new OrgHrmAsyncApiServiceImpl(); + + private final OrgHrmAsyncMapper orgHrmAsyncMapper = Util.getMapper(OrgHrmAsyncMapper.class); + + private final SubCompanyComInfo sci = new SubCompanyComInfo(); + + @Override + public Map initSubCompany() { + return orgHrmAsyncMapper.selectSubCompany(); + } + + @Override + public List asyncDepartment() { + List departmentInfo = orgHrmAsyncApiService.getDepartmentInfo(); + //TODO 分部(条件待确认) + List subList = departmentInfo + .stream() + .filter(item -> -1 == item.getParentid()) + .sorted(Comparator.comparing(OtherSysDepartment::getId)) + .collect(Collectors.toList()); + addHrmSubCompany(subList); + + // 过滤出父节点并根据id进行升序排序 + List rootDepList = departmentInfo + .stream() + .filter(item -> 0 == item.getHasChild() && -1 != item.getParentid()) + .sorted(Comparator.comparing(OtherSysDepartment::getId)) + .collect(Collectors.toList()); + + return null; + } + + /** + *

同步数据到分部

+ * @author xuanran.wang + * @dateTime 2023/4/6 13:37 + * @param departmentList 部门数据集合 + **/ + public void addHrmSubCompany(List departmentList){ + //新增的分部id + int subId; + char separator = weaver.general.Util.getSeparator(); + RecordSet rsSch = new RecordSet(); + // 分部数据 + Map subCompany = initSubCompany(); + for (OtherSysDepartment department : departmentList) { + subId = Util.getIntValue(Util.null2DefaultStr(subCompany.get(department.getId()),""),-1); + if(subId < 0){ + String para = department.getName() + separator + department.getName() + separator + "1" + separator + + department.getId()+ separator + "" + separator +department.getOrder(); + rsSch.executeProc("HrmSubCompany_Insert", para); + if (rsSch.next()) { + subId = rsSch.getInt(1); + } + } + updateTable("HrmSubCompany", subId, 0, department); + } + //清除全部分部缓存 + sci.removeCompanyCache(); + } + + /** + *

同步数据到分部

+ * @author xuanran.wang + * @dateTime 2023/4/6 13:37 + * @param departmentList 部门数据集合 + **/ + public void addHrmDepartment(List departmentList){ + //新增的分部id + int id = 0; + char separator = weaver.general.Util.getSeparator(); + RecordSet rsSch = new RecordSet(); + for (OtherSysDepartment department : departmentList) { + String para = department.getName() + separator + department.getName() + separator + "1" + separator + + department.getParentid() + separator + "" + separator +department.getOrder(); + rsSch.executeProc("HrmSubCompany_Insert", para); + if (rsSch.next()) { + id = rsSch.getInt(1); + updateTable("HrmSubCompany", id, 0, department); + } + } + //清除全部分部缓存 + sci.removeCompanyCache(); + } + + /** + *

更新分部数据

+ * @author xuanran.wang + * @dateTime 2023/4/6 13:35 + * @param tableName 表名 + * @param id 数据id + * @param type 类型 + * @param o 对象 + **/ + public void updateTable(String tableName, int id, int type, Object o){ + StringBuilder sb = new StringBuilder("update "); + sb.append(tableName).append(" set "); + Map params; + try { + params = ShBigDataUtil.parseCusDbEntityMapping(type, o); + }catch (Exception e){ + throw new CustomerException("parseCusDbEntityMapping error!"); + } + for (Map.Entry entry : params.entrySet()) { + sb.append(entry.getKey()) + .append(" = #{") + .append(entry.getKey()) + .append("},"); + } + sb.deleteCharAt(sb.length() - 1); + sb.append(" where id = ").append(id); + boolean success = orgHrmAsyncMapper.updateSubInfo(sb.toString(), params); + if(!success){ + throw new CustomerException(Util.logStr("update {} sql error!", tableName)); + } + //同步分部数据到矩阵 + MatrixUtil.updateSubcompayData(String.valueOf(id)); + } + + public void setChildList(List departmentList){ + if(departmentList.size() == 0){ + return; + } + for (OtherSysDepartment department : departmentList) { + List childList = departmentList + .stream() + .filter(item -> department.getId() == item.getParentid()) + .collect(Collectors.toList()); + department.setChildList(childList); + if(CollectionUtils.isNotEmpty(childList)){ + setChildList(childList); + } + } + } + + +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/SendTodoTaskImpl.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/SendTodoTaskImpl.java new file mode 100644 index 0000000..3b205dc --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/SendTodoTaskImpl.java @@ -0,0 +1,162 @@ +package weaver.xuanran.wang.sh_bigdata.task_async; + +import aiyh.utils.ThreadPoolConfig; +import aiyh.utils.Util; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.ofs.interfaces.SendRequestStatusDataInterfaces; +import weaver.workflow.request.todo.DataObj; +import weaver.workflow.request.todo.RequestStatusObj; +import weaver.xuanran.wang.sh_bigdata.common.util.SendTodoTaskUtil; +import weaver.xuanran.wang.sh_bigdata.task_async.service.impl.SendTodoTaskServiceImpl; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; + +/** + *

上海大数据中心统一待办推送

+ * + * @author xuanran.wang + * @date 2023/4/6 15:43 + */ +public class SendTodoTaskImpl implements SendRequestStatusDataInterfaces { + /** + * 后台设置id + */ + public String id; + /** + * 设置的系统编号 + */ + public String syscode; + /** + * 服务器URL + */ + public String serverurl; + /** + * 流程白名单 + */ + public ArrayList workflowwhitelist; + /** + * 人员白名单 + */ + public ArrayList userwhitelist; + + + public String getId() { + return id; + } + + public String getSyscode() { + return syscode; + } + + public String getServerurl() { + return serverurl; + } + + public ArrayList getWorkflowwhitelist() { + return workflowwhitelist; + } + + public ArrayList getUserwhitelist() { + return userwhitelist; + } + + + private final SendTodoTaskServiceImpl sendTodoTaskService = new SendTodoTaskServiceImpl(); + private final ExecutorService pool = ThreadPoolConfig.createThreadPoolInstance(); + private final SendTodoTaskUtil sendTodoTaskUtil = new SendTodoTaskUtil(); + private final Logger log = Util.getLogger(); + + @Override + public void SendRequestStatusData(ArrayList dataList) { + for (DataObj dataObj : dataList) { + List todoList = sendTodoTaskUtil.distantList(dataObj.getTododatas()); + List doneList = sendTodoTaskUtil.distantList(dataObj.getDonedatas()); + try { + pool.execute(() -> { + log.info("todoList => \n" + JSONObject.toJSONString(todoList)); + log.info("doneList => \n" + JSONObject.toJSONString(doneList)); + if (CollectionUtils.isNotEmpty(todoList)) { + sendTodoTaskService.sendTodo(todoList); + } + if (CollectionUtils.isNotEmpty(doneList)) { + sendTodoTaskService.sendDone(doneList); + } + }); + } catch (Exception e) { + log.error("SendTodoTaskImpl error! " + e.getMessage()); + } + } + } + + /** + * 格式化JSON格式输出 + * + * @param jsonStr + * @return 返回指定格式化的数据 + */ + public static String formatJson(String jsonStr) { + if (null == jsonStr || "".equals(jsonStr)) + return ""; + StringBuilder sb = new StringBuilder(); + char last = '\0'; + char current = '\0'; + int indent = 0; + boolean isInQuotationMarks = false; + for (int i = 0; i < jsonStr.length(); i++) { + last = current; + current = jsonStr.charAt(i); + switch (current) { + case '"': + if (last != '\\') { + isInQuotationMarks = !isInQuotationMarks; + } + sb.append(current); + break; + case '{': + case '[': + sb.append(current); + if (!isInQuotationMarks) { + sb.append('\n'); + indent++; + addIndentBlank(sb, indent); + } + break; + case '}': + case ']': + + if (!isInQuotationMarks) { + sb.append('\n'); + indent--; + addIndentBlank(sb, indent); + } + sb.append(current); + break; + case ',': + sb.append(current); + break; + default: + sb.append(current); + } + } + + return sb.toString(); + } + + /** + * 添加space(缩进) + * + * @param sb + * @param indent + */ + private static void addIndentBlank(StringBuilder sb, int indent) { + for (int i = 0; i < indent; i++) { + sb.append('\t'); + } + } + +} \ No newline at end of file diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTask.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTask.java new file mode 100644 index 0000000..a69e3e9 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTask.java @@ -0,0 +1,23 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.entity; + +import aiyh.utils.annotation.recordset.SqlOracleDbFieldAnn; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import weaver.xuanran.wang.common.annocation.SqlFieldMapping; + +/** + *

已办实体

+ * + * @author xuanran.wang + * @date 2023/4/6 22:21 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CusDoneTask { + @SqlFieldMapping + private String taskNum; + private int status; + private String appId; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTaskOA.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTaskOA.java new file mode 100644 index 0000000..8b3da57 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusDoneTaskOA.java @@ -0,0 +1,39 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import weaver.xuanran.wang.common.annocation.SqlFieldMapping; + +/** + *

已办oa实体类

+ * + * @author xuanran.wang + * @date 2023/4/7 13:19 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CusDoneTaskOA extends CusDoneTask{ + @SqlFieldMapping + private String sourceTaskId; + @SqlFieldMapping + private String response; + @SqlFieldMapping + private String requestJson; + @SqlFieldMapping + private int success; + @SqlFieldMapping + private String requestUrl; + @SqlFieldMapping + private int taskType; + @SqlFieldMapping + private String sendTime; + /** + *

异常

+ **/ + @SqlFieldMapping + private String error; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java new file mode 100644 index 0000000..fe8a8a8 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTask.java @@ -0,0 +1,29 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import weaver.xuanran.wang.common.annocation.SqlFieldMapping; +import weaver.xuanran.wang.common.annocation.SqlUpdateWhereField; + +/** + *

待办实体

+ * + * @author xuanran.wang + * @date 2023/4/6 16:27 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CusTodoTask { + @SqlFieldMapping + protected String taskNum; + protected String appId; + @SqlFieldMapping + protected String taskName; + protected String taskDesc; + protected String linkUrl; + protected String mobileLinkUrl; + protected String receiver; + protected String sender; +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTaskToOADetail.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTaskToOADetail.java new file mode 100644 index 0000000..ab804ce --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/entity/CusTodoTaskToOADetail.java @@ -0,0 +1,68 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import weaver.xuanran.wang.common.annocation.SqlFieldMapping; +import weaver.xuanran.wang.common.annocation.SqlUpdateWhereField; + +/** + *

写入oa日志表的实体

+ * + * @author xuanran.wang + * @date 2023/4/6 20:18 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +public class CusTodoTaskToOADetail extends CusTodoTask{ + /** + *

任务类型

+ **/ + @SqlFieldMapping + private int taskType; + /** + *

请求路径

+ **/ + @SqlFieldMapping + private String requestUrl; + /** + *

接口响应

+ **/ + @SqlFieldMapping + private String response; + /** + *

任务源id

+ **/ + @SqlFieldMapping + @SqlUpdateWhereField + private String sourceTaskId; + /** + *

成功/失败

+ **/ + @SqlFieldMapping + private int success; + /** + *

已办发送状态

+ **/ + @SqlFieldMapping + private int status; + /** + *

待办json

+ **/ + @SqlFieldMapping + private String requestJson; + /** + *

发送时间

+ **/ + @SqlFieldMapping + private String sendTime; + /** + *

异常

+ **/ + @SqlFieldMapping + private String error; + public CusTodoTaskToOADetail() { + super(); + } +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/mapper/SendTodoTaskMapper.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/mapper/SendTodoTaskMapper.java new file mode 100644 index 0000000..360a26a --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/mapper/SendTodoTaskMapper.java @@ -0,0 +1,30 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.mapper; + +import aiyh.utils.annotation.recordset.*; + +import java.util.List; +import java.util.Map; + +/** + *

统一待办推送mapper

+ * + * @author xuanran.wang + * @date 2023/4/6 16:49 + */ +@SqlMapper +public interface SendTodoTaskMapper { + @Select("select hrmtransrule from ofs_sendinfo where syscode = #{sysCode}") + String querySendTodoUserConvert(@ParamMapper("sysCode") String sysCode); + @Select("select oaaddress from systemset") + String queryOAAddress(); + + @Select("select taskNum from uf_todo_task_log " + + "where sourceTaskId = #{sourceTaskId} and taskType = 0 and status = 0 and success = 0") + List queryUnSendTodoTaskList(@ParamMapper("sourceTaskId") String sourceTaskId); + + @Update("update uf_todo_task_log set status = 1 where taskNum in (${taskNums})") + boolean updateStatusByTaskNum(@ParamMapper("taskNums") List taskNums); + + @Select(custom = true) + List selectHrmConvertId(@SqlString String sql, @ParamMapper("ids") List ids); +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/SendTodoTaskService.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/SendTodoTaskService.java new file mode 100644 index 0000000..e90d8a7 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/SendTodoTaskService.java @@ -0,0 +1,16 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.service; + +import weaver.workflow.request.todo.RequestStatusObj; + +import java.util.List; + +/** + *

发送待办和已办

+ * + * @author xuanran.wang + * @date 2023/4/6 16:31 + */ +public interface SendTodoTaskService { + void sendTodo(List todoList); + void sendDone(List doneList); +} diff --git a/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/impl/SendTodoTaskServiceImpl.java b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/impl/SendTodoTaskServiceImpl.java new file mode 100644 index 0000000..748848b --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/sh_bigdata/task_async/service/impl/SendTodoTaskServiceImpl.java @@ -0,0 +1,152 @@ +package weaver.xuanran.wang.sh_bigdata.task_async.service.impl; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import weaver.general.TimeUtil; +import weaver.workflow.request.todo.RequestStatusObj; +import weaver.xuanran.wang.common.util.CusInfoToOAUtil; +import weaver.xuanran.wang.sh_bigdata.common.entity.CusSuccess; +import weaver.xuanran.wang.sh_bigdata.common.util.RequestMasterPlate; +import weaver.xuanran.wang.sh_bigdata.common.util.ShBigDataUtil; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusDoneTask; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusDoneTaskOA; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusTodoTask; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusTodoTaskToOADetail; +import weaver.xuanran.wang.sh_bigdata.task_async.mapper.SendTodoTaskMapper; +import weaver.xuanran.wang.sh_bigdata.task_async.service.SendTodoTaskService; +import weaver.xuanran.wang.sh_bigdata.common.util.SendTodoTaskUtil; + +import javax.ws.rs.core.MediaType; +import java.util.*; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/4/6 16:46 + */ +@Data +public class SendTodoTaskServiceImpl implements SendTodoTaskService { + private final Logger log = Util.getLogger(); + private String appId; + private final SendTodoTaskUtil sendTodoTaskUtil = new SendTodoTaskUtil(); + private String addTodoTaskUrl; + private String updateTodoTaskUrl; + private static final String MODEL_NAME = "uf_todo_task_log"; + private final HashMap header = new HashMap<>(); + private int modelId; + private final RequestMasterPlate requestMasterPlate = new RequestMasterPlate(); + private final SendTodoTaskMapper mapper = Util.getMapper(SendTodoTaskMapper.class); + + + { + sendTodoTaskUtil.setAppId(ShBigDataUtil.getPropertiesValByKey("appId")); + modelId = Util.getIntValue(ShBigDataUtil.getPropertiesValByKey("modelId"),-1); + addTodoTaskUrl = ShBigDataUtil.getPropertiesValByKey("addTodoTaskUrl"); + updateTodoTaskUrl = ShBigDataUtil.getPropertiesValByKey("updateTodoTaskUrl"); + header.put("Content-Type", MediaType.APPLICATION_JSON); + } + + @Override + public void sendTodo(List todoList) { + try { + CusSuccess cusSuccess = CusSuccess.builder() + .successField("code") + .successValue(200) + .errorMsg("msg") + .dataKey("") + .build(); + + List taskInfo = sendTodoTaskUtil.getTodoTaskInfo(todoList); + log.info("---------------- todoTaskInfo ---------------- \n" + JSONObject.toJSONString(taskInfo)); + Map response = null; + int success = 0; + String error = null; + try { + response = requestMasterPlate.apiPost(ShBigDataUtil.addToken2Url(addTodoTaskUrl), taskInfo, header, cusSuccess); + }catch (Exception e){ + log.error("Send Todo API Post Error! " + Util.getErrString(e)); + error = "Send Todo API Post Error! " + e.getMessage(); + success = 1; + } + ArrayList details = new ArrayList<>(); + for (CusTodoTask cusTodoTask : taskInfo) { + + CusTodoTaskToOADetail detail = new CusTodoTaskToOADetail(); + detail.setTaskNum(cusTodoTask.getTaskNum()); + detail.setRequestUrl(addTodoTaskUrl); + detail.setTaskName(cusTodoTask.getTaskName()); + detail.setTaskType(0); + detail.setStatus(0); + detail.setSuccess(success); + detail.setResponse(JSONObject.toJSONString(cusSuccess.getResponse() == null ? response : cusSuccess.getResponse())); + detail.setRequestJson(JSONObject.toJSONString(cusTodoTask)); + String sourceTaskId = detail.getTaskNum().substring(0, detail.getTaskNum().length() - 10); + detail.setSourceTaskId(sourceTaskId); + detail.setSendTime(TimeUtil.getCurrentTimeString()); + detail.setError(error); + details.add(detail); + } + CusInfoToOAUtil.executeBatchByEntity(modelId, details,""); + }catch (Exception e){ + log.error("send todo error! " + Util.getErrString(e)); + } + + + } + + @Override + public void sendDone(List doneList) { + try { + CusSuccess cusSuccess = CusSuccess.builder() + .successField("code") + .successValue(200) + .errorMsg("msg") + .dataKey("") + .build(); + + List doneTaskInfo = sendTodoTaskUtil.getDoneTaskInfo(doneList); + log.info("---------------- doneTaskInfo ---------------- \n" + JSONObject.toJSONString(doneTaskInfo)); + Map response = null; + ArrayList list = new ArrayList<>(); + ArrayList successTaskIds = new ArrayList<>(); + String error = ""; + for (CusDoneTask doneTask : doneTaskInfo) { + int success = 0; + try { + response = requestMasterPlate.apiPost(ShBigDataUtil.addToken2Url(updateTodoTaskUrl), doneTask, header, cusSuccess); + successTaskIds.add(doneTask.getTaskNum()); + }catch (Exception e){ + log.error("Send Todo API Post Error! " + Util.getErrString(e)); + error = "Send Todo API Post Error! " + Util.getErrString(e); + success = 1; + } + CusDoneTaskOA taskOA = new CusDoneTaskOA(); + taskOA.setTaskNum(doneTask.getTaskNum()); + taskOA.setTaskType(1); + String sourceTaskId = doneTask.getTaskNum().substring(0, doneTask.getTaskNum().length() - 10); + taskOA.setSourceTaskId(sourceTaskId); + taskOA.setResponse(JSONObject.toJSONString(cusSuccess.getResponse() == null ? response : cusSuccess.getResponse())); + taskOA.setRequestUrl(updateTodoTaskUrl); + taskOA.setRequestJson(JSONObject.toJSONString(doneTask)); + taskOA.setSuccess(success); + taskOA.setSendTime(TimeUtil.getCurrentTimeString()); + taskOA.setError(error); + list.add(taskOA); + } + CusInfoToOAUtil.executeBatchByEntity(modelId, list,""); + if(CollectionUtils.isNotEmpty(successTaskIds)){ + mapper.updateStatusByTaskNum(successTaskIds); + } + }catch (Exception e){ + log.error("send done error! " + Util.getErrString(e)); + } + } + + +} diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/entity/MQMessage.java b/src/main/java/weaver/xuanran/wang/shyl_mq/entity/MQMessage.java index ae01080..1972dd0 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/entity/MQMessage.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/entity/MQMessage.java @@ -24,7 +24,7 @@ public class MQMessage { * AUTH_CONSOLE_USERINFO_PASSWORD_TOPIC: 密码修改队列 *

**/ - @SqlFieldMapping() + @SqlFieldMapping private String topic; /** *

消息内容操作类型

@@ -35,19 +35,19 @@ public class MQMessage { * PASSWORD_ACTION: 修改密码 *

**/ - @SqlFieldMapping() + @SqlFieldMapping private String actionType; /** *

消息发送时间

**/ - @SqlFieldMapping() + @SqlFieldMapping private String sendTime; /** *

消息业务内容,json 格式,分业务(用户、机构、密码修改)

**/ - @SqlFieldMapping() + @SqlFieldMapping private String content; - @SqlFieldMapping() + @SqlFieldMapping private String error; } diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/mapper/ConsumerMapper.java b/src/main/java/weaver/xuanran/wang/shyl_mq/mapper/ConsumerMapper.java index 1d6bab2..e1ec671 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/mapper/ConsumerMapper.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/mapper/ConsumerMapper.java @@ -100,7 +100,7 @@ public interface ConsumerMapper { * @param id id * @return true/false **/ - @Delete("delete from hrmresource where id = #{id}") + @Delete("update hrmresource set status = 7 where id = #{id}") boolean deleteHrmById(@ParamMapper("id") String id); /** @@ -115,4 +115,8 @@ public interface ConsumerMapper { @Select("select count(1) from uf_mqLog where messageId = #{messageId}") int getMainIdFromMQLogByMessageId(@ParamMapper("messageId") String messageId); + + @Update("update hrmresource set loginId = #{loginId} where id = #{id}") + boolean updateHrmLoginIdById(@ParamMapper("id") String id, + @ParamMapper("loginId") String loginId); } diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/service/ProducerService.java b/src/main/java/weaver/xuanran/wang/shyl_mq/service/ProducerService.java index 75c5bbc..e6ad383 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/service/ProducerService.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/service/ProducerService.java @@ -29,7 +29,7 @@ public class ProducerService { private final Logger logger = Util.getLogger(); private final DealWithMapping dealWithMapping = new DealWithMapping(); - private final ToolUtil toolUtil = new ToolUtil(); + private final HttpUtils httpUtils = new HttpUtils(); { @@ -54,7 +54,7 @@ public class ProducerService { ChangeRequestParam changeRequestParam){ RequestMappingConfig requestMappingConfig = dealWithMapping.treeDealWithUniqueCode(onlyMark); String selectMainSql = CommonUtil.getSelectSql(requestMappingConfig, tableName); - logger.info("查询主表sql : " + selectMainSql); +// logger.info("查询主表sql : " + selectMainSql); RecordSet recordSet = new RecordSet(); recordSet.executeQuery(selectMainSql, requestId); Map requestParam = new HashMap<>(); @@ -69,10 +69,6 @@ public class ProducerService { if(!Objects.isNull(changeRequestParam)){ changeRequestParam.changeRequestParam(requestParam); } -// logger.info(Util.logStr("requestId : {}, msg:{}", requestId, JSONObject.toJSONString(requestParam))); - String sendMQ = Util.null2DefaultStr(toolUtil.getSystemParamValue("sendMQ"),""); - if("1".equals(sendMQ)){ - RocketConsumerUtil.producerSendMsg(configName,JSONObject.toJSONString(requestParam), requestId); - } + RocketConsumerUtil.producerSendMsg(configName, JSONObject.toJSONString(requestParam), requestId); } } diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/PassWordServiceImpl.java b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/PassWordServiceImpl.java index b9cf11a..4a5198c 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/PassWordServiceImpl.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/PassWordServiceImpl.java @@ -42,14 +42,14 @@ public class PassWordServiceImpl extends CusInfoActionService { String content = message.getContent(); ModifyPassWord passWord = JSONObject.parseObject(content, ModifyPassWord.class); logger.info(Util.logStr("cusPassWordAction messageId: {},UserInfo : {} ",message.getId(),JSONObject.toJSONString(passWord))); - String outKey = passWord.getId(); - String hrmId = consumerMapper.getHrmIdByOutKey(outKey); - if(StringUtils.isBlank(hrmId)){ - throw new CustomerException(Util.logStr("the userId is {} , no personnel information found in oa!", outKey)); - } - if (!consumerMapper.updatePasswordById(hrmId, Util.getEncrypt(passWord.getPassword()))) { - throw new CustomerException("update user password error!"); - } +// String outKey = passWord.getId(); +// String hrmId = consumerMapper.getHrmIdByOutKey(outKey); +// if(StringUtils.isBlank(hrmId)){ +// throw new CustomerException(Util.logStr("the userId is {} , no personnel information found in oa!", outKey)); +// } +// if (!consumerMapper.updatePasswordById(hrmId, Util.getEncrypt(passWord.getPassword()))) { +// throw new CustomerException("update user password error!"); +// } writeInOA(message.getId()); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } catch (Exception e) { diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..8a126d0 --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImpl.java @@ -0,0 +1,124 @@ +package weaver.xuanran.wang.shyl_mq.service.impl; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; +import weaver.hrm.resource.ResourceComInfo; +import weaver.xuanran.wang.shyl_mq.entity.MQMessage; +import weaver.xuanran.wang.shyl_mq.entity.UserInfo; +import weaver.xuanran.wang.shyl_mq.service.CusInfoActionService; + + +/** + *

用户业务方法

+ * + * @Author xuanran.wang + * @Date 2022/12/30 13:04 + */ +public class UserServiceImpl extends CusInfoActionService { + private Logger logger = Util.getLogger("mq-consumer-user"); + + { + if(null == logger){ + logger = Util.getLogger("mq-consumer-user"); + } + } + + /** + *

用户新增

+ * @author xuanran.wang + * @dateTime 2023/1/3 13:37 + * @param message mq消息 + * @return 成功/重试 + **/ + @Override + public ConsumeConcurrentlyStatus cusCreateAction(MQMessage message) { + try { + String content = message.getContent(); + UserInfo userInfo = JSONObject.parseObject(content, UserInfo.class); + logger.info(Util.logStr("userCusCreateAction messageId: {}, UserInfo : {} ",message.getId(), JSONObject.toJSONString(userInfo))); + updateLoginId(userInfo); + writeInOA(message.getId()); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + }catch (Exception e){ + throw new CustomerException(Util.logStr("hrmCreateAction error : {}", e.getMessage())); + } + } + + /** + *

用户删除

+ * @author xuanran.wang + * @dateTime 2023/1/3 13:38 + * @param message mq消息 + * @return 成功/重试 + **/ + @Override + public ConsumeConcurrentlyStatus cusDeleteAction(MQMessage message) { + try { + String content = message.getContent(); + UserInfo userInfo = JSONObject.parseObject(content, UserInfo.class); + logger.info(Util.logStr("userCusDeleteAction messageId: {},UserInfo : {} ", message.getId(),JSONObject.toJSONString(userInfo))); + String id = Util.null2DefaultStr(userInfo.getId(),""); + if(StringUtils.isBlank(id)){ + throw new CustomerException("del user id not null!"); + } + if (!consumerMapper.deleteHrmById(id)) { + throw new CustomerException("del user sql execute error!"); + } + ResourceComInfo resourceComInfo = new ResourceComInfo(); + resourceComInfo.updateResourceInfoCache(id); + writeInOA(message.getId()); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } catch (Exception e) { + throw new CustomerException(Util.logStr("hrmDeleteAction execute error : [{}]!", e.getMessage())); + } + } + + /** + *

用户更新

+ * @author xuanran.wang + * @dateTime 2023/1/3 13:39 + * @param message mq消息 + * @return 成功/重试 + **/ + @Override + public ConsumeConcurrentlyStatus cusUpdateAction(MQMessage message) { + try { + String content = message.getContent(); + UserInfo userInfo = JSONObject.parseObject(content, UserInfo.class); + logger.info(Util.logStr("userCusUpdateAction messageId: {},UserInfo : {} ", message.getId(), JSONObject.toJSONString(userInfo))); + updateLoginId(userInfo); + writeInOA(message.getId()); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + }catch (Exception e){ + throw new CustomerException(Util.logStr("userCusUpdateAction execute error : [{}]!", e.getMessage())); + } + } + /** + *

<更新登陆名/h1> + * @author xuanran.wang + * @dateTime 2023/3/28 13:07 + * @param userInfo 用户实体 + **/ + public void updateLoginId(UserInfo userInfo) throws Exception { + String id = Util.null2DefaultStr(userInfo.getId(),""); + String userName = Util.null2DefaultStr(userInfo.getUserName(),""); + if(StringUtils.isBlank(id) || StringUtils.isBlank(userName)){ + throw new CustomerException("create user id or userName can not null!"); + } + if (!consumerMapper.updateHrmLoginIdById(id, userName)) { + throw new CustomerException("update loginId sql execute error!"); + } + ResourceComInfo resourceComInfo = new ResourceComInfo(); + // 清空缓存 + resourceComInfo.updateResourceInfoCache(id); + } + + @Override + public ConsumeConcurrentlyStatus cusPassWordAction(MQMessage message) { + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } +} diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java index 759e1e2..3f97c57 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/service/impl/UserServiceImplBack.java @@ -22,12 +22,12 @@ import java.util.List; import java.util.Map; /** - *

用户业务方法

+ *

用户业务方法-废弃

* * @Author xuanran.wang * @Date 2022/12/30 13:04 */ -public class UserServiceImpl extends CusInfoActionService { +public class UserServiceImplBack extends CusInfoActionService { private Logger logger = Util.getLogger("mq-consumer-user"); { diff --git a/src/main/java/weaver/xuanran/wang/shyl_mq/util/RocketConsumerUtil.java b/src/main/java/weaver/xuanran/wang/shyl_mq/util/RocketConsumerUtil.java index a27c413..c6b564d 100644 --- a/src/main/java/weaver/xuanran/wang/shyl_mq/util/RocketConsumerUtil.java +++ b/src/main/java/weaver/xuanran/wang/shyl_mq/util/RocketConsumerUtil.java @@ -1,4 +1,4 @@ -package weaver.xuanran.wang.shyl_mq.util;//package weaver.xuanran.wang.shyl.mq.util; +package weaver.xuanran.wang.shyl_mq.util; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; @@ -37,15 +37,21 @@ import java.util.*; */ public class RocketConsumerUtil { private static Logger log = Util.getLogger("mq-util"); + + private static Logger producerLog = Util.getLogger("mq-producer"); private static final ConsumerMapper consumerMapper = Util.getMapper(ConsumerMapper.class); private static final ToolUtil tool = new ToolUtil(); private static final int ERROR_LOG_ID; + private static final ToolUtil toolUtil = new ToolUtil(); static { ERROR_LOG_ID = Util.getIntValue(tool.getSystemParamValue("mqErrorLogModelId"), -1); if(log == null){ log = Util.getLogger("mq-util"); } + if(producerLog == null){ + producerLog = Util.getLogger("mq-producer"); + } } /** @@ -83,7 +89,7 @@ public class RocketConsumerUtil { CusInfoActionService cusInfoActionService, String configName){ Map configMap = RocketMQFactory.CONFIG_MAPS.get(configName); int maxReconsumeTimes = Util.getIntValue(Util.null2String(configMap.get("MaxReconsumeTimes")), RocketMQConstant.DEFAULT_MAX_RECONSUME_TIMES); - MessageExt messageExt = null; + MessageExt messageExt; String msgBody = ""; String mqMessageId = ""; MQMessage mqMessage = null; @@ -143,7 +149,7 @@ public class RocketConsumerUtil { mqMessage.setError(e.getMessage()); List ids = CusInfoToOAUtil.executeBatchByEntity(ERROR_LOG_ID, Collections.singletonList(mqMessage), ""); if(CollectionUtils.isEmpty(ids)){ - log.error("insert into mq_error_log failed!"); + log.error(Util.logStr("messageId : {}, insert into mq_error_log failed!", mqMessageId)); } } log.error(Util.logStr("MQ producer error already bigger maxReconsumeTimes! messageId : {}",mqMessageId)); @@ -164,6 +170,10 @@ public class RocketConsumerUtil { * @param requestId 请求id **/ public static void producerSendMsg(String configName, String msg, String requestId) { + String sendMQ = Util.null2DefaultStr(toolUtil.getSystemParamValue("sendMQ"),""); + if(!"1".equals(sendMQ)){ + return; + } // 先从本地缓存中获取生产者对象 DefaultMQProducer producer = RocketMQFactory.getMQProducer(configName); // 获取配置信息 @@ -171,9 +181,10 @@ public class RocketConsumerUtil { // 队列名 String topic = Util.null2DefaultStr(configMap.get("Topic"), ""); // tag - String tag = Util.null2DefaultStr(configMap.get("Tag"), ""); +// String tag = Util.null2DefaultStr(configMap.get("Tag"), ""); Message message; try { + producerLog.info(Util.logStr("requestId: {}, msg: {}", requestId, msg)); message = new Message(topic, msg.getBytes(RemotingHelper.DEFAULT_CHARSET)); } catch (Exception e) { throw new CustomerException(Util.logStr("init message error : {} !", e.getMessage())); @@ -190,12 +201,12 @@ public class RocketConsumerUtil { } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) { throw new CustomerException(Util.logStr("producer send message error!: {}", e.getMessage())); } - log.info(Util.logStr("requestId: {}, result : {}",requestId, JSONObject.toJSONString(result))); + producerLog.info(Util.logStr("requestId: {}, result : {}",requestId, JSONObject.toJSONString(result))); SendStatus sendStatus = result.getSendStatus(); // 如果失败 if (!SendStatus.SEND_OK.equals(sendStatus)) { String error = Util.logStr("producer send message call back status is not ok! the message is {}, the status is {}.", msg, sendStatus); - log.error(error); + producerLog.error(error); // 如果重试超过最大次数 if(count >= RocketMQConstant.SEND_MAX_COUNT){ throw new CustomerException(error + " and retry > max"); diff --git a/src/main/resources/WEB-INF/prop/prop2map/OACarTest.properties b/src/main/resources/WEB-INF/prop/prop2map/OACarTest.properties new file mode 100644 index 0000000..516ecc6 --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/OACarTest.properties @@ -0,0 +1,5 @@ +producerGroup=weaver-car +serverAddr=114.115.168.220:9876 +topic=AUTH_CONSOLE_ORG_TOPIC +tag=* +consumerGroup=weaver-car-consumer diff --git a/src/main/resources/WEB-INF/prop/prop2map/ShBigdataConf.properties b/src/main/resources/WEB-INF/prop/prop2map/ShBigdataConf.properties new file mode 100644 index 0000000..448dd3f --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/ShBigdataConf.properties @@ -0,0 +1,24 @@ +# ??????? +corpSecret=5eab6957b4944d75acfa9cfcc8feff5a +agentId=10000060 +corpId=wwdbb6b075752cc1b9 +# ??token??? +tokenUrl=http://ramos-develop.shdata.com:11080/uranus/cgi-bin/gettoken +# ?????? +userInfoUrl=http://ramos-develop.shdata.com:11080/uranus/cgi-bin/request/user/get +# ?????? +departmentInfoUrl=http://ramos-develop.shdata.com:11080/uranus/cgi-bin/request/department/list +# ?????? +addTodoTaskUrl=http://ramos-develop.shdata.com:11080/uranus/cgi-bin/request/task/create +# ?????? +updateTodoTaskUrl=http://ramos-develop.shdata.com:11080/uranus/cgi-bin/request/task/update +# ?????????appId +appId=wwdbb6b075752cc1b9 +# ????????????ID +modelId=112 +# ???????????sql ????????outkey ??sql?? select outkey from hrmresource where id in (${ids}) ?? +hrmSenderConvertRuleSql=select lastname from hrmresource where id in (${ids}) +# ????? +hrmReceiveConvertRuleSql=select lastname from hrmresource where id in (${ids}) +# oa token?????????? +expiryBeforeTime=5 \ No newline at end of file diff --git a/src/main/resources/WEB-INF/prop/prop2map/VmsKafka.properties b/src/main/resources/WEB-INF/prop/prop2map/VmsKafka.properties new file mode 100644 index 0000000..33eb23e --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/VmsKafka.properties @@ -0,0 +1,5 @@ +bootstrap.servers=10.184.42.41:9094,10.184.42.42:9094,10.184.42.40:9094 +acks=all +retries=1 +key.serializer=org.apache.kafka.common.serialization.StringSerializer +value.serializer=org.apache.kafka.common.serialization.StringSerializer \ No newline at end of file diff --git a/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java b/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java index c1ea590..cadd360 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java +++ b/src/test/java/xuanran/wang/http_test/annotations/CusRequestClient.java @@ -1,5 +1,9 @@ package xuanran.wang.http_test.annotations; +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.request_type.CusRequestType; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + import java.lang.annotation.*; /** @@ -11,5 +15,10 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented +@CusRequestAddress() public @interface CusRequestClient { + @AliasFor(annotation = CusRequestAddress.class, attribute = "host") + String host() default ""; + @AliasFor(annotation = CusRequestAddress.class, attribute = "port") + int port() default 0; } diff --git a/src/test/java/xuanran/wang/http_test/annotations/CusRequestUrl.java b/src/test/java/xuanran/wang/http_test/annotations/CusRequestUrl.java new file mode 100644 index 0000000..299db5e --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/CusRequestUrl.java @@ -0,0 +1,16 @@ +package xuanran.wang.http_test.annotations; + +import java.lang.annotation.*; + +/** + *

请求地址

+ * + * @author xuanran.wang + * @date 2023/3/16 19:59 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Documented +public @interface CusRequestUrl { + String url(); +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/body/CusRequestBody.java b/src/test/java/xuanran/wang/http_test/annotations/body/CusRequestBody.java new file mode 100644 index 0000000..0b72ed0 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/body/CusRequestBody.java @@ -0,0 +1,16 @@ +package xuanran.wang.http_test.annotations.body; + +import java.lang.annotation.*; + +/** + *

请求体

+ * + * @author xuanran.wang + * @date 2023/3/20 21:27 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +@Documented +public @interface CusRequestBody { + +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/handle/CusHandle.java b/src/test/java/xuanran/wang/http_test/annotations/handle/CusHandle.java new file mode 100644 index 0000000..ee01d9c --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/handle/CusHandle.java @@ -0,0 +1,16 @@ +package xuanran.wang.http_test.annotations.handle; + +import java.lang.annotation.*; + +/** + *

自定义handle注解

+ * + * @author xuanran.wang + * @date 2023/3/16 15:37 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface CusHandle { + int order() default 0; +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/handle/CusPreLoadHandle.java b/src/test/java/xuanran/wang/http_test/annotations/handle/CusPreLoadHandle.java new file mode 100644 index 0000000..54e9634 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/handle/CusPreLoadHandle.java @@ -0,0 +1,23 @@ +package xuanran.wang.http_test.annotations.handle; + +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.annotations.request_type.CusRequestType; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + +import java.lang.annotation.*; + +/** + *

请求前置加载

+ * + * @author xuanran.wang + * @date 2023/3/20 21:14 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +@CusHandle(order = 0) +public @interface CusPreLoadHandle { + @AliasFor(annotation = CusHandle.class, attribute = "order") + int order() default 0; +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/handle/CusReqAfterHandleRegister.java b/src/test/java/xuanran/wang/http_test/annotations/handle/CusReqAfterHandleRegister.java new file mode 100644 index 0000000..172c5af --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/handle/CusReqAfterHandleRegister.java @@ -0,0 +1,19 @@ +package xuanran.wang.http_test.annotations.handle; + +import xuanran.wang.http_test.handle.CusRequestAfterHandle; +import xuanran.wang.http_test.test.TestRequestAfterHandle; + +import java.lang.annotation.*; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/24 14:44 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Documented +public @interface CusReqAfterHandleRegister { + Class afterHandle(); +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/handle/CusResponseSuccessHandle.java b/src/test/java/xuanran/wang/http_test/annotations/handle/CusResponseSuccessHandle.java new file mode 100644 index 0000000..5f2755d --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/handle/CusResponseSuccessHandle.java @@ -0,0 +1,19 @@ +package xuanran.wang.http_test.annotations.handle; + +import java.lang.annotation.*; + +/** + *

响应体成功失败标识

+ * + * @author xuanran.wang + * @date 2023/3/22 11:29 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Documented +public @interface CusResponseSuccessHandle { + String successKey(); + String successCondition(); + String errorMsg(); + String data(); +} diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_path/CusPathQuery.java b/src/test/java/xuanran/wang/http_test/annotations/request_path/CusPathQuery.java index c6c3706..3fc2936 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/request_path/CusPathQuery.java +++ b/src/test/java/xuanran/wang/http_test/annotations/request_path/CusPathQuery.java @@ -14,7 +14,7 @@ import java.lang.annotation.*; * @date 2023/3/14 22:50 */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) +@Target({ElementType.METHOD,ElementType.PARAMETER}) @Documented public @interface CusPathQuery { /** diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestDelete.java b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestDelete.java index a20a87a..427f25f 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestDelete.java +++ b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestDelete.java @@ -1,5 +1,9 @@ package xuanran.wang.http_test.annotations.request_type; +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + import java.lang.annotation.*; /** @@ -11,6 +15,12 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Documented +@CusRequestUrl(url = "") +@CusRequestType(requestType = CusRequestClientConstant.DELETE) public @interface CusRequestDelete { - String url() default ""; + @AliasFor(annotation = CusRequestUrl.class, attribute = "url") + String url(); + + @AliasFor(annotation = CusRequestType.class, attribute = "requestType") + int requestType() default CusRequestClientConstant.DELETE; } diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestGet.java b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestGet.java index 14a7ec2..ad1fe1d 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestGet.java +++ b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestGet.java @@ -1,5 +1,9 @@ package xuanran.wang.http_test.annotations.request_type; +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + import java.lang.annotation.*; /** @@ -9,8 +13,14 @@ import java.lang.annotation.*; * @date 2023/3/10 10:15 */ @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) +@Target({ElementType.METHOD, ElementType.TYPE}) @Documented +@CusRequestUrl(url = "") +@CusRequestType(requestType = CusRequestClientConstant.GET) public @interface CusRequestGet{ - String url() default ""; + @AliasFor(annotation = CusRequestUrl.class, attribute = "url") + String url(); + + @AliasFor(annotation = CusRequestType.class, attribute = "requestType") + int requestType() default CusRequestClientConstant.GET; } diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPost.java b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPost.java index 4871a05..57f6806 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPost.java +++ b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPost.java @@ -1,5 +1,9 @@ package xuanran.wang.http_test.annotations.request_type; +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + import java.lang.annotation.*; /** @@ -11,6 +15,12 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented +@CusRequestUrl(url = "") +@CusRequestType(requestType = CusRequestClientConstant.POST) public @interface CusRequestPost { - String url() default ""; + @AliasFor(annotation = CusRequestUrl.class, attribute = "url") + String url(); + + @AliasFor(annotation = CusRequestType.class, attribute = "requestType") + int requestType() default CusRequestClientConstant.POST; } diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPut.java b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPut.java index 0fd5c5d..9a06cb2 100644 --- a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPut.java +++ b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestPut.java @@ -1,5 +1,9 @@ package xuanran.wang.http_test.annotations.request_type; +import aiyh.utils.tool.cn.hutool.core.annotation.AliasFor; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.constant.CusRequestClientConstant; + import java.lang.annotation.*; /** @@ -11,6 +15,12 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented +@CusRequestUrl(url = "") +@CusRequestType(requestType = CusRequestClientConstant.PUT) public @interface CusRequestPut { - String url() default ""; + @AliasFor(annotation = CusRequestUrl.class, attribute = "url") + String url(); + + @AliasFor(annotation = CusRequestType.class, attribute = "requestType") + int requestType() default CusRequestClientConstant.PUT; } diff --git a/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestType.java b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestType.java new file mode 100644 index 0000000..53b12a9 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/annotations/request_type/CusRequestType.java @@ -0,0 +1,16 @@ +package xuanran.wang.http_test.annotations.request_type; + +import java.lang.annotation.*; + +/** + *

请求类型

+ * + * @author xuanran.wang + * @date 2023/3/16 23:07 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Documented +public @interface CusRequestType { + int requestType() default 0; +} diff --git a/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java b/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java index d368610..0d83b8d 100644 --- a/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java +++ b/src/test/java/xuanran/wang/http_test/constant/CusRequestClientConstant.java @@ -1,5 +1,16 @@ package xuanran.wang.http_test.constant; +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; +import xuanran.wang.http_test.entity.CusRequestEntity; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + /** *

请求工具常量

* @@ -11,5 +22,51 @@ public class CusRequestClientConstant { public static final int POST = 1; public static final int DELETE = 2; public static final int PUT = 3; - public static final int HEADER = -1; + public static final int HTTP_SUCCESS_CODE = 200; + public static final Map> CONVERT = new HashMap<>(); + public static final String IS_NOT_NULL = "{ is not null }"; + public static final String EQUALS = "{ equals }"; + public static final String EQUALS_IGNORE_CASE = "{ equalsIgnoreCase }"; + + static { + CONVERT.put(IS_NOT_NULL, cusRequest ->{ + Map responseMap = cusRequest.getResponseMap(); + CusResponseSuccessHandle responseSuccessHandle = cusRequest.getResponseSuccessHandle(); + String key = responseSuccessHandle.successKey(); + String errorMsg = responseSuccessHandle.errorMsg(); + String successValue = Util.null2DefaultStr(Util.getValueByKeyStr(key, responseMap),""); + if (successValue == null) { + throw new CustomerException(Util.logStr("is not null check response error! the error is {}", responseMap.get(errorMsg))); + } + return JSONObject.toJSONString(responseMap.get(responseSuccessHandle.data())); + }); + + CONVERT.put(EQUALS, cusRequest ->{ + Map responseMap = cusRequest.getResponseMap(); + CusResponseSuccessHandle responseSuccessHandle = cusRequest.getResponseSuccessHandle(); + String key = responseSuccessHandle.successKey(); + String successCondition = responseSuccessHandle.successCondition(); + String errorMsg = responseSuccessHandle.errorMsg(); + String successValue = Util.null2DefaultStr(Util.getValueByKeyStr(key, responseMap),""); + String successConditionValue = successCondition.trim().replace(EQUALS, "").trim(); + if(!successConditionValue.equals(successValue)){ + throw new CustomerException(Util.logStr("equals check response error! the error is {}", responseMap.get(errorMsg))); + } + return JSONObject.toJSONString(responseMap.get(responseSuccessHandle.data())); + }); + + CONVERT.put(EQUALS_IGNORE_CASE, cusRequest ->{ + Map responseMap = cusRequest.getResponseMap(); + CusResponseSuccessHandle responseSuccessHandle = cusRequest.getResponseSuccessHandle(); + String key = responseSuccessHandle.successKey(); + String successCondition = responseSuccessHandle.successCondition(); + String errorMsg = responseSuccessHandle.errorMsg(); + String successValue = Util.null2DefaultStr(Util.getValueByKeyStr(key, responseMap),""); + String successConditionValue = successCondition.trim().replace(EQUALS_IGNORE_CASE, "").trim(); + if(!successConditionValue.equalsIgnoreCase(Util.null2DefaultStr(successValue,""))){ + throw new CustomerException(Util.logStr("equalsIgnoreCase check response error! the error is {}", responseMap.get(errorMsg))); + } + return JSONObject.toJSONString(responseMap.get(responseSuccessHandle.data())); + }); + } } diff --git a/src/test/java/xuanran/wang/http_test/entity/CusHandleEntity.java b/src/test/java/xuanran/wang/http_test/entity/CusHandleEntity.java new file mode 100644 index 0000000..9fe49f0 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/entity/CusHandleEntity.java @@ -0,0 +1,16 @@ +package xuanran.wang.http_test.entity; + +import lombok.Data; + +/** + *

自定义handle

+ * + * @author xuanran.wang + * @date 2023/3/16 16:07 + */ +@Data +public class CusHandleEntity { + private Class handleClass; + private int order; + private String packageName; +} diff --git a/src/test/java/xuanran/wang/http_test/entity/CusRequestEntity.java b/src/test/java/xuanran/wang/http_test/entity/CusRequestEntity.java index 143ac83..67c06e9 100644 --- a/src/test/java/xuanran/wang/http_test/entity/CusRequestEntity.java +++ b/src/test/java/xuanran/wang/http_test/entity/CusRequestEntity.java @@ -4,7 +4,10 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; +import xuanran.wang.http_test.handle.CusRequestAfterHandle; +import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; @@ -19,11 +22,17 @@ import java.util.function.Consumer; @Setter @Getter public class CusRequestEntity{ - private String url; - private Map headers; - private Map pathParams; - private Object bodyParams; - private int requestType; + private String url = ""; + private Map headers = new HashMap<>(); + private Map pathParams = new HashMap<>(); + private Object bodyParams = new Object(); + private int requestType = -1; private Consumer consumer; - private boolean async; + private boolean async = false; + private String host = ""; + private int port; + private Class returnType; + private CusRequestAfterHandle cusRequestAfter; + private CusResponseSuccessHandle responseSuccessHandle; + private Map responseMap; } diff --git a/src/test/java/xuanran/wang/http_test/entity/CusResponseSuccess.java b/src/test/java/xuanran/wang/http_test/entity/CusResponseSuccess.java new file mode 100644 index 0000000..3bed5a1 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/entity/CusResponseSuccess.java @@ -0,0 +1,21 @@ +package xuanran.wang.http_test.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

接口响应成功标识对象

+ * + * @author xuanran.wang + * @date 2023/3/29 16:58 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CusResponseSuccess { + private String successKey; + private String successCondition; + private String errorMsg; + private String data; +} diff --git a/src/test/java/xuanran/wang/http_test/handle/CusHandleCenter.java b/src/test/java/xuanran/wang/http_test/handle/CusHandleCenter.java new file mode 100644 index 0000000..4bcafaa --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/CusHandleCenter.java @@ -0,0 +1,129 @@ +package xuanran.wang.http_test.handle; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.tool.cn.hutool.core.annotation.AnnotationUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import org.apache.log4j.Logger; +import xuanran.wang.http_test.annotations.handle.CusReqAfterHandleRegister; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; +import xuanran.wang.http_test.annotations.request_type.CusRequestType; +import xuanran.wang.http_test.constant.CusRequestClientConstant; +import xuanran.wang.http_test.entity.CusHandleEntity; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.path_handle.CusBodyParseHandle; +import xuanran.wang.http_test.handle.request_handle.CusRequestGetHandle; +import xuanran.wang.http_test.handle.request_handle.CusRequestPostHandle; +import xuanran.wang.http_test.handle.request_handle.CusUrlHandle; +import xuanran.wang.http_test.handle.request_handle.CusDefaultRequestAfterHandle; +import xuanran.wang.http_test.handle.util.HandleUtil; +import xuanran.wang.http_test.proxy.RequestUtil; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

处理器中心对象

+ * + * @author xuanran.wang + * @date 2023/3/16 22:38 + */ +public class CusHandleCenter{ + + private final Logger log = Util.getLogger(); + + private final Queue preloadQueue = new LinkedList<>(); + private final Map requestHandle = new HashMap<>(); + private final CusRequestAfterHandle cusRequestAfterHandle = new CusDefaultRequestAfterHandle(); + + { + requestHandle.put(CusRequestClientConstant.GET, new CusRequestGetHandle()); + requestHandle.put(CusRequestClientConstant.POST, new CusRequestPostHandle()); + preloadQueue.add(new CusUrlHandle()); + preloadQueue.add(new CusBodyParseHandle()); + } + + public void requestBeforeHandle(CusRequestEntity cusRequest, Method method, Object[] args){ + try { + log.info("preloadQueue => " + JSONObject.toJSONString(preloadQueue)); + // 前置加载处理 + for (CusRequestBeforeHandle handle : preloadQueue) { + handle.handle(cusRequest, method, args); + } + // 扫描执行handle包下面的所有加了CusHandle注解的实现方法并按order进行排序 包的顺序随机 + HashMap> scan = HandleUtil.scanHandle(); + log.info("scan => " + JSONObject.toJSONString(scan)); + for (Map.Entry> entry : scan.entrySet()) { + List value = entry.getValue(); + List collect = value.stream().sorted(Comparator.comparingInt(CusHandleEntity::getOrder)).collect(Collectors.toList()); + log.info("扫描到的handle : " + JSONObject.toJSONString(collect)); + for (CusHandleEntity handle : collect) { + Class handleClass = handle.getHandleClass(); + if (CusRequestBeforeHandle.class.isAssignableFrom(handleClass)) { + CusRequestBeforeHandle o = (CusRequestBeforeHandle) handleClass.newInstance(); + o.handle(cusRequest, method, args); + } + } + } + }catch (Exception e){ + throw new CustomerException("execute requestBeforeHandle error! " + e.getMessage()); + } + } + + public ResponeVo requestHandle(CusRequestEntity cusRequest, Method method){ + try { + CusRequestType requestType = AnnotationUtil.getSynthesizedAnnotation(method, CusRequestType.class); + return requestHandle.get(requestType.requestType()).execute(cusRequest); + }catch (Exception e){ + throw new CustomerException("request error! " + e.getMessage()); + } + } + + public Object requestAfterHandle(Method method, CusRequestEntity cusRequest, ResponeVo responseVo){ + if(cusRequest.getCusRequestAfter() == null){ + CusReqAfterHandleRegister cusReqAfterHandleRegister = method.getDeclaredAnnotation(CusReqAfterHandleRegister.class); + if(cusReqAfterHandleRegister != null){ + RequestUtil.setCusRequestAfter(cusReqAfterHandleRegister, cusRequest); + } + } +// Type genericReturnType = method.getGenericReturnType(); + cusRequest.setReturnType(method.getReturnType()); + CusResponseSuccessHandle cusResponseSuccessHandle = method.getDeclaredAnnotation(CusResponseSuccessHandle.class); + if(cusResponseSuccessHandle != null && cusRequest.getResponseSuccessHandle() == null){ + cusRequest.setResponseSuccessHandle(cusResponseSuccessHandle); + } + return requestAfterHandle(cusRequest, responseVo); + } + + private Object requestAfterHandle(CusRequestEntity cusRequest, ResponeVo responseVo){ + if(responseVo == null){ + throw new CustomerException("CusRequestAfterHandle responseVo is null!"); + } + int code = responseVo.getCode(); + if(CusRequestClientConstant.HTTP_SUCCESS_CODE != code){ + String url = cusRequest.getUrl(); + log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 + "this request heard is [{}],but response status code is [{}]," + + "this response is [{}]", cusRequest.getUrl(), JSON.toJSON(cusRequest.getBodyParams()), JSON.toJSONString(cusRequest.getHeaders()), responseVo.getCode(), // 相应状态码 + responseVo.getEntityString())); + throw new CustomerException(Util.logStr("can not fetch [{}]", url)); // + } + CusRequestAfterHandle handle = cusRequest.getCusRequestAfter() == null ? new CusDefaultRequestAfterHandle() : cusRequest.getCusRequestAfter(); + cusRequest.setCusRequestAfter(handle); + log.info(Util.logStr("cusRequest: {}", JSONObject.toJSONString(cusRequest))); + Object res = handle.parseResponse(cusRequest, responseVo); + handle.service(cusRequest, responseVo); + return res; + } + + + public void registerPreHandle(CusRequestBeforeHandle handle){ + preloadQueue.add(handle); + } + +} diff --git a/src/test/java/xuanran/wang/http_test/handle/CusRequestAfterHandle.java b/src/test/java/xuanran/wang/http_test/handle/CusRequestAfterHandle.java new file mode 100644 index 0000000..543f6b0 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/CusRequestAfterHandle.java @@ -0,0 +1,31 @@ +package xuanran.wang.http_test.handle; + +import aiyh.utils.httpUtil.ResponeVo; +import xuanran.wang.http_test.entity.CusRequestEntity; + + +/** + *

请求后处理器

+ * + * @author xuanran.wang + * @date 2023/3/16 23:57 + */ +public interface CusRequestAfterHandle{ + /** + *

解析响应方法

+ * @author xuanran.wang + * @dateTime 2023/3/24 15:32 + * @param cusRequest 请求对象 + * @param responseVo 响应对象 + **/ + Object parseResponse(CusRequestEntity cusRequest, ResponeVo responseVo); + + /** + *

do something

+ * @author xuanran.wang + * @dateTime 2023/3/24 15:32 + * @param cusRequest 请求对象 + * @param responseVo 响应对象 + **/ + void service(CusRequestEntity cusRequest, ResponeVo responseVo); +} diff --git a/src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java b/src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java index 48faa20..4e0e80b 100644 --- a/src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java +++ b/src/test/java/xuanran/wang/http_test/handle/CusRequestBeforeHandle.java @@ -10,6 +10,6 @@ import java.lang.reflect.Method; * @author xuanran.wang * @date 2023/3/10 11:38 */ -public interface RequestBeforeHandle { - void handle(CusRequestEntity requestEntity, Method method, Object[] args); +public interface CusRequestBeforeHandle { + void handle(CusRequestEntity cusRequest, Method method, Object[] args); } diff --git a/src/test/java/xuanran/wang/http_test/handle/CusRequestHandle.java b/src/test/java/xuanran/wang/http_test/handle/CusRequestHandle.java new file mode 100644 index 0000000..06901f6 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/CusRequestHandle.java @@ -0,0 +1,42 @@ +package xuanran.wang.http_test.handle; + +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import xuanran.wang.http_test.entity.CusRequestEntity; + +import java.io.IOException; +import java.lang.reflect.Method; + +/** + *

请求参数初始化之后请求之前handle

+ * + * @author xuanran.wang + * @date 2023/3/16 23:21 + */ +public abstract class CusRequestHandle { + protected HttpUtils httpUtils = new HttpUtils(); + + protected final ResponeVo execute(CusRequestEntity cusRequest) throws IOException{ + String host = cusRequest.getHost(); + int port = cusRequest.getPort(); + String url = cusRequest.getUrl(); + StringBuilder realRequestUrl = new StringBuilder(); + if(url.startsWith("http:") || url.startsWith("https:")){ + realRequestUrl.append(url); + }else { + realRequestUrl.append(host); + if(!host.endsWith(":")){ + realRequestUrl.append(":"); + } + realRequestUrl.append(port); + if(!url.endsWith("/")){ + realRequestUrl.append("/"); + } + realRequestUrl.append(url); + } + cusRequest.setUrl(realRequestUrl.toString()); + return request(cusRequest); + } + // 执行具体的请求方法 + protected abstract ResponeVo request(CusRequestEntity cusRequest) throws IOException; +} diff --git a/src/test/java/xuanran/wang/http_test/handle/header_handle/RequestHeaderHandle.java b/src/test/java/xuanran/wang/http_test/handle/header_handle/RequestHeaderHandle.java new file mode 100644 index 0000000..7baeadb --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/header_handle/RequestHeaderHandle.java @@ -0,0 +1,84 @@ +package xuanran.wang.http_test.handle.header_handle; +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import xuanran.wang.http_test.annotations.handle.CusHandle; +import xuanran.wang.http_test.annotations.header.CusRequestHeader; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestBeforeHandle; +import xuanran.wang.http_test.interfaces.CusCreateRequestHeader; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.HashMap; +import java.util.Map; + +/** + *

请求头处理

+ * + * @author xuanran.wang + * @date 2023/3/10 14:42 + */ +@CusHandle +public class RequestHeaderHandle implements CusRequestBeforeHandle { + + @Override + public void handle(CusRequestEntity cusRequest, Method method, Object[] args) { + CusRequestHeader methodCusRequestHeader = method.getDeclaredAnnotation(CusRequestHeader.class); + if(methodCusRequestHeader == null){ + return; + } + // 数组形式 + String[] headersArr = methodCusRequestHeader.cusHeaders(); + HashMap headers = new HashMap<>(); + if(headersArr != null){ + for (String headerStr : headersArr) { + String[] split = headerStr.split(":"); + String key = Util.null2DefaultStr(split[0],"").trim(); + String val = Util.null2DefaultStr(split[1],"").trim(); + if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(val)){ + headers.put(key, val); + } + } + } + + // java代码自定义 + String path = Util.null2DefaultStr(methodCusRequestHeader.cusHeadersClassPath(),""); + if(StringUtils.isNotBlank(path)){ + Class clazz; + try { + clazz = Class.forName(path); + } catch (ClassNotFoundException e) { + throw new CustomerException(Util.logStr("自定义请求头java类文件没找到!: {}", path)); + } + if(!CusCreateRequestHeader.class.isAssignableFrom(clazz)){ + throw new CustomerException(Util.logStr("当前类路径:[{}] ,未实现CusCreateRequestHeader接口!", path)); + } + CusCreateRequestHeader o; + try { + o = (CusCreateRequestHeader) clazz.newInstance(); + }catch (InstantiationException | IllegalAccessException e) { + throw new CustomerException(Util.logStr("实例化 [{}] 对象失败! error:{}", path, e.getMessage())); + } + Map cusCreateHeader = o.createHeader(); + if(MapUtils.isNotEmpty(cusCreateHeader)){ + headers.putAll(cusCreateHeader); + } + } + // 参数中 + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + CusRequestHeader requestHeader = parameter.getAnnotation(CusRequestHeader.class); + if(requestHeader != null){ + String val = Util.null2DefaultStr(args[i], "").trim(); + String key = requestHeader.value().trim(); + if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(val)){ + headers.put(key, val); + } + } + } + cusRequest.getHeaders().putAll(headers); + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/path_handle/CusBodyParseHandle.java b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusBodyParseHandle.java new file mode 100644 index 0000000..03735dd --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusBodyParseHandle.java @@ -0,0 +1,39 @@ +package xuanran.wang.http_test.handle.path_handle; + +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.annotation.AnnotationUtil; +import org.springframework.web.bind.annotation.RequestBody; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.annotations.body.CusRequestBody; +import xuanran.wang.http_test.annotations.request_type.CusRequestType; +import xuanran.wang.http_test.constant.CusRequestClientConstant; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestBeforeHandle; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Map; + +/** + *

请求体处理

+ * + * @author xuanran.wang + * @date 2023/3/20 21:21 + */ +public class CusBodyParseHandle implements CusRequestBeforeHandle { + @Override + public void handle(CusRequestEntity cusRequest, Method method, Object[] args) { + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + CusRequestBody requestBody = parameter.getDeclaredAnnotation(CusRequestBody.class); + CusRequestType requestType = AnnotationUtil.getSynthesizedAnnotation(method, CusRequestType.class); + if(null != requestBody && + null != requestType && + requestType.requestType() != CusRequestClientConstant.GET){ + cusRequest.setBodyParams(args[i]); + } + } + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java index d9cf5b8..dc874d8 100644 --- a/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java +++ b/src/test/java/xuanran/wang/http_test/handle/path_handle/CusPathParseHandle.java @@ -2,9 +2,10 @@ package xuanran.wang.http_test.handle.path_handle; import aiyh.utils.Util; import org.apache.commons.lang3.StringUtils; +import xuanran.wang.http_test.annotations.handle.CusHandle; import xuanran.wang.http_test.annotations.request_path.CusPathQuery; import xuanran.wang.http_test.entity.CusRequestEntity; -import xuanran.wang.http_test.handle.RequestBeforeHandle; +import xuanran.wang.http_test.handle.CusRequestBeforeHandle; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -16,11 +17,12 @@ import java.util.Map; * @author xuanran.wang * @date 2023/3/14 23:11 */ -public class CusFieldKeyParseHandle implements RequestBeforeHandle { +@CusHandle +public class CusPathParseHandle implements CusRequestBeforeHandle { @Override - public void handle(CusRequestEntity requestEntity, Method method, Object[] args) { + public void handle(CusRequestEntity cusRequest, Method method, Object[] args) { Parameter[] parameters = method.getParameters(); - String url = requestEntity.getUrl(); + String url = cusRequest.getUrl(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; CusPathQuery cusPathQuery = parameter.getDeclaredAnnotation(CusPathQuery.class); @@ -33,11 +35,11 @@ public class CusFieldKeyParseHandle implements RequestBeforeHandle { }else { Class clazz = parameter.getType(); if(clazz.isAssignableFrom(Map.class)){ - requestEntity.getPathParams().putAll((Map) arg); + cusRequest.getPathParams().putAll((Map) arg); } } } } - requestEntity.setUrl(url); + cusRequest.setUrl(url); } } diff --git a/src/test/java/xuanran/wang/http_test/handle/path_handle/TestHandle.java b/src/test/java/xuanran/wang/http_test/handle/path_handle/TestHandle.java new file mode 100644 index 0000000..3133ded --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/path_handle/TestHandle.java @@ -0,0 +1,22 @@ +package xuanran.wang.http_test.handle.path_handle; + +import xuanran.wang.http_test.annotations.handle.CusHandle; +import xuanran.wang.http_test.annotations.handle.CusPreLoadHandle; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestBeforeHandle; + +import java.lang.reflect.Method; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/16 16:22 + */ +@CusHandle +public class TestHandle implements CusRequestBeforeHandle { + @Override + public void handle(CusRequestEntity cusRequest, Method method, Object[] args) { + System.out.println("TestHandle 111"); + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/request_handle/CusDefaultRequestAfterHandle.java b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusDefaultRequestAfterHandle.java new file mode 100644 index 0000000..500e3c0 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusDefaultRequestAfterHandle.java @@ -0,0 +1,47 @@ +package xuanran.wang.http_test.handle.request_handle; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; +import xuanran.wang.http_test.constant.CusRequestClientConstant; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestAfterHandle; + +import java.util.Map; + +/** + *

默认的请求后处理响应类

+ * + * @author xuanran.wang + * @date 2023/3/17 11:03 + */ +public class CusDefaultRequestAfterHandle implements CusRequestAfterHandle { + + @Override + public Object parseResponse(CusRequestEntity cusRequest, ResponeVo responseVo) { + Class returnType = cusRequest.getReturnType(); + if(ResponeVo.class.isAssignableFrom(returnType)) { + return responseVo; + } + String json = responseVo.getEntityString(); + cusRequest.setResponseMap(responseVo.getResponseMap()); + CusResponseSuccessHandle responseSuccessHandle = cusRequest.getResponseSuccessHandle(); + if(responseSuccessHandle != null){ + String successCondition = responseSuccessHandle.successCondition(); + String str = successCondition.substring(0, successCondition.lastIndexOf("}") + 1); + json = Util.null2DefaultStr(CusRequestClientConstant.CONVERT + .get(str) + .apply(cusRequest),""); + } + return JSONObject.parseObject(json, returnType); + } + + @Override + public void service(CusRequestEntity cusRequest, ResponeVo responeVo){ + + } + +} diff --git a/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestGetHandle.java b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestGetHandle.java new file mode 100644 index 0000000..6d8b84c --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestGetHandle.java @@ -0,0 +1,21 @@ +package xuanran.wang.http_test.handle.request_handle; + +import aiyh.utils.httpUtil.ResponeVo; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestHandle; + +import java.io.IOException; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/16 23:20 + */ +public class CusRequestGetHandle extends CusRequestHandle { + + @Override + protected ResponeVo request(CusRequestEntity cusRequest) throws IOException { + return httpUtils.apiGet(cusRequest.getUrl(), cusRequest.getPathParams(), cusRequest.getHeaders()); + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestPostHandle.java b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestPostHandle.java new file mode 100644 index 0000000..56719ea --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusRequestPostHandle.java @@ -0,0 +1,21 @@ +package xuanran.wang.http_test.handle.request_handle; + +import aiyh.utils.httpUtil.ResponeVo; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestHandle; + +import java.io.IOException; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/16 23:20 + */ +public class CusRequestPostHandle extends CusRequestHandle { + + @Override + protected ResponeVo request(CusRequestEntity cusRequest) throws IOException { + return httpUtils.apiPostObject(cusRequest.getUrl(), cusRequest.getBodyParams(), cusRequest.getHeaders()); + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/request_handle/CusUrlHandle.java b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusUrlHandle.java new file mode 100644 index 0000000..d5c9edb --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/request_handle/CusUrlHandle.java @@ -0,0 +1,29 @@ +package xuanran.wang.http_test.handle.request_handle; + +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.annotation.AnnotationUtil; +import xuanran.wang.http_test.annotations.CusRequestUrl; +import xuanran.wang.http_test.annotations.request_type.CusRequestType; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.CusRequestBeforeHandle; + +import java.lang.reflect.Method; + +/** + *

方法路径拼接处理

+ * + * @author xuanran.wang + * @date 2023/3/16 19:51 + */ +public class CusUrlHandle implements CusRequestBeforeHandle { + @Override + public void handle(CusRequestEntity cusRequest, Method method, Object[] args) { + CusRequestUrl requestUrl = AnnotationUtil.getSynthesizedAnnotation(method, CusRequestUrl.class); + if(requestUrl == null){ + throw new CustomerException("method not found CusRequestUrl!"); + } + cusRequest.setUrl(requestUrl.url()); + Class returnType = method.getReturnType(); + cusRequest.setReturnType(returnType); + } +} diff --git a/src/test/java/xuanran/wang/http_test/handle/util/HandleUtil.java b/src/test/java/xuanran/wang/http_test/handle/util/HandleUtil.java new file mode 100644 index 0000000..1590e99 --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/handle/util/HandleUtil.java @@ -0,0 +1,179 @@ +package xuanran.wang.http_test.handle.util; + +import aiyh.utils.excention.CustomerException; +import ebu7common.youhong.ai.bean.Builder; +import xuanran.wang.http_test.annotations.handle.CusHandle; +import xuanran.wang.http_test.entity.CusHandleEntity; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/16 15:42 + */ +public class HandleUtil { + /** + *

扫描指定路径下对class文件

+ * @author xuanran.wang + * @dateTime 2023/3/16 16:02 + * @return class + **/ + public static HashMap> scanHandle() throws ClassNotFoundException{ + String packageName = HandleUtil.class.getPackage().getName(); + return scan(packageName.substring(0, packageName.lastIndexOf("."))); + } + + /** + * 扫描指定路径下的类文件 + * + * @param packagePath 包路径 + */ + private static HashMap> scan(String packagePath) throws ClassNotFoundException { + // 转化包路径为文件路径 + String scanPath = packagePath.replace(".", "/"); + // 扫描 + ClassLoader classLoader = HandleUtil.class.getClassLoader(); + URL resource = classLoader.getResource(scanPath); + Set fileNameSet = new LinkedHashSet<>(); + if (resource == null) { + throw new CustomerException("package is not found! :" + packagePath); + } + String rootPath = getRootPath(resource); + if (isJarFile(resource.getFile())) { + try { + // 是jar包使用JarInputStream + JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(Paths.get(rootPath))); + JarEntry nextJarEntry = jarInputStream.getNextJarEntry(); + // 遍历 + while (null != nextJarEntry) { + String name = nextJarEntry.getName(); + // 如果是指定包名下的文件并且是.class结尾,那就保存它 + if (name.startsWith(scanPath) && isClassFile(name)) { + fileNameSet.add(name.replace(".class", "")); + } + nextJarEntry = jarInputStream.getNextJarEntry(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } else { + // 是文件夹,获取该文件夹下所有文件 + Set allFilePath = getAllFilePath(rootPath); + for (String filePath : allFilePath) { + fileNameSet.add(transFilePathToPackagePath(filePath, scanPath)); + } + } + HashMap> maps = new HashMap<>(); + for (String fileName : fileNameSet) { + String packageName = fileName.substring(0, fileName.lastIndexOf(".")); + Class scanClass = Class.forName(fileName, false, HandleUtil.class.getClassLoader()); + CusHandle annotation = scanClass.getAnnotation(CusHandle.class); + if(null != annotation){ + CusHandleEntity cusHandleEntity = Builder.builder(CusHandleEntity::new) + .with(CusHandleEntity::setHandleClass, scanClass) + .with(CusHandleEntity::setOrder, annotation.order()) + .with(CusHandleEntity::setPackageName, packageName) + .build(); + List cusHandleEntities = new ArrayList<>(); + if(maps.containsKey(packageName)){ + cusHandleEntities = maps.get(packageName); + } + cusHandleEntities.add(cusHandleEntity); + maps.put(packageName, cusHandleEntities); + } + } + return maps; + } + + /** + * 遍历获取某个文件下所有文件名称 + * + * @param path path + * @return Set + */ + private static Set getAllFilePath(String path) { + Set fileSet = new LinkedHashSet<>(); + File file = new File(path); + return getAllFilePath(fileSet, file); + } + + /** + * 递归遍历获取某个文件下所有文件名称 + * + * @param fileSet fileSet + * @param file 源文件 + * @return Set + */ + private static Set getAllFilePath(Set fileSet, File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File file1 : files) { + getAllFilePath(fileSet, file1); + } + } + } else { + if (isClassFile(file.getAbsolutePath())) { + fileSet.add(file.getAbsolutePath()); + } + return fileSet; + } + return fileSet; + } + + /** + * 把文件路径转为包路径 + * + * @param filePath filePath + * @param scanPath 扫描路径 + * @return String + */ + private static String transFilePathToPackagePath(String filePath, String scanPath) { + filePath = filePath.replace("\\", "/"); + String substring = filePath.substring(filePath.indexOf(scanPath), filePath.indexOf(".class")); + return substring.replace("\\", ".").replace("/", "."); + } + + /** + * 判断一个文件是不是jar包 + * + * @param fileName fileName + * @return true-是,false-否 + */ + private static boolean isJarFile(String fileName) { + return fileName.contains(".jar!"); + } + + /** + * 判断一个文件class文件 + * + * @param fileName fileName + * @return true-是,false-否 + */ + private static boolean isClassFile(String fileName) { + return fileName.endsWith(".class"); + } + + /** + * 获取文件路径 + * + * @param url url + * @return String + */ + private static String getRootPath(URL url) { + String path = url.getFile(); + if (path.contains("!")) { + return path.substring(5, path.indexOf("!")); + } + return path; + } + +} diff --git a/src/test/java/xuanran/wang/http_test/proxy/RequestUtil.java b/src/test/java/xuanran/wang/http_test/proxy/RequestUtil.java index f0c7cc2..169237b 100644 --- a/src/test/java/xuanran/wang/http_test/proxy/RequestUtil.java +++ b/src/test/java/xuanran/wang/http_test/proxy/RequestUtil.java @@ -3,30 +3,21 @@ package xuanran.wang.http_test.proxy; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; import aiyh.utils.httpUtil.ResponeVo; -import aiyh.utils.httpUtil.util.HttpUtils; -import com.alibaba.fastjson.JSON; +import aiyh.utils.tool.cn.hutool.core.annotation.AnnotationUtil; import com.alibaba.fastjson.JSONObject; import org.apache.log4j.Logger; import xuanran.wang.http_test.annotations.*; -import xuanran.wang.http_test.annotations.async.CusAsync; -import xuanran.wang.http_test.annotations.request_type.CusRequestDelete; -import xuanran.wang.http_test.annotations.request_type.CusRequestGet; -import xuanran.wang.http_test.annotations.request_type.CusRequestPost; -import xuanran.wang.http_test.annotations.request_type.CusRequestPut; -import xuanran.wang.http_test.constant.RequestUtilConstant; +import xuanran.wang.http_test.annotations.handle.CusReqAfterHandleRegister; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; import xuanran.wang.http_test.entity.CusRequestEntity; -import xuanran.wang.http_test.handle.*; -import xuanran.wang.http_test.handle.path_handle.CusFieldKeyParseHandle; +import xuanran.wang.http_test.handle.CusHandleCenter; +import xuanran.wang.http_test.handle.CusRequestAfterHandle; -import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.lang.reflect.Proxy; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; + /** *

声明式发送http请求

@@ -36,57 +27,59 @@ import java.util.function.Function; */ public class RequestUtil implements InvocationHandler { private CusRequestAddress cusRequestAddress = null; - private final HttpUtils httpUtils = new HttpUtils(); private final Logger log = Util.getLogger(); - private boolean async = false; + private final CusHandleCenter handleCenter = new CusHandleCenter(); + private final CusRequestEntity cusRequest = new CusRequestEntity(); public T getRequestClient(Class clazz){ - Annotation annotation = clazz.getDeclaredAnnotation(CusRequest.class); + Annotation annotation = clazz.getDeclaredAnnotation(CusRequestClient.class); if(annotation == null){ - throw new CustomerException("该类未添加CusRequest注解!"); + throw new CustomerException(Util.logStr(clazz.getName() + " not found CusRequestClient annotation!")); + } + // 请求后处理 + CusReqAfterHandleRegister cusReqAfterHandleRegister = clazz.getDeclaredAnnotation(CusReqAfterHandleRegister.class); + if(cusReqAfterHandleRegister != null){ + setCusRequestAfter(cusReqAfterHandleRegister, cusRequest); + } + // 响应处理 + CusResponseSuccessHandle cusResponseSuccessHandle = clazz.getDeclaredAnnotation(CusResponseSuccessHandle.class); + if(cusResponseSuccessHandle != null){ + cusRequest.setResponseSuccessHandle(cusResponseSuccessHandle); } cusRequestAddress = clazz.getDeclaredAnnotation(CusRequestAddress.class); - if(null != clazz.getDeclaredAnnotation(CusAsync.class)){ - async = true; - } + cusRequestAddress = AnnotationUtil.getSynthesizedAnnotation(clazz, CusRequestAddress.class); +// if(null != clazz.getDeclaredAnnotation(CusAsync.class)){ +// async = true; +// } return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) { - StringBuilder url = new StringBuilder(); - CusRequestEntity cusRequest = new CusRequestEntity(); if(cusRequestAddress != null){ String host = Util.null2DefaultStr(cusRequestAddress.host(),""); int port = Util.getIntValue( Util.null2DefaultStr(cusRequestAddress.port(),""),0); - url.append(host) - .append(":") - .append(port); - cusRequest.setUrl(url.toString()); + cusRequest.setHost(host); + cusRequest.setPort(port); } - CusFieldKeyParseHandle keyParseHandle = new CusFieldKeyParseHandle(); - keyParseHandle.handle(cusRequest, method, args); - log.info("cusRequest : \n" + JSONObject.toJSONString(cusRequest)); - return ""; + handleCenter.requestBeforeHandle(cusRequest, method, args); + log.info("requestHandle : \n" + JSONObject.toJSONString(cusRequest)); + ResponeVo responeVo = handleCenter.requestHandle(cusRequest, method); + return handleCenter.requestAfterHandle(method, cusRequest, responeVo); } - private String appendPath(StringBuilder url, String path){ - if(!path.endsWith("/")){ - url.append("/"); - } - url.append(path); - return url.toString(); - } - - public Object get(String url, Map params, Map headers) throws IOException { - return httpUtils.apiGet(url, params, headers); - } - - public static boolean isJSON(String str) { - try { - JSON.parse(str); - return true; - } catch (Exception e) { - return false; + public static void setCusRequestAfter(CusReqAfterHandleRegister cusReqAfterHandleRegister, + CusRequestEntity cusRequest){ + if(cusReqAfterHandleRegister != null){ + Class clazz = cusReqAfterHandleRegister.afterHandle(); + if (CusRequestAfterHandle.class.isAssignableFrom(clazz)) { + try { + Object cusRequestAfter = clazz.newInstance(); + cusRequest.setCusRequestAfter((CusRequestAfterHandle) cusRequestAfter); + }catch (Exception e){ + throw new CustomerException(Util.logStr("class : {}, newInstance error!", e.getMessage())); + } + } } } + } diff --git a/src/test/java/xuanran/wang/http_test/service/TestService.java b/src/test/java/xuanran/wang/http_test/service/TestService.java index 00e770b..e74ea59 100644 --- a/src/test/java/xuanran/wang/http_test/service/TestService.java +++ b/src/test/java/xuanran/wang/http_test/service/TestService.java @@ -1,11 +1,15 @@ package xuanran.wang.http_test.service; -import aiyh.utils.httpUtil.ResponeVo; import xuanran.wang.http_test.annotations.*; +import xuanran.wang.http_test.annotations.body.CusRequestBody; +import xuanran.wang.http_test.annotations.handle.CusResponseSuccessHandle; import xuanran.wang.http_test.annotations.header.CusRequestHeader; +import xuanran.wang.http_test.annotations.request_path.CusPathQuery; import xuanran.wang.http_test.annotations.request_type.CusRequestGet; import xuanran.wang.http_test.annotations.request_type.CusRequestPost; +import xuanran.wang.http_test.constant.CusRequestClientConstant; +import java.util.List; import java.util.Map; /** @@ -14,19 +18,20 @@ import java.util.Map; * @author xuanran.wang * @date 2023/3/10 12:39 */ -@CusRequest -@CusRequestAddress(host = "http://114.115.168.220/educate-plat/api/v1/class/getClassList/{test}", port = 8191) +@CusRequestClient(host = "http://114.115.168.220", port = 8191) +//@CusReqAfterHandleRegister(afterHandle = TestRequestAfterHandle.class) public interface TestService { - - @CusRequestGet(url = "educate-plat/api/v1/class/getClassList/{test}") - @CusRequestHeader(cusHeaders = {"sa: sasa", "sas:11212"}) - String getStu(Map path, - @PostBody Map body, - @CusRequestHeader("hsjhdsad") String test, - @CusPathQuery("test") String test1); - - @CusRequestPost(url = "test/post/sas") - @CusRequestHeader(cusHeaders = {"content-Type: application/json"}, cusHeadersClassPath = "java.fsdfds") - String getStu(@PostBody Map body); + @CusRequestGet(url = "educate-plat/api/v1/class/getClassList") + @CusRequestHeader(cusHeaders = {"sa: sasa", "sas:11212","content-Type:application/json"}) + @CusResponseSuccessHandle( + successKey = "code", + successCondition = CusRequestClientConstant.EQUALS + " 0 ", + errorMsg = "msg", + data = "data" + ) + Map getStu(Map path, + @CusRequestBody Map body, + @CusRequestHeader("hsjhdsad") String test, + @CusPathQuery("test") String test1); } diff --git a/src/test/java/xuanran/wang/http_test/test/RequestTest.java b/src/test/java/xuanran/wang/http_test/test/RequestTest.java index ca18084..7b3dccf 100644 --- a/src/test/java/xuanran/wang/http_test/test/RequestTest.java +++ b/src/test/java/xuanran/wang/http_test/test/RequestTest.java @@ -1,13 +1,18 @@ package xuanran.wang.http_test.test; -import aiyh.utils.httpUtil.ResponeVo; import basetest.BaseTest; +import com.alibaba.fastjson.JSONObject; +import com.api.doc.migrate.util.FtpUtil; +import com.jcraft.jsch.ChannelSftp; import org.junit.Test; +import weaver.backup.utils.ZipUtil; +import xuanran.wang.http_test.entity.CusHandleEntity; +import xuanran.wang.http_test.handle.util.HandleUtil; import xuanran.wang.http_test.proxy.CusUtil; -import xuanran.wang.http_test.proxy.RequestUtil; import xuanran.wang.http_test.service.TestService; -import java.util.HashMap; +import java.util.*; +import java.util.stream.Collectors; /** *

@@ -24,7 +29,6 @@ public class RequestTest extends BaseTest { map.put("a","1"); map.put("b","2"); HashMap body = new HashMap<>(); - body.put("a","3"); body.put("b","4"); @@ -32,10 +36,29 @@ public class RequestTest extends BaseTest { path.put("e","5"); path.put("f","6"); - requestClient.getStu(map, body, "a", "test1111"); + Map stu = requestClient.getStu(map, body, "a", "test1111"); + log.info("stu : \n" + JSONObject.toJSONString(stu)); +// String json = "{\"xuanran.wang.http_test.requestBeforeHandle.path_handle\":[{\"handleClass\":\"xuanran.wang.http_test.requestBeforeHandle.path_handle.CusPathParseHandle\",\"order\":0,\"packageName\":\"xuanran.wang.http_test.requestBeforeHandle.path_handle\"},{\"handleClass\":\"xuanran.wang.http_test.requestBeforeHandle.path_handle.TestHandle\",\"order\":99,\"packageName\":\"xuanran.wang.http_test.requestBeforeHandle.path_handle\"}],\"xuanran.wang.http_test.requestBeforeHandle.header_handle\":[{\"handleClass\":\"xuanran.wang.http_test.requestBeforeHandle.header_handle.RequestHeaderHandle\",\"order\":0,\"packageName\":\"xuanran.wang.http_test.requestBeforeHandle.header_handle\"}]}"; +// System.out.println(JSONObject.parseObject(JSONObject.toJSONString(json), Map.class)); // String stu1 = requestClient.getStu(body); + } + + @Test + public void testA(){ + try { + HashMap> scan = HandleUtil.scanHandle(); + for (Map.Entry> entry : scan.entrySet()) { + List value = entry.getValue(); + List collect = value.stream().sorted(Comparator.comparingInt(CusHandleEntity::getOrder)).collect(Collectors.toList()); + log.info("collect : " + JSONObject.toJSONString(collect)); + } + log.info("scan => " + JSONObject.toJSONString(scan)); + }catch (Exception e){ + log.info("erro => " + e.getMessage()); + } + } } diff --git a/src/test/java/xuanran/wang/http_test/test/TestRequestAfterHandle.java b/src/test/java/xuanran/wang/http_test/test/TestRequestAfterHandle.java new file mode 100644 index 0000000..a55804d --- /dev/null +++ b/src/test/java/xuanran/wang/http_test/test/TestRequestAfterHandle.java @@ -0,0 +1,20 @@ +package xuanran.wang.http_test.test; + +import aiyh.utils.httpUtil.ResponeVo; +import xuanran.wang.http_test.entity.CusRequestEntity; +import xuanran.wang.http_test.handle.request_handle.CusDefaultRequestAfterHandle; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/20 14:48 + */ +public class TestRequestAfterHandle extends CusDefaultRequestAfterHandle { + + @Override + public void service(CusRequestEntity cusRequest, ResponeVo responseVo) { + System.out.println("============== ceshi xia ==============="); + } + +} diff --git a/src/test/java/xuanran/wang/immc/Kafka/MQTest.java b/src/test/java/xuanran/wang/immc/Kafka/MQTest.java new file mode 100644 index 0000000..d2d69fe --- /dev/null +++ b/src/test/java/xuanran/wang/immc/Kafka/MQTest.java @@ -0,0 +1,363 @@ +package xuanran.wang.immc.Kafka; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import basetest.BaseTest; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.sun.tools.internal.ws.wsdl.document.soap.SOAPUse; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.Future; +import java.util.stream.Collectors; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.springframework.beans.BeanUtils; +import weaver.conn.RecordSet; +import weaver.workflow.request.todo.RequestStatusObj; +import weaver.xuanran.wang.common.annocation.SqlFieldMapping; +import weaver.xuanran.wang.common.annocation.SqlUpdateWhereField; +import weaver.xuanran.wang.common.util.CusInfoToOAUtil; +import weaver.xuanran.wang.sh_bigdata.common.util.SendTodoTaskUtil; +import weaver.xuanran.wang.sh_bigdata.common.util.ShBigDataUtil; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.entity.OtherSysDepartment; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.OrgHrmAsyncApiService; +import weaver.xuanran.wang.sh_bigdata.org_hrm_async.service.impl.OrgHrmAsyncApiServiceImpl; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusDoneTask; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusDoneTaskOA; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusTodoTask; +import weaver.xuanran.wang.sh_bigdata.task_async.entity.CusTodoTaskToOADetail; +import weaver.xuanran.wang.sh_bigdata.task_async.mapper.SendTodoTaskMapper; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/30 11:06 + */ +public class MQTest extends BaseTest { + + @Test + public void testProducer(){ + // 设置Kafka生产者的配置属性 + Properties props = new Properties(); + props.put("bootstrap.servers", "10.184.42.41:9094,10.184.42.42:9094,10.184.42.40:9094"); +// props.put("acks", "all"); +// props.put("retries", 0); +// props.put("batch.size", 16384); +// props.put("linger.ms", 1); +// props.put("buffer.memory", 33554432); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + Map configMap = Util.getProperties2Map("VmsKafka"); + if(MapUtils.isEmpty(configMap)){ + throw new CustomerException("please check /web-inf/prop2map has VmsKafka.properties"); + } + // 创建Kafka生产者实例 + KafkaProducer producer =new KafkaProducer(configMap); + + // 发送消息到指定主题 + String topic = "oa_service_immc_topic_uat"; + String message = "Hello, Kafka!"; + ProducerRecord record = new ProducerRecord<>(topic, message); + Future send = producer.send(record); + + // 关闭Kafka生产者实例 + producer.close(); + + + + } + + @Test + public void testA(){ + RecordSet rs = new RecordSet(); + rs.executeQuery("select je from formtable_main_20 where requestid = ?", 353354); + rs.next(); + Map mapMapping = getMapMapping(rs); + System.out.println("mapMapping => " + JSONObject.toJSONString(mapMapping)); + } + + @Test + public void testB(){ + String json = "{\n" + + " \"errcode\":0,\n" + + " \"errmsg\":\"ok\",\n" + + " \"access_token\": \"accesstoken000001\",\n" + + " \"expires_in\": 7200\n" + + "}"; + Map map = JSONObject.parseObject(json, Map.class); + String dataKey = "access_token"; + String parse = parse(map, dataKey).toString(); + System.out.println("parse => " +JSONObject.toJSONString(parse)); + } + + public T parse(Map response, String dataKey){ + dataKey = Util.null2DefaultStr(dataKey, ""); + String[] split = dataKey.split("\\."); + int len = split.length; + if(len == 0 || StringUtils.isBlank(dataKey)){ + return (T)response; + } + for (int i = 0; i < len - 1; i++) { + response = (Map) response.get(split[i]); + } + return (T) response.get(split[len - 1]); + } + + private static Map getMapMapping(RecordSet rs) { + Map map = new HashMap<>(); + String[] columnType = rs.getColumnTypeName(); + int colCounts; + colCounts = rs.getColCounts() == 0 ? columnType.length : rs.getColCounts(); + for (int i = 1; i <= colCounts; i++) { + String key; + String type = "varchar"; + if (columnType != null) { + if (columnType.length != colCounts) { + type = "varchar"; + } else { + type = columnType[i - 1]; + } + } + key = rs.getColumnName(i).toLowerCase(); + if ("int".equalsIgnoreCase(type) || "Integer".equalsIgnoreCase(type) + || "Long".equalsIgnoreCase(type) || "BIGINT".equalsIgnoreCase(type) + || "NUMBER".equalsIgnoreCase(type) || "INTEGER".equalsIgnoreCase(type) + || "TINYINT".equalsIgnoreCase(type) || "SMALLINT".equalsIgnoreCase(type)) { + map.put(key, rs.getInt(i) == -1 ? rs.getString(i) : rs.getInt(i)); + continue; + } + if ("FLOAT".equalsIgnoreCase(type)) { + map.put(key, rs.getFloat(i)); + continue; + } + if ("DATE".equalsIgnoreCase(type) || "TIMESTAMP".equalsIgnoreCase(type) + || "DATETIME".equalsIgnoreCase(type)) { + map.put(key, rs.getString(i)); + continue; + } + if ("DOUBLE".equalsIgnoreCase(type)) { + map.put(key, rs.getDouble(i)); + continue; + } + if ("DECIMAL".equalsIgnoreCase(type) || "NUMERIC".equalsIgnoreCase(type)) { + String val = weaver.general.Util.null2String(rs.getString(i)); + BigDecimal decimal; + if(StringUtils.isBlank(val)){ + decimal = new BigDecimal("0"); + }else { + decimal = new BigDecimal(val); + } + map.put(key, decimal); + continue; + } + map.put(key, rs.getString(i)); + } + return map; + } + + private final OrgHrmAsyncApiService orgHrmAsyncApiService = new OrgHrmAsyncApiServiceImpl(); + @Test + public void testC(){ + String json = "[{\"id\":1,\"name\":\"上海市\",\"parentid\":-1,\"order\":100000000,\"hasChild\":1},{\"id\":2,\"name\":\"市委\",\"parentid\":1,\"order\":100000000,\"hasChild\":0},{\"id\":14,\"name\":\"市人大\",\"parentid\":1,\"order\":99999500,\"hasChild\":1},{\"id\":15,\"name\":\"市人大常委会办公厅\",\"parentid\":14,\"order\":100000000,\"hasChild\":0},{\"id\":16,\"name\":\"市政府\",\"parentid\":1,\"order\":99999000,\"hasChild\":1},{\"id\":18,\"name\":\"市政府办公厅\",\"parentid\":16,\"order\":99999500,\"hasChild\":1},{\"id\":19,\"name\":\"秘书处\",\"parentid\":18,\"order\":100000000,\"hasChild\":0},{\"id\":20,\"name\":\"督查室\",\"parentid\":18,\"order\":99999500,\"hasChild\":0},{\"id\":21,\"name\":\"建议提案处\",\"parentid\":18,\"order\":99999000,\"hasChild\":0},{\"id\":22,\"name\":\"综合处\",\"parentid\":18,\"order\":99998500,\"hasChild\":0},{\"id\":23,\"name\":\"区政处\",\"parentid\":18,\"order\":99998000,\"hasChild\":0},{\"id\":24,\"name\":\"联络处\",\"parentid\":18,\"order\":99997500,\"hasChild\":0},{\"id\":25,\"name\":\"总值班室\",\"parentid\":18,\"order\":99997000,\"hasChild\":0},{\"id\":26,\"name\":\"政务公开办公室\",\"parentid\":18,\"order\":99996500,\"hasChild\":0},{\"id\":27,\"name\":\"数据发展管理办\",\"parentid\":18,\"order\":99996000,\"hasChild\":0},{\"id\":28,\"name\":\"法律事务办\",\"parentid\":18,\"order\":99995500,\"hasChild\":0},{\"id\":29,\"name\":\"政府职能转变协调处\",\"parentid\":18,\"order\":99995000,\"hasChild\":0},{\"id\":30,\"name\":\"政务服务处\",\"parentid\":18,\"order\":99994500,\"hasChild\":0},{\"id\":31,\"name\":\"上海发布办公室\",\"parentid\":18,\"order\":99994000,\"hasChild\":0},{\"id\":32,\"name\":\"打击走私综合治理处\",\"parentid\":18,\"order\":99993500,\"hasChild\":0},{\"id\":33,\"name\":\"城运规划处\",\"parentid\":18,\"order\":99993000,\"hasChild\":0},{\"id\":34,\"name\":\"指挥协调处\",\"parentid\":18,\"order\":99992500,\"hasChild\":0},{\"id\":35,\"name\":\"党政办公室\",\"parentid\":18,\"order\":99992000,\"hasChild\":0},{\"id\":36,\"name\":\"人事处\",\"parentid\":18,\"order\":99991500,\"hasChild\":0},{\"id\":37,\"name\":\"行政处\",\"parentid\":18,\"order\":99991000,\"hasChild\":0},{\"id\":38,\"name\":\"驻办公厅纪检组\",\"parentid\":18,\"order\":99990500,\"hasChild\":0},{\"id\":39,\"name\":\"市大数据中心\",\"parentid\":18,\"order\":99990000,\"hasChild\":0},{\"id\":40,\"name\":\"文印中心\",\"parentid\":18,\"order\":99989500,\"hasChild\":0},{\"id\":41,\"name\":\"离退休干部管理服务中心\",\"parentid\":18,\"order\":99989000,\"hasChild\":0},{\"id\":42,\"name\":\"市发展改革委\",\"parentid\":16,\"order\":99999000,\"hasChild\":1},{\"id\":43,\"name\":\"委领导\",\"parentid\":42,\"order\":100000000,\"hasChild\":0},{\"id\":44,\"name\":\"内设机构\",\"parentid\":42,\"order\":99999500,\"hasChild\":0},{\"id\":45,\"name\":\"直属单位\",\"parentid\":42,\"order\":99999000,\"hasChild\":0},{\"id\":46,\"name\":\"市经济信息化委\",\"parentid\":16,\"order\":99998500,\"hasChild\":1},{\"id\":47,\"name\":\"委领导\",\"parentid\":46,\"order\":100000000,\"hasChild\":0},{\"id\":48,\"name\":\"内设机构\",\"parentid\":46,\"order\":99999500,\"hasChild\":0},{\"id\":49,\"name\":\"直属单位\",\"parentid\":46,\"order\":99999000,\"hasChild\":0},{\"id\":50,\"name\":\"市商务委\",\"parentid\":16,\"order\":99998000,\"hasChild\":1},{\"id\":51,\"name\":\"委领导\",\"parentid\":50,\"order\":100000000,\"hasChild\":0},{\"id\":52,\"name\":\"内设机构\",\"parentid\":50,\"order\":99999500,\"hasChild\":0},{\"id\":53,\"name\":\"直属单位\",\"parentid\":50,\"order\":99999000,\"hasChild\":0},{\"id\":54,\"name\":\"市教委\",\"parentid\":16,\"order\":99997500,\"hasChild\":1},{\"id\":55,\"name\":\"委领导\",\"parentid\":54,\"order\":100000000,\"hasChild\":0},{\"id\":56,\"name\":\"内设机构\",\"parentid\":54,\"order\":99999500,\"hasChild\":0},{\"id\":57,\"name\":\"直属单位\",\"parentid\":54,\"order\":99999000,\"hasChild\":0},{\"id\":58,\"name\":\"市科委\",\"parentid\":16,\"order\":99997000,\"hasChild\":1},{\"id\":59,\"name\":\"委领导\",\"parentid\":58,\"order\":100000000,\"hasChild\":0},{\"id\":60,\"name\":\"内设机构\",\"parentid\":58,\"order\":99999500,\"hasChild\":0},{\"id\":61,\"name\":\"直属单位\",\"parentid\":58,\"order\":99999000,\"hasChild\":0},{\"id\":62,\"name\":\"市民族宗教局\",\"parentid\":16,\"order\":99996500,\"hasChild\":1},{\"id\":63,\"name\":\"委领导\",\"parentid\":62,\"order\":100000000,\"hasChild\":0},{\"id\":64,\"name\":\"内设机构\",\"parentid\":62,\"order\":99999500,\"hasChild\":0},{\"id\":65,\"name\":\"直属单位\",\"parentid\":62,\"order\":99999000,\"hasChild\":0},{\"id\":66,\"name\":\"市公安局\",\"parentid\":16,\"order\":99996000,\"hasChild\":1},{\"id\":67,\"name\":\"委领导\",\"parentid\":66,\"order\":100000000,\"hasChild\":0},{\"id\":68,\"name\":\"内设机构\",\"parentid\":66,\"order\":99999500,\"hasChild\":0},{\"id\":69,\"name\":\"直属单位\",\"parentid\":66,\"order\":99999000,\"hasChild\":0},{\"id\":70,\"name\":\"市民政局\",\"parentid\":16,\"order\":99995500,\"hasChild\":1},{\"id\":71,\"name\":\"局领导\",\"parentid\":70,\"order\":100000000,\"hasChild\":0},{\"id\":72,\"name\":\"内设机构\",\"parentid\":70,\"order\":99999500,\"hasChild\":0},{\"id\":73,\"name\":\"直属单位\",\"parentid\":70,\"order\":99999000,\"hasChild\":0},{\"id\":74,\"name\":\"市司法局\",\"parentid\":16,\"order\":99995000,\"hasChild\":1},{\"id\":75,\"name\":\"局领导\",\"parentid\":74,\"order\":100000000,\"hasChild\":0},{\"id\":76,\"name\":\"内设机构\",\"parentid\":74,\"order\":99999500,\"hasChild\":0},{\"id\":77,\"name\":\"直属单位\",\"parentid\":74,\"order\":99999000,\"hasChild\":0},{\"id\":78,\"name\":\"市财政局\",\"parentid\":16,\"order\":99994500,\"hasChild\":1},{\"id\":79,\"name\":\"局领导\",\"parentid\":78,\"order\":100000000,\"hasChild\":0},{\"id\":80,\"name\":\"内设机构\",\"parentid\":78,\"order\":99999500,\"hasChild\":0},{\"id\":81,\"name\":\"直属单位\",\"parentid\":78,\"order\":99999000,\"hasChild\":0},{\"id\":82,\"name\":\"市人力资源社会保障局\",\"parentid\":16,\"order\":99994000,\"hasChild\":1},{\"id\":83,\"name\":\"局领导\",\"parentid\":82,\"order\":100000000,\"hasChild\":0},{\"id\":84,\"name\":\"内设机构\",\"parentid\":82,\"order\":99999500,\"hasChild\":0},{\"id\":85,\"name\":\"直属单位\",\"parentid\":82,\"order\":99999000,\"hasChild\":0},{\"id\":86,\"name\":\"市规划资源局\",\"parentid\":16,\"order\":99993500,\"hasChild\":1},{\"id\":87,\"name\":\"内设机构\",\"parentid\":86,\"order\":100000000,\"hasChild\":0},{\"id\":88,\"name\":\"直属单位\",\"parentid\":86,\"order\":99999500,\"hasChild\":0},{\"id\":89,\"name\":\"市生态环境局\",\"parentid\":16,\"order\":99993000,\"hasChild\":1},{\"id\":93,\"name\":\"市住房城乡建设管理委\",\"parentid\":16,\"order\":99992500,\"hasChild\":1},{\"id\":94,\"name\":\"委领导\",\"parentid\":93,\"order\":100000000,\"hasChild\":0},{\"id\":95,\"name\":\"内设机构\",\"parentid\":93,\"order\":99999500,\"hasChild\":0},{\"id\":96,\"name\":\"直属单位\",\"parentid\":93,\"order\":99999000,\"hasChild\":0},{\"id\":97,\"name\":\"市交通委\",\"parentid\":16,\"order\":99992000,\"hasChild\":1},{\"id\":98,\"name\":\"委领导\",\"parentid\":97,\"order\":100000000,\"hasChild\":0},{\"id\":99,\"name\":\"内设机构\",\"parentid\":97,\"order\":99999500,\"hasChild\":0},{\"id\":100,\"name\":\"直属单位\",\"parentid\":97,\"order\":99999000,\"hasChild\":0},{\"id\":101,\"name\":\"市农业农村委\",\"parentid\":16,\"order\":99991500,\"hasChild\":1},{\"id\":102,\"name\":\"委领导\",\"parentid\":101,\"order\":100000000,\"hasChild\":0},{\"id\":103,\"name\":\"内设机构\",\"parentid\":101,\"order\":99999500,\"hasChild\":0},{\"id\":104,\"name\":\"直属单位\",\"parentid\":101,\"order\":99999000,\"hasChild\":0},{\"id\":105,\"name\":\"市水务局\",\"parentid\":16,\"order\":99991000,\"hasChild\":1},{\"id\":107,\"name\":\"局机关\",\"parentid\":105,\"order\":100000000,\"hasChild\":1},{\"id\":108,\"name\":\"局属单位\",\"parentid\":105,\"order\":99999500,\"hasChild\":1},{\"id\":109,\"name\":\"市文化旅游局\",\"parentid\":16,\"order\":99990500,\"hasChild\":1},{\"id\":110,\"name\":\"局领导\",\"parentid\":109,\"order\":100000000,\"hasChild\":0},{\"id\":111,\"name\":\"内设机构\",\"parentid\":109,\"order\":99999500,\"hasChild\":0},{\"id\":112,\"name\":\"直属单位\",\"parentid\":109,\"order\":99999000,\"hasChild\":0},{\"id\":113,\"name\":\"市卫生健康委\",\"parentid\":16,\"order\":99990000,\"hasChild\":1},{\"id\":114,\"name\":\"委领导\",\"parentid\":113,\"order\":100000000,\"hasChild\":0},{\"id\":115,\"name\":\"内设机构\",\"parentid\":113,\"order\":99999500,\"hasChild\":0},{\"id\":116,\"name\":\"直属单位\",\"parentid\":113,\"order\":99999000,\"hasChild\":0},{\"id\":117,\"name\":\"市退役军人局\",\"parentid\":16,\"order\":99989500,\"hasChild\":1},{\"id\":119,\"name\":\"局机关\",\"parentid\":117,\"order\":100000000,\"hasChild\":1},{\"id\":120,\"name\":\"局属单位\",\"parentid\":117,\"order\":99999500,\"hasChild\":1},{\"id\":121,\"name\":\"市应急局\",\"parentid\":16,\"order\":99989000,\"hasChild\":1},{\"id\":122,\"name\":\"局领导\",\"parentid\":121,\"order\":100000000,\"hasChild\":0},{\"id\":123,\"name\":\"内设机构\",\"parentid\":121,\"order\":99999500,\"hasChild\":0},{\"id\":124,\"name\":\"直属单位\",\"parentid\":121,\"order\":99999000,\"hasChild\":0},{\"id\":125,\"name\":\"市消防救援总队\",\"parentid\":121,\"order\":99998500,\"hasChild\":0},{\"id\":126,\"name\":\"市审计局\",\"parentid\":16,\"order\":99988500,\"hasChild\":1},{\"id\":127,\"name\":\"局领导\",\"parentid\":126,\"order\":100000000,\"hasChild\":0},{\"id\":128,\"name\":\"内设机构\",\"parentid\":126,\"order\":99999500,\"hasChild\":0},{\"id\":129,\"name\":\"直属单位\",\"parentid\":126,\"order\":99999000,\"hasChild\":0},{\"id\":130,\"name\":\"市市场监管局\",\"parentid\":16,\"order\":99988000,\"hasChild\":1},{\"id\":131,\"name\":\"局领导\",\"parentid\":130,\"order\":100000000,\"hasChild\":0},{\"id\":132,\"name\":\"内设机构\",\"parentid\":130,\"order\":99999500,\"hasChild\":0},{\"id\":133,\"name\":\"直属单位\",\"parentid\":130,\"order\":99999000,\"hasChild\":0},{\"id\":134,\"name\":\"市地方金融监管局\",\"parentid\":16,\"order\":99987500,\"hasChild\":1},{\"id\":135,\"name\":\"局领导\",\"parentid\":134,\"order\":100000000,\"hasChild\":0},{\"id\":136,\"name\":\"内设机构\",\"parentid\":134,\"order\":99999500,\"hasChild\":0},{\"id\":137,\"name\":\"直属单位\",\"parentid\":134,\"order\":99999000,\"hasChild\":0},{\"id\":138,\"name\":\"市政府外办\",\"parentid\":16,\"order\":99987000,\"hasChild\":1},{\"id\":139,\"name\":\"办领导\",\"parentid\":138,\"order\":100000000,\"hasChild\":0},{\"id\":140,\"name\":\"内设机构\",\"parentid\":138,\"order\":99999500,\"hasChild\":0},{\"id\":141,\"name\":\"直属单位\",\"parentid\":138,\"order\":99999000,\"hasChild\":0},{\"id\":142,\"name\":\"市国资委\",\"parentid\":16,\"order\":99986500,\"hasChild\":1},{\"id\":144,\"name\":\"委机关\",\"parentid\":142,\"order\":100000000,\"hasChild\":1},{\"id\":145,\"name\":\"委属单位\",\"parentid\":142,\"order\":99999500,\"hasChild\":1},{\"id\":146,\"name\":\"市体育局\",\"parentid\":16,\"order\":99986000,\"hasChild\":1},{\"id\":150,\"name\":\"市统计局\",\"parentid\":16,\"order\":99985500,\"hasChild\":1},{\"id\":151,\"name\":\"局领导\",\"parentid\":150,\"order\":100000000,\"hasChild\":0},{\"id\":152,\"name\":\"内设机构\",\"parentid\":150,\"order\":99999500,\"hasChild\":0},{\"id\":153,\"name\":\"直属单位\",\"parentid\":150,\"order\":99999000,\"hasChild\":0},{\"id\":154,\"name\":\"市医保局\",\"parentid\":16,\"order\":99985000,\"hasChild\":1},{\"id\":155,\"name\":\"局领导\",\"parentid\":154,\"order\":100000000,\"hasChild\":0},{\"id\":156,\"name\":\"内设机构\",\"parentid\":154,\"order\":99999500,\"hasChild\":0},{\"id\":157,\"name\":\"直属单位\",\"parentid\":154,\"order\":99999000,\"hasChild\":0},{\"id\":158,\"name\":\"市绿化市容局\",\"parentid\":16,\"order\":99984500,\"hasChild\":1},{\"id\":159,\"name\":\"局领导\",\"parentid\":158,\"order\":100000000,\"hasChild\":0},{\"id\":160,\"name\":\"内设机构\",\"parentid\":158,\"order\":99999500,\"hasChild\":0},{\"id\":161,\"name\":\"直属单位\",\"parentid\":158,\"order\":99999000,\"hasChild\":0},{\"id\":162,\"name\":\"市机管局\",\"parentid\":16,\"order\":99984000,\"hasChild\":1},{\"id\":166,\"name\":\"市民防办\",\"parentid\":16,\"order\":99983500,\"hasChild\":1},{\"id\":170,\"name\":\"市政府合作交流办\",\"parentid\":16,\"order\":99983000,\"hasChild\":1},{\"id\":171,\"name\":\"办领导\",\"parentid\":170,\"order\":100000000,\"hasChild\":0},{\"id\":172,\"name\":\"内设机构\",\"parentid\":170,\"order\":99999500,\"hasChild\":0},{\"id\":173,\"name\":\"直属单位\",\"parentid\":170,\"order\":99999000,\"hasChild\":0},{\"id\":174,\"name\":\"市政府研究室\",\"parentid\":16,\"order\":99982500,\"hasChild\":1},{\"id\":175,\"name\":\"室领导\",\"parentid\":174,\"order\":100000000,\"hasChild\":0},{\"id\":177,\"name\":\"直属单位\",\"parentid\":174,\"order\":99999000,\"hasChild\":0},{\"id\":178,\"name\":\"市政府参事室\",\"parentid\":16,\"order\":99982000,\"hasChild\":1},{\"id\":182,\"name\":\"市知识产权局\",\"parentid\":16,\"order\":99981500,\"hasChild\":1},{\"id\":183,\"name\":\"局领导\",\"parentid\":182,\"order\":100000000,\"hasChild\":0},{\"id\":184,\"name\":\"内设机构\",\"parentid\":182,\"order\":99999500,\"hasChild\":0},{\"id\":185,\"name\":\"直属单位\",\"parentid\":182,\"order\":99999000,\"hasChild\":0},{\"id\":186,\"name\":\"市粮食物资储备局\",\"parentid\":16,\"order\":99981000,\"hasChild\":1},{\"id\":187,\"name\":\"局领导\",\"parentid\":186,\"order\":100000000,\"hasChild\":0},{\"id\":188,\"name\":\"内设机构\",\"parentid\":186,\"order\":99999500,\"hasChild\":0},{\"id\":189,\"name\":\"直属单位\",\"parentid\":186,\"order\":99999000,\"hasChild\":0},{\"id\":190,\"name\":\"市监狱管理局\",\"parentid\":16,\"order\":99980500,\"hasChild\":1},{\"id\":191,\"name\":\"局领导\",\"parentid\":190,\"order\":100000000,\"hasChild\":0},{\"id\":192,\"name\":\"内设机构\",\"parentid\":190,\"order\":99999500,\"hasChild\":0},{\"id\":193,\"name\":\"直属单位\",\"parentid\":190,\"order\":99999000,\"hasChild\":0},{\"id\":194,\"name\":\"市城管执法局\",\"parentid\":16,\"order\":99980000,\"hasChild\":1},{\"id\":195,\"name\":\"局领导\",\"parentid\":194,\"order\":100000000,\"hasChild\":0},{\"id\":196,\"name\":\"内设机构\",\"parentid\":194,\"order\":99999500,\"hasChild\":0},{\"id\":197,\"name\":\"直属单位\",\"parentid\":194,\"order\":99999000,\"hasChild\":0},{\"id\":198,\"name\":\"市房屋管理局\",\"parentid\":16,\"order\":99979500,\"hasChild\":1},{\"id\":199,\"name\":\"局领导\",\"parentid\":198,\"order\":100000000,\"hasChild\":0},{\"id\":200,\"name\":\"内设机构\",\"parentid\":198,\"order\":99999500,\"hasChild\":0},{\"id\":201,\"name\":\"直属单位\",\"parentid\":198,\"order\":99999000,\"hasChild\":0},{\"id\":202,\"name\":\"市药品监督管理局\",\"parentid\":16,\"order\":99979000,\"hasChild\":1},{\"id\":203,\"name\":\"局领导\",\"parentid\":202,\"order\":100000000,\"hasChild\":0},{\"id\":204,\"name\":\"内设机构\",\"parentid\":202,\"order\":99999500,\"hasChild\":0},{\"id\":205,\"name\":\"直属单位\",\"parentid\":202,\"order\":99999000,\"hasChild\":0},{\"id\":206,\"name\":\"市道路运输管理局\",\"parentid\":16,\"order\":99978500,\"hasChild\":1},{\"id\":207,\"name\":\"局领导\",\"parentid\":206,\"order\":100000000,\"hasChild\":0},{\"id\":208,\"name\":\"内设机构\",\"parentid\":206,\"order\":99999500,\"hasChild\":0},{\"id\":209,\"name\":\"直属单位\",\"parentid\":206,\"order\":99999000,\"hasChild\":0},{\"id\":210,\"name\":\"国家税务总局上海市税务局\",\"parentid\":16,\"order\":99978000,\"hasChild\":1},{\"id\":211,\"name\":\"局领导\",\"parentid\":210,\"order\":100000000,\"hasChild\":0},{\"id\":212,\"name\":\"内设机构\",\"parentid\":210,\"order\":99999500,\"hasChild\":0},{\"id\":213,\"name\":\"直属单位\",\"parentid\":210,\"order\":99999000,\"hasChild\":0},{\"id\":214,\"name\":\"市政府发展研究中心\",\"parentid\":16,\"order\":99977500,\"hasChild\":1},{\"id\":215,\"name\":\"中心领导\",\"parentid\":214,\"order\":100000000,\"hasChild\":0},{\"id\":216,\"name\":\"内设机构\",\"parentid\":214,\"order\":99999500,\"hasChild\":0},{\"id\":217,\"name\":\"直属单位\",\"parentid\":214,\"order\":99999000,\"hasChild\":0},{\"id\":218,\"name\":\"市政协\",\"parentid\":1,\"order\":99997500,\"hasChild\":1},{\"id\":219,\"name\":\"市政协办公厅\",\"parentid\":218,\"order\":100000000,\"hasChild\":0},{\"id\":220,\"name\":\"市法院\",\"parentid\":1,\"order\":99998500,\"hasChild\":0},{\"id\":221,\"name\":\"市检察院\",\"parentid\":1,\"order\":99998000,\"hasChild\":0},{\"id\":222,\"name\":\"各区\",\"parentid\":1,\"order\":99997000,\"hasChild\":1},{\"id\":223,\"name\":\"浦东新区\",\"parentid\":222,\"order\":100000000,\"hasChild\":1},{\"id\":224,\"name\":\"区委\",\"parentid\":223,\"order\":100000000,\"hasChild\":0},{\"id\":225,\"name\":\"区人大\",\"parentid\":223,\"order\":99999500,\"hasChild\":0},{\"id\":226,\"name\":\"区政府\",\"parentid\":223,\"order\":99999000,\"hasChild\":0},{\"id\":227,\"name\":\"区政协\",\"parentid\":223,\"order\":99998500,\"hasChild\":0},{\"id\":228,\"name\":\"区法院\",\"parentid\":223,\"order\":99998000,\"hasChild\":0},{\"id\":229,\"name\":\"区检察院\",\"parentid\":223,\"order\":99997500,\"hasChild\":0},{\"id\":230,\"name\":\"街镇\",\"parentid\":223,\"order\":99997000,\"hasChild\":0},{\"id\":231,\"name\":\"黄浦区\",\"parentid\":222,\"order\":99999500,\"hasChild\":1},{\"id\":232,\"name\":\"区委\",\"parentid\":231,\"order\":100000000,\"hasChild\":0},{\"id\":233,\"name\":\"区人大\",\"parentid\":231,\"order\":99999500,\"hasChild\":0},{\"id\":234,\"name\":\"区政府\",\"parentid\":231,\"order\":99999000,\"hasChild\":0},{\"id\":235,\"name\":\"区政协\",\"parentid\":231,\"order\":99998500,\"hasChild\":0},{\"id\":236,\"name\":\"区法院\",\"parentid\":231,\"order\":99998000,\"hasChild\":0},{\"id\":237,\"name\":\"区检察院\",\"parentid\":231,\"order\":99997500,\"hasChild\":0},{\"id\":238,\"name\":\"街道\",\"parentid\":231,\"order\":99997000,\"hasChild\":0},{\"id\":239,\"name\":\"静安区\",\"parentid\":222,\"order\":99999000,\"hasChild\":1},{\"id\":240,\"name\":\"区委\",\"parentid\":239,\"order\":100000000,\"hasChild\":0},{\"id\":241,\"name\":\"区人大\",\"parentid\":239,\"order\":99999500,\"hasChild\":0},{\"id\":242,\"name\":\"区政府\",\"parentid\":239,\"order\":99999000,\"hasChild\":0},{\"id\":243,\"name\":\"区政协\",\"parentid\":239,\"order\":99998500,\"hasChild\":0},{\"id\":244,\"name\":\"区法院\",\"parentid\":239,\"order\":99998000,\"hasChild\":0},{\"id\":245,\"name\":\"区检察院\",\"parentid\":239,\"order\":99997500,\"hasChild\":0},{\"id\":246,\"name\":\"街镇\",\"parentid\":239,\"order\":99997000,\"hasChild\":0},{\"id\":247,\"name\":\"徐汇区\",\"parentid\":222,\"order\":99998500,\"hasChild\":1},{\"id\":248,\"name\":\"区委\",\"parentid\":247,\"order\":100000000,\"hasChild\":0},{\"id\":249,\"name\":\"区人大\",\"parentid\":247,\"order\":99999500,\"hasChild\":0},{\"id\":250,\"name\":\"区政府\",\"parentid\":247,\"order\":99999000,\"hasChild\":1},{\"id\":251,\"name\":\"区政协\",\"parentid\":247,\"order\":99998500,\"hasChild\":0},{\"id\":252,\"name\":\"区法院\",\"parentid\":247,\"order\":99998000,\"hasChild\":0},{\"id\":253,\"name\":\"区检察院\",\"parentid\":247,\"order\":99997500,\"hasChild\":0},{\"id\":254,\"name\":\"街镇\",\"parentid\":247,\"order\":99997000,\"hasChild\":0},{\"id\":255,\"name\":\"长宁区\",\"parentid\":222,\"order\":99998000,\"hasChild\":1},{\"id\":256,\"name\":\"区委\",\"parentid\":255,\"order\":100000000,\"hasChild\":0},{\"id\":257,\"name\":\"区人大\",\"parentid\":255,\"order\":99999500,\"hasChild\":0},{\"id\":258,\"name\":\"区政府\",\"parentid\":255,\"order\":99999000,\"hasChild\":0},{\"id\":259,\"name\":\"区政协\",\"parentid\":255,\"order\":99998500,\"hasChild\":0},{\"id\":260,\"name\":\"区法院\",\"parentid\":255,\"order\":99998000,\"hasChild\":0},{\"id\":261,\"name\":\"区检察院\",\"parentid\":255,\"order\":99997500,\"hasChild\":0},{\"id\":262,\"name\":\"街镇\",\"parentid\":255,\"order\":99997000,\"hasChild\":0},{\"id\":263,\"name\":\"普陀区\",\"parentid\":222,\"order\":99997500,\"hasChild\":1},{\"id\":264,\"name\":\"区委\",\"parentid\":263,\"order\":100000000,\"hasChild\":0},{\"id\":265,\"name\":\"区人大\",\"parentid\":263,\"order\":99999500,\"hasChild\":0},{\"id\":266,\"name\":\"区政府\",\"parentid\":263,\"order\":99999000,\"hasChild\":0},{\"id\":267,\"name\":\"区政协\",\"parentid\":263,\"order\":99998500,\"hasChild\":0},{\"id\":268,\"name\":\"区法院\",\"parentid\":263,\"order\":99998000,\"hasChild\":0},{\"id\":269,\"name\":\"区检察院\",\"parentid\":263,\"order\":99997500,\"hasChild\":0},{\"id\":270,\"name\":\"街镇\",\"parentid\":263,\"order\":99997000,\"hasChild\":0},{\"id\":271,\"name\":\"虹口区\",\"parentid\":222,\"order\":99997000,\"hasChild\":1},{\"id\":272,\"name\":\"区委\",\"parentid\":271,\"order\":100000000,\"hasChild\":0},{\"id\":273,\"name\":\"区人大\",\"parentid\":271,\"order\":99999500,\"hasChild\":0},{\"id\":274,\"name\":\"区政府\",\"parentid\":271,\"order\":99999000,\"hasChild\":0},{\"id\":275,\"name\":\"区政协\",\"parentid\":271,\"order\":99998500,\"hasChild\":0},{\"id\":276,\"name\":\"区法院\",\"parentid\":271,\"order\":99998000,\"hasChild\":0},{\"id\":277,\"name\":\"区检察院\",\"parentid\":271,\"order\":99997500,\"hasChild\":0},{\"id\":278,\"name\":\"街镇\",\"parentid\":271,\"order\":99997000,\"hasChild\":0},{\"id\":279,\"name\":\"杨浦区\",\"parentid\":222,\"order\":99996500,\"hasChild\":1},{\"id\":280,\"name\":\"区委\",\"parentid\":279,\"order\":100000000,\"hasChild\":0},{\"id\":281,\"name\":\"区人大\",\"parentid\":279,\"order\":99999500,\"hasChild\":0},{\"id\":282,\"name\":\"区政府\",\"parentid\":279,\"order\":99999000,\"hasChild\":0},{\"id\":283,\"name\":\"区政协\",\"parentid\":279,\"order\":99998500,\"hasChild\":0},{\"id\":284,\"name\":\"区法院\",\"parentid\":279,\"order\":99998000,\"hasChild\":0},{\"id\":285,\"name\":\"区检察院\",\"parentid\":279,\"order\":99997500,\"hasChild\":0},{\"id\":286,\"name\":\"街镇\",\"parentid\":279,\"order\":99997000,\"hasChild\":0},{\"id\":287,\"name\":\"宝山区\",\"parentid\":222,\"order\":99996000,\"hasChild\":1},{\"id\":288,\"name\":\"区委\",\"parentid\":287,\"order\":100000000,\"hasChild\":0},{\"id\":289,\"name\":\"区人大\",\"parentid\":287,\"order\":99999500,\"hasChild\":0},{\"id\":290,\"name\":\"区政府\",\"parentid\":287,\"order\":99999000,\"hasChild\":0},{\"id\":291,\"name\":\"区政协\",\"parentid\":287,\"order\":99998500,\"hasChild\":0},{\"id\":292,\"name\":\"区法院\",\"parentid\":287,\"order\":99998000,\"hasChild\":0},{\"id\":293,\"name\":\"区检察院\",\"parentid\":287,\"order\":99997500,\"hasChild\":0},{\"id\":294,\"name\":\"街镇\",\"parentid\":287,\"order\":99997000,\"hasChild\":0},{\"id\":295,\"name\":\"闵行区\",\"parentid\":222,\"order\":99995500,\"hasChild\":1},{\"id\":296,\"name\":\"区委\",\"parentid\":295,\"order\":100000000,\"hasChild\":0},{\"id\":297,\"name\":\"区人大\",\"parentid\":295,\"order\":99999500,\"hasChild\":0},{\"id\":298,\"name\":\"区政府\",\"parentid\":295,\"order\":99999000,\"hasChild\":0},{\"id\":299,\"name\":\"区政协\",\"parentid\":295,\"order\":99998500,\"hasChild\":0},{\"id\":300,\"name\":\"区法院\",\"parentid\":295,\"order\":99998000,\"hasChild\":0},{\"id\":301,\"name\":\"区检察院\",\"parentid\":295,\"order\":99997500,\"hasChild\":0},{\"id\":302,\"name\":\"街镇\",\"parentid\":295,\"order\":99997000,\"hasChild\":0},{\"id\":303,\"name\":\"嘉定区\",\"parentid\":222,\"order\":99995000,\"hasChild\":1},{\"id\":304,\"name\":\"区委\",\"parentid\":303,\"order\":100000000,\"hasChild\":0},{\"id\":305,\"name\":\"区人大\",\"parentid\":303,\"order\":99999500,\"hasChild\":0},{\"id\":306,\"name\":\"区政府\",\"parentid\":303,\"order\":99999000,\"hasChild\":0},{\"id\":307,\"name\":\"区政协\",\"parentid\":303,\"order\":99998500,\"hasChild\":0},{\"id\":308,\"name\":\"区法院\",\"parentid\":303,\"order\":99998000,\"hasChild\":0},{\"id\":309,\"name\":\"区检察院\",\"parentid\":303,\"order\":99997500,\"hasChild\":0},{\"id\":310,\"name\":\"街镇\",\"parentid\":303,\"order\":99997000,\"hasChild\":0},{\"id\":311,\"name\":\"金山区\",\"parentid\":222,\"order\":99994500,\"hasChild\":1},{\"id\":312,\"name\":\"区委\",\"parentid\":311,\"order\":100000000,\"hasChild\":0},{\"id\":313,\"name\":\"区人大\",\"parentid\":311,\"order\":99999500,\"hasChild\":0},{\"id\":314,\"name\":\"区政府\",\"parentid\":311,\"order\":99999000,\"hasChild\":0},{\"id\":315,\"name\":\"区政协\",\"parentid\":311,\"order\":99998500,\"hasChild\":0},{\"id\":316,\"name\":\"区法院\",\"parentid\":311,\"order\":99998000,\"hasChild\":0},{\"id\":317,\"name\":\"区检察院\",\"parentid\":311,\"order\":99997500,\"hasChild\":0},{\"id\":318,\"name\":\"街镇\",\"parentid\":311,\"order\":99997000,\"hasChild\":0},{\"id\":319,\"name\":\"松江区\",\"parentid\":222,\"order\":99994000,\"hasChild\":1},{\"id\":320,\"name\":\"区委\",\"parentid\":319,\"order\":100000000,\"hasChild\":0},{\"id\":321,\"name\":\"区人大\",\"parentid\":319,\"order\":99999500,\"hasChild\":0},{\"id\":322,\"name\":\"区政府\",\"parentid\":319,\"order\":99999000,\"hasChild\":0},{\"id\":323,\"name\":\"区政协\",\"parentid\":319,\"order\":99998500,\"hasChild\":0},{\"id\":324,\"name\":\"区法院\",\"parentid\":319,\"order\":99998000,\"hasChild\":0},{\"id\":325,\"name\":\"区检察院\",\"parentid\":319,\"order\":99997500,\"hasChild\":0},{\"id\":326,\"name\":\"街镇\",\"parentid\":319,\"order\":99997000,\"hasChild\":0},{\"id\":327,\"name\":\"青浦区\",\"parentid\":222,\"order\":99993500,\"hasChild\":1},{\"id\":328,\"name\":\"区委\",\"parentid\":327,\"order\":100000000,\"hasChild\":0},{\"id\":329,\"name\":\"区人大\",\"parentid\":327,\"order\":99999500,\"hasChild\":0},{\"id\":330,\"name\":\"区政府\",\"parentid\":327,\"order\":99999000,\"hasChild\":0},{\"id\":331,\"name\":\"区政协\",\"parentid\":327,\"order\":99998500,\"hasChild\":0},{\"id\":332,\"name\":\"区法院\",\"parentid\":327,\"order\":99998000,\"hasChild\":0},{\"id\":333,\"name\":\"区检察院\",\"parentid\":327,\"order\":99997500,\"hasChild\":0},{\"id\":334,\"name\":\"街镇\",\"parentid\":327,\"order\":99997000,\"hasChild\":0},{\"id\":335,\"name\":\"奉贤区\",\"parentid\":222,\"order\":99993000,\"hasChild\":1},{\"id\":336,\"name\":\"区委\",\"parentid\":335,\"order\":100000000,\"hasChild\":0},{\"id\":337,\"name\":\"区人大\",\"parentid\":335,\"order\":99999500,\"hasChild\":0},{\"id\":338,\"name\":\"区政府\",\"parentid\":335,\"order\":99999000,\"hasChild\":0},{\"id\":339,\"name\":\"区政协\",\"parentid\":335,\"order\":99998500,\"hasChild\":0},{\"id\":340,\"name\":\"区法院\",\"parentid\":335,\"order\":99998000,\"hasChild\":0},{\"id\":341,\"name\":\"区检察院\",\"parentid\":335,\"order\":99997500,\"hasChild\":0},{\"id\":342,\"name\":\"街镇\",\"parentid\":335,\"order\":99997000,\"hasChild\":0},{\"id\":343,\"name\":\"崇明区\",\"parentid\":222,\"order\":99992500,\"hasChild\":1},{\"id\":344,\"name\":\"区委\",\"parentid\":343,\"order\":100000000,\"hasChild\":0},{\"id\":345,\"name\":\"区人大\",\"parentid\":343,\"order\":99999500,\"hasChild\":0},{\"id\":346,\"name\":\"区政府\",\"parentid\":343,\"order\":99999000,\"hasChild\":0},{\"id\":347,\"name\":\"区政协\",\"parentid\":343,\"order\":99998500,\"hasChild\":0},{\"id\":348,\"name\":\"区法院\",\"parentid\":343,\"order\":99998000,\"hasChild\":0},{\"id\":349,\"name\":\"区检察院\",\"parentid\":343,\"order\":99997500,\"hasChild\":0},{\"id\":350,\"name\":\"街道乡镇\",\"parentid\":343,\"order\":99997000,\"hasChild\":0},{\"id\":351,\"name\":\"业务条线\",\"parentid\":1,\"order\":99996500,\"hasChild\":1},{\"id\":352,\"name\":\"办公室和值班室系统\",\"parentid\":351,\"order\":99999500,\"hasChild\":0},{\"id\":353,\"name\":\"城运系统\",\"parentid\":351,\"order\":99999000,\"hasChild\":0},{\"id\":354,\"name\":\"网格系统\",\"parentid\":351,\"order\":99998500,\"hasChild\":0},{\"id\":355,\"name\":\"防汛防台系统\",\"parentid\":351,\"order\":99998000,\"hasChild\":0},{\"id\":356,\"name\":\"统一综合执法系统\",\"parentid\":351,\"order\":99997000,\"hasChild\":0},{\"id\":357,\"name\":\"重要会议保障\",\"parentid\":351,\"order\":99997500,\"hasChild\":0},{\"id\":358,\"name\":\"TEST-ZONE\",\"parentid\":667,\"order\":100000000,\"hasChild\":1},{\"id\":360,\"name\":\"正通过管理通讯录同时可手动编辑正\",\"parentid\":404,\"order\":100000000,\"hasChild\":1},{\"id\":362,\"name\":\"测试数据\",\"parentid\":358,\"order\":99999500,\"hasChild\":0},{\"id\":363,\"name\":\"测试数据1\",\"parentid\":358,\"order\":99993500,\"hasChild\":1},{\"id\":364,\"name\":\"测试数据2\",\"parentid\":358,\"order\":99994500,\"hasChild\":0},{\"id\":365,\"name\":\"超长部门名称测试超长部门名称测试\",\"parentid\":363,\"order\":100000000,\"hasChild\":0},{\"id\":366,\"name\":\"测试子部门\",\"parentid\":450,\"order\":99999500,\"hasChild\":0},{\"id\":368,\"name\":\"新建子部门\",\"parentid\":408,\"order\":99999000,\"hasChild\":0},{\"id\":369,\"name\":\"测试\",\"parentid\":358,\"order\":99998000,\"hasChild\":1},{\"id\":376,\"name\":\"1\",\"parentid\":450,\"order\":100000000,\"hasChild\":0},{\"id\":377,\"name\":\"23333\",\"parentid\":450,\"order\":99998500,\"hasChild\":0},{\"id\":378,\"name\":\"3\",\"parentid\":405,\"order\":100000000,\"hasChild\":1},{\"id\":380,\"name\":\"2\",\"parentid\":358,\"order\":99996000,\"hasChild\":1},{\"id\":399,\"name\":\"正在通过管理员权限\",\"parentid\":360,\"order\":100000000,\"hasChild\":0},{\"id\":400,\"name\":\"正在通过\",\"parentid\":405,\"order\":99999500,\"hasChild\":0},{\"id\":403,\"name\":\"1\",\"parentid\":358,\"order\":99996500,\"hasChild\":0},{\"id\":404,\"name\":\"21\",\"parentid\":450,\"order\":99999000,\"hasChild\":1},{\"id\":405,\"name\":\"dy测试\",\"parentid\":358,\"order\":99998500,\"hasChild\":1},{\"id\":406,\"name\":\"asdfa\",\"parentid\":408,\"order\":100000000,\"hasChild\":0},{\"id\":407,\"name\":\"asdfasdf'\",\"parentid\":408,\"order\":99998500,\"hasChild\":0},{\"id\":408,\"name\":\"dy测试22\",\"parentid\":405,\"order\":99999000,\"hasChild\":1},{\"id\":410,\"name\":\"局领导班子\",\"parentid\":107,\"order\":100000000,\"hasChild\":0},{\"id\":411,\"name\":\"二级巡视员\",\"parentid\":107,\"order\":99999500,\"hasChild\":0},{\"id\":412,\"name\":\"办公室\",\"parentid\":107,\"order\":99999000,\"hasChild\":0},{\"id\":413,\"name\":\"政策研究室\",\"parentid\":107,\"order\":99998500,\"hasChild\":0},{\"id\":414,\"name\":\"法规处\",\"parentid\":107,\"order\":99998000,\"hasChild\":0},{\"id\":415,\"name\":\"组织人事处(老干部处)\",\"parentid\":107,\"order\":99997500,\"hasChild\":0},{\"id\":416,\"name\":\"综合规划处\",\"parentid\":107,\"order\":99997000,\"hasChild\":0},{\"id\":417,\"name\":\"计划财务处\",\"parentid\":107,\"order\":99996500,\"hasChild\":0},{\"id\":418,\"name\":\"科技信息处(社会宣传处)\",\"parentid\":107,\"order\":99996000,\"hasChild\":0},{\"id\":419,\"name\":\"河长制工作处(综合督导处)\",\"parentid\":107,\"order\":99995500,\"hasChild\":0},{\"id\":420,\"name\":\"水资源管理处(上海市节约用水办公室)\",\"parentid\":107,\"order\":99995000,\"hasChild\":0},{\"id\":421,\"name\":\"建设管理处\",\"parentid\":107,\"order\":99994500,\"hasChild\":0},{\"id\":422,\"name\":\"水利管理处(水土保持处)\",\"parentid\":107,\"order\":99994000,\"hasChild\":0},{\"id\":423,\"name\":\"海域海岛管理处(海洋经济协调处)\",\"parentid\":107,\"order\":99993500,\"hasChild\":0},{\"id\":424,\"name\":\"水旱和海洋灾害防御处\",\"parentid\":107,\"order\":99993000,\"hasChild\":0},{\"id\":425,\"name\":\"设施运行管理处(安全监督处)\",\"parentid\":107,\"order\":99992500,\"hasChild\":0},{\"id\":426,\"name\":\"审计室\",\"parentid\":107,\"order\":99992000,\"hasChild\":0},{\"id\":427,\"name\":\"工会\",\"parentid\":107,\"order\":99991500,\"hasChild\":0},{\"id\":428,\"name\":\"机关党委\",\"parentid\":107,\"order\":99991000,\"hasChild\":0},{\"id\":429,\"name\":\"团委\",\"parentid\":107,\"order\":99990500,\"hasChild\":0},{\"id\":430,\"name\":\"纪检监察组\",\"parentid\":107,\"order\":99990000,\"hasChild\":0},{\"id\":431,\"name\":\"文印室\",\"parentid\":107,\"order\":99989500,\"hasChild\":0},{\"id\":432,\"name\":\"局网站编辑部\",\"parentid\":107,\"order\":99989000,\"hasChild\":0},{\"id\":433,\"name\":\"水务志编辑室\",\"parentid\":107,\"order\":99988500,\"hasChild\":0},{\"id\":434,\"name\":\"老干部活动中心\",\"parentid\":107,\"order\":99988000,\"hasChild\":0},{\"id\":435,\"name\":\"上海市水务局执法总队(中国海监上海市总队)\",\"parentid\":108,\"order\":100000000,\"hasChild\":0},{\"id\":436,\"name\":\"上海市水务局行政服务中心(上海市海洋局行政服务中心)\",\"parentid\":108,\"order\":99999500,\"hasChild\":0},{\"id\":437,\"name\":\"上海市水利管理事务中心(上海市河湖管理事务中心)\",\"parentid\":108,\"order\":99999000,\"hasChild\":0},{\"id\":438,\"name\":\"上海市供水管理事务中心(上海市节约用水促进中心)\",\"parentid\":108,\"order\":99998500,\"hasChild\":0},{\"id\":439,\"name\":\"上海市排水管理事务中心\",\"parentid\":108,\"order\":99998000,\"hasChild\":0},{\"id\":440,\"name\":\"上海市堤防泵闸建设运行中心\",\"parentid\":108,\"order\":99997500,\"hasChild\":0},{\"id\":441,\"name\":\"上海市水文总站\",\"parentid\":108,\"order\":99997000,\"hasChild\":0},{\"id\":442,\"name\":\"上海市水务规划设计研究院(上海市海洋规划设计研究院)\",\"parentid\":108,\"order\":99996500,\"hasChild\":0},{\"id\":443,\"name\":\"上海市供水调度监测中心\",\"parentid\":108,\"order\":99996000,\"hasChild\":0},{\"id\":444,\"name\":\"上海市水务建设工程安全质量监督中心站(上海市水务工程定额管理站)\",\"parentid\":108,\"order\":99995500,\"hasChild\":0},{\"id\":445,\"name\":\"上海市水旱灾害防御技术中心\",\"parentid\":108,\"order\":99995000,\"hasChild\":0},{\"id\":446,\"name\":\"上海市海洋管理事务中心\",\"parentid\":108,\"order\":99994500,\"hasChild\":0},{\"id\":447,\"name\":\"上海市海洋监测预报中心\",\"parentid\":108,\"order\":99994000,\"hasChild\":0},{\"id\":449,\"name\":\"一个部门\",\"parentid\":378,\"order\":99999000,\"hasChild\":0},{\"id\":450,\"name\":\"test\",\"parentid\":380,\"order\":99999500,\"hasChild\":1},{\"id\":453,\"name\":\"委领导\",\"parentid\":144,\"order\":100000000,\"hasChild\":0},{\"id\":454,\"name\":\"党委办公室\",\"parentid\":144,\"order\":99999500,\"hasChild\":0},{\"id\":455,\"name\":\"组织处\",\"parentid\":144,\"order\":99999000,\"hasChild\":0},{\"id\":456,\"name\":\"宣传处\",\"parentid\":144,\"order\":99998500,\"hasChild\":0},{\"id\":457,\"name\":\"企业领导人员管理处\",\"parentid\":144,\"order\":99998000,\"hasChild\":0},{\"id\":458,\"name\":\"老干部处\",\"parentid\":144,\"order\":99997500,\"hasChild\":0},{\"id\":459,\"name\":\"办公室\",\"parentid\":144,\"order\":99997000,\"hasChild\":0},{\"id\":460,\"name\":\"人事处\",\"parentid\":144,\"order\":99996500,\"hasChild\":0},{\"id\":461,\"name\":\"研究室\",\"parentid\":144,\"order\":99996000,\"hasChild\":0},{\"id\":462,\"name\":\"政策法规处\",\"parentid\":144,\"order\":99995500,\"hasChild\":0},{\"id\":463,\"name\":\"规划发展处\",\"parentid\":144,\"order\":99995000,\"hasChild\":0},{\"id\":464,\"name\":\"创新发展处\",\"parentid\":144,\"order\":99994500,\"hasChild\":0},{\"id\":465,\"name\":\"企业改革处(城镇集体资产管理处)\",\"parentid\":144,\"order\":99994000,\"hasChild\":0},{\"id\":466,\"name\":\"金融企业发展处\",\"parentid\":144,\"order\":99993500,\"hasChild\":0},{\"id\":467,\"name\":\"产权管理处(资本运营管理处)\",\"parentid\":144,\"order\":99993000,\"hasChild\":0},{\"id\":468,\"name\":\"评估管理处\",\"parentid\":144,\"order\":99992500,\"hasChild\":0},{\"id\":469,\"name\":\"审计监督处(稽查办公室)\",\"parentid\":144,\"order\":99992000,\"hasChild\":0},{\"id\":470,\"name\":\"财务评价处\",\"parentid\":144,\"order\":99991500,\"hasChild\":0},{\"id\":471,\"name\":\"业绩考核处\",\"parentid\":144,\"order\":99991000,\"hasChild\":0},{\"id\":472,\"name\":\"分配保障处\",\"parentid\":144,\"order\":99990500,\"hasChild\":0},{\"id\":473,\"name\":\"综合协调处\",\"parentid\":144,\"order\":99990000,\"hasChild\":0},{\"id\":474,\"name\":\"公司治理处\",\"parentid\":144,\"order\":99989500,\"hasChild\":0},{\"id\":475,\"name\":\"信息化管理处\",\"parentid\":144,\"order\":99989000,\"hasChild\":0},{\"id\":476,\"name\":\"信访办公室\",\"parentid\":144,\"order\":99988500,\"hasChild\":0},{\"id\":477,\"name\":\"直属机关党委\",\"parentid\":144,\"order\":99988000,\"hasChild\":0},{\"id\":478,\"name\":\"上海市国有资产监督管理委员会企业发展服务中心\",\"parentid\":145,\"order\":100000000,\"hasChild\":0},{\"id\":479,\"name\":\"上海市国资国企改革发展研究中心\",\"parentid\":145,\"order\":99999500,\"hasChild\":0},{\"id\":480,\"name\":\"上海市国有企业绩效评价中心(上海市国有资产监督管理委员会稽查事务中心)\",\"parentid\":145,\"order\":99999000,\"hasChild\":0},{\"id\":481,\"name\":\"局领导\",\"parentid\":119,\"order\":100000000,\"hasChild\":0},{\"id\":482,\"name\":\"办公室\",\"parentid\":119,\"order\":99999500,\"hasChild\":0},{\"id\":483,\"name\":\"组织人事处\",\"parentid\":119,\"order\":99999000,\"hasChild\":0},{\"id\":484,\"name\":\"政策法规处\",\"parentid\":119,\"order\":99998500,\"hasChild\":0},{\"id\":485,\"name\":\"规划财务处\",\"parentid\":119,\"order\":99998000,\"hasChild\":0},{\"id\":486,\"name\":\"思想政治和权益维护处\",\"parentid\":119,\"order\":99997500,\"hasChild\":0},{\"id\":487,\"name\":\"移交安置处(就业创业处)\",\"parentid\":119,\"order\":99997000,\"hasChild\":0},{\"id\":488,\"name\":\"军休服务管理处\",\"parentid\":119,\"order\":99996500,\"hasChild\":0},{\"id\":489,\"name\":\"拥军优抚处(褒扬纪念处)\",\"parentid\":119,\"order\":99996000,\"hasChild\":0},{\"id\":490,\"name\":\"直属机关党委\",\"parentid\":119,\"order\":99995500,\"hasChild\":0},{\"id\":491,\"name\":\"上海市双拥服务中心\",\"parentid\":120,\"order\":100000000,\"hasChild\":0},{\"id\":492,\"name\":\"上海市军队离休退休干部活动中心\",\"parentid\":120,\"order\":99999500,\"hasChild\":0},{\"id\":493,\"name\":\"上海市荣誉军人疗养院\",\"parentid\":120,\"order\":99999000,\"hasChild\":0},{\"id\":494,\"name\":\"上海市龙华烈士陵园(龙华烈士纪念馆)\",\"parentid\":120,\"order\":99998500,\"hasChild\":0},{\"id\":495,\"name\":\"上海市军队离退休干部古美休养所\",\"parentid\":120,\"order\":99998000,\"hasChild\":0},{\"id\":496,\"name\":\"上海市军供站\",\"parentid\":120,\"order\":99997500,\"hasChild\":0},{\"id\":497,\"name\":\"上海市退役军人服务中心\",\"parentid\":120,\"order\":99997000,\"hasChild\":0},{\"id\":498,\"name\":\"参事室领导\",\"parentid\":178,\"order\":100000000,\"hasChild\":0},{\"id\":499,\"name\":\"秘书处\",\"parentid\":503,\"order\":100000000,\"hasChild\":0},{\"id\":500,\"name\":\"宣传交流处\",\"parentid\":503,\"order\":99999500,\"hasChild\":0},{\"id\":501,\"name\":\"参事业务处\",\"parentid\":503,\"order\":99999000,\"hasChild\":0},{\"id\":502,\"name\":\"组织人事处\",\"parentid\":503,\"order\":99998500,\"hasChild\":0},{\"id\":503,\"name\":\"内设机构\",\"parentid\":178,\"order\":99999500,\"hasChild\":1},{\"id\":504,\"name\":\"局机关\",\"parentid\":162,\"order\":100000000,\"hasChild\":1},{\"id\":505,\"name\":\"办公室\",\"parentid\":504,\"order\":100000000,\"hasChild\":0},{\"id\":506,\"name\":\"政策法规处(研究室)\",\"parentid\":504,\"order\":99999500,\"hasChild\":0},{\"id\":507,\"name\":\"人事处(老干部处)\",\"parentid\":504,\"order\":99999000,\"hasChild\":0},{\"id\":508,\"name\":\"财务处(审计室)\",\"parentid\":504,\"order\":99998500,\"hasChild\":0},{\"id\":509,\"name\":\"国有资产管理处\",\"parentid\":504,\"order\":99998000,\"hasChild\":0},{\"id\":510,\"name\":\"办公用房与人防设施处\",\"parentid\":504,\"order\":99997500,\"hasChild\":0},{\"id\":511,\"name\":\"车辆管理处\",\"parentid\":504,\"order\":99997000,\"hasChild\":0},{\"id\":512,\"name\":\"公共机构节能管理处\",\"parentid\":504,\"order\":99996500,\"hasChild\":0},{\"id\":513,\"name\":\"服务监管处(后勤改革指导处)\",\"parentid\":504,\"order\":99996000,\"hasChild\":0},{\"id\":514,\"name\":\"住房管理处\",\"parentid\":504,\"order\":99995500,\"hasChild\":0},{\"id\":515,\"name\":\"局管单位\",\"parentid\":162,\"order\":99999000,\"hasChild\":1},{\"id\":516,\"name\":\"上海市孙中山宋庆龄文物管理委员会\",\"parentid\":515,\"order\":100000000,\"hasChild\":0},{\"id\":517,\"name\":\"上海上勤(集团)有限公司\",\"parentid\":515,\"order\":99999500,\"hasChild\":0},{\"id\":518,\"name\":\"上海展览中心(集团)有限公司\",\"parentid\":515,\"order\":99999000,\"hasChild\":0},{\"id\":519,\"name\":\"上海孙中山故居纪念馆\",\"parentid\":515,\"order\":99998500,\"hasChild\":0},{\"id\":520,\"name\":\"上海宋庆龄故居纪念馆\",\"parentid\":515,\"order\":99998000,\"hasChild\":0},{\"id\":521,\"name\":\"中华人民共和国名誉主席宋庆龄陵园管理处(上海市万国公墓管理处)\",\"parentid\":515,\"order\":99997500,\"hasChild\":0},{\"id\":522,\"name\":\"局机关\",\"parentid\":146,\"order\":100000000,\"hasChild\":1},{\"id\":523,\"name\":\"局领导\",\"parentid\":522,\"order\":100000000,\"hasChild\":0},{\"id\":524,\"name\":\"办公室\",\"parentid\":522,\"order\":99999500,\"hasChild\":0},{\"id\":525,\"name\":\"规划产业处(法规处)\",\"parentid\":522,\"order\":99999000,\"hasChild\":0},{\"id\":526,\"name\":\"人事处(外事处)\",\"parentid\":522,\"order\":99998500,\"hasChild\":0},{\"id\":527,\"name\":\"财务处(设施建设处)\",\"parentid\":522,\"order\":99998000,\"hasChild\":0},{\"id\":528,\"name\":\"群众体育处\",\"parentid\":522,\"order\":99997500,\"hasChild\":0},{\"id\":529,\"name\":\"竞技体育处\",\"parentid\":522,\"order\":99997000,\"hasChild\":0},{\"id\":530,\"name\":\"青少年体育处(科教处)\",\"parentid\":522,\"order\":99996500,\"hasChild\":0},{\"id\":531,\"name\":\"竞赛处\",\"parentid\":522,\"order\":99996000,\"hasChild\":0},{\"id\":532,\"name\":\"局属单位\",\"parentid\":146,\"order\":99999500,\"hasChild\":1},{\"id\":533,\"name\":\"上海棋院(上海市棋牌运动管理中心)\",\"parentid\":532,\"order\":100000000,\"hasChild\":0},{\"id\":534,\"name\":\"上海市第二体育运动学校(上海市体育中学)\",\"parentid\":532,\"order\":99999500,\"hasChild\":0},{\"id\":535,\"name\":\"上海市划船俱乐部\",\"parentid\":532,\"order\":99999000,\"hasChild\":0},{\"id\":536,\"name\":\"上海市竞技体育训练管理中心\",\"parentid\":532,\"order\":99998500,\"hasChild\":0},{\"id\":537,\"name\":\"上海市科技体育运动管理中心\",\"parentid\":532,\"order\":99998000,\"hasChild\":0},{\"id\":538,\"name\":\"上海市马术运动管理中心\",\"parentid\":532,\"order\":99997500,\"hasChild\":0},{\"id\":539,\"name\":\"上海市青少年训练管理中心\",\"parentid\":532,\"order\":99997000,\"hasChild\":0},{\"id\":540,\"name\":\"上海市社会体育管理中心\",\"parentid\":532,\"order\":99996500,\"hasChild\":0},{\"id\":541,\"name\":\"上海市体育彩票管理中心\",\"parentid\":532,\"order\":99996000,\"hasChild\":0},{\"id\":542,\"name\":\"上海市体育场馆设施管理中心\",\"parentid\":532,\"order\":99995500,\"hasChild\":0},{\"id\":543,\"name\":\"上海市体育发展服务中心\",\"parentid\":532,\"order\":99995000,\"hasChild\":0},{\"id\":544,\"name\":\"上海市体育宣传教育中心\",\"parentid\":532,\"order\":99994500,\"hasChild\":0},{\"id\":545,\"name\":\"上海市体育训练基地管理中心\",\"parentid\":532,\"order\":99994000,\"hasChild\":0},{\"id\":546,\"name\":\"上海市体育运动学校\",\"parentid\":532,\"order\":99993500,\"hasChild\":0},{\"id\":547,\"name\":\"上海体育科学研究所(上海市反兴奋剂中心)\",\"parentid\":532,\"order\":99993000,\"hasChild\":0},{\"id\":548,\"name\":\"上海武术院(上海市健身气功管理中心)\",\"parentid\":532,\"order\":99992500,\"hasChild\":0},{\"id\":549,\"name\":\"上海市体育发展基金会\",\"parentid\":532,\"order\":99992000,\"hasChild\":0},{\"id\":550,\"name\":\"办机关\",\"parentid\":166,\"order\":100000000,\"hasChild\":1},{\"id\":551,\"name\":\"办领导\",\"parentid\":550,\"order\":100000000,\"hasChild\":0},{\"id\":552,\"name\":\"秘书处\",\"parentid\":550,\"order\":99999500,\"hasChild\":0},{\"id\":553,\"name\":\"政策法规处(审计监督室)\",\"parentid\":550,\"order\":99999000,\"hasChild\":0},{\"id\":554,\"name\":\"指挥通信处\",\"parentid\":550,\"order\":99998500,\"hasChild\":0},{\"id\":555,\"name\":\"工程处\",\"parentid\":550,\"order\":99998000,\"hasChild\":0},{\"id\":556,\"name\":\"科技宣教处\",\"parentid\":550,\"order\":99997500,\"hasChild\":0},{\"id\":557,\"name\":\"计划财务处\",\"parentid\":550,\"order\":99997000,\"hasChild\":0},{\"id\":558,\"name\":\"组织人事处\",\"parentid\":550,\"order\":99996500,\"hasChild\":0},{\"id\":559,\"name\":\"直属单位\",\"parentid\":166,\"order\":99999500,\"hasChild\":1},{\"id\":560,\"name\":\"上海市民防监督管理事务中心\",\"parentid\":559,\"order\":100000000,\"hasChild\":0},{\"id\":561,\"name\":\"上海市民防科学研究所\",\"parentid\":559,\"order\":99999500,\"hasChild\":0},{\"id\":562,\"name\":\"上海市民防指挥信息保障中心\",\"parentid\":559,\"order\":99999000,\"hasChild\":0},{\"id\":563,\"name\":\"上海市民防特种救援中心\",\"parentid\":559,\"order\":99998500,\"hasChild\":0},{\"id\":564,\"name\":\"上海市民防教育培训中心\",\"parentid\":559,\"order\":99998000,\"hasChild\":0},{\"id\":565,\"name\":\"局机关\",\"parentid\":89,\"order\":100000000,\"hasChild\":1},{\"id\":566,\"name\":\"局领导\",\"parentid\":565,\"order\":100000000,\"hasChild\":0},{\"id\":567,\"name\":\"办公室(宣传教育处、信访办公室)\",\"parentid\":565,\"order\":99999500,\"hasChild\":0},{\"id\":568,\"name\":\"生态环境保护督察办公室  \",\"parentid\":565,\"order\":99999000,\"hasChild\":0},{\"id\":569,\"name\":\"综合规划处(区域协作处)\",\"parentid\":565,\"order\":99998500,\"hasChild\":0},{\"id\":570,\"name\":\"法规与标准处\",\"parentid\":565,\"order\":99998000,\"hasChild\":0},{\"id\":571,\"name\":\"干部人事处\",\"parentid\":565,\"order\":99997500,\"hasChild\":0},{\"id\":572,\"name\":\"科技与国际合作处\",\"parentid\":565,\"order\":99997000,\"hasChild\":0},{\"id\":573,\"name\":\"自然生态保护处 \",\"parentid\":565,\"order\":99996500,\"hasChild\":0},{\"id\":574,\"name\":\"水生态环境处\",\"parentid\":565,\"order\":99996000,\"hasChild\":0},{\"id\":575,\"name\":\"海洋生态环境处\",\"parentid\":565,\"order\":99995500,\"hasChild\":0},{\"id\":576,\"name\":\"大气生态环境处\",\"parentid\":565,\"order\":99995000,\"hasChild\":0},{\"id\":577,\"name\":\"应对气候变化处\",\"parentid\":565,\"order\":99994500,\"hasChild\":0},{\"id\":578,\"name\":\"土壤生态环境处(固体废物与化学品处)\",\"parentid\":565,\"order\":99994000,\"hasChild\":0},{\"id\":579,\"name\":\"辐射安全管理处\",\"parentid\":565,\"order\":99993500,\"hasChild\":0},{\"id\":580,\"name\":\"环境影响评价与排放管理处\",\"parentid\":565,\"order\":99993000,\"hasChild\":0},{\"id\":581,\"name\":\"生态环境监测处\",\"parentid\":565,\"order\":99992500,\"hasChild\":0},{\"id\":582,\"name\":\"生态环境执法与应急处\",\"parentid\":565,\"order\":99992000,\"hasChild\":0},{\"id\":583,\"name\":\"局属单位\",\"parentid\":89,\"order\":99999500,\"hasChild\":1},{\"id\":584,\"name\":\"上海市环境科学研究院\",\"parentid\":583,\"order\":100000000,\"hasChild\":0},{\"id\":585,\"name\":\"上海市环境监测中心\",\"parentid\":583,\"order\":99999500,\"hasChild\":0},{\"id\":586,\"name\":\"上海市生态环境局执法总队\",\"parentid\":583,\"order\":99999000,\"hasChild\":0},{\"id\":587,\"name\":\"上海市辐射环境安全技术中心\",\"parentid\":583,\"order\":99998500,\"hasChild\":0},{\"id\":588,\"name\":\"上海市固体废物与化学品管理技术中心\",\"parentid\":583,\"order\":99998000,\"hasChild\":0},{\"id\":589,\"name\":\"上海市环境保护宣传教育中心\",\"parentid\":583,\"order\":99997500,\"hasChild\":0},{\"id\":590,\"name\":\"测试部门\",\"parentid\":358,\"order\":99997500,\"hasChild\":1},{\"id\":591,\"name\":\"测试子部门\",\"parentid\":590,\"order\":99999500,\"hasChild\":0},{\"id\":592,\"name\":\"测试子部门1\",\"parentid\":590,\"order\":100000000,\"hasChild\":0},{\"id\":593,\"name\":\"测试子部门2\",\"parentid\":590,\"order\":99999000,\"hasChild\":0},{\"id\":599,\"name\":\"推送简单\",\"parentid\":358,\"order\":99997000,\"hasChild\":1},{\"id\":602,\"name\":\"推送主节点变更测试\",\"parentid\":599,\"order\":99999500,\"hasChild\":0},{\"id\":603,\"name\":\"推送子部门\",\"parentid\":675,\"order\":100000000,\"hasChild\":1},{\"id\":606,\"name\":\"导出\",\"parentid\":358,\"order\":99995500,\"hasChild\":0},{\"id\":607,\"name\":\"ces\",\"parentid\":358,\"order\":99995000,\"hasChild\":0},{\"id\":610,\"name\":\"测试10-12\",\"parentid\":380,\"order\":100000000,\"hasChild\":0},{\"id\":611,\"name\":\"上海市大数据股份有限公司\",\"parentid\":351,\"order\":100000000,\"hasChild\":1},{\"id\":612,\"name\":\"人力资源管理部门\",\"parentid\":611,\"order\":99998500,\"hasChild\":0},{\"id\":613,\"name\":\"其他一些股份制有限公司\",\"parentid\":358,\"order\":99999000,\"hasChild\":1},{\"id\":614,\"name\":\"技术研发部门\",\"parentid\":611,\"order\":99998000,\"hasChild\":1},{\"id\":615,\"name\":\"行政执行部门\",\"parentid\":611,\"order\":99999500,\"hasChild\":0},{\"id\":616,\"name\":\"总裁办公室\",\"parentid\":611,\"order\":100000000,\"hasChild\":0},{\"id\":618,\"name\":\"行业集成组\",\"parentid\":614,\"order\":99999000,\"hasChild\":0},{\"id\":619,\"name\":\"云资源管理组\",\"parentid\":614,\"order\":100000000,\"hasChild\":0},{\"id\":620,\"name\":\"网络安全与运营维护组\",\"parentid\":614,\"order\":99998000,\"hasChild\":1},{\"id\":621,\"name\":\"大数据组\",\"parentid\":614,\"order\":99997500,\"hasChild\":0},{\"id\":622,\"name\":\"局属单位\",\"parentid\":162,\"order\":99999500,\"hasChild\":1},{\"id\":623,\"name\":\"离职人员\",\"parentid\":613,\"order\":100000000,\"hasChild\":0},{\"id\":624,\"name\":\"上海市市级机关建设管理事务中心\",\"parentid\":622,\"order\":100000000,\"hasChild\":0},{\"id\":625,\"name\":\"上海市市级机关国有资产事务中心(上海市机关事务行政服务中心)\",\"parentid\":622,\"order\":99999500,\"hasChild\":0},{\"id\":626,\"name\":\"上海市机关事务管理局人防工程管理中心(上海市机关事务管理局老干部活动室)\",\"parentid\":622,\"order\":99999000,\"hasChild\":0},{\"id\":627,\"name\":\"上海市市级机关第二幼儿园\",\"parentid\":622,\"order\":99998500,\"hasChild\":0},{\"id\":628,\"name\":\"上海市政府采购中心\",\"parentid\":622,\"order\":99998000,\"hasChild\":0},{\"id\":629,\"name\":\"财务会计部门\",\"parentid\":611,\"order\":99999000,\"hasChild\":0},{\"id\":647,\"name\":\"推送23\",\"parentid\":408,\"order\":99999500,\"hasChild\":0},{\"id\":648,\"name\":\"项目管理部门\",\"parentid\":614,\"order\":99998500,\"hasChild\":0},{\"id\":649,\"name\":\"SHDATA办公平台测试部门\",\"parentid\":358,\"order\":100000000,\"hasChild\":0},{\"id\":651,\"name\":\"0313测试部门全程\",\"parentid\":653,\"order\":100000000,\"hasChild\":1},{\"id\":653,\"name\":\"0313测试子部门全称\",\"parentid\":651,\"order\":100000000,\"hasChild\":1},{\"id\":665,\"name\":\"真的有很多人\",\"parentid\":668,\"order\":100000000,\"hasChild\":1},{\"id\":666,\"name\":\"泛微网络\",\"parentid\":351,\"order\":99996500,\"hasChild\":0},{\"id\":667,\"name\":\"测试组\",\"parentid\":614,\"order\":99999500,\"hasChild\":1},{\"id\":668,\"name\":\"可能有一个人\",\"parentid\":665,\"order\":100000000,\"hasChild\":1},{\"id\":670,\"name\":\"测试推全子部门\",\"parentid\":674,\"order\":100000000,\"hasChild\":1},{\"id\":674,\"name\":\"22\",\"parentid\":670,\"order\":100000000,\"hasChild\":1},{\"id\":675,\"name\":\"推送子子部门\",\"parentid\":603,\"order\":100000000,\"hasChild\":1},{\"id\":676,\"name\":\"区政府办公厅\",\"parentid\":250,\"order\":100000000,\"hasChild\":1},{\"id\":677,\"name\":\"区大数据中心\",\"parentid\":676,\"order\":100000000,\"hasChild\":0},{\"id\":678,\"name\":\"测试组\",\"parentid\":247,\"order\":99996500,\"hasChild\":0},{\"id\":679,\"name\":\"测试部门3\",\"parentid\":620,\"order\":100000001,\"hasChild\":0},{\"id\":680,\"name\":\"测试部门2\",\"parentid\":620,\"order\":99999500,\"hasChild\":0},{\"id\":681,\"name\":\"测试部门2_1\",\"parentid\":620,\"order\":100000001,\"hasChild\":0},{\"id\":682,\"name\":\"测试部门4\",\"parentid\":620,\"order\":100000001,\"hasChild\":0},{\"id\":683,\"name\":\"测试部门5\",\"parentid\":620,\"order\":100000000,\"hasChild\":0},{\"id\":688,\"name\":\"k测试5\",\"parentid\":369,\"order\":100000000,\"hasChild\":0},{\"id\":689,\"name\":\"k测试6\",\"parentid\":369,\"order\":99999500,\"hasChild\":0},{\"id\":690,\"name\":\"d测试1\",\"parentid\":667,\"order\":99999500,\"hasChild\":0},{\"id\":691,\"name\":\"d测试2\",\"parentid\":667,\"order\":99999000,\"hasChild\":0},{\"id\":692,\"name\":\"d测试3\",\"parentid\":667,\"order\":99998500,\"hasChild\":1},{\"id\":693,\"name\":\"d测试4\",\"parentid\":692,\"order\":100000000,\"hasChild\":1},{\"id\":694,\"name\":\"d测试5\",\"parentid\":693,\"order\":100000000,\"hasChild\":1},{\"id\":695,\"name\":\"d测试6\",\"parentid\":694,\"order\":100000000,\"hasChild\":1},{\"id\":696,\"name\":\"d测试7\",\"parentid\":695,\"order\":100000000,\"hasChild\":1},{\"id\":697,\"name\":\"d测试8\",\"parentid\":696,\"order\":100000000,\"hasChild\":1},{\"id\":698,\"name\":\"d测试9\",\"parentid\":697,\"order\":100000000,\"hasChild\":1},{\"id\":699,\"name\":\"d测试10\",\"parentid\":698,\"order\":100000000,\"hasChild\":0},{\"id\":700,\"name\":\"技术支持厂商\",\"parentid\":1,\"order\":99996000,\"hasChild\":1},{\"id\":701,\"name\":\"公务之家测试单位\",\"parentid\":700,\"order\":100000000,\"hasChild\":1},{\"id\":705,\"name\":\"局领导\",\"parentid\":701,\"order\":100000000,\"hasChild\":0},{\"id\":706,\"name\":\"财务处\",\"parentid\":701,\"order\":99999500,\"hasChild\":1},{\"id\":707,\"name\":\"开发部\",\"parentid\":701,\"order\":99999000,\"hasChild\":0},{\"id\":708,\"name\":\"测试部\",\"parentid\":701,\"order\":99998500,\"hasChild\":1},{\"id\":709,\"name\":\"财务一处\",\"parentid\":706,\"order\":100000000,\"hasChild\":1},{\"id\":710,\"name\":\"会计\",\"parentid\":709,\"order\":100000000,\"hasChild\":0},{\"id\":711,\"name\":\"一部\",\"parentid\":708,\"order\":100000000,\"hasChild\":0},{\"id\":712,\"name\":\"二部\",\"parentid\":708,\"order\":99999500,\"hasChild\":0}]"; +// List list = JSONObject.parseObject(json, List.class); + List departmentInfo = orgHrmAsyncApiService.getDepartmentInfo(); + System.out.println("departmentInfoList => " + departmentInfo); + // 过滤出父节点并根据id进行升序排序 + List rootDepList = departmentInfo + .stream() + .filter(item -> 1 == item.getHasChild() && -1 != item.getParentid()) + .sorted(Comparator.comparing(OtherSysDepartment::getId)) + .collect(Collectors.toList()); + System.out.println("rootDepList => "+ JSONObject.toJSONString(rootDepList)); + for (OtherSysDepartment sysDepartment : rootDepList) { + setChildList(sysDepartment, departmentInfo); + } + // 过滤出父节点并根据id进行升序排序 + + System.out.println("departmentInfo => " + JSONObject.toJSONString(departmentInfo, SerializerFeature.DisableCircularReferenceDetect)); + } + + public void setChildList(OtherSysDepartment department, List departmentList){ + if(department.getHasChild() == 0){ + return; + } + List childList = departmentList + .stream() + .filter(item -> department.getId() == item.getParentid()) + .collect(Collectors.toList()); + System.out.println("childList => " + JSONObject.toJSONString(childList)); + department.setChildList(childList); + for (OtherSysDepartment sysDepartment : childList) { + setChildList(sysDepartment, departmentList); + } + } + private final SendTodoTaskMapper mapper = Util.getMapper(SendTodoTaskMapper.class); + @Test + public void testD(){ + ArrayList details = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + CusTodoTaskToOADetail detail = new CusTodoTaskToOADetail(); + detail.setTaskNum("14672332" + (System.currentTimeMillis() / 1000)); + detail.setRequestUrl("11111"); + detail.setTaskName("taskName" + i); + detail.setTaskType(0); + detail.setStatus(0); + detail.setSuccess(0); + detail.setResponse("{\n" + + " \"code\": 200,\n" + + " \"msg\": \"操作成功\", //返回文字描述\n" + + " \"data\": null,\n" + + " \"total\": null,\n" + + " \"totalPage\": null,\n" + + " \"takeTime\": null\n" + + "}"); + detail.setRequestJson(JSONObject.toJSONString(detail)); + String sourceTaskId = detail.getTaskNum().substring(0, detail.getTaskNum().length() - 10); + detail.setSourceTaskId(sourceTaskId); + details.add(detail); + } +// CusInfoToOAUtil.executeBatchByEntity(111, details,""); + ArrayList list = new ArrayList<>(); + ArrayList successTaskIds = new ArrayList<>(); + List lists = mapper.queryUnSendTodoTaskList("14672332"); + for (String num : lists) { + int success = 0; + CusDoneTaskOA taskOA = new CusDoneTaskOA(); + taskOA.setTaskNum(num); + taskOA.setTaskType(1); + String sourceTaskId =num.substring(0, num.length() - 10); + taskOA.setSourceTaskId(sourceTaskId); + taskOA.setResponse("{\n" + + " \"code\": 200,\n" + + " \"msg\": \"操作成功\", //返回文字描述\n" + + " \"data\": null,\n" + + " \"total\": null,\n" + + " \"totalPage\": null,\n" + + " \"takeTime\": null\n" + + "}"); + taskOA.setRequestUrl("22222222"); + taskOA.setRequestJson(JSONObject.toJSONString(num)); + taskOA.setSuccess(success); + list.add(taskOA); + successTaskIds.add(num); + } + CusInfoToOAUtil.executeBatchByEntity(111, list,""); + mapper.updateStatusByTaskNum(successTaskIds); + } + + public void sqlTest(int modelId, List list, String whereSql){ + List> params = new ArrayList<>(); + List> whereParams = new ArrayList<>(); + StringBuilder whereSqlSb = new StringBuilder(); + LinkedHashSet whereFields = new LinkedHashSet<>(); + for (Object o : list) { + if(Objects.isNull(o)){ + continue; + } + Class clazz = o.getClass(); + Field[] fields = clazz.getDeclaredFields(); + LinkedHashMap linkedHashMap = new LinkedHashMap<>(); + ArrayList whereParam = new ArrayList<>(); + List fieldArr = Arrays.stream(fields).collect(Collectors.toList()); + Class superclass = clazz.getSuperclass(); + // 找出父类所有的字段 + while (superclass != null){ + fieldArr.addAll(Arrays.stream(superclass.getDeclaredFields()).collect(Collectors.toList())); + superclass = superclass.getSuperclass(); + } + for (Field field : fieldArr) { + field.setAccessible(true); + String fieldName = field.getName(); + Object fieldValue; + try { + fieldValue = field.get(o); + } catch (IllegalAccessException e) { + throw new CustomerException(Util.logStr("field get error! the error is :[{}]," + + "current field is: [{}], current obj is: [{}]", e.getMessage(), fieldName, JSONObject.toJSONString(o))); + } + if(Objects.isNull(fieldValue)){ + continue; + } + // 数据库字段映射 如果注解中没有值那么写入数据库就是实体类字段名 + SqlFieldMapping sqlFieldMapping = field.getAnnotation(SqlFieldMapping.class); + if(null == sqlFieldMapping){ + continue; + } + String sqlFieldMappingValue = sqlFieldMapping.value(); + if(StringUtils.isNotBlank(sqlFieldMappingValue)){ + fieldName = sqlFieldMappingValue; + } + linkedHashMap.put(fieldName, fieldValue); + + // 更新条件字段注解 + SqlUpdateWhereField sqlUpdateWhereField = field.getAnnotation(SqlUpdateWhereField.class); + if(null == sqlUpdateWhereField || !sqlUpdateWhereField.value()){ + continue; + } + if(StringUtils.isBlank(whereSql)){ + whereFields.add(fieldName + " = ? "); + } + whereParam.add(fieldValue.toString()); + } + params.add(linkedHashMap); + whereParams.add(whereParam); + } + if(!whereFields.isEmpty()){ + whereSqlSb = new StringBuilder("select id from #{tableName} where "); + for (String field : whereFields) { + whereSqlSb.append(field).append(" and "); + } + whereSql = whereSqlSb.substring(0, whereSqlSb.length() - 4); + } + System.out.println("params => " +JSONObject.toJSONString(params)); + System.out.println("whereParams => " +JSONObject.toJSONString(whereParams)); + System.out.println("whereSql => " +JSONObject.toJSONString(whereSql)); + + } + + + SendTodoTaskUtil sendTodoTaskUtil = new SendTodoTaskUtil(); + @Test + public void testToken(){ + String hrmConvertRuleSql = ShBigDataUtil.getPropertiesValByKey("hrmSenderConvertRuleSql"); + System.out.println("hrm =>" + hrmConvertRuleSql); + RequestStatusObj obj = new RequestStatusObj(); + obj.setRequestid(121323); + obj.setNodeid(12); + System.out.println("convert => " + sendTodoTaskUtil.getConvertHrm(0, obj, 22 + "," + 23)); +// String requestid = "8288283"; +// String detail = requestid + "" + (System.currentTimeMillis() / 1000); +// System.out.println(detail.substring(0, detail.length() - 10)); +// for (int i = 0; i < 10; i++) { +// int finalI = i; +// new Thread(()->{ +// try { +// if(finalI > 5){ +// Thread.sleep(1000 * 5 * finalI); +// } +// System.out.println("多线程校验token => " + ShBigDataUtil.getToken()); +// }catch (Exception e){ +// +// } +// +// }).start(); +// } +// +// try { +// Thread.sleep(1000 * 60 * 3); +// String token1 = ShBigDataUtil.getToken(); +// System.out.println("模拟过期 => " + token1); +// }catch (Exception e){ +// +// } + } +} diff --git a/src/test/java/xuanran/wang/mq/CusMQType.java b/src/test/java/xuanran/wang/mq/CusMQType.java new file mode 100644 index 0000000..37aebdb --- /dev/null +++ b/src/test/java/xuanran/wang/mq/CusMQType.java @@ -0,0 +1,17 @@ +package xuanran.wang.mq; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/4/3 15:13 + */ +public enum CusMQType { + ROCKET_MQ("RocketMQ",0), + KAFKA("Kafka",1), + RABBIT_MQ("RabbitMQ",2), + ACTIVE_MQ("ActiveMQ",3); + + CusMQType(String type, int code) { + } +} diff --git a/src/test/java/xuanran/wang/mq/consumer/DefaultConsumer.java b/src/test/java/xuanran/wang/mq/consumer/DefaultConsumer.java new file mode 100644 index 0000000..2c4e646 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/consumer/DefaultConsumer.java @@ -0,0 +1,21 @@ +package xuanran.wang.mq.consumer; + +import com.weaverboot.frame.ioc.anno.classAnno.WeaSysInitComponent; +import xuanran.wang.mq.infaces.CusMQClient; +import xuanran.wang.mq.infaces.callback.CusMQCallBack; +import xuanran.wang.mq.mq.CusMQFactory; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/4/3 15:04 + */ +@WeaSysInitComponent("MQ-消费者") +public class DefaultConsumer { + + public static void registerConsumer(String configName, String type, CusMQCallBack callBack){ + CusMQClient cusMQ = CusMQFactory.createCusMQ(configName, type); + cusMQ.consumer(callBack); + } +} diff --git a/src/test/java/xuanran/wang/mq/infaces/CusBaseMQ.java b/src/test/java/xuanran/wang/mq/infaces/CusBaseMQ.java new file mode 100644 index 0000000..734b7f7 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/CusBaseMQ.java @@ -0,0 +1,27 @@ +package xuanran.wang.mq.infaces; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import xuanran.wang.mq.infaces.aop.CusMQAop; + +/** + *

mq基础类

+ * + * @author xuanran.wang + * @date 2023/3/31 11:47 + */ +public interface CusBaseMQ { + Logger log = Util.getLogger(); + /** + *

初始化生产者

+ **/ + void initProducer(String configName); + /** + *

初始化消费者

+ **/ + void initConsumer(String configName); + /** + *

销毁

+ **/ + void destroy(); +} diff --git a/src/test/java/xuanran/wang/mq/infaces/CusConsumer.java b/src/test/java/xuanran/wang/mq/infaces/CusConsumer.java new file mode 100644 index 0000000..fbdcc67 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/CusConsumer.java @@ -0,0 +1,16 @@ +package xuanran.wang.mq.infaces; + +import xuanran.wang.mq.infaces.callback.CusMQCallBack; + +/** + *

消费者

+ * + * @author xuanran.wang + * @date 2023/3/31 11:56 + */ +public interface CusConsumer extends CusBaseMQ{ + /** + *

消费

+ **/ + void consumer(CusMQCallBack callBack); +} diff --git a/src/test/java/xuanran/wang/mq/infaces/CusMQClient.java b/src/test/java/xuanran/wang/mq/infaces/CusMQClient.java new file mode 100644 index 0000000..6c0d88f --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/CusMQClient.java @@ -0,0 +1,11 @@ +package xuanran.wang.mq.infaces; + +/** + *

客户端

+ * + * @author xuanran.wang + * @date 2023/3/31 13:09 + */ +public interface CusMQClient extends CusProducer, CusConsumer { +} + diff --git a/src/test/java/xuanran/wang/mq/infaces/CusProducer.java b/src/test/java/xuanran/wang/mq/infaces/CusProducer.java new file mode 100644 index 0000000..84cc44a --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/CusProducer.java @@ -0,0 +1,16 @@ +package xuanran.wang.mq.infaces; + +import java.util.Map; + +/** + *

生产者方法

+ * + * @author xuanran.wang + * @date 2023/3/30 11:37 + */ +public interface CusProducer extends CusBaseMQ{ + /** + *

生产者

+ **/ + void send(Object message); +} diff --git a/src/test/java/xuanran/wang/mq/infaces/aop/CusMQAop.java b/src/test/java/xuanran/wang/mq/infaces/aop/CusMQAop.java new file mode 100644 index 0000000..a5184af --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/aop/CusMQAop.java @@ -0,0 +1,18 @@ +package xuanran.wang.mq.infaces.aop; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; + +/** + *

切面

+ * + * @author xuanran.wang + * @date 2023/3/31 12:52 + */ +public interface CusMQAop { + void sendBefore(); + void sendAfter(); + void consumerBefore(); + void consumerAfter(); + void destroyBefore(); + void destroyAfter(); +} diff --git a/src/test/java/xuanran/wang/mq/infaces/callback/CusMQCallBack.java b/src/test/java/xuanran/wang/mq/infaces/callback/CusMQCallBack.java new file mode 100644 index 0000000..81a19a6 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/infaces/callback/CusMQCallBack.java @@ -0,0 +1,35 @@ +package xuanran.wang.mq.infaces.callback; + +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; +import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; +import org.apache.rocketmq.common.message.MessageExt; + +import java.util.List; + + +/** + *

回调

+ * + * @author xuanran.wang + * @date 2023/3/31 13:13 + */ +public interface CusMQCallBack { + /** + *

kafka 回调

+ * @author xuanran.wang + * @dateTime 2023/4/3 14:55 + * @param records 消息对象 + **/ + void kafkaCallBack(ConsumerRecords records); + /** + *

rocket-MQ 回调

+ * @author xuanran.wang + * @dateTime 2023/4/3 14:55 + * @param msgList 消息列表 + * @param context 上下文 + * @return 状态 + **/ + ConsumeConcurrentlyStatus rocketCallBack(List msgList, ConsumeConcurrentlyContext context); +} diff --git a/src/test/java/xuanran/wang/mq/mq/CusKafkaMQ.java b/src/test/java/xuanran/wang/mq/mq/CusKafkaMQ.java new file mode 100644 index 0000000..b17dc4d --- /dev/null +++ b/src/test/java/xuanran/wang/mq/mq/CusKafkaMQ.java @@ -0,0 +1,86 @@ +package xuanran.wang.mq.mq; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import lombok.NoArgsConstructor; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import xuanran.wang.mq.infaces.*; +import xuanran.wang.mq.infaces.aop.CusMQAop; +import xuanran.wang.mq.infaces.callback.CusMQCallBack; +import xuanran.wang.mq.util.CusMQUtil; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Map; + +/** + *

kafka

+ * + * @author xuanran.wang + * @date 2023/3/30 11:44 + */ +@NoArgsConstructor +public class CusKafkaMQ implements CusMQClient { + private KafkaProducer producer = null; + private KafkaConsumer consumer = null; + private Map config = null; + private CusMQAop cusMQAop = new DefaultCusMQAop(); + public CusKafkaMQ(CusMQAop cusMQAop){ + this.cusMQAop = cusMQAop; + } + + @Override + public void initProducer(String configName) { + config = CusMQUtil.getConfigMapByName(configName); + producer = new KafkaProducer<>(config); + } + + @Override + public void initConsumer(String configName) { + config = CusMQUtil.getConfigMapByName(configName); + consumer = new KafkaConsumer<>(config); + } + + @Override + public void send(Object message) { + String topic = Util.null2DefaultStr(config.get("topic"),""); + try { + producer.send(new ProducerRecord<>(topic, JSONObject.toJSONString(message))).get(); + }catch (Exception e){ + log.error(Util.logStr("kafka producer topic: {}, message: {}, error: {}", topic, JSONObject.toJSONString(message), e.getMessage())); + throw new CustomerException("kafka producer send message error!"); + }finally { + this.destroy(); + } + } + + @Override + public void consumer(CusMQCallBack callBack) { + new Thread(() -> { + try { + while (true) { + /*轮询获取数据*/ + ConsumerRecords records = consumer.poll(Duration.of(100, ChronoUnit.MILLIS)); + callBack.kafkaCallBack(records); + } + } finally { + consumer.close(); + } + }).start(); + } + + @Override + public void destroy() { + if(producer != null){ + producer.close(); + } + if(consumer != null){ + consumer.close(); + } + } + +} diff --git a/src/test/java/xuanran/wang/mq/mq/CusMQFactory.java b/src/test/java/xuanran/wang/mq/mq/CusMQFactory.java new file mode 100644 index 0000000..e2b9352 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/mq/CusMQFactory.java @@ -0,0 +1,45 @@ +package xuanran.wang.mq.mq; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import xuanran.wang.mq.infaces.CusMQClient; +import xuanran.wang.mq.infaces.aop.CusMQAop; + +/** + *

工厂

+ * + * @author xuanran.wang + * @date 2023/3/30 11:38 + */ +public class CusMQFactory { + + public static final String ROCKET_MQ = "0"; + + public static final String KAFKA = "1"; + + public static final String RABBIT_MQ = "2"; + + public static final String ACTIVE_MQ = "3"; + + public static CusMQClient createCusMQ(String configName, String type) { + return createCusMQ(configName, type, null); + } + + public static CusMQClient createCusMQ(String configName, String type, CusMQAop cusMQAop){ + CusMQClient cusAbstractMQ; + switch (type){ + case ROCKET_MQ: { + cusAbstractMQ = new CusRocketMQ(); + break; + } + case KAFKA: { + cusAbstractMQ = new CusKafkaMQ(); + break; + } + default: throw new CustomerException(Util.logStr("create CusMQClient error! type: {}, not support!", type)); + } + cusAbstractMQ.initConsumer(configName); + cusAbstractMQ.initProducer(configName); + return cusAbstractMQ; + } +} diff --git a/src/test/java/xuanran/wang/mq/mq/CusRocketMQ.java b/src/test/java/xuanran/wang/mq/mq/CusRocketMQ.java new file mode 100644 index 0000000..83f8497 --- /dev/null +++ b/src/test/java/xuanran/wang/mq/mq/CusRocketMQ.java @@ -0,0 +1,146 @@ +package xuanran.wang.mq.mq; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import lombok.NoArgsConstructor; +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.exception.MQBrokerException; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.client.producer.SendResult; +import org.apache.rocketmq.client.producer.SendStatus; +import org.apache.rocketmq.common.consumer.ConsumeFromWhere; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; +import org.apache.rocketmq.remoting.common.RemotingHelper; +import org.apache.rocketmq.remoting.exception.RemotingException; +import weaver.xuanran.wang.shyl_mq.constant.RocketMQConstant; +import xuanran.wang.mq.infaces.CusMQClient; +import xuanran.wang.mq.infaces.aop.CusMQAop; +import xuanran.wang.mq.infaces.callback.CusMQCallBack; +import xuanran.wang.mq.util.CusMQUtil; + +import java.util.List; +import java.util.Map; + +/** + *

自定义rocket-mq

+ * + * @author xuanran.wang + * @date 2023/3/31 13:02 + */ +@NoArgsConstructor +public class CusRocketMQ implements CusMQClient { + private DefaultMQProducer producer = null; + + private DefaultMQPushConsumer consumer = null; + + private Map config = null; + private CusMQAop cusMQAop = new DefaultCusMQAop(); + + public CusRocketMQ(CusMQAop cusMQAop){ + this.cusMQAop = cusMQAop; + } + + @Override + public void initProducer(String configName) { + Map configMap = CusMQUtil.getConfigMapByName(configName); + this.config = configMap; + producer = new DefaultMQProducer(Util.null2DefaultStr(configMap.get("producerGroup"),"")); + // 发送消息最大超时时间 默认60000 + int sendMsgTimeOut = Util.getIntValue(Util.null2String(configMap.get("sendMsgTimeOut")), RocketMQConstant.PRODUCER_SEND_MSG_TIME_OUT); + producer.setSendMsgTimeout(sendMsgTimeOut); + producer.setVipChannelEnabled(false); + producer.setNamesrvAddr(Util.null2String(configMap.get("serverAddr"))); + try { + producer.start(); + }catch (MQClientException e){ + throw new CustomerException(Util.logStr("producer start error!:{}",e.getMessage())); + } + } + + @Override + public void initConsumer(String configName) { + Map configMap = CusMQUtil.getConfigMapByName(configName); + this.config = configMap; + try { + int maxReconsumeTimes = Util.getIntValue(Util.null2String(configMap.get("maxReconsumeTimes")), RocketMQConstant.DEFAULT_MAX_RECONSUME_TIMES); + // 声明一个消费者consumer,需要传入一个组 weaver-consumer + consumer = new DefaultMQPushConsumer(Util.null2String(configMap.get("consumerGroup"))); + // 设置集群的NameServer地址,多个地址之间以分号分隔 183.192.65.118:9876 + consumer.setNamesrvAddr(Util.null2String(configMap.get("serverAddr"))); + // 设置consumer的消费策略 + consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); + // 集群模式消费,广播消费不会重试 + consumer.setMessageModel(MessageModel.CLUSTERING); + // 设置最大重试次数,默认是16次 + consumer.setMaxReconsumeTimes(maxReconsumeTimes); + // 设置consumer所订阅的Topic和Tag,*代表全部的Tag AUTH_CONSOLE_USERINFO_TOPIC + consumer.subscribe(Util.null2String(configMap.get("topic")),"*"); + // 是否开启vip + consumer.setVipChannelEnabled(false); + }catch (Exception e){ + throw new CustomerException(Util.logStr("init rocket MQ consumer error: {}!",e.getMessage())); + } + } + + @Override + public void destroy() { + if(producer != null){ + producer.shutdown(); + } + if(consumer != null){ + consumer.shutdown(); + } + } + + @Override + public void send(Object message) { + cusMQAop.sendBefore(); + // 队列名 + String topic = Util.null2DefaultStr(config.get("topic"), ""); + Message msg; + try { + msg = new Message(topic, JSONObject.toJSONString(message).getBytes(RemotingHelper.DEFAULT_CHARSET)); + } catch (Exception e) { + throw new CustomerException(Util.logStr("init message error : {} !", e.getMessage())); + } + // 发送成功标识 + boolean sendOk = false; + // 发送次数 + int count = 0; + do { + SendResult result; + count++; + try { + result = producer.send(msg); + } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) { + throw new CustomerException(Util.logStr("producer send message error!: {}", e.getMessage())); + } + SendStatus sendStatus = result.getSendStatus(); + // 如果失败 + if (!SendStatus.SEND_OK.equals(sendStatus)) { + String error = Util.logStr("producer send message call back status is not ok! the message is {}, the status is {}.", msg, sendStatus); + // 如果重试超过最大次数 + if(count >= RocketMQConstant.SEND_MAX_COUNT){ + throw new CustomerException(error + " and retry > max"); + } + }else { + sendOk = true; + } + } while (!sendOk); + cusMQAop.sendAfter(); + } + + + @Override + public void consumer(CusMQCallBack callBack) { + consumer.registerMessageListener(callBack::rocketCallBack); + try { + consumer.start(); + }catch (Exception e){ + throw new CustomerException("consumer start error : " + e.getMessage()); + } + } +} diff --git a/src/test/java/xuanran/wang/mq/mq/DefaultCusMQAop.java b/src/test/java/xuanran/wang/mq/mq/DefaultCusMQAop.java new file mode 100644 index 0000000..483264a --- /dev/null +++ b/src/test/java/xuanran/wang/mq/mq/DefaultCusMQAop.java @@ -0,0 +1,41 @@ +package xuanran.wang.mq.mq; + +import xuanran.wang.mq.infaces.aop.CusMQAop; + +/** + *

默认的aop

+ * + * @author xuanran.wang + * @date 2023/3/31 12:56 + */ +public class DefaultCusMQAop implements CusMQAop { + @Override + public void sendBefore() { + + } + + @Override + public void sendAfter() { + + } + + @Override + public void consumerBefore() { + + } + + @Override + public void consumerAfter() { + + } + + @Override + public void destroyBefore() { + + } + + @Override + public void destroyAfter() { + + } +} diff --git a/src/test/java/xuanran/wang/mq/test/MQTest.java b/src/test/java/xuanran/wang/mq/test/MQTest.java new file mode 100644 index 0000000..a9a99df --- /dev/null +++ b/src/test/java/xuanran/wang/mq/test/MQTest.java @@ -0,0 +1,58 @@ +package xuanran.wang.mq.test; + +import basetest.BaseTest; +import org.junit.Test; +import weaver.general.Util; +import xuanran.wang.mq.infaces.CusMQClient; +import xuanran.wang.mq.infaces.aop.CusMQAop; +import xuanran.wang.mq.mq.CusMQFactory; + +/** + *

+ * + * @author xuanran.wang + * @date 2023/3/31 12:34 + */ +public class MQTest extends BaseTest { + + @Test + public void testKafka(){ + CusMQAop cusMQAop = new CusMQAop() { + @Override + public void sendBefore() { + System.out.println("发送前!"); + } + + @Override + public void sendAfter() { + System.out.println("发送后!"); + } + + @Override + public void consumerBefore() { + System.out.println("消费前!"); + } + + @Override + public void consumerAfter() { + System.out.println("消费后!"); + } + + @Override + public void destroyBefore() { + System.out.println("销毁前!"); + } + + @Override + public void destroyAfter() { + System.out.println("销毁前!"); + } + }; + + CusMQClient cusMQ = CusMQFactory.createCusMQ("OACarTest", CusMQFactory.ROCKET_MQ); + + cusMQ.send("11212121212"); + + } + +} diff --git a/src/test/java/xuanran/wang/mq/util/CusMQUtil.java b/src/test/java/xuanran/wang/mq/util/CusMQUtil.java new file mode 100644 index 0000000..29d318b --- /dev/null +++ b/src/test/java/xuanran/wang/mq/util/CusMQUtil.java @@ -0,0 +1,53 @@ +package xuanran.wang.mq.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; + +import java.util.HashMap; +import java.util.Map; + +/** + *

mq工具类

+ * + * @author xuanran.wang + * @date 2023/3/31 11:52 + */ +public class CusMQUtil { + private static final Logger log = Util.getLogger(); + private static final String[] checkField = new String[]{"serverAddr", "topic"}; + /** + *

配置文件本地存储对象

+ **/ + public static Map> CONFIG_MAPS = new HashMap<>(16); + + /** + *

通过配置文件名称获取配置map

+ * @author xuanran.wang + * @dateTime 2023/1/4 13:18 + * @param configName 配置文件名称 + * @return 配置文件map + **/ + public synchronized static Map getConfigMapByName(String configName){ + Map configMap = new HashMap<>(); + if(!CONFIG_MAPS.containsKey(configName)){ + configMap = Util.getProperties2Map(configName); + checkConfig(configMap); + CONFIG_MAPS.put(configName, configMap); + }else { + configMap = CONFIG_MAPS.get(configName); + } + return configMap; + } + + public static void checkConfig(Map configMap){ + for (String field : checkField) { + if(!configMap.containsKey(field) && StringUtils.isBlank(Util.null2DefaultStr(configMap.get(field),""))){ + log.error("MQ config : " + JSONObject.toJSONString(configMap)); + throw new CustomerException("MQ config map not contains " + field + " or " + field + " is empty!"); + } + } + } +} diff --git a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java index 563e1dc..057a32b 100644 --- a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java +++ b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java @@ -174,25 +174,9 @@ public class AsyncTest extends BaseTest { consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { - MessageExt messageExt = list.get(0); - String msgBody; - MQMessage mqMessage; - try { - msgBody = new String(messageExt.getBody(), StandardCharsets.UTF_8); - if (StringUtils.isBlank(msgBody)) { - throw new CustomerException("MQ msgBody is empty!"); - } - mqMessage = JSONObject.parseObject(msgBody, MQMessage.class); - // 业务主体 - String content = Util.null2DefaultStr(mqMessage.getContent(), ""); - if (StringUtils.isBlank(content)) { - throw new CustomerException(Util.logStr("the messageId : {}, content is empty!", Util.null2DefaultStr(mqMessage.getId(), ""))); - } - log.info(Util.logStr("MQMessage : {} ", mqMessage)); - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; - } catch (Exception e) { - throw new CustomerException("consumeMessage => " + e.getMessage()); - } + System.out.println("msgs : " + JSONObject.toJSONString(list)); + System.out.println("context : " + JSONObject.toJSONString(consumeConcurrentlyContext)); + return ConsumeConcurrentlyStatus.RECONSUME_LATER; } }); consumer.start(); diff --git a/src/test/java/xuanran/wang/shyl/dataasync/MapperTest.java b/src/test/java/xuanran/wang/shyl/dataasync/MapperTest.java index 98a6fa5..1c548b6 100644 --- a/src/test/java/xuanran/wang/shyl/dataasync/MapperTest.java +++ b/src/test/java/xuanran/wang/shyl/dataasync/MapperTest.java @@ -6,14 +6,16 @@ import com.api.meeting.util.FieldUtil; import com.api.xuanran.wang.shyl.entity.meeting.MeetingCusFieldConfigMain; import com.api.xuanran.wang.shyl.service.MeetingService; import org.junit.Test; +import weaver.file.ImageFileManager; import weaver.general.TimeUtil; import weaver.general.Util; import weaver.systeminfo.SystemEnv; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; /** *

@@ -42,8 +44,32 @@ public class MapperTest extends BaseTest { } @Test - public void testC(){ - String s = TimeUtil.dateAdd("2023-03-02", -3); - log.info("time => " + s); + public void testC() throws IOException { + InputStream inputStream = new FileInputStream("/Users/wangxuanran/Downloads/chrome/1589665325711042c4c7c0e4ff4c6868.png"); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] bytes = outputStream.toByteArray(); + String str = Base64.getEncoder().encodeToString(bytes); + System.out.println("str => " + str); + + } + + @Test + public void testD(){ + String cusSql = "select a.docsubject fileName, concat('http://10.184.45.196/zjdownload?filed=', a.id)\n" + + " fullPath, RIGHT(c.imagefilename, INSTR(REVERSE(c.imagefilename),'.')) downloadType\n" + + "from docdetail a\n" + + "left join docimagefile b\n" + + "on a.id = b.docid\n" + + "left join docimagefile c\n" + + "on b.imagefileid = c.imagefileid\n" + + "where a.id in ${docIds}"; + String docIds = "1,2,3"; + cusSql = cusSql.replace("${docIds}", "( " + docIds + " )"); + System.out.println("cus => " + cusSql); } } From aeb04f41d40fb0b50672082f74b80a3accecbc05 Mon Sep 17 00:00:00 2001 From: "youHong.ai" <774495953@qq.com> Date: Fri, 14 Apr 2023 10:16:48 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/youhong.ai/yihong/index.js | 75 ++++++ src/main/java/aiyh/utils/Util.java | 16 ++ .../RequestLogAuthorityController.java | 6 +- .../mapper/RequestLogAuthorityMapper.java | 7 + .../service/RequestLogAuthorityService.java | 24 +- .../mapper/FunctionListMapper.java | 6 +- .../pojo/FunctionListConfigItem.java | 4 + .../impl/InterceptRequestLogImpl.java | 69 +++--- .../impl/RequestLogShowOrHiddenImpl.java | 59 +---- .../mapper/InterceptRequestLogMapper.java | 92 ++++++-- .../pojo/RequestLogPrivacyEntity.java | 40 ++++ .../util/PrivacyRequestLogUtil.java | 216 ++++++++++++++++++ .../config/service/SapConfigService.java | 9 +- .../prop/prop2map/JituMultilingual.properties | 16 ++ .../java/youhong/ai/utiltest/GenericTest.java | 29 ++- 15 files changed, 544 insertions(+), 124 deletions(-) create mode 100644 javascript/youhong.ai/yihong/index.js create mode 100644 src/main/java/com/customization/youhong/deerge/requestlog/pojo/RequestLogPrivacyEntity.java create mode 100644 src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java create mode 100644 src/main/resources/WEB-INF/prop/prop2map/JituMultilingual.properties diff --git a/javascript/youhong.ai/yihong/index.js b/javascript/youhong.ai/yihong/index.js new file mode 100644 index 0000000..bceba14 --- /dev/null +++ b/javascript/youhong.ai/yihong/index.js @@ -0,0 +1,75 @@ +/* ******************* 按钮变灰 ******************* */ +$(() => { + const disabledRightButton = function (...indexIds) { + indexIds.forEach(index => { + let buttons = $(".ant-menu-item.text-elli[ecid='_Route@9uoqid_Com@knmejd_WeaRightMenu@spqptt_Item@eu37n0_li@zyccqn']") + let nodeArr = [] + for (let i = 0; i < buttons.length; i++) { + let item = buttons[i] + nodeArr.push(findReact(item)) + } + let disableArr = [] + for (let i = 0; i < nodeArr.length; i++) { + let node = nodeArr[i] + if (index === i) { + node.props.disabled = true + node.setState({}) + disableArr.push(node) + } + + } + for (let i = 0; i < nodeArr.length; i++) { + let node = nodeArr[i] + let onMouseOver = node.onMouseOver + let onMouseLeave = node.onMouseLeave + node.onMouseOver = (...args) => { + disableArr.forEach(item => { + item.props.disabled = true + item.setState({}) + }) + onMouseOver(...args) + } + node.onMouseLeave = (...args) => { + disableArr.forEach(item => { + item.props.disabled = true + item.setState({}) + }) + onMouseLeave(...args) + } + } + }) + } + const findReact = function (dom, traverseUp = 0) { + const key = Object.keys(dom).find(key => { + return key.startsWith("__reactFiber$") // react 17+ + || key.startsWith("__reactInternalInstance$") + || key.startsWith("__reactEventHandlers$"); // react <17 + }); + const domFiber = dom[key]; + if (domFiber == null) return null; + // react <16 + if (domFiber._currentElement) { + let compFiber = domFiber._currentElement._owner; + for (let i = 0; i < traverseUp; i++) { + compFiber = compFiber._currentElement._owner; + } + return compFiber._instance; + } + // react 16+ + const GetCompFiber = fiber => { + let parentFiber = fiber.return; + while (typeof parentFiber.type == "string") { + parentFiber = parentFiber.return; + } + return parentFiber; + }; + let compFiber = GetCompFiber(domFiber); + for (let i = 0; i < traverseUp; i++) { + compFiber = GetCompFiber(compFiber); + } + return compFiber.stateNode; + } + window.disabledRightButton = disabledRightButton +}) + +/* ******************* 按钮变灰 ******************* */ \ No newline at end of file diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index cc5f158..0c7bf0d 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -3870,4 +3870,20 @@ public class Util extends weaver.general.Util { } return ip; } + + public static String parseLanguageString(String multiLanguageString, String languageId) { + // 将多语言字符串按 `~`~` 分隔成语言id和对应的文本 + String[] languageTextPairs = multiLanguageString.split("`~`"); + for (String pair : languageTextPairs) { + // 按 ` 分隔语言id和文本 + String[] parts = pair.split(" "); + if (parts[0].equals(languageId)) { + // 如果语言id匹配,返回对应文本 + return Util.joinEach(parts, " ").substring(languageId.length() + 1); + } + } + // 如果没有匹配的语言id,返回空字符串 + return ""; + } + } diff --git a/src/main/java/com/api/youhong/ai/geerde/requestlog/controller/RequestLogAuthorityController.java b/src/main/java/com/api/youhong/ai/geerde/requestlog/controller/RequestLogAuthorityController.java index b8cf5d8..b98f420 100644 --- a/src/main/java/com/api/youhong/ai/geerde/requestlog/controller/RequestLogAuthorityController.java +++ b/src/main/java/com/api/youhong/ai/geerde/requestlog/controller/RequestLogAuthorityController.java @@ -37,10 +37,12 @@ public class RequestLogAuthorityController { @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public String getPrivacyAuthority(@Context HttpServletRequest request, @Context HttpServletResponse response, - @QueryParam("workflowId") String workflowId) { + @QueryParam("workflowId") String workflowId, + @QueryParam("requestId") String requestId, + @QueryParam("nodeId") String nodeId) { try { User user = HrmUserVarify.getUser(request, response); - return ApiResult.success(service.getPrivacyAuthority(user, workflowId)); + return ApiResult.success(service.getPrivacyAuthority(user, workflowId, requestId, nodeId)); } catch (Exception e) { log.info("get privacy authority error!" + Util.getErrString(e)); return ApiResult.error(e.getMessage()); diff --git a/src/main/java/com/api/youhong/ai/geerde/requestlog/mapper/RequestLogAuthorityMapper.java b/src/main/java/com/api/youhong/ai/geerde/requestlog/mapper/RequestLogAuthorityMapper.java index 0201d68..e76d9b3 100644 --- a/src/main/java/com/api/youhong/ai/geerde/requestlog/mapper/RequestLogAuthorityMapper.java +++ b/src/main/java/com/api/youhong/ai/geerde/requestlog/mapper/RequestLogAuthorityMapper.java @@ -30,4 +30,11 @@ public interface RequestLogAuthorityMapper { "and (',' || authority_members || ',') like #{userLike} and enable_status = 1") RequestLogAuthority selectLogPrivacyConfig(@ParamMapper("userLike") String userLike, @ParamMapper("workflowId") String workflowId); + + + @Select("select id from uf_privacy_log_info where request_id = #{requestId} and " + + "node_id = #{nodeId} and user_id = #{userId} and enable_privacy = '1'") + Integer selectRequestLogId(@ParamMapper("requestId") String requestId, + @ParamMapper("nodeId") String nodeId, + @ParamMapper("userId") String userId); } diff --git a/src/main/java/com/api/youhong/ai/geerde/requestlog/service/RequestLogAuthorityService.java b/src/main/java/com/api/youhong/ai/geerde/requestlog/service/RequestLogAuthorityService.java index 05f3519..fe6f835 100644 --- a/src/main/java/com/api/youhong/ai/geerde/requestlog/service/RequestLogAuthorityService.java +++ b/src/main/java/com/api/youhong/ai/geerde/requestlog/service/RequestLogAuthorityService.java @@ -1,10 +1,13 @@ package com.api.youhong.ai.geerde.requestlog.service; import aiyh.utils.Util; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; import com.api.youhong.ai.geerde.requestlog.mapper.RequestLogAuthorityMapper; import com.api.youhong.ai.geerde.requestlog.pojo.RequestLogAuthority; import weaver.hrm.User; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; /** @@ -18,8 +21,25 @@ public class RequestLogAuthorityService { private final RequestLogAuthorityMapper mapper = Util.getMapper(RequestLogAuthorityMapper.class); - public boolean getPrivacyAuthority(User user, String workflowId) { + public Map getPrivacyAuthority(User user, String workflowId, String requestId, String nodeId) { + Map result = new HashMap<>(); + result.put("show", true); RequestLogAuthority requestLogAuthority = mapper.selectLogPrivacyConfig("%," + user.getUID() + ",%", workflowId); - return !Objects.isNull(requestLogAuthority); + if (Objects.isNull(requestLogAuthority)) { + // 不存在签字意见组中 + result.put("show", false); + return result; + } + if (StrUtil.isBlank(requestId) || "-1".equals(requestId)) { + result.put("enable", false); + return result; + } + Integer id = mapper.selectRequestLogId(requestId, nodeId, String.valueOf(user.getUID())); + if (id <= 0) { + result.put("enable", false); + } else { + result.put("enable", true); + } + return result; } } diff --git a/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/mapper/FunctionListMapper.java b/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/mapper/FunctionListMapper.java index 205abcd..6d7fdeb 100644 --- a/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/mapper/FunctionListMapper.java +++ b/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/mapper/FunctionListMapper.java @@ -27,8 +27,8 @@ public interface FunctionListMapper { column = "button_icon", id = @Id(value = String.class, methodId = 1)) ) - @Select("select * from uf_fun_list_config where CONCAT(',' , subcompany_id , ',') like #{userSubCompanyLike}") - @SelectOracle("select * from uf_fun_list_config where (',' || subcompany_id || ',') like #{userSubCompanyLike}") + @Select("select * from uf_fun_list_config where CONCAT(',' , subcompany_id , ',') like #{userSubCompanyLike} order by sort_num") + @SelectOracle("select * from uf_fun_list_config where (',' || subcompany_id || ',') like #{userSubCompanyLike} order by sort_num") List selectFunctionList(@ParamMapper("userSubCompanyLike") String userSubCompanyLike); @@ -42,7 +42,7 @@ public interface FunctionListMapper { column = "button_icon", id = @Id(value = String.class, methodId = 1)) ) - @Select("select * from uf_fun_list_config") + @Select("select * from uf_fun_list_config order by sort_num") List selectFunctionListAll(); /** diff --git a/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/pojo/FunctionListConfigItem.java b/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/pojo/FunctionListConfigItem.java index 0c72146..84d5006 100644 --- a/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/pojo/FunctionListConfigItem.java +++ b/src/main/java/com/api/youhong/ai/taibao/fcuntionlist/pojo/FunctionListConfigItem.java @@ -35,4 +35,8 @@ public class FunctionListConfigItem { /** 图标数量接口地址 */ @SqlOracleDbFieldAnn("NUMBER_URL") private String numberUrl; + + /** 排序字段 */ + @SqlOracleDbFieldAnn("SORT_NUM") + private String sortNum; } diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/impl/InterceptRequestLogImpl.java b/src/main/java/com/customization/youhong/deerge/requestlog/impl/InterceptRequestLogImpl.java index 5670e1c..45f36a5 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/impl/InterceptRequestLogImpl.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/impl/InterceptRequestLogImpl.java @@ -1,8 +1,7 @@ package com.customization.youhong.deerge.requestlog.impl; import aiyh.utils.Util; -import aiyh.utils.tool.cn.hutool.core.util.StrUtil; -import com.customization.youhong.deerge.requestlog.mapper.InterceptRequestLogMapper; +import com.customization.youhong.deerge.requestlog.util.PrivacyRequestLogUtil; import com.engine.core.cfg.annotation.ServiceDynamicProxy; import com.engine.core.cfg.annotation.ServiceMethodDynamicProxy; import com.engine.core.impl.aop.AbstractServiceProxy; @@ -11,11 +10,13 @@ import com.engine.workflow.entity.requestForm.RequestOperationResultBean; import com.engine.workflow.service.RequestFormService; import com.engine.workflow.service.impl.RequestFormServiceImpl; import org.apache.log4j.Logger; +import org.jetbrains.annotations.Nullable; import weaver.workflow.request.RequestManager; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; +import java.util.Objects; /** @@ -33,7 +34,7 @@ public class InterceptRequestLogImpl extends AbstractServiceProxy implements Req public static final String SUCCESS = "SUCCESS"; private final Logger log = Util.getLogger(); - private final InterceptRequestLogMapper mapper = Util.getMapper(InterceptRequestLogMapper.class); + private final PrivacyRequestLogUtil privacyRequestLogUtil = new PrivacyRequestLogUtil(); @Override public Map judgeCreateRight(HttpServletRequest request) { @@ -118,37 +119,40 @@ public class InterceptRequestLogImpl extends AbstractServiceProxy implements Req @Override @ServiceMethodDynamicProxy(desc = "保存和提交流程时,判断是否开启隐私") public Map requestSubmit(HttpServletRequest request) { - + log.info("requestSubmit:=>"); + return handlerRequestLogPrivacy(request); + } + + @Override + @ServiceMethodDynamicProxy(desc = "转发流程、意见征询时,判断是否开启隐私") + public Map forwardSubmit(HttpServletRequest request) { + log.info("forwardSubmit:=>"); + return handlerRequestLogPrivacy(request); + } + + @Override + @ServiceMethodDynamicProxy(desc = "转发流程、意见征询时,判断是否开启隐私") + public Map remarkSubmit(HttpServletRequest request) { + log.info("remarkSubmit:=>"); + return handlerRequestLogPrivacy(request); + } + + @Nullable + private Map handlerRequestLogPrivacy(HttpServletRequest request) { Map result = (Map) executeMethod(request); try { - log.info("调用提交流程和保存流程后的返回参数: " + result); RequestOperationResultBean data = (RequestOperationResultBean) result.get("data"); + if (Objects.isNull(data)) { + String success = Util.null2DefaultStr(result.get("success"), "false"); + if (Boolean.parseBoolean(success)) { + privacyRequestLogUtil.privacyRequestLogHandle(request); + } + return result; + } String type = Util.null2String(data.getType()); if (SUCCESS.equals(type)) { // 保存成功,这里对隐私的签字意见做处理 - String userId = request.getParameter("userId"); - String enablePrivacy = request.getParameter("enablePrivacy"); - String nodeId = request.getParameter("nodeid"); - String requestId = request.getParameter("requestid"); - String remark = request.getParameter("remark"); - if (StrUtil.isBlank(enablePrivacy)) { - return result; - } - if (!Boolean.parseBoolean(enablePrivacy)) { - return result; - } - if ("-1".equals(requestId)) { - Map submitParams = data.getSubmitParams(); - requestId = Util.null2String(submitParams.get("requestid")); - } - // 查询logId - Integer logId = mapper.selectRequestLogId(requestId, remark, nodeId, userId); - // 插入logId隐私信息 - int dataId = Util.getModeDataId("uf_privacy_log_info", 1); - Boolean flag = mapper.insertPrivacyLog(dataId, logId, userId, nodeId, requestId); - if (!flag) { - Util.deleteModeId("uf_privacy_log_info", dataId); - } + privacyRequestLogUtil.privacyRequestLogHandle(request); } } catch (Exception e) { log.error("add privacy request log error! " + Util.getErrString(e)); @@ -156,20 +160,11 @@ public class InterceptRequestLogImpl extends AbstractServiceProxy implements Req return result; } - @Override - public Map forwardSubmit(HttpServletRequest request) { - return null; - } - @Override public Map requestWithdraw(HttpServletRequest httpServletRequest) { return null; } - @Override - public Map remarkSubmit(HttpServletRequest request) { - return null; - } @Override public Map functionManage(HttpServletRequest request, HttpServletResponse response) { diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java b/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java index 719d594..b0f6be4 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java @@ -1,23 +1,17 @@ package com.customization.youhong.deerge.requestlog.impl; import aiyh.utils.Util; -import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; -import aiyh.utils.tool.cn.hutool.core.util.StrUtil; -import com.customization.youhong.deerge.requestlog.mapper.InterceptRequestLogMapper; +import com.alibaba.fastjson.JSON; +import com.customization.youhong.deerge.requestlog.util.PrivacyRequestLogUtil; import com.engine.core.cfg.annotation.ServiceDynamicProxy; import com.engine.core.cfg.annotation.ServiceMethodDynamicProxy; import com.engine.core.impl.aop.AbstractServiceProxy; import com.engine.workflow.service.RequestLogService; import com.engine.workflow.service.impl.RequestLogServiceImpl; import org.apache.log4j.Logger; -import weaver.hrm.HrmUserVarify; -import weaver.hrm.User; import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** *

是否显示隐私签字意见

@@ -29,9 +23,8 @@ import java.util.stream.Collectors; @ServiceDynamicProxy(target = RequestLogServiceImpl.class, desc = "拦截签字意见信息,是否需要隐私控制") public class RequestLogShowOrHiddenImpl extends AbstractServiceProxy implements RequestLogService { - private final Logger log = Util.getLogger(); + private final PrivacyRequestLogUtil privacyRequestLogUtil = new PrivacyRequestLogUtil(); - private final InterceptRequestLogMapper mapper = Util.getMapper(InterceptRequestLogMapper.class); @Override public Map getRequestLogBaseInfo(Map params) { @@ -42,52 +35,14 @@ public class RequestLogShowOrHiddenImpl extends AbstractServiceProxy implements @ServiceMethodDynamicProxy(desc = "控制是否显示隐私签字意见") public Map getRequestLogList(HttpServletRequest request, Map params) { Map result = (Map) executeMethod(request, params); - + Logger log = Util.getLogger(); try { - String isMonitor = request.getParameter("ismonitor"); - boolean isPrint = "1".equals(Util.null2String(request.getParameter("isprint"))); - // 如果是流程监控,全部返回 - if (!StrUtil.isBlank(isMonitor) && !isPrint) { - return result; - } - User user = HrmUserVarify.getUser(request, null); - List> logList = (List>) result.get("loglist"); - List logIds = new ArrayList<>(); - for (Map logInfo : logList) { - String logId = Util.null2String(logInfo.get("logid")); - logIds.add(logId); - } - String workflowId = Util.null2String(params.get("workflowid")); - if (StrUtil.isBlank(workflowId)) { - log.error("can not get value from params by wworkflowid!"); - return result; - } - List privacyLogIds; - // 如果是打印,所有隐私都不显示 - if (isPrint) { - privacyLogIds = mapper.selectPrivacyLogIdAll(Util.join(logIds, ","), "-1", Util.null2String(params.get("requestid"))); - } else { - // 如果不是,不显示除自己和隐私组之外的其他人的信息 - List userGroup = mapper.selectPrivacyGroup(workflowId, "%," + user.getUID() + ",%"); - if (CollectionUtil.isEmpty(userGroup)) { - // 不在权限组,不能查看隐私的签字意见 - privacyLogIds = mapper.selectPrivacyLogIdAll(Util.join(logIds, ","), String.valueOf(user.getUID()), Util.null2String(params.get("requestid"))); - } else { - privacyLogIds = mapper.selectPrivacyLogId(Util.join(logIds, ","), - Util.join(userGroup, ","), Util.null2String(params.get("requestid"))); - } - } - if (CollectionUtil.isEmpty(privacyLogIds)) { - return result; - } - List finalPrivacyLogIds = privacyLogIds; - List> newLogList = logList.stream() - .filter(item -> !finalPrivacyLogIds.contains(Util.null2String(item.get("logid")))) - .collect(Collectors.toList()); - result.put("loglist", newLogList); + privacyRequestLogUtil.requestLogList(result, params, request); + log.info("最终的返回结果: " + JSON.toJSONString(result)); } catch (Exception e) { log.error("filter request log list error!" + Util.getErrString(e)); } + return result; } diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java b/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java index cc89b77..f367c08 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java @@ -1,6 +1,7 @@ package com.customization.youhong.deerge.requestlog.mapper; import aiyh.utils.annotation.recordset.*; +import com.customization.youhong.deerge.requestlog.pojo.RequestLogPrivacyEntity; import java.util.List; @@ -14,19 +15,18 @@ import java.util.List; @SqlMapper public interface InterceptRequestLogMapper { + /** *

查询签字意见的id

* * @param requestId 流程requestid - * @param remark 签字意见内容 * @param nodeId 节点id * @param operator 操作者 * @return 签字意见id */ - @Select("select logid from workflow_requestlog where REQUESTID = #{requestId} and REMARK = #{remark} " + - "and NODEID = #{nodeId} and OPERATOR = #{operator}") + @Select("select logid from workflow_requestlog where REQUESTID = #{requestId} " + + "and NODEID = #{nodeId} and OPERATOR = #{operator} order by LOGID desc ") Integer selectRequestLogId(@ParamMapper("requestId") String requestId, - @ParamMapper("remark") String remark, @ParamMapper("nodeId") String nodeId, @ParamMapper("operator") String operator); @@ -42,40 +42,53 @@ public interface InterceptRequestLogMapper { */ @Update("update uf_privacy_log_info set request_id = #{requestId}," + - "node_id = #{nodeId}, user_id = #{userId},log_id = #{logId} " + + "node_id = #{nodeId}, user_id = #{userId},log_id = #{logId}," + + "target_hrm = case when target_hrm is null then #{targetHrm} else concat(concat(target_hrm,',') ,#{targetHrm}) end," + + "enable_privacy = #{enablePrivacy} " + "where id = #{dataId}") Boolean insertPrivacyLog( @ParamMapper("dataId") int dataId, @ParamMapper("logId") Integer logId, @ParamMapper("userId") String userId, @ParamMapper("nodeId") String nodeId, - @ParamMapper("requestId") String requestId); + @ParamMapper("requestId") String requestId, + @ParamMapper("targetHrm") String field5, + @ParamMapper("enablePrivacy") String enablePrivacy); + /** - *

查询隐私签字意见

+ *

跟新签字意见隐私状态

* - * @param logIds 签字意见ids - * @param uid 用户ID - * @param requestId 请求id - * @return 隐私签字意见 + * @param logId 签字意见id + * @param userId 用户id + * @param nodeId 节点id + * @param requestId 请求id + * @param enablePrivacy 是否隐私 + * @return 结果 */ - @Select("select log_id from uf_privacy_log_info where request_id = #{requestId} and user_id not in ($t{userId}) and log_id in ($t{logIds})") - List selectPrivacyLogId( - @ParamMapper("logIds") String logIds, - @ParamMapper("userId") String uid, - @ParamMapper("requestId") String requestId); + @Update("update uf_privacy_log_info set enable_privacy = #{enablePrivacy} where request_id = #{requestId} " + + "and node_id = #{nodeId} and user_id = #{userId} and log_id = #{logId},") + boolean updateRequestLogStatus(@ParamMapper("logId") Integer logId, + @ParamMapper("userId") String userId, + @ParamMapper("nodeId") String nodeId, + @ParamMapper("requestId") String requestId, + @ParamMapper("enablePrivacy") String enablePrivacy); /** - *

查询隐私签字意见

+ *

查询签字意见隐私表id

* - * @param logIds 签字意见ids - * @param requestId 请求id - * @return 隐私签字意见 + * @param requestId 流程id + * @param nodeId 节点id + * @param userId 用户id + * @param logId 签字意见id + * @return 结果 */ - @Select("select log_id from uf_privacy_log_info where request_id = #{requestId} and user_id <> #{userId} and log_id in ($t{logIds})") - List selectPrivacyLogIdAll(@ParamMapper("logIds") String logIds, - @ParamMapper("userId") String uid, - @ParamMapper("requestId") String requestId); + @Select("select id from uf_privacy_log_info where request_id = #{requestId} and " + + "node_id = #{nodeId} and user_id = #{userId} and log_id = #{logId}") + Integer selectRequestLogDataId(@ParamMapper("requestId") String requestId, + @ParamMapper("nodeId") String nodeId, + @ParamMapper("userId") String userId, + @ParamMapper("logId") String logId); /** @@ -91,4 +104,35 @@ public interface InterceptRequestLogMapper { "and workflow_type = #{workflowId} and (',' || authority_members || ',') like #{userLike}") List selectPrivacyGroup(@ParamMapper("workflowId") String workflowId, @ParamMapper("userLike") String userLike); + + /** + *

查询用户信息

+ * + * @param nodeId 节点id + * @param requestId 请求id + * @return 结果 + */ + @Select("select * from uf_privacy_log_info where request_id = #{requestId} and node_id = #{nodeId}") + RequestLogPrivacyEntity selectRequestLogUsers(@ParamMapper("nodeId") String nodeId, + @ParamMapper("requestId") String requestId); + + /** + *

查询所有启用隐私的签字意见id

+ * + * @param requestId 流程请求id + * @return 所有启用隐私的签字意见id + */ + @Select("select log_id from uf_privacy_log_info where request_id = #{requestId} and enable_privacy = 1") + List selectAllLogId(String requestId); + + /** + *

查询非当前用户所在隐私组的隐私签字意见

+ * + * @param userId 用户id + * @param requestId 流程请求id + * @return 查询结果 + */ + @Select("select log_id from uf_privacy_log_info where request_id = #{requestId} and user_id not in ($t{userId})") + List selectOtherGroupPrivacyLog(@ParamMapper("userId") String userId, + @ParamMapper("requestId") String requestId); } diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/pojo/RequestLogPrivacyEntity.java b/src/main/java/com/customization/youhong/deerge/requestlog/pojo/RequestLogPrivacyEntity.java new file mode 100644 index 0000000..b9ece16 --- /dev/null +++ b/src/main/java/com/customization/youhong/deerge/requestlog/pojo/RequestLogPrivacyEntity.java @@ -0,0 +1,40 @@ +package com.customization.youhong.deerge.requestlog.pojo; + +import aiyh.utils.annotation.recordset.SqlOracleDbFieldAnn; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

签字意见隐私日志信息

+ * + *

create: 2023/3/28 15:08

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class RequestLogPrivacyEntity { + /** id */ + @SqlOracleDbFieldAnn("ID") + private Integer id; + /** requestId */ + @SqlOracleDbFieldAnn("REQUEST_ID") + private String requestId; + /** 节点id */ + @SqlOracleDbFieldAnn("NODE_ID") + private String nodeId; + /** 用户id */ + @SqlOracleDbFieldAnn("USER_ID") + private String userId; + /** 签字意见id */ + @SqlOracleDbFieldAnn("LOG_ID") + private String logId; + /** 是否开启隐私 */ + @SqlOracleDbFieldAnn("ENABLE_PRIVACY") + private String enablePrivacy; + /** 转发签字意见等目标人员 */ + @SqlOracleDbFieldAnn("TARGET_HRM") + private String targetHrm; +} diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java b/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java new file mode 100644 index 0000000..99168e2 --- /dev/null +++ b/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java @@ -0,0 +1,216 @@ +package com.customization.youhong.deerge.requestlog.util; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.customization.youhong.deerge.requestlog.mapper.InterceptRequestLogMapper; +import com.customization.youhong.deerge.requestlog.pojo.RequestLogPrivacyEntity; +import org.apache.log4j.Logger; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

隐私签字意见处理

+ * + *

create: 2023/3/28 14:44

+ * + * @author youHong.ai + */ +public class PrivacyRequestLogUtil { + + private final InterceptRequestLogMapper mapper = Util.getMapper(InterceptRequestLogMapper.class); + + /** + *

隐私信息日志处理

+ * + * @param request 请求信息 + */ + public void privacyRequestLogHandle(HttpServletRequest request) { + Logger logger = Util.getLogger(); + User user = HrmUserVarify.getUser(request, null); + String userId = Util.null2String(user.getUID()); + String enablePrivacy = request.getParameter("enablePrivacy"); + String nodeId = request.getParameter("nodeid"); + String requestId = request.getParameter("requestid"); + String field5 = request.getParameter("field5"); + if (StrUtil.isBlank(enablePrivacy)) { + // 没有添加隐私按钮 + logger.info("没有添加隐私按钮!" + enablePrivacy); + hasNotEnablePrivacy(nodeId, requestId, userId, field5); + return; + } + + if (Boolean.parseBoolean(enablePrivacy)) { + // 开启了隐私权限 + // 查询 当前人员在当前节点的的签字意见id + logger.info("添加隐私按钮!开启隐私" + enablePrivacy); + insertRequestPrivacyLog(userId, nodeId, requestId, field5, "1"); + return; + } + logger.info("添加隐私按钮!未开启隐私"); + // 未开启隐私,更新签字意见隐私信息为不隐私 + Integer logId = mapper.selectRequestLogId(requestId, nodeId, userId); + if (logId > 0) { + mapper.updateRequestLogStatus(logId, userId, nodeId, requestId, "0"); + } + } + + /** + *

插入更新隐私信息

+ * + * @param userId 用户ID + * @param nodeId 节点id + * @param requestId 流程请求id + * @param field5 转发人员 + * @param enablePrivacy 是否开启隐私 + */ + private void insertRequestPrivacyLog(String userId, String nodeId, String requestId, String field5, String enablePrivacy) { + Integer logId = mapper.selectRequestLogId(requestId, nodeId, userId); + Logger logger = Util.getLogger(); + logger.info("查询到的logId是:" + logId); + if (logId <= 0) { + throw new CustomerException("request log id query error!\n"); + } + Integer dataId = mapper.selectRequestLogDataId(requestId, nodeId, userId, String.valueOf(logId)); + logger.info("查询到的数据id是:" + logId); + if (dataId <= 0) { + // 插入logId隐私信息 + dataId = Util.getModeDataId("uf_privacy_log_info", 1); + } + Boolean flag = mapper.insertPrivacyLog(dataId, logId, userId, nodeId, requestId, field5, enablePrivacy); + if (!flag) { + logger.info("更新失败签字意见隐私信息失败!"); + Util.deleteModeId("uf_privacy_log_info", dataId); + } else { + Util.rebuildModeDataShare(1, + Integer.parseInt(Util.getModeIdByTableName("uf_privacy_log_info")), + dataId); + } + } + + /** + *

没有添加隐私按钮开关的逻辑处理

+ * + * @param nodeId 节点id + * @param requestId 请求id + * @param userId 用户id + * @param field5 转发的用户信息 + */ + private void hasNotEnablePrivacy(String nodeId, String requestId, String userId, String field5) { + // 通过节点id,requestId和userId,查询当前用户是否在签字意见记录表中存在,存在则可能是转发等意见征询啥的 + RequestLogPrivacyEntity logPrivacyEntity = mapper.selectRequestLogUsers(nodeId, requestId); + if (Objects.isNull(logPrivacyEntity)) { + // 没有查询到相关数据,检查是否开启隐私 + return; + } + Logger logger = Util.getLogger(); + logger.info("查询到数据:" + JSON.toJSONString(logPrivacyEntity)); + String targetHrm = logPrivacyEntity.getTargetHrm(); + if (StrUtil.isBlank(targetHrm)) { + return; + } + String[] split = targetHrm.split(","); + List hrmIds = Arrays.asList(split); + logger.info("查询到hrmIds数据:" + JSON.toJSONString(hrmIds)); + logger.info("当前用户Id:" + userId); + if (hrmIds.contains(userId)) { + // 默认签字意见隐私 + insertRequestPrivacyLog(userId, nodeId, requestId, field5, "1"); + } + // 不是转发等情况回复,默认处理方式处理 + + } + + /** + *

流程日志列表隐藏控制列表

+ * + * @param result 结果 + * @param params 请求参数 + * @param request 请求体 + */ + + public void requestLogList(Map result, Map params, HttpServletRequest request) { + Logger logger = Util.getLogger(); + String isMonitor = request.getParameter("ismonitor"); + boolean isPrint = "1".equals(Util.null2String(request.getParameter("isprint"))); + String requestId = Util.null2String(params.get("requestid")); + User user = HrmUserVarify.getUser(request, null); + logger.info("结果: " + JSON.toJSONString(result)); + if (isPrint) { + // 打印 + hiddenAll(result, requestId); + logger.info("最终的结果: " + JSON.toJSONString(result)); + return; + } + // 是流程监控 + if (!StrUtil.isBlank(isMonitor)) { + logger.info("流程监控最终的结果: " + JSON.toJSONString(result)); + return; + } + + // 查询隐私组 + String workflowId = Util.null2String(params.get("workflowid")); + List privacyUserList = mapper.selectPrivacyGroup(workflowId, "%," + user.getUID() + ",%"); + if (CollectionUtil.isEmpty(privacyUserList)) { + // 不存在签字意见组中,所有隐私信息不可查看 + hiddenAll(result, requestId); + logger.info("不在隐私组最终的结果: " + JSON.toJSONString(result)); + return; + } + // 查询非本组隐私的隐私信息 + List> logList = (List>) result.get("loglist"); + List privacyLogList = mapper.selectOtherGroupPrivacyLog(Util.join(privacyUserList, ","), requestId); + hiddenContentOrHiddenLog(result, logList, privacyLogList); + } + + + /** + *

隐藏所有签字意见

+ * + * @param result 结果 + * @param requestId 请求id + */ + private void hiddenAll(Map result, String requestId) { + List> logList = (List>) result.get("loglist"); + List privacyLogIdList = mapper.selectAllLogId(requestId); + if (CollectionUtil.isEmpty(privacyLogIdList)) { + return; + } + hiddenContentOrHiddenLog(result, logList, privacyLogIdList); + } + + /** + *

隐藏内容或者整条日志

+ * + * @param result 结果 + * @param logList 日志list + * @param privacyLogIdList 隐私列表 + */ + private static void hiddenContentOrHiddenLog(Map result, List> logList, List privacyLogIdList) { + String showContent = Util.getCusConfigValueNullOrEmpty("REQUEST_LOG_SHOW_CONTENT", "false"); + if (!Boolean.parseBoolean(showContent)) { + List> newLogList = logList.stream() + .filter(item -> !privacyLogIdList.contains(Util.null2String(item.get("logid")))) + .collect(Collectors.toList()); + result.put("loglist", newLogList); + return; + } + List> newLogList = logList.stream() + .peek(item -> { + if (privacyLogIdList.contains(Util.null2String(item.get("logid")))) { + item.put("log_remarkHtml", ""); + } + }) + .collect(Collectors.toList()); + result.put("loglist", newLogList); + } +} diff --git a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/config/service/SapConfigService.java b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/config/service/SapConfigService.java index 4429ea8..82eb60a 100644 --- a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/config/service/SapConfigService.java +++ b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/config/service/SapConfigService.java @@ -1,6 +1,7 @@ package weaver.youhong.ai.haripijiu.action.sapdocking.config.service; import aiyh.utils.Util; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; import ebu7common.youhong.ai.bean.Builder; import org.apache.log4j.Logger; @@ -192,12 +193,14 @@ public class SapConfigService { List credit = collect.get(1); Assert.notEmpty(debit, "debit config not be null!"); - Assert.notEmpty(credit, "credit config not be bull!"); + List debtorList = getVoucherItems(workflowData, debit); result.add(debtorList); - List creditorList = getVoucherItems(workflowData, credit); - result.add(creditorList); + if (CollectionUtil.isNotEmpty(credit)) { + List creditorList = getVoucherItems(workflowData, credit); + result.add(creditorList); + } return result; } diff --git a/src/main/resources/WEB-INF/prop/prop2map/JituMultilingual.properties b/src/main/resources/WEB-INF/prop/prop2map/JituMultilingual.properties new file mode 100644 index 0000000..4d44973 --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/JituMultilingual.properties @@ -0,0 +1,16 @@ +#修改当前配置文件后需要重启, you must restart service at change the config file after +# +# 当前需要同步的语言, current active language +cus.multilingual.active=ZHS,IDN +#中文 +cus.multilingual.ZHS=7 +#印尼 +cus.multilingual.IDN=22 +# 泰语 +cus.multilingual.THA=17 +# 英语 +cus.multilingual.ENG=8 +# 越南 +cus.multilingual.VIE=14 +# 葡萄牙 +cus.multilingual.POR=21 \ No newline at end of file diff --git a/src/test/java/youhong/ai/utiltest/GenericTest.java b/src/test/java/youhong/ai/utiltest/GenericTest.java index 35b9269..86a43a4 100644 --- a/src/test/java/youhong/ai/utiltest/GenericTest.java +++ b/src/test/java/youhong/ai/utiltest/GenericTest.java @@ -1,5 +1,10 @@ package youhong.ai.utiltest; +import aiyh.utils.Util; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import basetest.BaseTest; +import org.junit.Test; + import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -8,7 +13,7 @@ import java.util.List; import java.util.Map; -public class GenericTest { +public class GenericTest extends BaseTest { private final List> map = new ArrayList<>(); @@ -55,4 +60,26 @@ public class GenericTest { } } + + @Test + public void teset() { + List list = new ArrayList(); + list.add(1); + list.add(2); + System.out.println(CollectionUtil.sub(list, 0, 10)); + } + + + @Test + public void parseLanguage() { + System.out.println(Util.parseLanguageString("~`~`7 行政管理`~`8 administrative management`~`9 行政管理`~`~", "8")); + } + + + @Test + public void teeet() throws ClassNotFoundException { + Class aClass = Class.forName("weaver.aiyh_jitu.pushdata.service.toones.GetUUIDFromProjectIdFieldImpl"); + System.out.println(aClass); + } + } \ No newline at end of file From a691c6def9070993347f41a922eef850e3cf1bb4 Mon Sep 17 00:00:00 2001 From: "youHong.ai" <774495953@qq.com> Date: Mon, 17 Apr 2023 22:47:28 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E7=AD=BE=E5=AD=97=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../youhong.ai/deerge/workflow_code_block.js | 114 + .../aiyh/utils/action/SafeCusBaseAction.java | 10 +- .../utils/action/mapper/SafeActionMapper.java | 20 + .../impl/RequestLogShowOrHiddenImpl.java | 1 - .../mapper/InterceptRequestLogMapper.java | 9 +- .../util/PrivacyRequestLogUtil.java | 93 +- .../biz/requestForm/RequestRemindBiz.java | 2186 +++++++++++++++++ .../ai/taibao/email/BlackListExpansion.java | 21 + .../ai/taibao/email/BlackListRegister.java | 38 + .../email/impl/InitBlackListServiceImpl.java | 64 + .../mapper/InitBlackEmailListMapper.java | 44 + .../config/enumtype/GetValueTypeEnum.java | 74 +- .../commons/config/mapper/DealWithMapper.java | 21 + .../config/service/DealWithMapping.java | 35 +- .../sapdocking/VoucherPayableAction.java | 14 +- .../sapdocking/VoucherPayableNewAction.java | 246 ++ .../youhong/ai/haripijiu/TestHaRiPiJiu.java | 5 +- src/test/java/youhong/ai/pcn/UtilTest.java | 4 + .../java/youhong/ai/taibao/TestTaiBao.java | 11 + .../java/youhong/ai/utiltest/GenericTest.java | 8 + 20 files changed, 2944 insertions(+), 74 deletions(-) create mode 100644 javascript/youhong.ai/deerge/workflow_code_block.js create mode 100644 src/main/java/aiyh/utils/action/mapper/SafeActionMapper.java create mode 100644 src/main/java/com/engine/workflow/biz/requestForm/RequestRemindBiz.java create mode 100644 src/main/java/com/engine/youhong/ai/taibao/email/BlackListExpansion.java create mode 100644 src/main/java/com/engine/youhong/ai/taibao/email/BlackListRegister.java create mode 100644 src/main/java/com/engine/youhong/ai/taibao/email/impl/InitBlackListServiceImpl.java create mode 100644 src/main/java/com/engine/youhong/ai/taibao/email/mapper/InitBlackEmailListMapper.java create mode 100644 src/main/java/weaver/xiao/commons/config/mapper/DealWithMapper.java create mode 100644 src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java diff --git a/javascript/youhong.ai/deerge/workflow_code_block.js b/javascript/youhong.ai/deerge/workflow_code_block.js new file mode 100644 index 0000000..e663aeb --- /dev/null +++ b/javascript/youhong.ai/deerge/workflow_code_block.js @@ -0,0 +1,114 @@ +/* ******************* 德尔格 明细物料历史数据折扣带出提示 by youhong.ai ******************* */ +$(() => { + let type = { + // 等于 + equalTo: (value, target) => value == target, + // 不等于 + notEqual: (value, target) => value != target, + // 大于 + greaterThan: (value, target) => +value > +target, + // 小于 + lessThan: (value, target) => +value < +target + } + // 值类型 + let valueType = { + // 固定值 + fixValue: 0, + // 流程字段 + field: 1 + } + let config = { + // 主表,填main + table: 'main', + // 明细表,明细1为detail_1,明细2为detail_2 + detail: 'detail_1', + redField: 'zk', + // 条件集合 + conditions: [{ + // 所属表 + table: 'detail_1', + // 字段 + field: 'wllx', + // 对比值 + value: 0, + // 值的类型 + valueType: valueType.fixValue, + // 值字段所在表 + valueTable: '', + // 条件类型 + type: type.equalTo + }, { + // 所属表 + table: 'detail_1', + // 字段 + field: 'zkdc', + // 对比值 + value: 'zk', + // 值的类型 + valueType: valueType.field, + // 值字段所在表 + valueTable: 'detail_1', + // 条件类型 + type: type.notEqual + }] + } + + runJs() + + function runJs() { + let detailAllRowIndexStr = WfForm.getDetailAllRowIndexStr(config.detail); + let rowIndexArr = detailAllRowIndexStr.split(","); + let flag = true + rowIndexArr.forEach(rowIndex => { + if (flag) { + flag = isTrue(rowIndex) + } else { + isTrue(rowIndex) + } + }) + if (!flag) { + WfForm.showConfirm("当前订单折扣不等于默认折扣"); + } + } + + + function isTrue(rowIndex) { + let flag = true + for (let i = 0; i < config.conditions.length; i++) { + let item = config.conditions[i] + let fieldId = WfForm.convertFieldNameToId(config, item.table) + let fieldMark = `${fieldId}_${rowIndex}` + let fieldValue = WfForm.getFieldValue(fieldMark) + if (item.valueType == valueType.fixValue) { + if (item.type(fieldValue, item.value)) { + continue + } + renderRed(`${WfForm.convertFieldNameToId(config.redField, config.detail)}_${rowIndex}`) + flag = false + } + if (item.valueType == valueType.field) { + if (item.type(fieldValue, WfForm.getFieldValue(item.value, item.valueTable))) { + continue + } + renderRed(`${WfForm.convertFieldNameToId(config.redField, config.detail)}_${rowIndex}`) + flag = false + } + } + return flag + } + + function renderRed(fieldMark) { + $(`#oTable0 .detail_odd_row.detail_data_row div[data-fieldmark='${fieldMark}'] .wf-form-input`).css({ + color: '#FFF', + background: 'red', + }) + $(`#oTable0 .detail_odd_row.detail_data_row div[data-fieldmark='${fieldMark}'] .wf-form-input input`).css({ + 'border-color': 'red', + background: 'red', + color: '#FFF' + }) + } +}) + +/* ******************* 德尔格 明细物料历史数据折扣带出提示 end ******************* */ + diff --git a/src/main/java/aiyh/utils/action/SafeCusBaseAction.java b/src/main/java/aiyh/utils/action/SafeCusBaseAction.java index 4812e87..dbf0b05 100644 --- a/src/main/java/aiyh/utils/action/SafeCusBaseAction.java +++ b/src/main/java/aiyh/utils/action/SafeCusBaseAction.java @@ -1,6 +1,7 @@ package aiyh.utils.action; import aiyh.utils.Util; +import aiyh.utils.action.mapper.SafeActionMapper; import aiyh.utils.excention.CustomerException; import com.google.common.base.Strings; import org.apache.log4j.Logger; @@ -29,6 +30,8 @@ public abstract class SafeCusBaseAction implements Action { protected final Logger log = Util.getLogger(); private final Map actionHandleMethod = new HashMap<>(); + private final SafeActionMapper mapper = Util.getMapper(SafeActionMapper.class); + /** *

初始化流程默认的处理方法

*/ @@ -191,7 +194,12 @@ public abstract class SafeCusBaseAction implements Action { protected Map getMainTableValue(RequestInfo requestInfo) { // 获取主表数据 Property[] propertyArr = requestInfo.getMainTableInfo().getProperty(); - return getStringMap(propertyArr); + Map result = getStringMap(propertyArr); + RequestManager requestManager = requestInfo.getRequestManager(); + String billTable = requestManager.getBillTableName(); + String id = mapper.selectIdByRequest(billTable, requestInfo.getRequestid()); + result.put("id", id); + return result; } @NotNull diff --git a/src/main/java/aiyh/utils/action/mapper/SafeActionMapper.java b/src/main/java/aiyh/utils/action/mapper/SafeActionMapper.java new file mode 100644 index 0000000..26956c9 --- /dev/null +++ b/src/main/java/aiyh/utils/action/mapper/SafeActionMapper.java @@ -0,0 +1,20 @@ +package aiyh.utils.action.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +/** + *

+ * + *

create: 2023/4/17 17:47

+ * + * @author youHong.ai + */ +@SqlMapper +public interface SafeActionMapper { + + @Select("select id from $t{billTable} where requestid = #{requestId}") + String selectIdByRequest(@ParamMapper("billTable") String billTable, + @ParamMapper("requestId") String requestId); +} diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java b/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java index b0f6be4..5516037 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/impl/RequestLogShowOrHiddenImpl.java @@ -38,7 +38,6 @@ public class RequestLogShowOrHiddenImpl extends AbstractServiceProxy implements Logger log = Util.getLogger(); try { privacyRequestLogUtil.requestLogList(result, params, request); - log.info("最终的返回结果: " + JSON.toJSONString(result)); } catch (Exception e) { log.error("filter request log list error!" + Util.getErrString(e)); } diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java b/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java index f367c08..902a088 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/mapper/InterceptRequestLogMapper.java @@ -4,6 +4,7 @@ import aiyh.utils.annotation.recordset.*; import com.customization.youhong.deerge.requestlog.pojo.RequestLogPrivacyEntity; import java.util.List; +import java.util.Map; /** *

拦截签字意见隐私处理

@@ -24,11 +25,11 @@ public interface InterceptRequestLogMapper { * @param operator 操作者 * @return 签字意见id */ - @Select("select logid from workflow_requestlog where REQUESTID = #{requestId} " + + @Select("select logid,operatetime from workflow_requestlog where REQUESTID = #{requestId} " + "and NODEID = #{nodeId} and OPERATOR = #{operator} order by LOGID desc ") - Integer selectRequestLogId(@ParamMapper("requestId") String requestId, - @ParamMapper("nodeId") String nodeId, - @ParamMapper("operator") String operator); + List> selectRequestLogId(@ParamMapper("requestId") String requestId, + @ParamMapper("nodeId") String nodeId, + @ParamMapper("operator") String operator); /** *

更新隐私信息

diff --git a/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java b/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java index 99168e2..9fa1c99 100644 --- a/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java +++ b/src/main/java/com/customization/youhong/deerge/requestlog/util/PrivacyRequestLogUtil.java @@ -12,10 +12,7 @@ import weaver.hrm.HrmUserVarify; import weaver.hrm.User; import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; /** @@ -58,10 +55,29 @@ public class PrivacyRequestLogUtil { } logger.info("添加隐私按钮!未开启隐私"); // 未开启隐私,更新签字意见隐私信息为不隐私 - Integer logId = mapper.selectRequestLogId(requestId, nodeId, userId); - if (logId > 0) { - mapper.updateRequestLogStatus(logId, userId, nodeId, requestId, "0"); + List> nodeIdMapList = mapper.selectRequestLogId(requestId, nodeId, userId); + logger.info("查询的log日志列表:" + nodeIdMapList); + if (CollectionUtil.isEmpty(nodeIdMapList)) { + return; } + Map firstLog = nodeIdMapList.get(0); + String operateTime = Util.null2String(firstLog.get("operatetime")); + List logList = new ArrayList<>(); + for (Map item : nodeIdMapList) { + String itemOperateTime = Util.null2String(item.get("operatetime")); + int logId = Integer.parseInt(Util.null2String(item.get("logid"))); + if (operateTime.equals(itemOperateTime)) { + logList.add(logId); + } else { + break; + } + } + for (Integer logId : logList) { + if (logId > 0) { + mapper.updateRequestLogStatus(logId, userId, nodeId, requestId, "0"); + } + } + } /** @@ -74,26 +90,45 @@ public class PrivacyRequestLogUtil { * @param enablePrivacy 是否开启隐私 */ private void insertRequestPrivacyLog(String userId, String nodeId, String requestId, String field5, String enablePrivacy) { - Integer logId = mapper.selectRequestLogId(requestId, nodeId, userId); Logger logger = Util.getLogger(); - logger.info("查询到的logId是:" + logId); - if (logId <= 0) { - throw new CustomerException("request log id query error!\n"); + + List> nodeIdMapList = mapper.selectRequestLogId(requestId, nodeId, userId); + logger.info("查询的log日志列表:" + nodeIdMapList); + if (CollectionUtil.isEmpty(nodeIdMapList)) { + return; } - Integer dataId = mapper.selectRequestLogDataId(requestId, nodeId, userId, String.valueOf(logId)); - logger.info("查询到的数据id是:" + logId); - if (dataId <= 0) { - // 插入logId隐私信息 - dataId = Util.getModeDataId("uf_privacy_log_info", 1); + Map firstLog = nodeIdMapList.get(0); + String operateTime = Util.null2String(firstLog.get("operatetime")); + List logList = new ArrayList<>(); + for (Map item : nodeIdMapList) { + String itemOperateTime = Util.null2String(item.get("operatetime")); + int logId = Integer.parseInt(Util.null2String(item.get("logid"))); + if (operateTime.equals(itemOperateTime)) { + logList.add(logId); + } else { + break; + } } - Boolean flag = mapper.insertPrivacyLog(dataId, logId, userId, nodeId, requestId, field5, enablePrivacy); - if (!flag) { - logger.info("更新失败签字意见隐私信息失败!"); - Util.deleteModeId("uf_privacy_log_info", dataId); - } else { - Util.rebuildModeDataShare(1, - Integer.parseInt(Util.getModeIdByTableName("uf_privacy_log_info")), - dataId); + for (Integer logId : logList) { + logger.info("查询到的logId是:" + logId); + if (logId <= 0) { + throw new CustomerException("request log id query error!\n"); + } + Integer dataId = mapper.selectRequestLogDataId(requestId, nodeId, userId, String.valueOf(logId)); + logger.info("查询到的数据id是:" + logId); + if (dataId <= 0) { + // 插入logId隐私信息 + dataId = Util.getModeDataId("uf_privacy_log_info", 1); + } + Boolean flag = mapper.insertPrivacyLog(dataId, logId, userId, nodeId, requestId, field5, enablePrivacy); + if (!flag) { + logger.info("更新失败签字意见隐私信息失败!"); + Util.deleteModeId("uf_privacy_log_info", dataId); + } else { + Util.rebuildModeDataShare(1, + Integer.parseInt(Util.getModeIdByTableName("uf_privacy_log_info")), + dataId); + } } } @@ -120,8 +155,6 @@ public class PrivacyRequestLogUtil { } String[] split = targetHrm.split(","); List hrmIds = Arrays.asList(split); - logger.info("查询到hrmIds数据:" + JSON.toJSONString(hrmIds)); - logger.info("当前用户Id:" + userId); if (hrmIds.contains(userId)) { // 默认签字意见隐私 insertRequestPrivacyLog(userId, nodeId, requestId, field5, "1"); @@ -139,21 +172,17 @@ public class PrivacyRequestLogUtil { */ public void requestLogList(Map result, Map params, HttpServletRequest request) { - Logger logger = Util.getLogger(); String isMonitor = request.getParameter("ismonitor"); boolean isPrint = "1".equals(Util.null2String(request.getParameter("isprint"))); String requestId = Util.null2String(params.get("requestid")); User user = HrmUserVarify.getUser(request, null); - logger.info("结果: " + JSON.toJSONString(result)); if (isPrint) { // 打印 hiddenAll(result, requestId); - logger.info("最终的结果: " + JSON.toJSONString(result)); return; } // 是流程监控 if (!StrUtil.isBlank(isMonitor)) { - logger.info("流程监控最终的结果: " + JSON.toJSONString(result)); return; } @@ -163,7 +192,6 @@ public class PrivacyRequestLogUtil { if (CollectionUtil.isEmpty(privacyUserList)) { // 不存在签字意见组中,所有隐私信息不可查看 hiddenAll(result, requestId); - logger.info("不在隐私组最终的结果: " + JSON.toJSONString(result)); return; } // 查询非本组隐私的隐私信息 @@ -197,6 +225,7 @@ public class PrivacyRequestLogUtil { */ private static void hiddenContentOrHiddenLog(Map result, List> logList, List privacyLogIdList) { String showContent = Util.getCusConfigValueNullOrEmpty("REQUEST_LOG_SHOW_CONTENT", "false"); + String requestLogShowContentDefault = Util.getCusConfigValueNullOrEmpty("requestLogShowContentDefault", ""); if (!Boolean.parseBoolean(showContent)) { List> newLogList = logList.stream() .filter(item -> !privacyLogIdList.contains(Util.null2String(item.get("logid")))) @@ -207,7 +236,7 @@ public class PrivacyRequestLogUtil { List> newLogList = logList.stream() .peek(item -> { if (privacyLogIdList.contains(Util.null2String(item.get("logid")))) { - item.put("log_remarkHtml", ""); + item.put("log_remarkHtml", requestLogShowContentDefault); } }) .collect(Collectors.toList()); diff --git a/src/main/java/com/engine/workflow/biz/requestForm/RequestRemindBiz.java b/src/main/java/com/engine/workflow/biz/requestForm/RequestRemindBiz.java new file mode 100644 index 0000000..6f3df02 --- /dev/null +++ b/src/main/java/com/engine/workflow/biz/requestForm/RequestRemindBiz.java @@ -0,0 +1,2186 @@ +package com.engine.workflow.biz.requestForm; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.api.sms.util.SmsSendUtil; +import com.engine.common.biz.EncryptConfigBiz; +import com.engine.core.impl.CommandExecutorUtil; +import com.engine.email.biz.EmailApprovalService; +import com.engine.workflow.biz.freeNode.FreeNodeBiz; +import com.engine.workflow.cmd.requestForm.emailApprove.GetEmailApproveParamCmd; +import com.engine.workflow.cmd.requestForm.remind.GetEmailRemindUrlCmd; +import com.engine.workflow.constant.RemindTypeEnum; +import com.engine.workflow.util.GetCustomLevelUtil; +import com.engine.workflow.util.WfToDocUtil; +import com.engine.youhong.ai.taibao.email.BlackListExpansion; +import com.engine.youhong.ai.taibao.email.BlackListRegister; +import com.google.common.base.Strings; +import weaver.conn.RecordSet; +import weaver.email.EmailApprovalRunnable; +import weaver.email.EmailWorkRunnable; +import weaver.general.*; +import weaver.hrm.User; +import weaver.hrm.online.HrmUserOnlineMap; +import weaver.interfaces.workflow.browser.Browser; +import weaver.interfaces.workflow.browser.BrowserBean; +import weaver.sms.SMSSaveAndSend; +import weaver.sms.SmsFromMouldEnum; +import weaver.systeminfo.SystemEnv; +import weaver.workflow.logging.Logger; +import weaver.workflow.logging.LoggerFactory; +import weaver.workflow.request.RequestDoc; +import weaver.workflow.request.RequestManager; +import weaver.workflow.request.WFAutoApproveUtils; +import weaver.workflow.request.entity.RequestOperateEntityTableNameEnum; +import weaver.workflow.workflow.WFManager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.*; + +/** + * @author jhush + * @desc 流程提醒 + * @date 2019/1/16 + */ +public class RequestRemindBiz { + + private final static Logger log = LoggerFactory.getLogger(RequestRemindBiz.class); + + public static final String SYSTEM_FIELD_LEVEL = "${fieldid_-2}"; + public static final String SYSTEM_FIELD_TITLE = "${fieldid_-3}"; + public static final String SYSTEM_FIELD_TITLE_LINK = "${fieldid_-3_link}"; + public static final String SYSTEM_FIELD_CREATEDATA = "${fieldid_-4}"; + public static final String SYSTEM_FIELD_APPROVE_BTN = "${fieldid_-5}"; + + public static final String APPROVE_PARAM_SIGN = "[ecParam]"; + public static final String APPROVE_PARAM = APPROVE_PARAM_SIGN + "%s" + APPROVE_PARAM_SIGN; + + + private User user; + + private String requestId; + private String wfId; + private String src; + private Map fieldDatas = null; + private Map> remindContent = null; + private Map> defaultRemindContent = null; + + public RequestRemindBiz() { + } + + public RequestRemindBiz(User user) { + if (user == null) user = new User(1); + this.user = user; + } + + public RequestRemindBiz(User user, int reqId, int wfId, String src) { + this(user); + this.requestId = String.valueOf(reqId); + this.wfId = String.valueOf(wfId); + this.src = src; + } + + /** + * 流程提醒 + * + * @param requestId + * @param wfId + * @param submitType + * @param remindType + * @param onLine + */ + public void requestRemind(int requestId, int wfId, String submitType, RemindTypeEnum remindType, int onLine) { + + Set currentNodeUser = this.getCurrentNodeUser(Util.null2String(requestId), onLine); + String remindUser = String.join(",", currentNodeUser); + this.printLog("2、rquestid: +" + requestId + ",userid:" + user.getUID() + ",user: " + remindUser); + + Map params = new HashMap<>(); + params.put("reminder", remindUser); + params.put("requestId", requestId); + params.put("workflowId", wfId); + params.put("submitType", submitType); + + if (remindType.getCode().equals(RemindTypeEnum.SMS.getCode())) this.requestRemind(params, RemindTypeEnum.SMS); + if (remindType.getCode().equals(RemindTypeEnum.EMAIL.getCode())) + this.requestRemind(params, RemindTypeEnum.EMAIL); + + } + + + /** + * 新创建的流程,给创建人发送提醒 + * + * @param requestId + * @param wfId + * @param submitType + * @param remindType + * @param onLine + */ + public void requestCreateRemind(int requestId, int wfId, String submitType, RemindTypeEnum remindType, int onLine) { + + Set userList = new HashSet<>(); + String sql = "select currentnodeid from workflow_requestbase where requestid = ? and currentnodetype=0"; + RecordSet rs = new RecordSet(); + rs.executeQuery(sql, requestId); + if (rs.next()) { + String currentnodeid = rs.getString(1); + sql = "select userid from workflow_currentoperator where requestid = ? and nodeid = ? and isremark in(0,1,4,6,7) "; + rs.executeQuery(sql, requestId, currentnodeid); + while (rs.next()) { + String userId = Util.null2String(rs.getString("userid")); + if (onLine == 1) { // 离线才发 + HrmUserOnlineMap hrmUserOnlineMap = HrmUserOnlineMap.getInstance(); + if (!hrmUserOnlineMap.isOnline(Util.getIntValue(userId))) { + userList.add(userId); + } + } else { + userList.add(userId); + } + } + String remindUser = String.join(",", userList); + + Map params = new HashMap<>(); + params.put("reminder", remindUser); + params.put("requestId", requestId); + params.put("workflowId", wfId); + params.put("submitType", submitType); + + if (remindType.getCode().equals(RemindTypeEnum.SMS.getCode())) + this.requestRemind(params, RemindTypeEnum.SMS); + if (remindType.getCode().equals(RemindTypeEnum.EMAIL.getCode())) + this.requestRemind(params, RemindTypeEnum.EMAIL); + } else { + new BaseBean().writeLog("当前流程不在创建节点requestId:" + requestId); + } + } + + /** + * 流程进入自动审批时,先提醒自动审批前当前节点上的抄送人 + * + * @param requestManager + */ + public void autoApproveCCRemind(int currentNodeId, RequestManager requestManager) { + + String requestId = String.valueOf(requestManager.getRequestid()); + + int wfId = requestManager.getWorkflowid(); + + RecordSet rs = new RecordSet(); + rs.executeQuery("select nodeid from workflow_requestoperatelog where requestid = ? and operatetype='submit' order by id desc", requestId); + if (rs.next()) { + int nodeId = Util.getIntValue(rs.getString(1)); + if (nodeId != currentNodeId) { + Set users = new HashSet<>(); + String sql = "select userid from workflow_currentoperator where requestid = ? and usertype = 0 and nodeid = ? and isremark in(8,9)"; + rs.executeQuery(sql, requestId, currentNodeId); + while (rs.next()) { + users.add(Util.null2String(rs.getString(1))); + } + + Map> defaultRemindContent = this.getDefaultRemindContent(); // 默认提醒内容 + Map fieldDatas = this.getFieldData(requestId); + + rs.executeQuery("select remindscope from workflow_base where id = ? ", wfId); + rs.next(); + int remindscope = Util.getIntValue(rs.getString("remindscope"), 0); + if (remindscope == 1) { + rs.executeQuery("select id,remindTypes,contenttype from wf_emailremind_set where workflowid = ? and nodeid = ? and ccNoRemind = 0", wfId, currentNodeId); + if (rs.next()) { + int id = rs.getInt(1); + String remindTypes = rs.getString(2); + int contenttype = rs.getInt(3); + String[] remindTypesArr = remindTypes.split(","); + for (String remindType : remindTypesArr) { + if (contenttype == 1) { + + String title = null; + String content = null; + int formData = 0; + int signData = 0; + int attachmentData = 0; + rs.executeQuery("select title,content,contentType,isformdata,issigndata,isattachmentdata from wf_emailremind_content " + + "where remindSetId = ? and remindType=? ", id, remindType); + while (rs.next()) { + String contentType = rs.getString(3); + if (contentType.equals(RemindTypeEnum.CC.getCode())) { + title = rs.getString(1); + content = rs.getString(2); + formData = Util.getIntValue(rs.getString(4), 0); + signData = Util.getIntValue(rs.getString(5), 0); + attachmentData = Util.getIntValue(rs.getString(6), 0); + } + } + + if (RemindTypeEnum.SMS.getCode().equals(remindType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.SMS.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + content = Strings.isNullOrEmpty(content) ? Util.null2String(info.get("content")) : content; + content = content.replace("_link", ""); // 默认内容中带有超链接字段 + content = Util.toHtmlMode(this.replaceFieldValue(fieldDatas, content)); + this.sendSMS(String.join(",", users), content, requestId); + } + if (RemindTypeEnum.EMAIL.getCode().equals(remindType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.EMAIL.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + title = Strings.isNullOrEmpty(title) ? Util.null2String(info.get("title")) : title; + content = Strings.isNullOrEmpty(content) ? Util.null2String(info.get("content")) : content; + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) + allAttchment.addAll(this.getRequestAttachment(requestId, String.valueOf(wfId))); + + title = this.replaceFieldValue(fieldDatas, title); + content = this.replaceFieldValue(fieldDatas, content); + this.sendEmail(String.join(",", users), title, content, requestId, String.join(",", allAttchment)); + } + + } else { + if (RemindTypeEnum.SMS.getCode().equals(remindType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.SMS.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + String content = Util.null2String(info.get("content")); + content = content.replace("_link", ""); // 默认内容中带有超链接字段 + content = Util.toHtmlMode(this.replaceFieldValue(fieldDatas, content)); + this.sendSMS(String.join(",", users), content, requestId); + } + if (RemindTypeEnum.EMAIL.getCode().equals(remindType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.EMAIL.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + String title = Util.null2String(info.get("title")); + String content = Util.null2String(info.get("content")); + int formData = Util.getIntValue(Util.null2String(info.get("isFormData")), 0); + int signData = Util.getIntValue(Util.null2String(info.get("isSignData")), 0); + int attachmentData = Util.getIntValue(Util.null2String(info.get("isAttachmentData")), 0); + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) + allAttchment.addAll(this.getRequestAttachment(requestId, String.valueOf(wfId))); + title = this.replaceFieldValue(fieldDatas, title); + content = this.replaceFieldValue(fieldDatas, content); + this.sendEmail(String.join(",", users), title, content, requestId, String.join(",", allAttchment)); + } + } + } + } + } else { + WFManager wfManager = getWfInfo(String.valueOf(wfId)); + boolean isCCNotRemind = "1".equals(wfManager.getIsCCNoRemind()); + if (!isCCNotRemind) { + + String defaultSmsRemind = wfManager.getIsDefaultSmsRemind(); + String defaultEmailRemind = wfManager.getIsDefaultEmailRemind(); + String mailMessageType = wfManager.getMailMessageType(); + String messageType = wfManager.getMessageType(); + + if ("1".equals(defaultSmsRemind) || "1".equals(messageType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.SMS.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + String content = Util.null2String(info.get("content")); + content = content.replace("_link", ""); // 默认内容中带有超链接字段 + content = Util.toHtmlMode(this.replaceFieldValue(fieldDatas, content)); + this.sendSMS(String.join(",", users), content, requestId); + } + if ("1".equals(defaultEmailRemind) || "1".equals(mailMessageType)) { + Map> contentMap = this.getRemindContent(String.valueOf(wfId), RemindTypeEnum.EMAIL.getCode()); + Map info = contentMap.get(RemindTypeEnum.CC.getCode()); + if (info == null) info = defaultRemindContent.get(RemindTypeEnum.CC.getCode()); + String title = Util.null2String(info.get("title")); + String content = Util.null2String(info.get("content")); + int formData = Util.getIntValue(Util.null2String(info.get("isFormData")), 0); + int signData = Util.getIntValue(Util.null2String(info.get("isSignData")), 0); + int attachmentData = Util.getIntValue(Util.null2String(info.get("isAttachmentData")), 0); + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) + allAttchment.addAll(this.getRequestAttachment(requestId, String.valueOf(wfId))); + title = this.replaceFieldValue(fieldDatas, title); + content = this.replaceFieldValue(fieldDatas, content); + this.sendEmail(String.join(",", users), title, content, requestId, String.join(",", allAttchment)); + + } + } + } + } + } + } + + /** + * 流程自动审批失败,提醒当前节点除抄送人之外的人员 + * + * @param requestManager + */ + public void failAutoApproveRemind(RequestManager requestManager) { + + int requestId = requestManager.getRequestid(); + int wfId = requestManager.getWorkflowid(); + int currentNoidId = requestManager.getNextNodeid(); + + + RecordSet rs = new RecordSet(); + Set users = new HashSet<>(); + + String sql = "select userid from workflow_currentoperator where requestid = ? and usertype = 0 and nodeid = ? and isremark in(0,1,4,6,7) "; + rs.executeQuery(sql, requestId, currentNoidId); + while (rs.next()) { + users.add(Util.null2String(rs.getString(1))); + } + + Map params = new HashMap<>(); + params.put("reminder", String.join(",", users)); + params.put("requestId", requestId); + params.put("workflowId", wfId); + params.put("submitType", "submit"); + + rs.executeQuery("select remindscope from workflow_base where id = ? ", wfId); + rs.next(); + int remindscope = Util.getIntValue(rs.getString("remindscope"), 0); + if (remindscope == 1) { + this.requestRemind(params, RemindTypeEnum.EMAIL); + return; + } + WFManager wfManager = getWfInfo(String.valueOf(wfId)); + String defaultSmsRemind = wfManager.getIsDefaultSmsRemind(); + String defaultEmailRemind = wfManager.getIsDefaultEmailRemind(); + String mailMessageType = wfManager.getMailMessageType(); + String messageType = wfManager.getMessageType(); + + if ("1".equals(defaultSmsRemind) || "1".equals(messageType)) this.requestRemind(params, RemindTypeEnum.SMS); + if ("1".equals(defaultEmailRemind) || "1".equals(mailMessageType)) + this.requestRemind(params, RemindTypeEnum.EMAIL); + this.requestEmailApproveRemind(this.wfId, this.requestId, src); + } + + /** + * 流程自动审批成功 + * 1、如果继续自动审批,不做任何提醒 + * 2、非自动审批,提醒自动审批后停留节点的操作者 + * + * @param requestManager + */ + public void successAutoApproveRemind(RequestManager requestManager) { + + List nextNodeids = requestManager.getNextnodeids(); + Map nodeInfoCache = requestManager.getNodeInfoCache(); + Set nodeInfoCacheKey = nodeInfoCache.keySet(); + + Set nodeIds = new HashSet<>(); + for (Object id : nextNodeids) { + int intId = Util.getIntValue((String) id); + boolean exists = false; + for (Integer cacheId : nodeInfoCacheKey) { + if (cacheId == intId) { + exists = true; + break; + } + } + if (!exists) { + nodeIds.add(String.valueOf(intId)); + } + } + this.printLog("successAutoApproveRemind nodeIds:" + nodeIds); + if (nodeIds.isEmpty()) return; + + int requestId = requestManager.getRequestid(); + int wfId = requestManager.getWorkflowid(); + + RecordSet rs = new RecordSet(); + Set users = new HashSet<>(); + + rs.executeQuery("select detailinfo from workflow_requestoperatelog where operatetype ='submit' and requestid = ? " + + " and ( isinvalid is null or isinvalid = '') order by id desc ", requestId); + if (rs.next()) { + String newIds = ""; + String detailInfo = Util.null2String(rs.getString(1)); + JSONObject jsonObject = JSONObject.parseObject(detailInfo); + if (jsonObject != null) { + JSONObject operaterInfo = jsonObject.getJSONObject("workflow_currentoperator"); + if (operaterInfo != null) { + newIds = operaterInfo.getString("newIds"); + } + } + if (newIds.length() > 0) { + String sql = "select userid from workflow_currentoperator where requestid = ? and usertype = 0 and isremark in(0,1,4,6,7,8,9) "; + sql += " and " + Util.getSubINClause(newIds, "id", "in"); + rs.executeQuery(sql, requestId); + while (rs.next()) { + users.add(Util.null2String(rs.getString(1))); + } + } + } + // 修正D节点中有1234个会签操作者,123自动审批成功后,4无法收到消息的问题 + String nodeIdStr = String.join(",", nodeIds); + String sql = "select userid from workflow_currentoperator where requestid = ? and usertype = 0 and isremark in(0,1,4,6,7) "; + sql += " and " + Util.getSubINClause(nodeIdStr, "nodeid", "in") + " and islasttimes =1 "; + rs.executeQuery(sql, requestId); + while (rs.next()) { + users.add(Util.null2String(rs.getString(1))); + } + + String reminder = String.join(",", users); + this.printLog("successAutoApproveRemind requestId:" + requestId + ",userd :" + reminder); + + Map params = new HashMap<>(); + params.put("reminder", reminder); + params.put("requestId", requestId); + params.put("workflowId", wfId); + params.put("submitType", "submit"); + params.put("nextNodeIds", nodeIdStr); + + this.requestEmailApproveRemind2(params); + + rs.executeQuery("select remindscope from workflow_base where id = ? ", wfId); + rs.next(); + int remindscope = Util.getIntValue(rs.getString("remindscope"), 0); + if (remindscope == 1) { + this.requestRemind(params, RemindTypeEnum.EMAIL); + return; + } + WFManager wfManager = getWfInfo(String.valueOf(wfId)); + String defaultSmsRemind = wfManager.getIsDefaultSmsRemind(); + String defaultEmailRemind = wfManager.getIsDefaultEmailRemind(); + String mailMessageType = wfManager.getMailMessageType(); + String messageType = wfManager.getMessageType(); + + if ("1".equals(defaultSmsRemind) || "1".equals(messageType)) this.requestRemind(params, RemindTypeEnum.SMS); + if ("1".equals(defaultEmailRemind) || "1".equals(mailMessageType)) + this.requestRemind(params, RemindTypeEnum.EMAIL); + + } + + /** + * 流程超时处理 + * + * @param requestid + * @param workflowid + */ + public void autoFlowRemind(int requestid, int workflowid, int flownextoperator) { + // 短信发起人 + RecordSet rs = new RecordSet(); + rs.executeQuery("select operator from workflow_requestLog where requestid = ? order by logid desc ", requestid); + rs.next(); + int operator = Util.getIntValue(rs.getString(1), 1); + this.user = new User(operator); + // 提醒 + if (flownextoperator == 1 || flownextoperator == 4) { + this.requestSubmitRemind4WebService(requestid, workflowid, -1, -1); + } else if (flownextoperator == 3) { + this.requestSubmitRemind4WebService(requestid, workflowid, "reject", -1, -1); + } else if (flownextoperator == 0) { // 超时干预 + + WFManager wfManager = getWfInfo(String.valueOf(workflowid)); + String defaultSmsRemind = wfManager.getIsDefaultSmsRemind(); + String defaultEmailRemind = wfManager.getIsDefaultEmailRemind(); + + // 提醒新增的人员 + List users = new ArrayList<>(); + String sql = "select a.userid from workflow_currentoperator a,workflow_requestbase b where a.nodeid = b.currentnodeid and a.requestid = b.requestid and a.isremark = 5 and b.requestid = ? "; + rs.executeQuery(sql, requestid); + while (rs.next()) { + users.add(Util.null2String(rs.getString(1))); + } + + Map params = new HashMap<>(); + params.put("reminder", String.join(",", users)); + params.put("requestId", requestid); + params.put("workflowId", workflowid); + params.put("submitType", "submit"); + + if ("1".equals(defaultSmsRemind)) this.requestRemind(params, RemindTypeEnum.SMS); + if ("1".equals(defaultEmailRemind)) this.requestRemind(params, RemindTypeEnum.EMAIL); + } + } + + /** + * 其他创建流程接口发送提醒 + * + * @param requestid + * @param workflowid + */ + public void requestSubmitRemind4WebService(int requestid, int workflowid, int sms, int email) { + this.requestSubmitRemind4WebService(requestid, workflowid, "submit", sms, email); + } + + /** + * 供创建流程接口使用,发送流程提醒 + * + * @param requestid + * @param workflowid + * @param submitType + * @param sms 自定义短信提醒标识,有该标识不使用系统设置中的配置 + * @param email 自定义邮件提醒标识,有该标识不使用系统设置中的配置 + */ + public void requestSubmitRemind4WebService(int requestid, int workflowid, String submitType, int sms, int email) { + + boolean isflowNext = RequestRemindBiz.isflowNext(requestid, submitType, user.getUID()); + this.printLog("requestSubmitRemind4WebService requestid:" + requestid + "submitType:" + submitType + "isflowNext:" + isflowNext); + + try { + WFManager wfManager = getWfInfo(String.valueOf(workflowid)); + int messageType = Util.getIntValue(Util.null2String(wfManager.getMessageType()), -1); + int mailMessageType = Util.getIntValue(Util.null2String(wfManager.getMailMessageType())); + int isDefaultSmsRemind = Util.getIntValue(Util.null2String(wfManager.getIsDefaultSmsRemind())); + int isDefaultEmailRemind = Util.getIntValue(Util.null2String(wfManager.getIsDefaultEmailRemind())); + + RecordSet rs = new RecordSet(); + rs.executeQuery("select remindscope from workflow_base where id = ?", workflowid); + if (rs.next()) { + int remindScope = rs.getInt(1); + if (remindScope == 1) { + email = 1; + sms = -1; + } else { + if (sms == -1 && (messageType >= 1 || isDefaultSmsRemind == 1)) sms = 1; + if (email == -1 && (mailMessageType == 1 || isDefaultEmailRemind == 1)) email = 1; + } + } + if (isflowNext) { + if (sms == 1) this.requestRemind(requestid, workflowid, submitType, RemindTypeEnum.SMS, messageType); + if (email == 1) this.requestRemind(requestid, workflowid, submitType, RemindTypeEnum.EMAIL, 0); + } else { + this.doRemind(requestid, user.getUID(), workflowid, submitType, String.valueOf(sms), String.valueOf(email)); + // 流程停留在创建节点,发送提醒 + if (sms == 1) + this.requestCreateRemind(requestid, workflowid, submitType, RemindTypeEnum.SMS, messageType); + if (email == 1) this.requestCreateRemind(requestid, workflowid, submitType, RemindTypeEnum.EMAIL, 0); + } + this.requestEmailApproveRemind(String.valueOf(workflowid), String.valueOf(requestid), submitType); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 流程提醒 + * + * @param params + * @param typeEnum + * @return + */ + public Map requestRemind(Map params, RemindTypeEnum typeEnum) { + + Map results = new HashMap<>(); + String requestId = Util.null2String(params.get("requestId")); + String remindUser = Util.null2String(params.get("reminder")); // 提醒人 + String wfId = Util.null2String(params.get("workflowId")); + String submitType = Util.null2String(params.get("submitType")); // 流程提交类型 + this.wfId = wfId; + this.requestId = requestId; + this.fieldDatas = this.getFieldData(requestId); + this.remindContent = this.getRemindContent(wfId, typeEnum.getCode()); + this.defaultRemindContent = this.getDefaultRemindContent(); + + if (Strings.isNullOrEmpty(remindUser)) { + this.printLog("6、requestRemind remindUser is empty. requestId:" + requestId); + results.put("success", false); + results.put("msg", "user set is empty"); + return results; + } + + RecordSet rs = new RecordSet(); + if (this.isArchiveNoRemind(wfId, requestId, rs)) return results; + + String allNextNodeIds = this.getSendNodes(requestId); + String nextNodeIds = Util.null2String(params.get("nextNodeIds")); // 依次逐个处理节点自动审批时节点ID + if (!Strings.isNullOrEmpty(nextNodeIds)) { + allNextNodeIds += "," + nextNodeIds; + } + String[] allNextNodeIdsArr = allNextNodeIds.split(","); + Set removeRepeat = new HashSet<>(); + for (int s = 0, len = allNextNodeIdsArr.length; s < len; s++) { + removeRepeat.add(allNextNodeIdsArr[s]); + } + allNextNodeIds = String.join(",", removeRepeat); + + this.printLog("4、rquestid: +" + requestId + ",userid:" + user.getUID() + ",nodes: " + allNextNodeIds); + + rs.executeQuery("select remindscope from workflow_base where id = ? ", wfId); + rs.next(); + int remindscope = Util.getIntValue(rs.getString("remindscope"), 0); + if (remindscope == 1) { + this.remindWithNode(remindUser, submitType, allNextNodeIds); + return results; + } + this.remindWithDefault(remindUser, submitType, allNextNodeIds, typeEnum); + + return results; + } + + /** + * 流程邮件审批提醒 + * + * @param wfId + * @param requestId + * @param submitType + * @param + * @return + */ + public Map requestEmailApproveRemind(String wfId, String requestId, String submitType) { + + Map results = new HashMap<>(); + RecordSet rs = new RecordSet(); + rs.executeQuery("select isEmailRemind from workflow_base where id = ?", wfId); + if (rs.next()) { + int isEmailRemind = Util.getIntValue(rs.getString("isEmailRemind"), 0); + if (isEmailRemind == 0) return results; + } + rs.executeQuery("select isEMailApprove,nodescope,defaultTitle,defaultContent,isFormData,isSignData,isAttachmentData from wf_emailapprove_set where workflowId = ? ", wfId); + if (rs.next()) { + int isEMailApprove = Util.getIntValue(rs.getString("isEMailApprove"), 0); + if (isEMailApprove == 1) { + + Set currentNodeUser = this.getCurrentNodeUser(Util.null2String(requestId), 0); + String remindUser = String.join(",", currentNodeUser); + this.printLog("13、rquestid: +" + requestId + ",userid:" + user.getUID() + ",user: " + remindUser); + + String emailCode = RemindTypeEnum.EMAIL.getCode(); + this.wfId = wfId; + this.requestId = requestId; + this.fieldDatas = this.getFieldData(requestId); + this.remindContent = this.getRemindContent(wfId, emailCode); + this.defaultRemindContent = this.getDefaultRemindContent(); + + if (Strings.isNullOrEmpty(remindUser)) { + this.printLog("6、requestRemind remindUser is empty. requestId:" + requestId); + results.put("success", false); + results.put("msg", "user set is empty"); + return results; + } + + String allNextNodeIds = this.getSendNodes(requestId); + this.printLog("12、rquestid: +" + requestId + ",userid:" + user.getUID() + ",nodes: " + allNextNodeIds); + + String defaultTitle = rs.getString("defaultTitle"); + String defaultContent = rs.getString("defaultContent"); + int isFormData = Util.getIntValue(rs.getString("isFormData"), 0); + int isSignData = Util.getIntValue(rs.getString("isSignData"), 0); + int isAttachmentData = Util.getIntValue(rs.getString("isAttachmentData"), 0); + int nodescope = Util.getIntValue(rs.getString("nodescope"), 0); + + if (nodescope == 1) { + this.approveRemindWithNode(defaultTitle, defaultContent, remindUser, submitType, allNextNodeIds, isFormData, isSignData, isAttachmentData); + return results; + } + this.approveRemindWithDefault(defaultTitle, defaultContent, remindUser, submitType, allNextNodeIds, isFormData, isSignData, isAttachmentData); + return results; + } + } + return results; + } + + + /** + * 流程自动审批 流程邮件审批提醒 + * + * @param + * @return + */ + public Map requestEmailApproveRemind2(Map params) { + + String wfId = Util.null2String(params.get("workflowId")); + String requestId = Util.null2String(params.get("requestId")); + String submitType = Util.null2String(params.get("submitType")); + String remindUser = Util.null2String(params.get("reminder")); + String nextNodeIds = Util.null2String(params.get("nextNodeIds")); + + Map results = new HashMap<>(); + RecordSet rs = new RecordSet(); + rs.executeQuery("select isEmailRemind from workflow_base where id = ?", wfId); + if (rs.next()) { + int isEmailRemind = Util.getIntValue(rs.getString("isEmailRemind"), 0); + if (isEmailRemind == 0) return results; + } + rs.executeQuery("select isEMailApprove,nodescope,defaultTitle,defaultContent,isFormData,isSignData,isAttachmentData from wf_emailapprove_set where workflowId = ? ", wfId); + if (rs.next()) { + int isEMailApprove = Util.getIntValue(rs.getString("isEMailApprove"), 0); + if (isEMailApprove == 1) { + + this.printLog("14、rquestid: +" + requestId + ",userid:" + user.getUID() + ",user: " + remindUser); + + String emailCode = RemindTypeEnum.EMAIL.getCode(); + this.wfId = wfId; + this.requestId = requestId; + this.fieldDatas = this.getFieldData(requestId); + this.remindContent = this.getRemindContent(wfId, emailCode); + this.defaultRemindContent = this.getDefaultRemindContent(); + + if (Strings.isNullOrEmpty(remindUser)) { + this.printLog("6、requestRemind remindUser is empty. requestId:" + requestId); + results.put("success", false); + results.put("msg", "user set is empty"); + return results; + } + + if (this.isArchiveNoRemind(wfId, requestId, rs)) return results; + + String allNextNodeIds = this.getSendNodes(requestId); + if (!Strings.isNullOrEmpty(nextNodeIds)) { + allNextNodeIds += "," + nextNodeIds; + } + String[] allNextNodeIdsArr = allNextNodeIds.split(","); + Set removeRepeat = new HashSet<>(); + for (int s = 0, len = allNextNodeIdsArr.length; s < len; s++) { + removeRepeat.add(allNextNodeIdsArr[s]); + } + allNextNodeIds = String.join(",", removeRepeat); + + this.printLog("15、rquestid: +" + requestId + ",userid:" + user.getUID() + ",nodes: " + allNextNodeIds); + + String defaultTitle = rs.getString("defaultTitle"); + String defaultContent = rs.getString("defaultContent"); + int isFormData = Util.getIntValue(rs.getString("isFormData"), 0); + int isSignData = Util.getIntValue(rs.getString("isSignData"), 0); + int isAttachmentData = Util.getIntValue(rs.getString("isAttachmentData"), 0); + int nodescope = Util.getIntValue(rs.getString("nodescope"), 0); + + if (nodescope == 1) { + this.approveRemindWithNode(defaultTitle, defaultContent, remindUser, submitType, allNextNodeIds, isFormData, isSignData, isAttachmentData); + return results; + } + this.approveRemindWithDefault(defaultTitle, defaultContent, remindUser, submitType, allNextNodeIds, isFormData, isSignData, isAttachmentData); + return results; + } + } + return results; + } + + + /** + * 节点邮件审批 + * + * @param defaultTitle + * @param defaultContent + * @param remindUser + * @param submitType + * @param isSignData + * @param isAttachmentData + */ + private void approveRemindWithNode(String defaultTitle, String defaultContent, String remindUser, String submitType, String allNextNodeIds, + int isFormData, int isSignData, int isAttachmentData) { + String nodeCondition = Util.getSubINClause(allNextNodeIds, "nodeId", "in"); + RecordSet rs = new RecordSet(); + rs.executeQuery("select nodeid,contentType,title,content,isFormData,isSignData,isAttachmentData from " + + " wf_emailapprove_content where workflowId = ? and " + nodeCondition, wfId); + while (rs.next()) { + + String nodeId = rs.getString("nodeid"); + boolean isDefault = Util.getIntValue(rs.getString("contentType"), 0) == 0; + + String title = rs.getString("title"); + String content = rs.getString("content"); + if (Strings.isNullOrEmpty(title) || isDefault) title = defaultTitle; + if (Strings.isNullOrEmpty(content) || isDefault) content = defaultContent; + + int formData = isDefault ? isFormData : Util.getIntValue(rs.getString("isFormData"), 0); + int attachmentData = isDefault ? isAttachmentData : Util.getIntValue(rs.getString("isAttachmentData"), 0); + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + int signData = isDefault ? isSignData : Util.getIntValue(rs.getString("isSignData"), 0); + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) allAttchment.addAll(this.getRequestAttachment(requestId, wfId)); + + // 4、该节点所有操作者 + Map users = this.getSendUsers(String.valueOf(requestId), remindUser, submitType, nodeId); + for (String key : users.keySet()) { + String userIdStr = users.get(key); + + if (Strings.isNullOrEmpty(userIdStr)) continue; + + // 审批、确认、退回做邮件审批 + boolean isApprove = this.isApproveAction(key); + if (isApprove) { + + Map approveRemindContent = remindContent.get(RemindTypeEnum.APPROVAL.getCode()); + if (approveRemindContent == null) + approveRemindContent = defaultRemindContent.get(RemindTypeEnum.APPROVAL.getCode()); + + if (Strings.isNullOrEmpty(title)) title = approveRemindContent.get("title"); + if (Strings.isNullOrEmpty(content)) content = approveRemindContent.get("content"); + // 追加邮件审批按钮 + if (content.indexOf(RequestRemindBiz.SYSTEM_FIELD_APPROVE_BTN) < 0) { + content += "
" + RequestRemindBiz.SYSTEM_FIELD_APPROVE_BTN; + } + String[] userIdArr = userIdStr.split(","); + for (String userId : userIdArr) { + Map btnDatas = this.getEmailApproveBtn(requestId, nodeId, userId); + fieldDatas.putAll(btnDatas); + String _title = title; + String _content = content; + _title = this.replaceFieldValue(fieldDatas, _title); + _content = this.replaceFieldValue(fieldDatas, _content); + this.sendEmail4Approve(userId, _title, _content, requestId, String.join(",", allAttchment)); + } + } + } + } + + } + + /** + * 默认邮件审批 + * + * @param defaultTitle 审批标题 + * @param defaultContent 审批内容 + * @param remindUser + * @param submitType + * @param sendNodeId + * @param isFormData + * @param isSignData + * @param isAttachmentData + */ + private void approveRemindWithDefault(String defaultTitle, String defaultContent, String remindUser, String submitType, + String sendNodeId, int isFormData, int isSignData, int isAttachmentData) { + Set allAttchment = new LinkedHashSet<>(); + if (isFormData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, isSignData, -1)); + } + if (isAttachmentData == 1) allAttchment.addAll(this.getRequestAttachment(requestId, wfId)); + + String[] nodeIds = sendNodeId.split(","); + for (String nodeId : nodeIds) { + Map users = this.getSendUsers(String.valueOf(requestId), remindUser, submitType, nodeId); + for (String key : users.keySet()) { + String userIdStr = users.get(key); + if (Strings.isNullOrEmpty(userIdStr)) continue; + + // 审批、确认、退回做邮件审批 + boolean isApprove = this.isApproveAction(key); + if (isApprove) { + + Map approveRemindContent = remindContent.get(RemindTypeEnum.APPROVAL.getCode()); + if (approveRemindContent == null) + approveRemindContent = defaultRemindContent.get(RemindTypeEnum.APPROVAL.getCode()); + + if (Strings.isNullOrEmpty(defaultTitle)) defaultTitle = approveRemindContent.get("title"); + if (Strings.isNullOrEmpty(defaultContent)) defaultContent = approveRemindContent.get("content"); + if (defaultContent.indexOf(RequestRemindBiz.SYSTEM_FIELD_APPROVE_BTN) < 0) { + defaultContent += "
" + RequestRemindBiz.SYSTEM_FIELD_APPROVE_BTN; + } + String[] userIdArr = userIdStr.split(","); + for (String userId : userIdArr) { + Map btnDatas = this.getEmailApproveBtn(requestId, nodeId, userId); + fieldDatas.putAll(btnDatas); + String title = defaultTitle; + String content = defaultContent; + title = this.replaceFieldValue(fieldDatas, title); + content = this.replaceFieldValue(fieldDatas, content); + this.sendEmail4Approve(userId, title, content, requestId, String.join(",", allAttchment)); + } + } + } + } + } + + /** + * 节点自定义提醒 + * + * @param remindUser + * @param submitType + * @param sendNodeId + */ + private void remindWithNode(String remindUser, String submitType, String sendNodeId) { + RecordSet rs = new RecordSet(); + // + rs.executeQuery("select isEmailRemind,isSmsRemind from workflow_base where id = ?", wfId); + int isEmailRemind = 0; + int isSmsRemind = 0; + if (rs.next()) { + isEmailRemind = rs.getInt(1); + isSmsRemind = rs.getInt(2); + } + String[] sendNodeArr = sendNodeId.split(","); + for (String nodeId : sendNodeArr) { + // 节点自定义 + rs.executeQuery("select id,contenttype,remindtypes,ccNoremind from wf_emailremind_set where workflowid=? and nodeid=?", wfId, nodeId); + if (rs.next()) { + String remindtypes = rs.getString("remindtypes"); + if (Strings.isNullOrEmpty(remindtypes)) { + this.printLog("11、rquestid: +" + requestId + ",userid:" + user.getUID() + ",节点没有自定义设置提醒:" + nodeId); + continue; + } + int contenttype = Util.getIntValue(rs.getString("contenttype"), 0); + int ccNoremind = Util.getIntValue(rs.getString("ccNoremind"), 0); + int remindSetId = rs.getInt("id"); + + String[] remindtypesArr = remindtypes.split(","); + for (String typeEnum : remindtypesArr) { + Map> nodeRemindContent = new HashMap<>(); + if (isEmailRemind != 1 && typeEnum.equals(RemindTypeEnum.EMAIL.getCode())) continue; + if (isSmsRemind != 1 && typeEnum.equals(RemindTypeEnum.SMS.getCode())) continue; + this.remindContent = this.getRemindContent(wfId, typeEnum); + if (contenttype == 1) { + rs.executeQuery("select contentType,title,content,isFormData,isSignData,isAttachmentData from wf_emailremind_content where remindSetId=? and remindType=?", remindSetId, typeEnum); + while (rs.next()) { + String contentType = rs.getString("contentType"); + String title = rs.getString("title"); + String content = rs.getString("content"); + String isFormData = rs.getString("isFormData"); + String isSignData = rs.getString("isSignData"); + String isAttachmentData = rs.getString("isAttachmentData"); + + Map contentMap = new HashMap<>(); + contentMap.put("title", title); + contentMap.put("content", content); + contentMap.put("isFormData", isFormData); + contentMap.put("isSignData", isSignData); + contentMap.put("isAttachmentData", isAttachmentData); + nodeRemindContent.put(contentType, contentMap); + } + } + + Map users = this.getSendUsers(String.valueOf(requestId), remindUser, submitType, nodeId); + for (String key : users.keySet()) { + if (Strings.isNullOrEmpty(users.get(key))) continue; + if (this.isEmailApprove(key, wfId, nodeId)) continue; + if (key.equals(RemindTypeEnum.CC.getCode()) && ccNoremind == 1) continue; + + Map info = nodeRemindContent.get(key); + Map nodeInfo = nodeRemindContent.get(key); + if (info == null) info = remindContent.get(key); + if (info == null) info = defaultRemindContent.get(key); + if (contenttype != 1) nodeInfo = info; + if (RemindTypeEnum.EMAIL.getCode().equals(typeEnum)) { + String title = Util.null2String(info.get("title")); + String content = Util.null2String(info.get("content")); + + int formData = 0; + int signData = 0; + int attachmentData = 0; + if (nodeInfo != null) { + formData = Util.getIntValue(Util.null2String(nodeInfo.get("isFormData")), 0); + signData = Util.getIntValue(Util.null2String(nodeInfo.get("isSignData")), 0); + attachmentData = Util.getIntValue(Util.null2String(nodeInfo.get("isAttachmentData")), 0); + } + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) allAttchment.addAll(this.getRequestAttachment(requestId, wfId)); + title = this.replaceFieldValue(fieldDatas, title); + content = this.replaceFieldValue(fieldDatas, content); + this.sendEmail(users.get(key), title, content, requestId, String.join(",", allAttchment)); + } + + if (RemindTypeEnum.SMS.getCode().equals(typeEnum)) { + String content = Util.null2String(info.get("content")); + content = content.replace("_link", ""); // 默认内容中带有超链接字段 + content = Util.toHtmlMode(this.replaceFieldValue(fieldDatas, content)); + this.sendSMS(users.get(key), content, requestId); + } + } + } + } else { + this.printLog("7、rquestid: +" + requestId + ",userid:" + user.getUID() + ",节点没有自定义设置提醒:" + nodeId); + } + } + } + + /** + * 默认邮件提醒 + * + * @param remindUser + * @param submitType + * @param sendNodeId + * @param typeEnum + */ + private void remindWithDefault(String remindUser, String submitType, String sendNodeId, RemindTypeEnum typeEnum) { + + + WFManager manager = getWfInfo(this.wfId); + int ccNotRemind = Util.getIntValue(manager.getIsCCNoRemind()); + + String[] sendNodeArr = sendNodeId.split(","); + for (String nodeId : sendNodeArr) { + Map users = this.getSendUsers(this.requestId, remindUser, submitType, nodeId); + for (String key : users.keySet()) { + if (this.isEmailApprove(key, wfId, nodeId)) continue; + if (Strings.isNullOrEmpty(users.get(key))) continue; + if (ccNotRemind == 1 && key.equals(RemindTypeEnum.CC.getCode())) continue; + + Map info = this.remindContent.get(key); + if (info == null) info = this.defaultRemindContent.get(key); + + if (typeEnum.getCode().equals(RemindTypeEnum.EMAIL.getCode())) { + String title = Util.null2String(info.get("title")); + String content = Util.null2String(info.get("content")); + int formData = Util.getIntValue(Util.null2String(info.get("isFormData")), 0); + int signData = Util.getIntValue(Util.null2String(info.get("isSignData")), 0); + int attachmentData = Util.getIntValue(Util.null2String(info.get("isAttachmentData")), 0); + Set allAttchment = new LinkedHashSet<>(); + if (formData == 1) { + allAttchment.add(this.getRequestFormPdf(requestId, signData, -1)); + } + if (attachmentData == 1) allAttchment.addAll(this.getRequestAttachment(requestId, wfId)); + title = this.replaceFieldValue(this.fieldDatas, title); + content = this.replaceFieldValue(this.fieldDatas, content); + this.sendEmail(users.get(key), title, content, this.requestId, String.join(",", allAttchment)); + } + + if (typeEnum.getCode().equals(RemindTypeEnum.SMS.getCode())) { + String content = Util.null2String(info.get("content")); + content = content.replace("_link", ""); // 默认内容中带有超链接字段 + content = Util.toHtmlMode(this.replaceFieldValue(this.fieldDatas, content)); + this.sendSMS(users.get(key), content, this.requestId); + } + } + } + } + + /** + * 替换字符串中的占位符 + * + * @param str + * @return + */ + public String replaceFieldValue(Map fieldDatas, String str) { + try { + for (String key : fieldDatas.keySet()) { + String fieldValue = Util.null2String(fieldDatas.get(key)); + fieldValue = Util.formatMultiLang(fieldValue, String.valueOf(user.getLanguage())); + fieldValue = RequestRemindBiz.parseSpecialChar(fieldValue); + key = RequestRemindBiz.parseSpecialChar(key); + str = str.replaceAll(key, fieldValue); + } + } catch (Exception e) { + e.printStackTrace(); + } + return str; + } + + /** + * 获取人员信息,并根据操作类型分组 + * + * @param requestId + * @param remindUser + * @return + */ + private Map getSendUsers(String requestId, String remindUser, String submitType, String sendNodeId) { + + Map users = new HashMap<>(); + + Set approvaUsers = new HashSet<>(); // 审批 + Set confirmUsers = new HashSet<>(); // 确认 + Set archiveUsers = new HashSet<>(); // 归档 + Set ccUsers = new HashSet<>(); // 抄送 + + if ("reject".equals(submitType)) { + users.put(RemindTypeEnum.BACK.getCode(), remindUser); + } else if ("forward".equals(submitType)) { + users.put(RemindTypeEnum.FORWARD.getCode(), remindUser); + } else if ("trans".equals(submitType)) { + users.put(RemindTypeEnum.TRANS.getCode(), remindUser); + } else if ("take".equals(submitType)) { + users.put(RemindTypeEnum.TAKE.getCode(), remindUser); + } else if ("chuanyue".equals(submitType)) { + users.put(RemindTypeEnum.CHUANYUE.getCode(), remindUser); + } else { + RecordSet rs = new RecordSet(); + String sql = "select wf.userid,wf.isremark,wf.preisremark," + + "(CASE WHEN nodeid < -1 THEN (SELECT nodetype FROM workflow_freenode t WHERE t.id = wf.nodeid ) " + + "ELSE (SELECT nodetype FROM workflow_flownode t1 WHERE t1.nodeid = wf.nodeid) end) AS nodetype " + + "from workflow_currentoperator wf where wf.usertype = 0 and wf.requestid = ? and " + + Util.getSubINClause(sendNodeId, "wf.nodeid", "IN") + " and " + + Util.getSubINClause(remindUser, "wf.userid", "IN"); + + this.printLog("8、getSendUsers sql:" + sql + ",requestid:" + requestId); + rs.executeQuery(sql, requestId); + while (rs.next()) { + String id = Util.null2String(rs.getString("userid")); + int isremark = Util.getIntValue(Util.null2String(rs.getString("isremark"))); + if (isremark == 2) continue; + int preisremark = Util.getIntValue(Util.null2String(rs.getString("preisremark"))); + int nodeType = Util.getIntValue(Util.null2String(rs.getString("nodetype"))); + if (isremark == 0 || isremark == 5 || (isremark != 4 && preisremark == 0)) { + if (nodeType == 1) {// 审批 + approvaUsers.add(id); + } else {// 确认 + confirmUsers.add(id); + } + } else if (isremark == 4) {// 归档 + archiveUsers.add(id); + } else {// 8,9抄送 + ccUsers.add(id); + } + } + + users.put(RemindTypeEnum.APPROVAL.getCode(), String.join(",", approvaUsers)); + users.put(RemindTypeEnum.ARCHIVE.getCode(), String.join(",", archiveUsers)); + users.put(RemindTypeEnum.CONFIRM.getCode(), String.join(",", confirmUsers)); + users.put(RemindTypeEnum.CC.getCode(), String.join(",", ccUsers)); + } + this.printLog("10、rquestid: +" + requestId + ",userid:" + user.getUID() + ",usersJson: " + JSONObject.toJSONString(users)); + return users; + } + + /** + * 获取流程提交后,实际到达的节点 + * + * @param requestId + * @return + */ + private String getSendNodes(String requestId) { + + Set nodeid = new HashSet(); + RecordSet rs = new RecordSet(); + rs.executeQuery("select detailinfo from workflow_requestoperatelog where requestid = ? and (isinvalid is null or isinvalid <> 1) and operatorid = ? order by id desc", requestId, user.getUID()); + if (rs.next()) { + String detailInfo = rs.getString("detailinfo"); + JSONObject tables = JSONObject.parseObject(detailInfo); + if (tables == null) return null; + + JSONObject operatorTable = tables.getJSONObject(RequestOperateEntityTableNameEnum.CURRENTOPERATOR.getTableName()); + if (operatorTable == null) return null; + + // 新增操作者 + String newIds = operatorTable.getString("newIds"); + if (!Strings.isNullOrEmpty(newIds)) { + rs.executeQuery("select nodeid from workflow_currentoperator where requestid = ? and " + Util.getSubINClause(newIds, "id", "in"), requestId); + while (rs.next()) { + nodeid.add(rs.getString(1)); + } + } + + Set operateId = new HashSet<>(); + JSONArray modifyDatas = operatorTable.getJSONArray("modifyData"); + for (int i = 0, len = modifyDatas.size(); i < len; i++) { + JSONObject datas = modifyDatas.getJSONObject(i); + String fieldName = datas.getString("fieldName"); + // A征询B,B回复时,A的操作者ID + if ("takisremark".equals(fieldName)) { + int nVal = datas.getIntValue("nVal"); + int oVal = datas.getIntValue("oVal"); + if (oVal == -2 && nVal == 0) operateId.add(datas.getString("entityId")); + } + // A征询B,B征询C,C回复时,B的操作者ID + if ("isremark".equals(fieldName)) { + int nVal = datas.getIntValue("nVal"); + int oVal = datas.getIntValue("oVal"); + if (oVal == 2 && nVal == 1) operateId.add(datas.getString("entityId")); + } + } + if (!operateId.isEmpty()) { + rs.executeQuery("select nodeid from workflow_currentoperator where " + + Util.getSubINClause(String.join(",", operateId), "id", "in")); + while (rs.next()) { + nodeid.add(rs.getString(1)); + } + } + } + return String.join(",", nodeid); + } + + /** + * 获取提醒内容 + * + * @param wfId + * @return + */ + private Map> getRemindContent(String wfId, String remindType) { + + RecordSet rs = new RecordSet(); + + Map> contentMap = new HashMap<>(); + rs.executeQuery("select * from workflow_remindcontent where workflowid=? and remindType=?", wfId, remindType); + + while (rs.next()) { + String remindContentType = Util.null2String(rs.getString("contenttype")); + String title = Util.null2String(rs.getString("title")); + String content = Util.null2String(rs.getString("content")); + String isFormData = Util.null2String(rs.getString("isFormData")); + String isSignData = Util.null2String(rs.getString("isSignData")); + String isAttachmentData = Util.null2String(rs.getString("isAttachmentData")); + + Map info = new HashMap<>(); + info.put("title", title); + info.put("content", content); + info.put("isFormData", isFormData); + info.put("isSignData", isSignData); + info.put("isAttachmentData", isAttachmentData); + + contentMap.put(remindContentType, info); + } + return contentMap; + } + + /** + * 获取默认提醒内容 + * + * @return + */ + public Map> getDefaultRemindContent() { + + Map> contentMap = new HashMap<>(); + + List remindContentType = RemindTypeEnum.getRemindContentType(); + Properties prop = this.getProp(); + for (RemindTypeEnum e : remindContentType) { + + String title = prop.getProperty(String.format("remind.msg.%s.title.value", e.getCode()), ""); + String content = prop.getProperty(String.format("remind.msg.%s.content.value", e.getCode()), ""); + String isFormData = prop.getProperty(String.format("remind.default.formdata", e.getCode()), ""); + String isSignData = prop.getProperty(String.format("remind.default.signdata", e.getCode()), ""); + String isAttachmentData = prop.getProperty(String.format("remind.default.attachmentdata", e.getCode()), ""); + + Map info = new HashMap<>(); + info.put("title", title); + info.put("content", content); + info.put("isFormData", isFormData); + info.put("isSignData", isSignData); + info.put("isAttachmentData", isAttachmentData); + + contentMap.put(e.getCode(), info); + } + + return contentMap; + } + + /** + * @param wfId + * @return + */ + private static WFManager getWfInfo(String wfId) { + WFManager wfManager = new WFManager(); + wfManager.setWfid(Util.getIntValue(wfId)); + try { + wfManager.getWfInfo(); + } catch (Exception e) { + new BaseBean().writeLog(e); + } + return wfManager; + } + + /** + * 获取流程当前节点操作者 + * + * @param requestId + * @return + */ + public Set getCurrentNodeUser(String requestId, int onLine) { + + Set userList = new HashSet<>(); + + RecordSet rs = new RecordSet(); + // 利用 workflow_requestoperatelog 查找当前人员,避免一个节点多次参与流转时,将前几次参与时的人员也找了出来 + String newIds = ""; + rs.executeQuery("select max(id) from workflow_requestoperatelog where (isinvalid is null or isinvalid <> 1 )" + + " and (operatetype = 'submit' or operatetype = 'reject' or operatetype = 'forceover' or operatetype='intervenor') and operatorid = ? and requestid = ?", user.getUID(), requestId); + if (rs.next()) { + String maxId = Util.null2String(rs.getString(1)); + rs.executeQuery("select detailInfo from workflow_requestoperatelog where id = ?", maxId); + if (rs.next()) { + String detailInfo = Util.null2String(rs.getString(1)); + JSONObject jsonObject = JSONObject.parseObject(detailInfo); + if (jsonObject != null) { + // 1、先检验workflow_currentoperator + JSONObject operaterInfo = jsonObject.getJSONObject("workflow_currentoperator"); + if (operaterInfo != null) { + newIds = operaterInfo.getString("newIds"); + } + } + } + } + if (Strings.isNullOrEmpty(newIds)) return userList; + + String sql = "select userid from workflow_currentoperator where requestid = ? and usertype = 0 and " + + Util.getSubINClause(newIds, "id", "in") + " and isremark in(0,1,4,6,7,8,9) "; + rs.executeQuery(sql, requestId); + while (rs.next()) { + String userId = Util.null2String(rs.getString("userid")); + if (onLine == 1) { // 离线才发 + HrmUserOnlineMap hrmUserOnlineMap = HrmUserOnlineMap.getInstance(); + if (!hrmUserOnlineMap.isOnline(Util.getIntValue(userId))) { + userList.add(userId); + } + } else { + userList.add(userId); + } + } + + return userList; + } + + /** + * 获取配置文件 + * + * @return + */ + public Properties getProp() { + + String root = GCONST.getPropertyPath(); + Properties prop = null; + + File f = new File(root + "MailMessage.properties"); + if (f.exists()) { + InputStreamReader is = null; + try { + is = new InputStreamReader(new FileInputStream(f), "gbk"); + prop = new Properties(); + prop.load(is); + } catch (IOException e) { + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + } + } + } + } + return prop; + } + + /** + * 是否开启流程提醒 + * + * @param wfManager + * @return + */ + public static boolean isOpenRemind(WFManager wfManager) { + + int isSmsRemind = Util.getIntValue(wfManager.getIsSmsRemind(), 0); + int isEmailRemind = Util.getIntValue(wfManager.getIsEmailRemind(), 0); + int mailMessageType = Util.getIntValue(wfManager.getMailMessageType(), 0); + + return (isSmsRemind + isEmailRemind + mailMessageType) > 0; + } + + /** + * 流程提交是否流转到了下一个节点 + * + * @param requestId + * @param src + * @return + */ + public static boolean isflowNext(int requestId, String src, int userId) { + + if ("intervenor".equals(src)) return true; + + boolean isflowNext = false; + RecordSet rs = new RecordSet(); + rs.executeQuery("select max(id) from workflow_requestoperatelog where (isinvalid is null or isinvalid <> 1 ) and (operatetype = 'submit' or operatetype = 'reject') and operatorid = ? and requestid = ?", userId, requestId); + if (rs.next()) { + String maxId = Util.null2String(rs.getString(1)); + rs.executeQuery("select detailInfo from workflow_requestoperatelog where id = ?", maxId); + if (rs.next()) { + String detailInfo = Util.null2String(rs.getString(1)); + JSONObject jsonObject = JSONObject.parseObject(detailInfo); + if (jsonObject != null) { + // 1、先检验workflow_currentoperator + JSONObject operaterInfo = jsonObject.getJSONObject("workflow_currentoperator"); + if (operaterInfo != null) { + String newIds = operaterInfo.getString("newIds"); + if (Strings.isNullOrEmpty(newIds)) return isflowNext; + } + // 2、 + JSONObject requestBase = jsonObject.getJSONObject("workflow_requestbase"); + if (requestBase != null) { + JSONArray modifyDatas = requestBase.getJSONArray("modifyData"); + for (int i = 0; i < modifyDatas.size(); i++) { + JSONObject data = modifyDatas.getJSONObject(i); + String fieldName = data.getString("fieldName"); + if ("currentnodeid".equals(fieldName)) { + int oVal = Util.getIntValue(Util.null2String(data.getString("oVal"))); + int nVal = Util.getIntValue(Util.null2String(data.getString("nVal"))); + if (nVal != oVal) { + isflowNext = true; + } + } + } + } + } + } + + } + return isflowNext; + } + + /** + * 获取表单数据 + * + * @param requestId + * @return + */ + private Map getFieldData(String requestId) { + + Map fieldDatas = new HashMap<>(); + + int isBill = 1; + int formid = -1; + + RecordSet rs = new RecordSet(); + rs.executeQuery("select workflowid,requestnamenew,requestlevel,createdate,createtime " + + "from workflow_requestbase where requestid=?", requestId); + rs.next(); + String wfId = Util.null2String(rs.getString("workflowid")); + String requestname = Util.null2String(rs.getString("requestnamenew")); + requestname = Util.formatMultiLang(requestname); // 处理多语言 + requestname = requestname.replaceAll("", "").replaceAll("", ""); + requestname = requestname.replaceAll("", "").replaceAll("", ""); + + String requestlevel = Util.null2String(rs.getString("requestlevel")); + + String createdate = Util.null2String(rs.getString("createdate")); + String createtime = Util.null2String(rs.getString("createtime")); + + // 判断老表单还是新表单 + rs.executeQuery("select isbill,formid from workflow_base where id=?", wfId); + if (rs.next()) { + isBill = Util.getIntValue(Util.null2String(rs.getString("isbill"))); + formid = Util.getIntValue(Util.null2String(rs.getString("formid"))); + } + RecordSet recordSet = new RecordSet(); + if (isBill == 1) { + recordSet.executeQuery("select id,fieldname from workflow_billfield where billid= ? and viewtype = 0", formid); + } else { + recordSet.executeQuery("select fd.id,fd.fieldname from" + + " workflow_formfield ff,workflow_formdict fd where ff.formid = ? and ff.fieldid = fd.id", formid); + } + while (recordSet.next()) { + String fieldId = Util.null2String(recordSet.getString("id")); + fieldDatas.put(String.format("${fieldid_%s}", fieldId), + this.getFiledValue(isBill, formid, Util.getIntValue(requestId), fieldId)); + } + requestlevel = Util.null2String(GetCustomLevelUtil.getLevel(requestlevel + "", user.getLanguage())); + + String requestNameLink = this.parseEmailLink(requestname, requestId); + + fieldDatas.put(RequestRemindBiz.SYSTEM_FIELD_LEVEL, requestlevel); + fieldDatas.put(RequestRemindBiz.SYSTEM_FIELD_TITLE, requestname); + fieldDatas.put(RequestRemindBiz.SYSTEM_FIELD_TITLE_LINK, requestNameLink); + fieldDatas.put(RequestRemindBiz.SYSTEM_FIELD_CREATEDATA, String.format("%s %s", createdate, createtime)); + + return fieldDatas; + } + + /** + * 获取各节点对应的审批按钮Html信息 + * + * @param requestId + * @param nodeId + * @param userId + * @return + */ + private Map getEmailApproveBtn(String requestId, String nodeId, String userId) { + + Map fieldDatas = new HashMap<>(); + + int languageId = User.getUserLang(Util.getIntValue(userId)); + RecordSet rs = new RecordSet(); + rs.executeQuery("select workflowid,requestnamenew " + + " from workflow_requestbase where requestid=?", requestId); + rs.next(); + String wfId = Util.null2String(rs.getString("workflowid")); + String requestnamenew = Util.null2String(rs.getString("requestnamenew")); + int nodeid = Util.getIntValue(nodeId); + if (nodeid < -1) { + nodeId = String.valueOf(FreeNodeBiz.getExtendNodeId(nodeid)); + } + // 节点类型:审批节点或者确认节点 + rs.executeQuery("select nodetype from workflow_flownode " + + " where workflowid = ? and nodeid= ?", wfId, nodeId); + rs.next(); + int nodetype = Util.getIntValue(rs.getString("nodetype"), -1); + if (nodetype == 3) { + fieldDatas.put(SYSTEM_FIELD_APPROVE_BTN, "(仅审批节点和确认节点有邮件审批按钮)"); + } else { + String submitname = ""; // 提交按钮的名称 : 创建, 审批, 实现 + String rejectName = "";// 退回 + rs.executeQuery("select submitname7,submitname8,submitname9,rejectName7,rejectName8,rejectName9 " + + " from workflow_nodecustomrcmenu where wfid = ? and nodeid= ?", wfId, nodeId); + rs.next(); + switch (languageId) { + case 8: + submitname = Util.null2String(rs.getString("submitname8")); + rejectName = Util.null2String(rs.getString("rejectName8")); + break; + case 9: + submitname = Util.null2String(rs.getString("submitname9")); + rejectName = Util.null2String(rs.getString("rejectName9")); + break; + default: + submitname = Util.null2String(rs.getString("submitname7")); + rejectName = Util.null2String(rs.getString("rejectName7")); + break; + } + + String defaultApproveBtn = null; // 提交 + String defaultConfirmBtn = null; // 批准 + String defaultRejectName = null; + rs.executeQuery("select submitName_0,submitName_1,rejectName from SystemCustomMenuSet"); + if (rs.next()) { + defaultApproveBtn = Util.processBody(Util.null2String(rs.getString("submitName_0")).trim(), + String.valueOf(languageId)); + defaultConfirmBtn = Util.processBody(Util.null2String(rs.getString("submitName_1")).trim(), + String.valueOf(languageId)); + defaultRejectName = Util.null2String(rs.getString("rejectName")); + } + if (Strings.isNullOrEmpty(submitname)) { + if (nodetype == 1) { + submitname = Strings.isNullOrEmpty(defaultApproveBtn) ? + SystemEnv.getHtmlLabelName(142, user.getLanguage()) : defaultApproveBtn; // 审批 + } else if (nodetype == 2 || nodetype == 0) { + submitname = Strings.isNullOrEmpty(defaultConfirmBtn) ? + SystemEnv.getHtmlLabelName(725, user.getLanguage()) : defaultConfirmBtn; // 确认 + } + } + if (Strings.isNullOrEmpty(rejectName)) { + rejectName = Strings.isNullOrEmpty(defaultRejectName) ? + SystemEnv.getHtmlLabelName(236, user.getLanguage()) : defaultRejectName; // 退回 + } + + String submitBtnHtml = ""; + EmailApprovalService emailApprovalService = new EmailApprovalService(); + Map emailApproveParams = new HashMap<>(); + emailApproveParams.put("nodeId", nodeId); + emailApproveParams.put("userId", userId); + emailApproveParams.put("reqId", requestId); + emailApproveParams.put("judgeFormMustInput", "1"); + + if (nodetype == 1) { + emailApproveParams.put("src", RequestEmailApproveBiz.SUBMIT); + String submitParams = this.getEmailApproveParams(emailApproveParams); + String encryptString = String.format(APPROVE_PARAM, submitParams); + submitBtnHtml = emailApprovalService.getRequestSubmitBtnHtml(requestnamenew, encryptString, submitname, languageId); + + emailApproveParams.put("src", RequestEmailApproveBiz.REJECT); + submitParams = this.getEmailApproveParams(emailApproveParams); + encryptString = String.format(APPROVE_PARAM, submitParams); + String rejectBtnHtml = emailApprovalService.getRequestRejectBtnHtml(requestnamenew, encryptString, rejectName, languageId); + submitBtnHtml += "   " + rejectBtnHtml; + } else if (nodetype == 2 || nodetype == 0) { + emailApproveParams.put("src", RequestEmailApproveBiz.SUBMIT); + String submitParams = this.getEmailApproveParams(emailApproveParams); + String encryptString = String.format(APPROVE_PARAM, submitParams); + submitBtnHtml = emailApprovalService.getRequestSubmitBtnHtml(requestnamenew, encryptString, submitname, languageId); + } + + fieldDatas.put(SYSTEM_FIELD_APPROVE_BTN, submitBtnHtml); + } + return fieldDatas; + } + + /** + * 邮件审批参数 + * + * @param params + * @return + */ + private String getEmailApproveParams(Map params) { + + Map requestParam = CommandExecutorUtil.execute(new GetEmailApproveParamCmd(user, params)); + String paramJsonStr = JSONObject.toJSONString(requestParam); + paramJsonStr = Base64.getEncoder().encodeToString(paramJsonStr.getBytes(StandardCharsets.UTF_8)); + + return paramJsonStr; + } + + /** + * @param requestNameNew + * @param requestId + * @return + */ + public String parseEmailLink(String requestNameNew, String requestId) { + + Map result = CommandExecutorUtil.execute(new GetEmailRemindUrlCmd(user, null, requestId, requestNameNew)); + + return (String) result.get("url"); + } + + /** + * 获取字段值 + */ + private String getFiledValue(int isbill, int formId, int requestId, String tempField) { + + String fieldValue = ""; + + String tablename = ""; + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + RecordSet rs3 = new RecordSet(); + if (isbill == 0) { + rs1.executeQuery("select workflow_formdict.fieldname,workflow_fieldlable.fieldlable,fieldhtmltype,type,workflow_formdict.fielddbtype from workflow_formdict,workflow_fieldlable where workflow_formdict.id=" + tempField + " and workflow_formdict.id=workflow_fieldlable.fieldid and workflow_fieldlable.formid= ? and langurageid= ?", formId, user.getLanguage()); + } else { + rs1.execute("select fieldname,fieldlabel,fieldhtmltype,type,fielddbtype from workflow_billfield where id=" + tempField); + } + if (rs1.next()) { + String tempLabel = rs1.getString(2); + String htmtype = rs1.getString(3); + String types = rs1.getString(4); + String fielddbtype = rs1.getString(5); + if (isbill == 1) { + tempLabel = SystemEnv.getHtmlLabelName(Util.getIntValue(tempLabel, -1), user.getLanguage()); + rs2.executeQuery("select tablename from workflow_bill where id = ?", formId); + if (rs2.next()) { + tablename = rs2.getString(1); + } + } + if ("7".equals(htmtype)) { + rs3.executeQuery("select type,fieldid,displayname,linkaddress,descriptivetext from workflow_specialfield a, workflow_billfield b where a.fieldid = b.id and a.isform='0' and a.isbill='1' and a.fieldid=?", tempField); + while (rs3.next()) { + int type = rs3.getInt("type"); + String tempValue = ""; + if (type == 1) { + tempValue = rs3.getString("displayname"); // 标题处舍去超链接 + } else { + tempValue = rs3.getString("descriptivetext"); + } + if (!tempValue.equals("")) { + if (fieldValue.equals("")) { + fieldValue = tempValue; + } else { + fieldValue = fieldValue + "," + tempValue; + } + } + } + } else { + if (!"".equals(tablename)) { + rs1.execute("select " + rs1.getString(1) + " from " + tablename + " where requestid=" + requestId); + rs1.isAutoDecrypt(false); + if (rs1.next()) { + + String tempValue = rs1.getString(1); + tempValue = EncryptConfigBiz.forceFormatDecryptData(tempValue); + if (htmtype.equals("3") && ("402".equals(types) || "403".equals(types))) { + return tempValue; + } else if (htmtype.equals("3") && types.equals("290")) { + if (!Strings.isNullOrEmpty(tempValue)) { + fieldValue = Strings.isNullOrEmpty(fieldValue) ? tempValue : fieldValue + ", " + tempValue; + } + } else if (htmtype.equals("3") && (types.equals("161") || types.equals("162"))) { + try { + ArrayList tempshowidlist = Util.TokenizerString(tempValue, ","); + tempValue = ""; + Browser browser = (Browser) StaticObj.getServiceByFullname(fielddbtype, Browser.class); + for (Object k : tempshowidlist) { + try { + BrowserBean bb = browser.searchById(String.valueOf(k)); + String name = Util.null2String(bb.getName()); + if (tempValue.equals("")) { + tempValue += name; + } else { + tempValue += " " + name; + } + } catch (Exception e) { + } + + } + } catch (Exception ee) { + } + + } else if (htmtype.equals("3") || htmtype.equals("6") || htmtype.equals("5")) { + try { + RequestDoc rd = new RequestDoc(); + tempValue = rd.getFieldValue(htmtype, types, tempValue, user.getLanguage(), tempField, "" + isbill, fielddbtype, ""); + } catch (Exception ee) { + } + + } else if (htmtype.equals("9")) { + if (!tempValue.equals("")) { + String lastAddr = ""; + String[] fields; + String[] locations = tempValue.split(LocateUtil.SPLIT_LOCATION); + for (int i = locations.length - 1; i >= 0; i--) { + if (locations[i].equals("")) { + continue; + } + fields = locations[i].split(LocateUtil.SPLIT_FIELD); + if (fields.length > 3 && !fields[3].equals("")) { + lastAddr = fields[3]; + break; + } + } + tempValue = lastAddr; + } + } + if (!(rs1.getString(1)).equals("") && !(htmtype.equals("3") && types.equals("290"))) { + if (!(htmtype.equals("9") && tempValue.equals(""))) { + fieldValue = Strings.isNullOrEmpty(fieldValue) ? tempValue : fieldValue + ", " + tempValue; + } + } + } + } + } + } + return Util.formatStringIfMultilang(fieldValue); + } + + /** + * 通过邮件方式发送提醒 + * + * @param sendUsers + * @param title + * @param content + */ + private void sendEmail(String sendUsers, String title, String content, String requestId, String allAttchment) { + + this.printLog("Request Email remind info:user=" + sendUsers + ";title=" + title + ";requestId=" + requestId); + if (Strings.isNullOrEmpty(sendUsers)) return; + + RecordSet rs = new RecordSet(); + + // 流程测试 + rs.executeQuery("select 1 from workflow_requestbase where requestid = ? and (deleted = 0 or deleted is null)", requestId); + if (!rs.next()) return; + Set mailAddress = new HashSet(); + rs.executeQuery("select hr.email from HrmResource hr where status in (0,1,2,3) AND " + Util.getSubINClause(sendUsers, "id", "in")); + while (rs.next()) { + String email = Util.null2String(rs.getString("email")); + if (!Strings.isNullOrEmpty(email)) { + mailAddress.add(email); + } + } + /* ******************* youhong.ai 添加发送邮箱的黑名单拓展start ******************* */ + for (BlackListExpansion blackListExpansion : BlackListRegister.getExpansionList()) { + Set mailAddress1 = blackListExpansion.sendEmailHandler(mailAddress); + if (Objects.nonNull(mailAddress1)) { + mailAddress = mailAddress1; + } + } + /* ******************* youhong.ai 添加发送邮箱的黑名单拓展 end ******************* */ + if (mailAddress.isEmpty()) return; + EmailWorkRunnable.threadModeReminder(String.join(",", mailAddress), "", "", title, content, allAttchment); + } + + /** + * 发送审批邮件 + * + * @param sendUsers + * @param title + * @param content + */ + private void sendEmail4Approve(String sendUsers, String title, String content, String requestId, String allAttchment) { + + this.printLog("Request Email approve info:user=" + sendUsers + ";title=" + title + ";requestId=" + requestId); + if (Strings.isNullOrEmpty(sendUsers)) return; + + RecordSet rs = new RecordSet(); + + // 流程测试 + rs.executeQuery("select 1 from workflow_requestbase where requestid = ? and (deleted = 0 or deleted is null)", requestId); + if (!rs.next()) return; + Set mailAddress = new HashSet(); + rs.executeQuery("select hr.email from HrmResource hr where status in (0,1,2,3) AND " + Util.getSubINClause(sendUsers, "id", "in")); + while (rs.next()) { + String email = Util.null2String(rs.getString("email")); + if (!Strings.isNullOrEmpty(email)) { + mailAddress.add(email); + } + } + /* ******************* youhong.ai 添加发送邮箱的黑名单拓展start ******************* */ + for (BlackListExpansion blackListExpansion : BlackListRegister.getExpansionApproveList()) { + Set mailAddress1 = blackListExpansion.sendEmailHandler(mailAddress); + if (Objects.nonNull(mailAddress1)) { + mailAddress = mailAddress1; + } + } + /* ******************* youhong.ai 添加发送邮箱的黑名单拓展 end ******************* */ + EmailApprovalRunnable.threadModeReminder(String.join(",", mailAddress), title, content, String.valueOf(requestId), allAttchment); + } + + /** + * 通过短信方式发送提醒 + * + * @param sendUsers 提醒人员 + * @param content 提醒内容 + * @param requestId + */ + private void sendSMS(String sendUsers, String content, String requestId) { + this.printLog("Request SMS remind info:user=" + sendUsers + ";title=" + content + ";requestId=" + requestId); + if (Strings.isNullOrEmpty(sendUsers)) return; + try { + content = content.replaceAll("<", "<").replaceAll(">", ">"); + RecordSet rs = new RecordSet(); + // 流程测试 + rs.executeQuery("select 1 from workflow_requestbase where requestid = ? and (deleted = 0 or deleted is null)", requestId); + if (!rs.next()) return; + + rs.executeQuery("select hr.id,hr.mobile from HrmResource hr where status in (0,1,2,3) AND " + Util.getSubINClause(sendUsers, "id", "in")); + Set sendUserPhone = new HashSet<>(); + while (rs.next()) { + + String userId = Util.null2String(rs.getString("id")); + String userPhone = Util.null2String(rs.getString("mobile")); + + if (sendUserPhone.contains(userPhone) || Strings.isNullOrEmpty(userPhone)) continue; + sendUserPhone.add(userPhone); + SMSSaveAndSend smsSaveAndSend = new SMSSaveAndSend(); + smsSaveAndSend.setMessage(SmsSendUtil.getSignMessage(user, content)); + smsSaveAndSend.setRechrmnumber(userPhone); + smsSaveAndSend.setReccrmnumber(""); + smsSaveAndSend.setCustomernumber(""); + + smsSaveAndSend.setRechrmids(userId); + smsSaveAndSend.setReccrmids(""); + smsSaveAndSend.setSendnumber(""); + smsSaveAndSend.setRequestid(Integer.parseInt(requestId)); + smsSaveAndSend.setUserid(user.getUID()); + smsSaveAndSend.setUsertype(user.getLogintype()); + smsSaveAndSend.setFrommould(SmsFromMouldEnum.WORKFLOW); + smsSaveAndSend.send(); + } + } catch (Exception e) { + } + } + + /** + * 流程提交不流转到下一节点,判断会签、依次逐个处理、循环上级审批 + * + * @param requestid + * @param userid + * @param wfId + * @param src + * @param isDefaultSmsRemind + * @param isDefaultEmailRemind + */ + public void doRemind(int requestid, int userid, int wfId, String src, String isDefaultSmsRemind, String isDefaultEmailRemind) { + RecordSet rs = new RecordSet(); + this.printLog("9、doRemind start requestId:" + requestid); + rs.executeQuery("select detailInfo from workflow_requestoperatelog where requestid = ? and operatorid = ? order by operatedate desc,operatetime desc", requestid, userid); + if (rs.next()) { + String detailInfo = Util.null2String(rs.getString("detailInfo")); + JSONObject jsonObject = JSONObject.parseObject(detailInfo); + JSONObject operators = null; + if (jsonObject != null) operators = jsonObject.getJSONObject("workflow_currentoperator"); + if (operators != null) { + String newIds = operators.getString("newIds"); + if (!Strings.isNullOrEmpty(newIds)) { + Set userIds = new HashSet<>(); + rs.executeQuery("select userid from workflow_currentoperator where " + Util.getSubINClause(newIds, "id", "IN")); + while (rs.next()) { + userIds.add(Util.null2String(rs.getString("userid"))); + } + Map params = new HashMap<>(); + params.put("reminder", String.join(",", userIds)); + params.put("requestId", requestid); + params.put("workflowId", wfId); + params.put("submitType", src); + if ("1".equals(isDefaultSmsRemind)) this.requestRemind(params, RemindTypeEnum.SMS); + if ("1".equals(isDefaultEmailRemind)) this.requestRemind(params, RemindTypeEnum.EMAIL); + } + } + } + } + + public static void updateRemindTypes(String remindTypes, int requestid) { + RecordSet recordSet = new RecordSet(); + recordSet.executeUpdate("update workflow_requestbase set remindTypes=? where requestid = ?", remindTypes, requestid); + } + + /** + * 获取主表字段方法供提醒内容设置界面使用,默认增加(流程标题)这个系统字段 + * + * @return + */ + public List> getMainFields(String workflowId) { + + int isBill = -1; + int formId = -1; + + RecordSet rs = new RecordSet(); + String sql = "SELECT formid , isbill FROM workflow_base WHERE id = ?"; + rs.executeQuery(sql, workflowId); + if (rs.next()) { + isBill = rs.getInt("isBill"); + formId = rs.getInt("formId"); + } + + List> fields = new ArrayList<>(); + // 系统字段请求标题 + Map requestTitle = new HashMap<>(); + requestTitle.put("key", SYSTEM_FIELD_TITLE); + requestTitle.put("showname", SystemEnv.getHtmlLabelName(26876, user.getLanguage())); + requestTitle.put("multClickable", true); + requestTitle.put("clickable", true); + + fields.add(requestTitle); + + Map requestTitleLink = new HashMap<>(); + requestTitleLink.put("key", SYSTEM_FIELD_TITLE_LINK); + requestTitleLink.put("showname", SystemEnv.getHtmlLabelName(391184, user.getLanguage())); + requestTitleLink.put("multClickable", true); + requestTitleLink.put("clickable", true); + fields.add(requestTitleLink); + + Map emergencyLevel = new HashMap<>(); + emergencyLevel.put("key", SYSTEM_FIELD_LEVEL); + emergencyLevel.put("showname", SystemEnv.getHtmlLabelName(15534, user.getLanguage())); + emergencyLevel.put("multClickable", true); + emergencyLevel.put("clickable", true); + fields.add(emergencyLevel); + + Map createDate = new HashMap<>(); + createDate.put("key", SYSTEM_FIELD_CREATEDATA); + createDate.put("showname", SystemEnv.getHtmlLabelName(502863, user.getLanguage())); + createDate.put("multClickable", true); + createDate.put("clickable", true); + fields.add(createDate); + + Map field = null; + // 主表字段 + if (isBill == 1) { + sql = "SELECT " + + " f.id, f.fieldname," + + " l.labelname " + + " FROM " + + " workflow_billfield f " + + " LEFT JOIN ( SELECT * FROM HTMLLABELInfo WHERE languageid = ? ) l ON f.fieldlabel= l.indexid " + + "WHERE " + + " f.billid = ? " + + " AND f.viewtype = 0"; + rs.executeQuery(sql, user.getLanguage(), formId); + } else { + rs.executeQuery("select fd.id,fd.fieldname,fd.description as labelname from workflow_formfield ff,workflow_formdict fd where ff.formid = ? and ff.fieldid = fd.id", formId); + } + while (rs.next()) { + int fieldId = Util.getIntValue(Util.null2String(rs.getString("id"))); + String fieldName = Util.null2String(rs.getString("labelname")); + if (Strings.isNullOrEmpty(fieldName)) { + fieldName = Util.null2String(rs.getString("fieldname")); + } + field = new HashMap<>(); + field.put("key", String.format("${fieldid_%s}", fieldId)); + field.put("showname", Util.formatMultiLang(fieldName)); + field.put("multClickable", true); + field.put("clickable", true); + fields.add(field); + } + + return fields; + } + + /** + * @param workflowId + * @return + */ + public List> getMainFields4EmailApprove(String workflowId) { + + List> mainFields = getMainFields(workflowId); + + // 增加流程审批按钮 + Map emailApproveBtn = new HashMap<>(); + emailApproveBtn.put("key", SYSTEM_FIELD_APPROVE_BTN); + emailApproveBtn.put("showname", SystemEnv.getHtmlLabelName(527685, user.getLanguage())); + emailApproveBtn.put("clickable", false); + emailApproveBtn.put("multClickable", false); + mainFields.add(emailApproveBtn); + + return mainFields; + } + + /** + * 下一节点中,除去自动审批的节点(自动审批节点不需要提醒) + * + * @param requestManager + * @return + */ + public Set remindNodes(RequestManager requestManager) { + + List nextNodeids = requestManager.getNextnodeids(); + Map nodeInfoCache = requestManager.getNodeInfoCache(); + Set nodeInfoCacheKey = nodeInfoCache.keySet(); + + Set nodeIds = new HashSet<>(); + for (Object id : nextNodeids) { + int intId = Util.getIntValue((String) id); + boolean exists = false; + for (Integer cacheId : nodeInfoCacheKey) { + if (cacheId == intId) { + exists = true; + break; + } + } + if (!exists) { + nodeIds.add(String.valueOf(intId)); + } + } + + return nodeIds; + } + + /** + * 处理特殊字符 + * + * @param sourceStr + * @return + */ + public static String parseSpecialChar(String sourceStr) { + + return sourceStr.replace("\\", "\\\\") + .replace("$", "\\$") + .replace("{", "\\{") + .replace("}", "\\}") + .replace("*", "\\*") + .replace("[", "\\[") + .replace("]", "\\]") + .replace("(", "\\(") + .replace(")", "\\)") + .replace(".", "\\.") + .replace("+", "\\+"); + } + + /** + * 流程表单转PDF + * TODO 模板ID + * + * @param requestid + * @param keepsign 保留签字意见 + * @param modeid 模板ID + * @return + */ + private String getRequestFormPdf(String requestid, int keepsign, int modeid) { + WfToDocUtil wfdocUtil = new WfToDocUtil(); + Map params = new HashMap(); + params.put("requestid", requestid); + params.put("onlyHtml", 0); + params.put("keepsign", keepsign); + Map modeImage = wfdocUtil.getFileId(params, user); + return Util.null2String(modeImage.get("pdf")); + } + + /** + * 获取流程主表附件字段 + * TODO 明细表附件字段、签字意见附件 + * + * @param requestid + * @return + */ + private Set getRequestAttachment(String requestid, String wfId) { + + Set attachmentId = new HashSet<>(); + // 判断老表单还是新表单 + RecordSet rs = new RecordSet(); + rs.executeQuery("select isbill,formid from workflow_base where id=?", wfId); + int isBill = 0; + int formid = -1; + if (rs.next()) { + isBill = Util.getIntValue(Util.null2String(rs.getString("isbill"))); + formid = Util.getIntValue(Util.null2String(rs.getString("formid"))); + } + if (isBill == 1) { + Set fieldName = new HashSet<>(); + rs.executeQuery("select fieldname from workflow_billfield where billid = ? and fieldhtmltype = 6 and viewtype= 0", formid); + while (rs.next()) { + fieldName.add(rs.getString("fieldname")); + } + if (!fieldName.isEmpty()) { + rs.executeQuery("select tablename from workflow_bill where id = ?", formid); + rs.next(); + String tablename = rs.getString("tablename"); + String columns = String.join(",", fieldName); + rs.executeQuery("select " + columns + " from " + tablename + " where requestid = ?", requestid); + rs.next(); + String[] columnName = rs.getColumnName(); + for (String col : columnName) { + attachmentId.add(rs.getString(col)); + } + } + } else { + Set fieldName = new HashSet<>(); + rs.executeQuery("select fd.fieldname from workflow_formfield ff,workflow_formdict fd where ff.formid = ? and ff.fieldid = fd.id and ff.isdetail<>1 and fd.fieldhtmltype = 6", formid); + while (rs.next()) { + fieldName.add(rs.getString("fieldname")); + } + if (!fieldName.isEmpty()) { + String columns = String.join(",", fieldName); + rs.executeQuery("select " + columns + " from workflow_form where requestid = ?", requestid); + rs.next(); + String[] columnName = rs.getColumnName(); + for (String col : columnName) { + attachmentId.add(rs.getString(col)); + } + } + } + String docIds = String.join(",", attachmentId); + this.printLog(requestid + " --getRequestAttachment--" + docIds); + Set imagefileId = new HashSet<>(); + if (Strings.isNullOrEmpty(docIds)) return imagefileId; + rs.executeQuery("select imagefileid from docimagefile where " + Util.getSubINClause(docIds, "docid", "in")); + while (rs.next()) { + imagefileId.add(rs.getString(1)); + } + this.printLog(requestid + " --getRequestAttachment--" + String.join(",", imagefileId)); + return imagefileId; + } + + private boolean isArchiveNoRemind(String wfId, String requestId, RecordSet rs) { + + rs.executeQuery("select 1 from workflow_base where id = ? and remindscope = 1", wfId); + if (rs.next()) { + return false; + } + + WFManager wfManager = RequestRemindBiz.getWfInfo(wfId); + int notRemindifArchived = Util.getIntValue(wfManager.getNotRemindifArchived(), 0); + int archiveNoMailAlert = Util.getIntValue(wfManager.getArchiveNoMailAlert(), 0); + int archiveNoMsgAlert = Util.getIntValue(wfManager.getArchiveNoMsgAlert(), 0); + int isArchiveNoRemind = Util.getIntValue(wfManager.getIsArchiveNoRemind(), 0); + + isArchiveNoRemind += (notRemindifArchived + archiveNoMailAlert + archiveNoMsgAlert); + if (isArchiveNoRemind > 0) { + this.printLog("5、requestRemind isArchiveNoRemind. requestId:" + requestId); + rs.executeQuery("select 1 from workflow_requestbase where requestid=? and currentnodetype = '3' ", requestId); + return rs.next(); + } + return false; + } + + /** + * 当前操作是否为审批行为 + * + * @param submitType + * @return + */ + private boolean isApproveAction(String submitType) { + return (submitType.equals(RemindTypeEnum.APPROVAL.getCode()) + || submitType.equals(RemindTypeEnum.BACK.getCode()) + || submitType.equals(RemindTypeEnum.CONFIRM.getCode())); + } + + /** + * 提醒节点是否有邮件审批 + * + * @param submitType + * @param wfId + * @param nodeId + * @return + */ + private boolean isEmailApprove(String submitType, String wfId, String nodeId) { + boolean isApproveAction = this.isApproveAction(submitType); + RecordSet rs = new RecordSet(); + rs.executeQuery("select isEMailApprove,nodescope from wf_emailapprove_set where workflowId = ? ", wfId); + if (rs.next()) { + int isEMailApprove = rs.getInt(1); + int nodescope = rs.getInt(2); + if (isEMailApprove == 0) return false; + if (isEMailApprove == 1 && isApproveAction) { + if (nodescope == 0) return true; + rs.executeQuery("select 1 from wf_emailapprove_content where workflowid = ? and nodeid = ? ", wfId, nodeId); + return rs.next(); + } + } + return false; + } + + + private void printLog(String info) { + String threadName = Thread.currentThread().getName(); + log.info(threadName + "--" + info); + } +} diff --git a/src/main/java/com/engine/youhong/ai/taibao/email/BlackListExpansion.java b/src/main/java/com/engine/youhong/ai/taibao/email/BlackListExpansion.java new file mode 100644 index 0000000..986f2bf --- /dev/null +++ b/src/main/java/com/engine/youhong/ai/taibao/email/BlackListExpansion.java @@ -0,0 +1,21 @@ +package com.engine.youhong.ai.taibao.email; + +import java.util.Set; + +/** + *

黑名单扩展接口

+ * + *

create: 2023/4/14 17:07

+ * + * @author youHong.ai + */ +public interface BlackListExpansion { + + /** + *

发送邮件

+ * + * @param mailAddress 邮箱地址 + * @return 邮箱地址 + */ + Set sendEmailHandler(Set mailAddress); +} diff --git a/src/main/java/com/engine/youhong/ai/taibao/email/BlackListRegister.java b/src/main/java/com/engine/youhong/ai/taibao/email/BlackListRegister.java new file mode 100644 index 0000000..4d63bd3 --- /dev/null +++ b/src/main/java/com/engine/youhong/ai/taibao/email/BlackListRegister.java @@ -0,0 +1,38 @@ +package com.engine.youhong.ai.taibao.email; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + *

注册信息

+ * + *

create: 2023/4/14 17:09

+ * + * @author youHong.ai + */ +public class BlackListRegister { + + private static final List EXPANSION_LIST = new ArrayList<>(); + private static final List EXPANSION_APPROVE_LIST = new ArrayList<>(); + + public static void registerExpansion(BlackListExpansion blackListExpansion) { + if (Objects.nonNull(blackListExpansion)) { + EXPANSION_LIST.add(blackListExpansion); + } + } + + public static void registerAPPROVEExpansion(BlackListExpansion blackListExpansion) { + if (Objects.nonNull(blackListExpansion)) { + EXPANSION_APPROVE_LIST.add(blackListExpansion); + } + } + + public static List getExpansionList() { + return EXPANSION_LIST; + } + + public static List getExpansionApproveList() { + return EXPANSION_APPROVE_LIST; + } +} diff --git a/src/main/java/com/engine/youhong/ai/taibao/email/impl/InitBlackListServiceImpl.java b/src/main/java/com/engine/youhong/ai/taibao/email/impl/InitBlackListServiceImpl.java new file mode 100644 index 0000000..cb6e5e6 --- /dev/null +++ b/src/main/java/com/engine/youhong/ai/taibao/email/impl/InitBlackListServiceImpl.java @@ -0,0 +1,64 @@ +package com.engine.youhong.ai.taibao.email.impl; + +import aiyh.utils.Util; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import com.engine.youhong.ai.taibao.email.BlackListRegister; +import com.engine.youhong.ai.taibao.email.mapper.InitBlackEmailListMapper; +import com.weaverboot.frame.ioc.anno.classAnno.WeaSysInitComponent; +import com.weaverboot.frame.ioc.anno.methodAnno.WeaSysInit; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

初始化扩展信息

+ * + *

create: 2023/4/14 17:15

+ * + * @author youHong.ai + */ + +@WeaSysInitComponent("注册email黑名单拦截器") +public class InitBlackListServiceImpl { + + private final InitBlackEmailListMapper mapper = Util.getMapper(InitBlackEmailListMapper.class); + + @WeaSysInit(order = 1, description = "注册拦截邮箱黑名单") + public void init() { + Util.getLogger().info("注册拦截邮箱黑名单,init"); + BlackListRegister.registerExpansion(set -> { + if (Objects.isNull(set)) { + return null; + } + List hrmList = mapper.selectWorkflowBlackEmailList(); + String ids = Util.join(hrmList, ","); + List blackEmailList = mapper.selectEmailListByHrmIds(ids); + if (CollectionUtil.isEmpty(blackEmailList)) { + return set; + } + return set.stream() + .filter(item -> !blackEmailList.contains(item)) + .collect(Collectors.toSet()); + }); + } + + @WeaSysInit(order = 2, description = "注册拦截邮箱黑名单") + public void initApprove() { + Util.getLogger().info("注册拦截邮箱黑名单,initApprove"); + BlackListRegister.registerAPPROVEExpansion(set -> { + if (Objects.isNull(set)) { + return null; + } + String ids = mapper.selectWorkflowApproveBlackEmailList(); + List blackEmailList = mapper.selectEmailListByHrmIds(ids); + if (CollectionUtil.isEmpty(blackEmailList)) { + return set; + } + return set.stream() + .filter(item -> !blackEmailList.contains(item)) + .collect(Collectors.toSet()); + }); + } + +} diff --git a/src/main/java/com/engine/youhong/ai/taibao/email/mapper/InitBlackEmailListMapper.java b/src/main/java/com/engine/youhong/ai/taibao/email/mapper/InitBlackEmailListMapper.java new file mode 100644 index 0000000..cb23cce --- /dev/null +++ b/src/main/java/com/engine/youhong/ai/taibao/email/mapper/InitBlackEmailListMapper.java @@ -0,0 +1,44 @@ +package com.engine.youhong.ai.taibao.email.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; + +/** + *

+ * + *

create: 2023/4/14 17:20

+ * + * @author youHong.ai + */ +@SqlMapper +public interface InitBlackEmailListMapper { + + + /** + *

查询流程黑名单

+ * + * @return email黑名单 + */ + @Select("select black_hrm from uf_black_email_conf where type = 0") + List selectWorkflowBlackEmailList(); + + /** + *

查询流程黑名单

+ * + * @return email黑名单 + */ + @Select("select email from uf_black_email_conf where type = 1") + String selectWorkflowApproveBlackEmailList(); + + + /** + *

根据人员id查询邮件id

+ * + * @param ids 人员ids + * @return 邮件列表 + */ + @Select("select email from hrmresource where id in ($t{ids})") + List selectEmailListByHrmIds(String ids); +} diff --git a/src/main/java/weaver/xiao/commons/config/enumtype/GetValueTypeEnum.java b/src/main/java/weaver/xiao/commons/config/enumtype/GetValueTypeEnum.java index 51727d2..1b27887 100644 --- a/src/main/java/weaver/xiao/commons/config/enumtype/GetValueTypeEnum.java +++ b/src/main/java/weaver/xiao/commons/config/enumtype/GetValueTypeEnum.java @@ -10,35 +10,47 @@ import java.util.Map; */ public enum GetValueTypeEnum { - - WORKFLOW_FIELD("0"), - DEFAULT_VALUE("1"), - CURRENT_TIME("3"), - CUS_SQL("4"), - REQUEST_ID("5"), - MAIN_DATA_ID("6"), - RANDOM("7"), - ATTACHMENT("8"), - - CUS_INTERFACE("9"), - - CUS_FIELD("10"); - - private static final Map LOOK_UP = new HashMap<>(8); - - static { - for (GetValueTypeEnum getValueTypeEnum : EnumSet.allOf(GetValueTypeEnum.class)) { - LOOK_UP.put(getValueTypeEnum.value, getValueTypeEnum); - } - } - - public final String value; - - GetValueTypeEnum(String value) { - this.value = value; - } - - public static GetValueTypeEnum getEnum(String value) { - return LOOK_UP.get(value); - } + /** 流程字段 */ + WORKFLOW_FIELD("0"), + /** 默认值 */ + DEFAULT_VALUE("1"), + /** 当前时间 */ + CURRENT_TIME("3"), + /** 自定义sql */ + CUS_SQL("4"), + /** 流程请求id */ + REQUEST_ID("5"), + /** 主表数据id */ + MAIN_DATA_ID("6"), + /** 随机值 */ + RANDOM("7"), + /** 附件 */ + ATTACHMENT("8"), + /** 自定义接口 */ + + CUS_INTERFACE("9"), + + /** 自定义字段 */ + CUS_FIELD("10"), + + /** 自定义mapper sql */ + CUS_MAPPER_SQL("11"); + + private static final Map LOOK_UP = new HashMap<>(8); + + static { + for (GetValueTypeEnum getValueTypeEnum : EnumSet.allOf(GetValueTypeEnum.class)) { + LOOK_UP.put(getValueTypeEnum.value, getValueTypeEnum); + } + } + + public final String value; + + GetValueTypeEnum(String value) { + this.value = value; + } + + public static GetValueTypeEnum getEnum(String value) { + return LOOK_UP.get(value); + } } diff --git a/src/main/java/weaver/xiao/commons/config/mapper/DealWithMapper.java b/src/main/java/weaver/xiao/commons/config/mapper/DealWithMapper.java new file mode 100644 index 0000000..bd4684b --- /dev/null +++ b/src/main/java/weaver/xiao/commons/config/mapper/DealWithMapper.java @@ -0,0 +1,21 @@ +package weaver.xiao.commons.config.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.SqlString; + +import java.util.Map; + +/** + *

+ * + *

create: 2023/4/17 22:21

+ * + * @author youHong.ai + */ +@SqlMapper +public interface DealWithMapper { + + @Select(custom = true) + String selectCustomSql(@SqlString String sql, Map params); +} diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index 1219d1e..956879a 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -15,6 +15,7 @@ import weaver.xiao.commons.config.enumtype.GetValueTypeEnum; import weaver.xiao.commons.config.enumtype.ParamTypeEnum; import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; import weaver.xiao.commons.config.interfacies.CusInterfaceListValue; +import weaver.xiao.commons.config.mapper.DealWithMapper; import weaver.xiao.commons.exception.ValueDealException; import weaver.zwl.common.ToolUtil; @@ -57,6 +58,16 @@ public class DealWithMapping extends ToolUtil { private RecordSet tempRs; + private DealWithMapper mapper = null; + + { + try { + mapper = aiyh.utils.Util.getMapper(DealWithMapper.class); + } catch (Exception e) { + this.writeErrorLog("缺少 aiyh_utils.jar依赖,初始化失败!"); + } + } + /** *

将日期字符串转换为Date对象

* @@ -123,9 +134,9 @@ public class DealWithMapping extends ToolUtil { */ String val = Util.null2String(rs.getString(i)); BigDecimal decimal; - if(StringUtils.isBlank(val)){ + if (StringUtils.isBlank(val)) { decimal = new BigDecimal("0"); - }else { + } else { decimal = new BigDecimal(val); } map.put(key, decimal); @@ -748,6 +759,16 @@ public class DealWithMapping extends ToolUtil { value = detailMap.get(valueContext.trim()); } break; + case CUS_MAPPER_SQL: { + Map param = new HashMap<>(); + param.put("main", mainMap); + param.put("dt", detailMap); + if (mapper == null) { + throw new RuntimeException("缺少 aiyh_utils.jar依赖,无法使用mapper!"); + } + value = mapper.selectCustomSql(valueContext, param); + } + break; default: throw new ValueDealException("不支持的取值方式"); } @@ -1088,6 +1109,16 @@ public class DealWithMapping extends ToolUtil { } } break; + case CUS_MAPPER_SQL: { + Map param = new HashMap<>(); + param.put("main", mainMap); + param.put("dt", detailMap); + if (mapper == null) { + throw new RuntimeException("缺少 aiyh_utils.jar依赖,无法使用mapper!"); + } + value = mapper.selectCustomSql(valueContext, param); + } + break; default: throw new ValueDealException("不支持的取值方式"); } diff --git a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableAction.java b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableAction.java index 8ed33c8..a0d146d 100644 --- a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableAction.java +++ b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableAction.java @@ -72,6 +72,16 @@ public class VoucherPayableAction extends SafeCusBaseAction { @RequiredMark("ip") private String ip; + + @PrintParamMark + @RequiredMark("应付凭证远程文件名称前缀") + private String pavFileName; + + + @PrintParamMark + @RequiredMark("付款凭证远程文件名称前缀") + private String pmvFileName; + @PrintParamMark @ActionOptionalParam(desc = "是否删除生成的临时本地文件,true - 删除 false - 不删除", value = "false") private String deleteTemp = "false"; @@ -86,10 +96,10 @@ public class VoucherPayableAction extends SafeCusBaseAction { String fileName = ""; String remotePath = ""; if (Integer.parseInt(voucherType) == 1) { - fileName = "Pav" + Util.getTime("yyyyMMddHHmmss") + ".txt"; + fileName = pavFileName + Util.getTime("yyyyMMddHHmmssSSSS") + ".txt"; remotePath = pavRemotePath; } else if (Integer.parseInt(voucherType) == 2) { - fileName = "Pmv" + Util.getTime("yyyyMMddHHmmss") + ".txt"; + fileName = pmvFileName + Util.getTime("yyyyMMddHHmmssSSSS") + ".txt"; remotePath = pmvRemotePath; } log.info("远程连接地址:" + "smb://" + ip + remotePath); diff --git a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java new file mode 100644 index 0000000..7fbe5fa --- /dev/null +++ b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java @@ -0,0 +1,246 @@ +package weaver.youhong.ai.haripijiu.action.sapdocking; + +import aiyh.utils.Util; +import aiyh.utils.action.SafeCusBaseAction; +import aiyh.utils.annotation.*; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; +import weaver.general.GCONST; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.service.DealWithMapping; +import weaver.youhong.ai.haripijiu.action.sapdocking.util.SmbjUtil; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + *

对私凭证action

+ * + *

create: 2023/4/17 14:57

+ * + * @author youHong.ai + */ +@ActionDesc(author = "youhong.ai", value = "对私凭证action") +@Setter +public class VoucherPayableNewAction extends SafeCusBaseAction { + + + private final DealWithMapping dealWithMapping = new DealWithMapping(); + + @PrintParamMark + @RequiredMark("请求参数配置表配置唯一标识字段!") + @ActionDefaultTestValue("duisi") + private String onlyMark; + + @PrintParamMark + @ActionOptionalParam(value = "false", desc = "是否自动提交流程 false : 不提交; true : 提交") + private String submitAction = "false"; + + @PrintParamMark + @ActionOptionalParam(value = "true", desc = "是否失败后阻断流程, false : 不阻断; true: 阻断") + private String block = "true"; + + @PrintParamMark + @RequiredMark("凭证类型,1- 应付凭证; 2- 付款凭证") + private String voucherType; + + + @PrintParamMark + @RequiredMark("应付凭证远程路径") + private String pavRemotePath; + + + @PrintParamMark + @RequiredMark("付款凭证远程路径") + private String pmvRemotePath; + + @PrintParamMark + @RequiredMark("用户名") + private String userName; + + @PrintParamMark + @RequiredMark("密码") + private String password; + + + @PrintParamMark + @RequiredMark("ip") + private String ip; + + + @PrintParamMark + @RequiredMark("应付凭证远程文件名称前缀") + private String pavFileName; + + + @PrintParamMark + @RequiredMark("付款凭证远程文件名称前缀") + private String pmvFileName; + + @PrintParamMark + @ActionOptionalParam(desc = "是否删除生成的临时本地文件,true - 删除 false - 不删除", value = "false") + private String deleteTemp = "false"; + + + @Override + public void doSubmit(String requestId, String billTable, int workflowId, User user, RequestInfo requestInfo) { + + try { + SmbjUtil smbjUtil = new SmbjUtil(); + String tempFilePath = getFile(billTable, requestInfo); + String fileName = ""; + String remotePath = ""; + if (Integer.parseInt(voucherType) == 1) { + fileName = pavFileName + Util.getTime("yyyyMMddHHmmssSSSS") + ".txt"; + remotePath = pavRemotePath; + } else if (Integer.parseInt(voucherType) == 2) { + fileName = pmvFileName + Util.getTime("yyyyMMddHHmmssSSSS") + ".txt"; + remotePath = pmvRemotePath; + } + log.info("远程连接地址:" + "smb://" + ip + remotePath); + log.info("本地文件地址: " + tempFilePath); + smbjUtil.smbPut("smb://" + ip + remotePath, tempFilePath, userName, password, fileName); + if (Boolean.parseBoolean(deleteTemp)) { + Files.delete(Paths.get(tempFilePath)); + } + /* ******************* 是否提交流程 ******************* */ + if (Boolean.parseBoolean(submitAction)) { + this.submitWorkflow(requestId, user.getUID()); + } + } catch (Exception e) { + log.error("推送应付款凭证失败!" + e.getMessage()); + if (Boolean.parseBoolean(block)) { + throw new CustomerException(e.getMessage(), e); + } + } + } + + public void submitWorkflow(String requestId, Integer userId) { + Util.submitWorkflowThread(Integer.parseInt(requestId), userId, "sap对接自动提交流程!"); + } + + private String getFile(String billTable, RequestInfo requestInfo) { + dealWithMapping.setMainTable(billTable); + RequestMappingConfig requestMappingConfig = dealWithMapping.treeDealWithUniqueCode(onlyMark); + Map requestParam = dealWithMapping.getRequestParam(getObjMainTableValue(requestInfo), requestMappingConfig); + Assert.notEmpty(requestParam, "query config error, can not query result by onlyMark:[{}],Please check the configuration table", onlyMark); + // 借方 + List debit = (List) requestParam.get("debit"); + // 贷方 + List creditSide = (List) requestParam.get("creditSide"); + // 凭证头 + Map heads = (Map) requestParam.get("heads"); + Assert.notEmpty(heads, "No relevant voucher header data was found. Please check the configuration table and process table data."); + Assert.notEmpty(debit, "No relevant voucher details have been queried. Please check whether there is data in the process schedule."); + Assert.notEmpty(creditSide, "No credit data was found. Please check whether the configuration table is configured correctly and whether the process data exists."); + return createFile(debit, creditSide, heads); + } + + + private String createFile(List debit, List creditSide, Map heads) { + StringBuilder sb = new StringBuilder(); + // 写入凭证头 + List headKeys = new ArrayList<>(); + for (Map.Entry entry : heads.entrySet()) { + headKeys.add(entry.getKey()); + } + headKeys = sortKey(headKeys); + for (String headKey : headKeys) { + sb.append(heads.get(headKey)).append("\t"); + } + sb.deleteCharAt(sb.lastIndexOf("\t")); + sb.append("\r\n"); + // 写入借方信息 + writeList(debit, sb); + // 写入贷方信息 + writeList(creditSide, sb); + String filePath = getFilePath(); + try { + OutputStreamWriter out = new OutputStreamWriter( + Files.newOutputStream(Paths.get(filePath)), StandardCharsets.UTF_8); + out.write(sb.toString()); + out.close(); + + } catch (IOException e) { + throw new CustomerException(Util.logStr("can not writer file [{}]", filePath)); + } + + return filePath; + } + + private void writeList(List list, StringBuilder sb) { + Map firstMap = (Map) list.get(0); + List keys = new ArrayList<>(); + for (Map.Entry entry : firstMap.entrySet()) { + keys.add(entry.getKey()); + } + if (list.size() > 1) { + Map secondMap = (Map) list.get(1); + for (Map.Entry entry : secondMap.entrySet()) { + if (keys.contains(entry.getKey())) { + continue; + } + keys.add(entry.getKey()); + } + } + keys = sortKey(keys); + for (Object o : list) { + Map map = (Map) o; + for (String key : keys) { + if (map.containsKey(key)) { + sb.append(map.get(key)) + .append("\t"); + } + } + sb.deleteCharAt(sb.lastIndexOf("\t")); + sb.append("\r\n"); + } + } + + private List sortKey(List list) { + return list.stream() + .map(Integer::parseInt) + .sorted() + .map(Util::null2String) + .collect(Collectors.toList()); + } + + @NotNull + private String getFilePath() { + String sysFilePath = GCONST.getSysFilePath(); + String filePath; + if (sysFilePath.endsWith(File.separator)) { + filePath = sysFilePath + "cus_temp" + File.separator + "voucher-new" + File.separator + + System.currentTimeMillis() + "-voucher-new-" + UUID.randomUUID() + ".txt"; + } else { + filePath = sysFilePath + File.separator + "cus_temp" + File.separator + "voucher" + File.separator + + System.currentTimeMillis() + "-voucher-new-" + UUID.randomUUID() + ".txt"; + } + Path path = Paths.get(filePath); + if (!Files.exists(path)) { + Path parent = path.getParent(); + try { + Files.createDirectories(parent); + } catch (IOException e) { + throw new CustomerException(Util.logStr("can not create file [{}]", filePath)); + } + } + return filePath; + } + + +} diff --git a/src/test/java/youhong/ai/haripijiu/TestHaRiPiJiu.java b/src/test/java/youhong/ai/haripijiu/TestHaRiPiJiu.java index 50f1450..681fb1c 100644 --- a/src/test/java/youhong/ai/haripijiu/TestHaRiPiJiu.java +++ b/src/test/java/youhong/ai/haripijiu/TestHaRiPiJiu.java @@ -1,10 +1,12 @@ package youhong.ai.haripijiu; import aiyh.utils.GenerateFileUtil; +import aiyh.utils.Util; import basetest.BaseTest; import org.junit.Test; import weaver.youhong.ai.haripijiu.action.sapdocking.ReceiptAndPaymentAction; import weaver.youhong.ai.haripijiu.action.sapdocking.VoucherPayableAction; +import weaver.youhong.ai.haripijiu.action.sapdocking.VoucherPayableNewAction; /** *

测试

@@ -24,6 +26,7 @@ public class TestHaRiPiJiu extends BaseTest { @Test public void test1() { - + + Util.actionTest(VoucherPayableNewAction.class, 405407); } } diff --git a/src/test/java/youhong/ai/pcn/UtilTest.java b/src/test/java/youhong/ai/pcn/UtilTest.java index 1c1a056..142899d 100644 --- a/src/test/java/youhong/ai/pcn/UtilTest.java +++ b/src/test/java/youhong/ai/pcn/UtilTest.java @@ -296,4 +296,8 @@ public class UtilTest extends BaseTest { } + @Test + public void testSS() { + out.println(Util.getTime("yyyyMMddHHmmssSSSS")); + } } diff --git a/src/test/java/youhong/ai/taibao/TestTaiBao.java b/src/test/java/youhong/ai/taibao/TestTaiBao.java index 8e125c1..58a4d1c 100644 --- a/src/test/java/youhong/ai/taibao/TestTaiBao.java +++ b/src/test/java/youhong/ai/taibao/TestTaiBao.java @@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONArray; import com.api.youhong.ai.taibao.fcuntionlist.service.FunctionListService; import com.api.youhong.ai.taibao.qikan.service.PeriodicalService; import com.cloudstore.dev.api.util.Util_DataCache; +import com.engine.youhong.ai.taibao.email.mapper.InitBlackEmailListMapper; import org.junit.Test; import weaver.conn.RecordSet; import weaver.general.BaseBean; @@ -158,4 +159,14 @@ public class TestTaiBao extends BaseTest { public void testTableModelId() { System.out.println(Util.getModeIdByTableName("uf_privacy_log_info")); } + + + @Test + public void testEmailSelect() { + InitBlackEmailListMapper mapper = Util.getMapper(InitBlackEmailListMapper.class); + List hrmList = mapper.selectWorkflowBlackEmailList(); + String ids = Util.join(hrmList, ","); + List strings = mapper.selectEmailListByHrmIds(ids); + System.out.println(JSON.toJSONString(strings)); + } } diff --git a/src/test/java/youhong/ai/utiltest/GenericTest.java b/src/test/java/youhong/ai/utiltest/GenericTest.java index 86a43a4..a038ea5 100644 --- a/src/test/java/youhong/ai/utiltest/GenericTest.java +++ b/src/test/java/youhong/ai/utiltest/GenericTest.java @@ -1,9 +1,11 @@ package youhong.ai.utiltest; +import aiyh.utils.GenerateFileUtil; import aiyh.utils.Util; import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; import basetest.BaseTest; import org.junit.Test; +import weaver.youhong.ai.haripijiu.action.sapdocking.VoucherPayableNewAction; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; @@ -82,4 +84,10 @@ public class GenericTest extends BaseTest { System.out.println(aClass); } + @Test + public void testGre() { + GenerateFileUtil.createActionDocument(VoucherPayableNewAction.class); + } + + } \ No newline at end of file