ScheduleTask.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. package com.malk.eastar.schedule;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.malk.eastar.model.AITableParam;
  6. import com.malk.eastar.model.AITableResult;
  7. import com.malk.eastar.service.MDTableClient;
  8. import com.malk.eastar.service.EastarTbService;
  9. import com.malk.eastar.service.YidaService;
  10. import com.malk.server.aliwork.YDConf;
  11. import com.malk.server.aliwork.YDParam;
  12. import com.malk.server.aliwork.YDSearch;
  13. import com.malk.service.aliwork.YDClient;
  14. import com.malk.service.aliwork.YDService;
  15. import com.malk.utils.PublicUtil;
  16. import com.malk.utils.UtilDateTime;
  17. import com.malk.utils.UtilMap;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.apache.commons.lang3.StringUtils;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  22. import org.springframework.context.annotation.Configuration;
  23. import org.springframework.scheduling.annotation.EnableScheduling;
  24. import org.springframework.scheduling.annotation.Scheduled;
  25. import java.time.LocalDate;
  26. import java.time.LocalTime;
  27. import java.util.*;
  28. /**
  29. * @EnableScheduling 开启定时任务 [配置参考McScheduleTask]
  30. */
  31. @Slf4j
  32. @Configuration
  33. @EnableScheduling
  34. @ConditionalOnProperty(name = {"enable.scheduling"})
  35. public class ScheduleTask {
  36. @Autowired
  37. private YDClient ydClient;
  38. @Autowired
  39. private EastarTbService eastarTbService;
  40. @Autowired
  41. private YDService ydService;
  42. //add by Jason 20260313 start
  43. @Autowired
  44. private MDTableClient mdTableClient;
  45. //add by Jason 20260313 end
  46. //add by Jason 20260522 start
  47. @Autowired
  48. private YidaService yidaService;
  49. //add by Jason 20260522 end
  50. /**
  51. * 私海客户流出
  52. */
  53. @Scheduled(cron = "0 0 5 * * ?")
  54. public void releasePrivatePoolCustomers() {
  55. log.info("私海客户流出定时任务");
  56. try {
  57. //查询所有已建联客户跟进记录
  58. List<Map> establishContactData = yidaService.queryLtcCustomerEstablishContactData();
  59. log.info("已建联跟进记录数:"+ establishContactData.size());
  60. //查询超过3天未跟进的私海新客户记录
  61. long endTime = UtilDateTime.getLocalDateTimeTimeStamp(LocalDate.now().minusDays(3).atTime(LocalTime.MIN));
  62. List ydFilters = Arrays.asList(
  63. // new YDSearch("radioField_mnpdkss9","否","测试使用", YDSearch.Type.RADIO_FIELD,YDSearch.Operator.EQ),
  64. new YDSearch("radioField_md6q7oxa","私","公海or私海", YDSearch.Type.RADIO_FIELD,YDSearch.Operator.EQ),
  65. new YDSearch("radioField_md6q7ox8","新","新老客户", YDSearch.Type.RADIO_FIELD,YDSearch.Operator.EQ),
  66. new YDSearch("dateField_l3tw3kfn",endTime,"最后跟进时间",YDSearch.Type.DATE_FIELD,YDSearch.Operator.LT)
  67. );
  68. List<Map> ltcCustomerData = yidaService.queryLtcNotFollowedCustomerData(ydFilters);
  69. log.info("超过3天未跟进的私海新客户记录数:"+ ltcCustomerData.size());
  70. //排除已建联
  71. Set<String> contactedCustomerCodes = new HashSet<>();
  72. for(Map contactRecord : establishContactData){
  73. String customerCode = UtilMap.getString(contactRecord, "customerCode");
  74. if(StringUtils.isNotEmpty(customerCode)){
  75. contactedCustomerCodes.add(customerCode);
  76. }
  77. }
  78. List<Map> filteredCustomerData = new ArrayList<>();
  79. for(Map customerRecord : ltcCustomerData){
  80. String customerCode = UtilMap.getString(customerRecord, "customerCode");
  81. if(!contactedCustomerCodes.contains(customerCode)){
  82. filteredCustomerData.add(customerRecord);
  83. }
  84. }
  85. log.info("排除已建联后的记录数:"+ filteredCustomerData.size());
  86. Map alertDetailRecord;
  87. for (Map customerRecord : filteredCustomerData) {
  88. alertDetailRecord = new HashMap();
  89. alertDetailRecord.put("businessUserId",UtilMap.getString(customerRecord, "userId"));
  90. alertDetailRecord.put("formInstId",UtilMap.getString(customerRecord, "formInstId"));
  91. alertDetailRecord.put("customerName",UtilMap.getString(customerRecord, "customerName"));
  92. alertDetailRecord.put("customerCode",UtilMap.getString(customerRecord, "customerCode"));
  93. alertDetailRecord.put("today", UtilDateTime.getLocalDateTimeTimeStamp(LocalDate.now().atStartOfDay()));
  94. // alertDetailRecord.put("tomorrow", UtilDateTime.getLocalDateTimeTimeStamp(LocalDate.now().plusDays(1).atStartOfDay()));
  95. alertDetailRecord.put("remark","私海,新客户,未建联,超过3天未跟进");
  96. yidaService.addAlertDetail(alertDetailRecord);
  97. }
  98. //按业务员分组,统计客户数量
  99. Map<String, List<Map>> customerGroupBySales = new HashMap<>();
  100. for (Map customerRecord : filteredCustomerData) {
  101. String salesPerson = UtilMap.getString(customerRecord, "userId");
  102. if (StringUtils.isEmpty(salesPerson)) {
  103. salesPerson = "未知业务员";
  104. }
  105. customerGroupBySales.computeIfAbsent(salesPerson, k -> new ArrayList<>()).add(customerRecord);
  106. }
  107. Map alertLogRecord;
  108. for (Map.Entry<String, List<Map>> entry : customerGroupBySales.entrySet()) {
  109. log.info("业务员: {}, 可能会流出客户数量: {}", entry.getKey(), entry.getValue().size());
  110. //新增私海客户流出告警日志
  111. alertLogRecord = new HashMap();
  112. alertLogRecord.put("businessUserId",entry.getKey());
  113. alertLogRecord.put("customerNum",entry.getValue().size());
  114. alertLogRecord.put("today", UtilDateTime.getLocalDateTimeTimeStamp(LocalDate.now().atStartOfDay()));
  115. yidaService.addAlertLog(alertLogRecord);
  116. }
  117. //查询超过30天未跟进的私海新客户记录
  118. // long endTime= UtilDateTime.getLocalDateTimeTimeStamp(LocalDate.now().minusDays(30).atTime(LocalTime.MIN));
  119. // List<Map> list= (List<Map>) ydClient.queryData(YDParam.builder().formUuid("FORM-9261FABA687B4D1D917617F53B4A5DB7UN16").searchCondition(JSONObject.toJSONString(
  120. // Arrays.asList(
  121. // new YDSearch("radioField_md6q7oxa","私","公私海", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ),
  122. // new YDSearch("radioField_md6q7ox8","新","新老客户", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ),
  123. // new YDSearch("dateField_l3tw3kfn",endTime,"截至跟进时间",YDSearch.Type.DATE_FIELD,YDSearch.Operator.LT)
  124. // )
  125. // )).build(), YDConf.FORM_QUERY.retrieve_list).getData();
  126. // for(Map map:list){
  127. // log.info("客户:{}释放为公海", UtilMap.getMap(map,"formData").get("textField_lqanqe6j"));
  128. // ydClient.operateData(YDParam.builder().formInstId(UtilMap.getString(map,"formInstanceId")).updateFormDataJson(
  129. // JSONObject.toJSONString(UtilMap.map("radioField_md6q7oxa, employeeField_lqanqe6n, employeeField_lqx3act6","公","[]","[]"))
  130. // ).build(), YDConf.FORM_OPERATION.update);
  131. // }
  132. }catch (Exception e){
  133. log.error("私海客户流出定时任务异常",e);
  134. }
  135. log.info("私海客户流出定时任务执行完成");
  136. }
  137. /**
  138. */
  139. // @Scheduled(cron = "0 30 6 * * ?")
  140. public void syncTaskCount() {
  141. log.info("同步任务状态数量");
  142. try {
  143. List<Map> list= (List<Map>) ydClient.queryData(YDParam.builder().formUuid("FORM-D8DFF1F8C07A4869BCC850090F3A3B4EE0AV").searchCondition(JSONObject.toJSONString(
  144. Arrays.asList(
  145. new YDSearch("selectField_me2hylde",Arrays.asList("立项阶段","样品阶段","生产阶段","包装阶段","出货阶段","收尾阶段"),"项目状态", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.CONTAINS)
  146. )
  147. )).build(), YDConf.FORM_QUERY.retrieve_list).getData();
  148. for(Map map:list){
  149. Map formData =UtilMap.getMap(map,"formData");
  150. log.info("任务数量同步:项目:{} ", formData.get("textField_me87x1nz"));
  151. String pid=UtilMap.getString(formData,"textField_me2hyldc");
  152. String tbPid=UtilMap.getString(formData,"textField_mecmytpo");
  153. if(PublicUtil.isNull(tbPid)){
  154. continue;
  155. }
  156. String projectState=UtilMap.getString(formData,"selectField_me2hylde");
  157. String fid=UtilMap.getString(map,"formInstanceId");
  158. List<UtilMap.assDetail> assDetails=UtilMap.getAssFieldValue(formData,"associationFormField_me9n24kk_id");
  159. if(assDetails!=null&&assDetails.size()>0){
  160. String tastTypeName= assDetails.get(0).title; // 项目任务类型
  161. eastarTbService.taskCount(pid,tbPid,fid,tastTypeName,projectState);
  162. }
  163. }
  164. }catch (Exception e){
  165. e.printStackTrace();
  166. }
  167. }
  168. // @Scheduled(cron = "0 30 1 1 1 ?")
  169. public void syncCust(){
  170. log.info("同步客户上一年等级");
  171. List<Map> list= ydService.queryAllFormData(YDParam.builder().formUuid("FORM-9261FABA687B4D1D917617F53B4A5DB7UN16").build());
  172. for(Map map:list){
  173. Map formData =UtilMap.getMap(map,"formData");
  174. log.info("任务数量同步:客户:{},等级:{} ", formData.get("textField_lqanqe6j"),formData.get("selectField_mcsoft5i"));
  175. Map updateMap=new HashMap();
  176. updateMap.put("selectField_mfkshib3",formData.get("selectField_mcsoft5i"));
  177. updateMap.put("numberField_mfkshib2",0);
  178. updateMap.put("selectField_mcsoft5i","E");
  179. String fid=UtilMap.getString(map,"formInstanceId");
  180. ydClient.operateData(YDParam.builder().formInstId(fid).updateFormDataJson(JSONObject.toJSONString(updateMap)).useLatestFormSchemaVersion(true).build(), YDConf.FORM_OPERATION.update);
  181. Map recod=new HashMap();
  182. recod.put("textField_lqanqe6j",formData.get("textField_lqanqe6j"));
  183. recod.put("textField_mfkrv5w6",formData.get("serialNumberField_lqanqe6i"));
  184. recod.put("selectField_mcsoft5i",formData.get("selectField_mcsoft5i"));
  185. recod.put("dateField_mfkrv5w8",UtilDateTime.getLocalDateTimeTimeStamp((LocalDate.of(LocalDate.now().getYear()-1,1,1).atStartOfDay())));
  186. recod.put("associationFormField_mfkrv5w7",Arrays.asList(UtilMap.map("formType, formUuid, instanceId, title, appType","receipt","FORM-9261FABA687B4D1D917617F53B4A5DB7UN16",fid,formData.get("textField_lqanqe6j"),"APP_GM7D1NW6XCD0ZJBPVH51")));
  187. ydClient.operateData(YDParam.builder().formDataJson(JSONObject.toJSONString(recod)).formUuid("FORM-51F53E33609C4E20A918D5C55E237E95Z2GS").build(), YDConf.FORM_OPERATION.create);
  188. }
  189. }
  190. /**
  191. * 项目总表表2未填写完成统计
  192. * 每日9点55
  193. */
  194. @Scheduled(cron = "0 55 9 * * ?")
  195. public void table2IncompleteStatistics() {
  196. log.info("定时更新项目台账填写情况表");
  197. /*
  198. 查询【表2】项目台账所有项目状态为Pending、Done、Closed的记录
  199. */
  200. JSONArray table2RecordsFilter = new JSONArray();
  201. String baseId = "G53mjyd80pEr5grBfpjmMX6586zbX04v";
  202. String sheetIdOrName = "pl6sz00";
  203. Map<String,Object> param = new HashMap<>();
  204. param.put("operatorId","aj1wcWqKLXITiPDwbMIjUbAiEiE"); //操作人(Jason)的unionId
  205. AITableParam aiTableParam = new AITableParam();
  206. aiTableParam.setMaxResults(100);
  207. JSONObject filter = new JSONObject();
  208. filter.put("combination","and");
  209. JSONArray conditions = new JSONArray();
  210. JSONObject condition = new JSONObject();
  211. condition.put("field","项目状态");
  212. condition.put("operator","notContain");
  213. condition.put("value",new String[]{"Pending","Done","Closed"});
  214. conditions.add(condition);
  215. filter.put("conditions",conditions);
  216. aiTableParam.setFilter(filter);
  217. AITableResult aiTableResult;
  218. boolean hasMore = true;
  219. int pageNo = 1;
  220. JSONArray records;
  221. log.info("查询【表2】项目台账所有项目状态为Pending、Done、Closed的记录");
  222. while(hasMore){
  223. aiTableResult = mdTableClient.queryMultiRecords(baseId,sheetIdOrName,param,aiTableParam);
  224. hasMore = aiTableResult.getHasMore();
  225. log.info("当前第"+pageNo+"页");
  226. log.info("记录数="+aiTableResult.getRecords().size());
  227. records = aiTableResult.getRecords();
  228. for(int i=0;i<records.size();i++){
  229. table2RecordsFilter.add(records.getJSONObject(i));
  230. }
  231. log.info("是否有更多数据:"+hasMore);
  232. pageNo++;
  233. aiTableParam.setNextToken(aiTableResult.getNextToken());
  234. }
  235. /*
  236. 统计计划开始时间和计划结束时间未填的
  237. */
  238. List<String> checkEmptyRecordList = new ArrayList<>();
  239. String[] checkEmptyFieldArr = new String[]{
  240. "计划:开始白样【交付进度】",
  241. "计划:结束白样【交付进度】",
  242. "计划:开始制版【交付进度】",
  243. "计划:结束制版【交付进度】",
  244. "计划:开始产前样【交付进度】",
  245. "计划:结束产前样【交付进度】",
  246. "计划:开始大货【交付进度】",
  247. "计划:结束大货【交付进度】",
  248. "计划:开始包装【交付进度】",
  249. "计划:结束包装【交付进度】",
  250. "计划:开始出货【交付进度】",
  251. "计划:结束出货时间【交付进度】"
  252. };
  253. JSONObject table2Record;
  254. JSONObject fields;
  255. String unionIdPM;
  256. String checkFailureStr;
  257. JSONArray pmJSONArray;
  258. // System.out.println("表2PM:");
  259. for(int i=0;i<table2RecordsFilter.size();i++){
  260. table2Record = table2RecordsFilter.getJSONObject(i);
  261. fields = table2Record.getJSONObject("fields");
  262. pmJSONArray = fields.getJSONArray("PM(Owner)【人事】");
  263. if(pmJSONArray == null){
  264. continue;
  265. }
  266. unionIdPM = pmJSONArray.getJSONObject(0).getString("unionId");
  267. for(String checkEmptyField : checkEmptyFieldArr){
  268. if(StringUtils.isEmpty(fields.getString(checkEmptyField))){
  269. checkFailureStr = unionIdPM + "_" + checkEmptyField+"未填写";
  270. // System.out.println(checkFailureStr);
  271. checkEmptyRecordList.add(checkFailureStr);
  272. }
  273. }
  274. }
  275. // System.out.println("checkEmptyRecordList:");
  276. // System.out.println(JSON.toJSONString(checkEmptyRecordList));
  277. /*
  278. 查询【参数表-人事】部门为销售部、客服部的记录
  279. */
  280. JSONArray empRecordsFilter = new JSONArray();
  281. sheetIdOrName = "rtOAveM";
  282. aiTableParam = new AITableParam();
  283. aiTableParam.setMaxResults(100);
  284. filter = new JSONObject();
  285. filter.put("combination","and");
  286. conditions = new JSONArray();
  287. condition = new JSONObject();
  288. condition.put("field","部门");
  289. condition.put("operator","contain");
  290. condition.put("value",new String[]{"销售部","客服部"});
  291. conditions.add(condition);
  292. filter.put("conditions",conditions);
  293. aiTableParam.setFilter(filter);
  294. log.info("查询【参数表-人事】部门为销售部、客服部的记录");
  295. aiTableResult = mdTableClient.queryMultiRecords(baseId,sheetIdOrName,param,aiTableParam);
  296. hasMore = aiTableResult.getHasMore();
  297. log.info("是否有更多数据:"+hasMore);
  298. log.info("销售和PM人员记录数="+aiTableResult.getRecords().size());
  299. records = aiTableResult.getRecords();
  300. for(int i=0;i<records.size();i++){
  301. empRecordsFilter.add(records.getJSONObject(i));
  302. }
  303. JSONObject empRecord;
  304. String deptId;
  305. String unionIdPMLeader;
  306. // System.out.println("人员列表:");
  307. Map<String,Object> unionIdMap = new HashMap<>();
  308. for(int i=0; i<empRecordsFilter.size(); i++){
  309. fields = empRecordsFilter.getJSONObject(i).getJSONObject("fields");
  310. unionIdPM = fields.getJSONArray("人员").getJSONObject(0).getString("unionId");
  311. deptId = fields.getJSONObject("部门").getString("id");
  312. if(fields.getJSONArray("销售组长") != null){
  313. unionIdPMLeader = fields.getJSONArray("销售组长").getJSONObject(0).getString("unionId");
  314. }else{
  315. unionIdPMLeader = "U2puyufsTtwvfTXmWQoG0wiEiE";
  316. }
  317. // System.out.println("unionIdPM="+unionIdPM+",deptId="+deptId+",unionIdPMLeader="+unionIdPMLeader);
  318. empRecord = new JSONObject();
  319. empRecord.put("deptId",deptId);
  320. empRecord.put("unionIdPMLeader",unionIdPMLeader);
  321. unionIdMap.put(unionIdPM,empRecord);
  322. }
  323. /*
  324. 新增项目台账填写情况表记录
  325. */
  326. JSONObject insertData = new JSONObject();
  327. JSONArray insertRecords = new JSONArray();
  328. JSONObject insertRecord;
  329. JSONArray pmLeaderJSONArray;
  330. JSONObject unionIdJSONObject;
  331. for(String str : checkEmptyRecordList){
  332. unionIdPM = str.split("_")[0];
  333. empRecord = (JSONObject) unionIdMap.get(unionIdPM);
  334. fields = new JSONObject();
  335. fields.put("日期", DateUtil.today());
  336. unionIdJSONObject = new JSONObject();
  337. unionIdJSONObject.put("unionId",unionIdPM);
  338. pmJSONArray = new JSONArray();
  339. pmJSONArray.add(unionIdJSONObject);
  340. fields.put("负责人",pmJSONArray);
  341. unionIdJSONObject = new JSONObject();
  342. unionIdJSONObject.put("unionId",empRecord.getString("unionIdPMLeader"));
  343. pmLeaderJSONArray = new JSONArray();
  344. pmLeaderJSONArray.add(unionIdJSONObject);
  345. fields.put("组长",pmLeaderJSONArray);
  346. fields.put("填写情况", str.split("_")[1]);
  347. insertRecord = new JSONObject();
  348. insertRecord.put("fields",fields);
  349. // log.info(JSON.toJSONString(insertRecord));
  350. insertRecords.add(insertRecord);
  351. }
  352. String result;
  353. JSONArray newInsertRecords;
  354. sheetIdOrName = "OTgxt4G";
  355. if(insertRecords.size() > 100){
  356. pageNo = 1;
  357. while(insertRecords.size() > 100){
  358. newInsertRecords = new JSONArray();
  359. records = new JSONArray();
  360. for (int i = 0; i < insertRecords.size(); i++) {
  361. if(i<100){
  362. newInsertRecords.add(insertRecords.getJSONObject(i));
  363. }else{
  364. records.add(insertRecords.getJSONObject(i));
  365. }
  366. }
  367. insertData.put("records",newInsertRecords);
  368. // log.info(JSON.toJSONString(insertData));
  369. result = mdTableClient.createMultiRecords(baseId,sheetIdOrName,param,insertData);
  370. log.info("新增项目台账填写情况表记录结果,第"+pageNo+"页:");
  371. log.info(result);
  372. insertRecords = records;
  373. pageNo++;
  374. }
  375. }
  376. if(insertRecords.size() > 0){
  377. insertData.put("records",insertRecords);
  378. // log.info(JSON.toJSONString(insertData));
  379. sheetIdOrName = "OTgxt4G";
  380. result = mdTableClient.createMultiRecords(baseId,sheetIdOrName,param,insertData);
  381. log.info("新增项目台账填写情况表记录结果,第"+pageNo+"页:");
  382. log.info(result);
  383. }
  384. }
  385. }