LMImplService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package com.malk.lemeng.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.malk.lemeng.service.LMService;
  4. import com.malk.server.aliwork.YDConf;
  5. import com.malk.server.aliwork.YDParam;
  6. import com.malk.server.dingtalk.DDConf;
  7. import com.malk.service.aliwork.YDClient;
  8. import com.malk.service.aliwork.YDService;
  9. import com.malk.service.dingtalk.DDClient;
  10. import com.malk.service.dingtalk.DDClient_Contacts;
  11. import com.malk.service.dingtalk.DDClient_Personnel;
  12. import com.malk.utils.UtilFile;
  13. import com.malk.utils.UtilMap;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.apache.commons.lang3.StringUtils;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.stereotype.Service;
  18. import java.util.*;
  19. @Service
  20. @Slf4j
  21. public class LMImplService implements LMService {
  22. @Autowired
  23. private DDClient ddClient;
  24. @Autowired
  25. private DDConf ddConf;
  26. @Autowired
  27. private DDClient_Contacts ddClient_contacts;
  28. @Autowired
  29. private DDClient_Personnel ddClient_personnel;
  30. @Autowired
  31. private YDClient ydClient;
  32. /**
  33. * 同步花名册信息
  34. */
  35. @Override
  36. public void syncRoster() {
  37. // 花名册元数据
  38. List<Map> metaList = (List<Map>) UtilFile.readJsonObjectFromResource("static/json/personnel.json"); // 本地匹配了宜搭组件ID
  39. // List<Map> metaList = ddClient_personnel.getPersonnelMeta(ddClient.getAccessToken(), ddConf.getAgentId());
  40. // 同步全量人员
  41. ddClient_contacts.getDepartmentId_all(ddClient.getAccessToken(), true).forEach(deptId -> {
  42. List<String> userIds = ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(), deptId);
  43. log.info("dept, {}, userIds, {}", deptId, userIds.size());
  44. if (userIds.size() == 0) {
  45. return;
  46. }
  47. // 员工花名册信息
  48. ddClient_personnel.getEmployeeInfos(ddClient.getAccessToken(), userIds, ddConf.getAgentId(), null).forEach(employeeInfo -> {
  49. // 通过元数据字段code, 匹配员工花名册value
  50. List<Map> employeeField = (List<Map>) employeeInfo.get("field_data_list");
  51. // 宜搭表单数据
  52. Map formData = UtilMap.map("employeeField_limrznyp", Arrays.asList(employeeInfo.get("userid"))); // 成员权限
  53. metaList.forEach(meta -> {
  54. boolean isDetail = UtilMap.getBoolean(meta, "detail");
  55. List<Map> metaField = (List<Map>) meta.get("field_meta_info_list");
  56. Map detail = new HashMap(); // 明细行
  57. metaField.forEach(field -> {
  58. // 元数据内一些系统字段无 field_code, sys00 基本信息分组下 使用 field_name
  59. Optional optional = employeeField.stream().filter(employee -> field.get("field_code").equals(employee.get("field_code")) || employee.get("field_name").equals(field.get("field_name"))).findAny();
  60. if (optional.isPresent()) {
  61. // 数据组装
  62. Map employee = (Map) optional.get();
  63. String value = UtilMap.getString(((List<Map>) employee.get("field_value_list")).get(0), "label");
  64. log.info("分组 -> {}, 是否明细 -> {}; 字段 -> {}, 值 -> {}", meta.get("group_name"), meta.get("detail"), field.get("field_name"), value);
  65. // 值处理
  66. if (field.containsKey("comp_id")) {
  67. if (isDetail) {
  68. detail.put(field.get("comp_id"), value);
  69. } else {
  70. formData.put(field.get("comp_id"), value);
  71. }
  72. }
  73. }
  74. });
  75. // 明细表
  76. if (isDetail && meta.containsKey("comp_id")) {
  77. formData.put(meta.get("comp_id"), Arrays.asList(detail));
  78. }
  79. });
  80. // 宜搭更新 todo 查询同步数据, 代码内匹配, 而不是循环内查询
  81. YDParam ydParam = YDParam.builder()
  82. .searchFieldJson(JSON.toJSONString(UtilMap.map("employeeField_limrznyp", formData.get("employeeField_limrznyp"))))
  83. .formUuid("FORM-54C47C335C054FFBAECCA0B92100A341PGD2")
  84. .build();
  85. List<String> formInstIds = (List<String>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form_id).getData();
  86. if (formInstIds.size() > 0) {
  87. ydParam.setFormInstanceId(formInstIds.get(0));
  88. ydParam.setUpdateFormDataJson(JSON.toJSONString(formData));
  89. ydClient.operateData(ydParam, YDConf.FORM_OPERATION.update);
  90. } else {
  91. ydParam.setFormDataJson(JSON.toJSONString(formData));
  92. ydClient.operateData(ydParam, YDConf.FORM_OPERATION.create);
  93. }
  94. });
  95. });
  96. }
  97. @Autowired
  98. private YDService ydService;
  99. private static final int BUDGET_PER = 200;
  100. /**
  101. * 同步部门信息
  102. */
  103. @Override
  104. public void syncDepartment() {
  105. // 部门已同步数据
  106. List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
  107. .formUuid("FORM-B6F662B18C3F4D7D855CFE50243394AFQPOH")
  108. .build());
  109. // 匹配钉钉通讯录
  110. List<Long> deptList = ddClient_contacts.getDepartmentId_all(ddClient.getAccessToken(), true, DDConf.TOP_DEPARTMENT);
  111. for (long deptId : deptList) {
  112. List<String> userIds = ddClient_contacts.listDepartmentUserId(ddClient.getAccessToken(), deptId);
  113. if (userIds.size() == 0) {
  114. continue;
  115. }
  116. Map info = ddClient_contacts.getDepartmentInfo(ddClient.getAccessToken(), deptId);
  117. Map formData = UtilMap.map("textField_lpcff8zu, numberField_lr70cqsl, numberField_lr70cqsk", info.get("name"), info.get("parent_id"), info.get("dept_id"));
  118. // todo 部门ID写入需要是string集合\数组, 封装
  119. formData.putAll(UtilMap.map("employeeField_lpmbmyaa, departmentSelectField_lpaks312", info.get("dept_manager_userid_list"), Arrays.asList(String.valueOf(info.get("dept_id")))));// float budget = userIds.size() * 200; // 部门人均
  120. float budget = userIds.size() * BUDGET_PER; // 部门人均
  121. formData.putAll(UtilMap.map("numberField_lr71bkuj, employeeField_lr71bkui, numberField_lr71mvbk", userIds.size(), userIds, budget));
  122. // Upsert操作, 记录当月预算
  123. Optional optional = dataList.stream().filter(item -> deptId == UtilMap.getLong(item, "numberField_lr70cqsk")).findAny();
  124. if (optional.isPresent()) {
  125. formData.put("employeeField_lr71bkui", UtilMap.getString((Map) optional.get(), "employeeField_lr71bkui_id")); // 非常规组件数据处理
  126. ydClient.operateData(YDParam.builder()
  127. .formInstanceId(UtilMap.getString((Map) optional.get(), "instanceId"))
  128. .updateFormDataJson(JSON.toJSONString(formData))
  129. .build(), YDConf.FORM_OPERATION.update);
  130. continue;
  131. }
  132. formData.putAll(UtilMap.map("numberField_lpaks318, numberField_lpayajrp, numberField_lpayajrn", 0, 0, 0));
  133. formData.putAll(UtilMap.map("radioField_lpaks316", "是")); // test
  134. ydClient.operateData(YDParam.builder()
  135. .formUuid("FORM-B6F662B18C3F4D7D855CFE50243394AFQPOH")
  136. .formDataJson(JSON.toJSONString(formData))
  137. .build(), YDConf.FORM_OPERATION.create);
  138. }
  139. }
  140. /// 涉及行政归属, 拆分规则
  141. private void updateBalance(Map item, int budget, float quota) {
  142. item.put("numberField_lpaks318", UtilMap.getFloat(item, "numberField_lpaks318") + budget); // 总经费
  143. item.put("numberField_lpayajrn", UtilMap.getFloat(item, "numberField_lpayajrn") + budget); // 可用余额
  144. item.put("numberField_lr7yq38c", UtilMap.getFloat(item, "numberField_lr7yq38c") + budget); // 修改前总金额
  145. item.put("numberField_lr71mvbk", UtilMap.getFloat(item, "numberField_lr71mvbk") + budget); // 当月预计预算
  146. item.put("numberField_lr71bkuj", UtilMap.getInt(item, "numberField_lr71bkuj") + quota); // 部门人数
  147. }
  148. /**
  149. * 部门预算统计
  150. */
  151. @Override
  152. public void calcBudget() {
  153. // 部门已同步数据
  154. List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
  155. .formUuid("FORM-B6F662B18C3F4D7D855CFE50243394AFQPOH")
  156. .build());
  157. // prd 不存在一人多部门情况, 若是涉及行政归属则手动维护
  158. List<Map> manualList = ydService.queryFormData_all(YDParam.builder()
  159. .formUuid("FORM-A192B0134C184B1A84A791F322AA4D60N4F2")
  160. .build());
  161. for (Map data : manualList) {
  162. String userId = String.valueOf(UtilMap.getList(data, "employeeField_lroz3y2w_id").get(0));
  163. Map srcDpet = dataList.stream().filter(item -> UtilMap.getList(data, "employeeField_lr71bkui_id").contains(userId)).findAny().get();
  164. updateBalance(srcDpet, -BUDGET_PER, -1); // 去除原部门个人金额
  165. boolean multi = StringUtils.isNotBlank(UtilMap.getString(data, "numberField_lroz3y37"));
  166. if (multi) {
  167. Map curDpet = dataList.stream().filter(item -> UtilMap.getList(data, "numberField_lroz3y37").contains(item.get("numberField_lr70cqsk"))).findAny().get();
  168. updateBalance(curDpet, BUDGET_PER / 2, 0.5f); // 累加部门2个人金额一半
  169. }
  170. Map curDpet = dataList.stream().filter(item -> UtilMap.getList(data, "numberField_lr70cqsk").contains(item.get("numberField_lr70cqsk"))).findAny().get();
  171. updateBalance(curDpet, multi ? BUDGET_PER / 2 : BUDGET_PER, multi ? 0.5f : 1f); // 累加部门1个人金额
  172. }
  173. // prd todo 非独立预算部门, 累计到父部门, 若父部门为空, 持续往上累加
  174. dataList.forEach(item -> {
  175. if ("是".equals(item.get("radioField_lpaks316"))) {
  176. int budget = UtilMap.getInt(item, "numberField_lr71mvbk");
  177. // 冗余修改记录, 保留修改前金额并重置budget, 避免重复调用
  178. item.putAll(UtilMap.map("numberField_lr7yq38c, numberField_lr71mvbk", UtilMap.getFloat(item, "numberField_lpaks318"), 0));
  179. item.put("numberField_lpaks318", UtilMap.getFloat(item, "numberField_lpaks318") + budget);
  180. item.put("numberField_lpayajrn", UtilMap.getFloat(item, "numberField_lpayajrn") + budget);
  181. item.putAll(UtilMap.map("employeeField_lr71bkui, departmentSelectField_lpaks312", item.get("employeeField_lr71bkui_id"), item.get("departmentSelectField_lpaks312_id"))); // 非常规组件数据处理
  182. // ydClient.operateData(YDParam.builder()
  183. // .formInstanceId(UtilMap.getString(item, "instanceId"))
  184. // .updateFormDataJson(JSON.toJSONString(item))
  185. // .build(), YDConf.FORM_OPERATION.update);
  186. }
  187. });
  188. }
  189. /// test
  190. @Override
  191. public void test() {
  192. ddClient_personnel.getPersonnelMeta(ddClient.getAccessToken(), ddConf.getAgentId());
  193. }
  194. }