WeComStaffDataJob.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package com.tzld.piaoquan.offline.job;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.tzld.piaoquan.growth.common.common.enums.TimeEnum;
  5. import com.tzld.piaoquan.growth.common.component.HttpPoolClient;
  6. import com.tzld.piaoquan.growth.common.component.ProxyHttpPoolClient;
  7. import com.tzld.piaoquan.growth.common.dao.mapper.*;
  8. import com.tzld.piaoquan.growth.common.model.bo.XxlJobParam;
  9. import com.tzld.piaoquan.growth.common.model.po.*;
  10. import com.tzld.piaoquan.growth.common.service.WeComAccessTokenService;
  11. import com.tzld.piaoquan.growth.common.utils.DateUtil;
  12. import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
  13. import com.xxl.job.core.biz.model.ReturnT;
  14. import com.xxl.job.core.handler.annotation.XxlJob;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Component;
  19. import org.springframework.util.CollectionUtils;
  20. import java.io.IOException;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Objects;
  25. import java.util.stream.Collectors;
  26. import static com.tzld.piaoquan.growth.common.common.constant.WeComConstant.*;
  27. @Slf4j
  28. @Component
  29. public class WeComStaffDataJob {
  30. @Autowired
  31. private HttpPoolClient httpPoolClient;
  32. @Autowired
  33. private ProxyHttpPoolClient proxyHttpPoolClient;
  34. @Autowired
  35. private WeComAccessTokenService weComAccessTokenService;
  36. @Autowired
  37. private StaffMapper staffMapper;
  38. @Autowired
  39. private CorpMapper corpMapper;
  40. @Autowired
  41. private StaffStatisticsTotalMapper staffStatisticsTotalMapper;
  42. @Autowired
  43. private StaffGroupStatisticsTotalMapper staffGroupStatisticsTotalMapper;
  44. @Autowired
  45. private CorpStatisticsTotalMapper corpStatisticsTotalMapper;
  46. @XxlJob("syncStaffJob")
  47. public ReturnT<String> syncStaff(String param) {
  48. try {
  49. XxlJobParam xxlJobParam = new XxlJobParam();
  50. if (StringUtils.isNotEmpty(param)) {
  51. xxlJobParam = JSONObject.parseObject(param, XxlJobParam.class);
  52. }
  53. CorpExample corpExample = new CorpExample();
  54. if (xxlJobParam.getCorpId() != null) {
  55. corpExample.createCriteria().andIdEqualTo(xxlJobParam.getCorpId());
  56. }
  57. List<Corp> corps = corpMapper.selectByExample(corpExample);
  58. if (CollectionUtils.isEmpty(corps)) {
  59. return ReturnT.SUCCESS;
  60. }
  61. for (Corp corp : corps) {
  62. List<String> carrierIdList = getCarrierIdList(corp.getId());
  63. if (CollectionUtils.isEmpty(carrierIdList)) {
  64. continue;
  65. }
  66. for (String carrierId : carrierIdList) {
  67. JSONObject carrierInfo = getCarrierInfo(corp.getId(), carrierId);
  68. StaffExample example = new StaffExample();
  69. example.createCriteria().andCarrierIdEqualTo(carrierId).andCorpIdEqualTo(corp.getId());
  70. List<Staff> staffList = staffMapper.selectByExample(example);
  71. if (CollectionUtils.isEmpty(staffList)) {
  72. Staff staff = new Staff();
  73. staff.setCorpId(corp.getId());
  74. staff.setCarrierId(carrierId);
  75. if (Objects.nonNull(carrierInfo) && carrierInfo.containsKey("name")) {
  76. staff.setRemark(carrierInfo.getString("name"));
  77. } else {
  78. staff.setRemark("");
  79. }
  80. staffMapper.insert(staff);
  81. } else {
  82. Staff staff = staffList.get(0);
  83. if (Objects.nonNull(carrierInfo) && carrierInfo.containsKey("name")) {
  84. staff.setRemark(carrierInfo.getString("name"));
  85. staffMapper.updateByPrimaryKeySelective(staff);
  86. }
  87. }
  88. }
  89. }
  90. } catch (Exception e) {
  91. LarkRobotUtil.sendMessage("更新员工失败");
  92. log.error("insertStaff error", e);
  93. }
  94. return ReturnT.SUCCESS;
  95. }
  96. private List<String> getCarrierIdList(Long corpId) throws IOException {
  97. String weComAccessToken = weComAccessTokenService.getWeComAccessToken(corpId);
  98. String url = String.format(GET_WE_COM_FOLLOW_USER_LIST + "?access_token=%s", weComAccessToken);
  99. String res;
  100. if (corpId == 1L) {
  101. res = httpPoolClient.get(url);
  102. } else {
  103. res = proxyHttpPoolClient.get(url);
  104. }
  105. log.info("getCarrierIdList corp = {}, res={}", corpId, res);
  106. JSONObject jsonObject = JSONObject.parseObject(res);
  107. Integer errcode = jsonObject.getInteger("errcode");
  108. if (errcode == 0) {
  109. return jsonObject.getJSONArray("follow_user").stream().map(String::valueOf).collect(Collectors.toList());
  110. }
  111. return null;
  112. }
  113. private JSONObject getCarrierInfo(Long corpId, String userId) throws IOException {
  114. String weComAccessToken = weComAccessTokenService.getWeComAccessToken(corpId);
  115. String url = String.format(GET_WE_COM_FOLLOW_USER_DETAIL + "?access_token=%s", weComAccessToken);
  116. url = String.format(url + "&userid=%s", userId);
  117. String res;
  118. if (corpId == 1L) {
  119. res = httpPoolClient.get(url);
  120. } else {
  121. res = proxyHttpPoolClient.get(url);
  122. }
  123. log.info("getCarrierInfo corp = {} , userId = {}, res={}", corpId, userId, res);
  124. JSONObject jsonObject = JSONObject.parseObject(res);
  125. Integer errcode = jsonObject.getInteger("errcode");
  126. if (errcode == 0) {
  127. return jsonObject;
  128. }
  129. return null;
  130. }
  131. @XxlJob("statisticsTotalJob")
  132. public ReturnT<String> statisticsTotal(String param) throws IOException {
  133. String date;
  134. if (StringUtils.isNotEmpty(param)) {
  135. date = param;
  136. } else {
  137. date = DateUtil.getBeforeDayDateString1();
  138. }
  139. long startTime = DateUtil.dateStrToTimestamp(date, "yyyy-MM-dd");
  140. long endTime = startTime + TimeEnum.DAY.getTime() - 1;
  141. StaffExample staffExample = new StaffExample();
  142. staffExample.createCriteria().andIsDeleteEqualTo(0);
  143. List<Staff> staffs = staffMapper.selectByExample(staffExample);
  144. for (Staff staff : staffs) {
  145. statisticsStaffTotal(staff, startTime, endTime, date);
  146. statisticsStaffGroupTotal(staff, startTime, date);
  147. }
  148. StaffStatisticsTotalExample staffStatisticsTotalExample = new StaffStatisticsTotalExample();
  149. staffStatisticsTotalExample.createCriteria().andDateEqualTo(date);
  150. List<StaffStatisticsTotal> staffStatisticsTotals = staffStatisticsTotalMapper.selectByExample(staffStatisticsTotalExample);
  151. if (!CollectionUtils.isEmpty(staffStatisticsTotals)) {
  152. // 2. 分组并多字段求和(不使用构造方法)
  153. List<CorpStatisticsTotal> results = processStaffStatistics(staffStatisticsTotals);
  154. for (CorpStatisticsTotal corpStatisticsTotal : results) {
  155. corpStatisticsTotal.setDate(date);
  156. try {
  157. corpStatisticsTotalMapper.insertSelective(corpStatisticsTotal);
  158. } catch (Exception e) {
  159. log.error("insert corpStatisticsTotal error", e);
  160. }
  161. }
  162. }
  163. return ReturnT.SUCCESS;
  164. }
  165. public List<CorpStatisticsTotal> processStaffStatistics(List<StaffStatisticsTotal> staffStatisticsTotals) {
  166. // 使用 toMap 收集器高效分组和聚合
  167. Map<Long, CorpStatisticsTotal> resultMap = staffStatisticsTotals.stream()
  168. .collect(Collectors.toMap(
  169. StaffStatisticsTotal::getCorpId,
  170. this::convertToCorpStats, // 方法引用转换
  171. this::mergeCorpStats // 方法引用合并
  172. ));
  173. return new ArrayList<>(resultMap.values());
  174. }
  175. private CorpStatisticsTotal mergeCorpStats(CorpStatisticsTotal existing, CorpStatisticsTotal newcomer) {
  176. existing.setChatCnt(existing.getChatCnt() + newcomer.getChatCnt());
  177. existing.setMessageCnt(existing.getMessageCnt() + newcomer.getMessageCnt());
  178. existing.setNegativeFeedbackCnt(existing.getNegativeFeedbackCnt() + newcomer.getNegativeFeedbackCnt());
  179. existing.setNewApplyCnt(existing.getNewApplyCnt() + newcomer.getNewApplyCnt());
  180. existing.setNewContactCnt(existing.getNewContactCnt() + newcomer.getNewContactCnt());
  181. return existing;
  182. }
  183. // 转换方法:将 Staff 对象转换为 Corp 对象
  184. private CorpStatisticsTotal convertToCorpStats(StaffStatisticsTotal staff) {
  185. CorpStatisticsTotal corp = new CorpStatisticsTotal();
  186. corp.setCorpId(staff.getCorpId());
  187. corp.setChatCnt(staff.getChatCnt());
  188. corp.setMessageCnt(staff.getMessageCnt());
  189. corp.setNegativeFeedbackCnt(staff.getNegativeFeedbackCnt());
  190. corp.setNewApplyCnt(staff.getNewApplyCnt());
  191. corp.setNewContactCnt(staff.getNewContactCnt());
  192. return corp;
  193. }
  194. private void statisticsStaffTotal(Staff staff, long startTime, long endTime, String date) throws IOException {
  195. Long corpId = staff.getCorpId();
  196. StaffStatisticsTotalExample example = new StaffStatisticsTotalExample();
  197. example.createCriteria().andCorpIdEqualTo(corpId).andStaffIdEqualTo(staff.getId()).andDateEqualTo(date);
  198. long l = staffStatisticsTotalMapper.countByExample(example);
  199. if (l > 0) {
  200. return;
  201. }
  202. String accessToken = weComAccessTokenService.getWeComAccessToken(corpId);
  203. String url = POST_WE_COM_USER_BEHAVIOR_DATA
  204. + "?access_token=" + accessToken;
  205. JSONObject params = new JSONObject();
  206. params.put("start_time", startTime);
  207. params.put("end_time", endTime);
  208. JSONArray userIds = new JSONArray();
  209. userIds.add(staff.getCarrierId());
  210. params.put("userid", userIds);
  211. String res;
  212. if (staff.getCorpId() == 1L) {
  213. res = httpPoolClient.post(url, params.toJSONString());
  214. } else {
  215. res = proxyHttpPoolClient.post(url, params.toJSONString());
  216. }
  217. if (StringUtils.isNotEmpty(res)) {
  218. JSONObject jsonObject = JSONObject.parseObject(res);
  219. Integer errcode = jsonObject.getInteger("errcode");
  220. if (errcode == 0) {
  221. JSONArray jsonArray = jsonObject.getJSONArray("behavior_data");
  222. if (!jsonArray.isEmpty()) {
  223. JSONObject data = jsonArray.getJSONObject(0);
  224. StaffStatisticsTotal statisticsTotal = new StaffStatisticsTotal();
  225. statisticsTotal.setStatTime(data.getLong("stat_time"));
  226. statisticsTotal.setChatCnt(data.getInteger("chat_cnt"));
  227. statisticsTotal.setMessageCnt(data.getInteger("message_cnt"));
  228. statisticsTotal.setNegativeFeedbackCnt(data.getInteger("negative_feedback_cnt"));
  229. statisticsTotal.setNewApplyCnt(data.getInteger("new_apply_cnt"));
  230. statisticsTotal.setNewContactCnt(data.getInteger("new_contact_cnt"));
  231. statisticsTotal.setDate(date);
  232. statisticsTotal.setCorpId(corpId);
  233. statisticsTotal.setStaffId(staff.getId());
  234. statisticsTotal.setUserId(staff.getCarrierId());
  235. staffStatisticsTotalMapper.insertSelective(statisticsTotal);
  236. }
  237. }
  238. }
  239. }
  240. private void statisticsStaffGroupTotal(Staff staff, long startTime, String date) throws IOException {
  241. Long corpId = staff.getCorpId();
  242. StaffGroupStatisticsTotalExample example = new StaffGroupStatisticsTotalExample();
  243. example.createCriteria().andCorpIdEqualTo(corpId).andStaffIdEqualTo(staff.getId()).andDateEqualTo(date);
  244. long l = staffGroupStatisticsTotalMapper.countByExample(example);
  245. if (l > 0) {
  246. return;
  247. }
  248. String accessToken = weComAccessTokenService.getWeComAccessToken(corpId);
  249. String url = POST_WE_COM_USER_GROUP_CHAT_STATISTIC
  250. + "?access_token=" + accessToken;
  251. JSONObject params = new JSONObject();
  252. params.put("day_begin_time", startTime);
  253. JSONObject ownerFilter = new JSONObject();
  254. JSONArray userIds = new JSONArray();
  255. userIds.add(staff.getCarrierId());
  256. ownerFilter.put("userid_list", userIds);
  257. params.put("owner_filter", ownerFilter);
  258. System.out.println(JSONObject.toJSONString(params));
  259. String res;
  260. if (staff.getCorpId() == 1L) {
  261. res = httpPoolClient.post(url, params.toJSONString());
  262. } else {
  263. res = proxyHttpPoolClient.post(url, params.toJSONString());
  264. }
  265. if (StringUtils.isNotEmpty(res)) {
  266. JSONObject jsonObject = JSONObject.parseObject(res);
  267. Integer errcode = jsonObject.getInteger("errcode");
  268. if (errcode == 0) {
  269. JSONArray jsonArray = jsonObject.getJSONArray("items");
  270. if (!jsonArray.isEmpty()) {
  271. StaffGroupStatisticsTotal statisticsTotal = new StaffGroupStatisticsTotal();
  272. JSONObject data = jsonArray.getJSONObject(0).getJSONObject("data");
  273. statisticsTotal.setStatTime(jsonArray.getJSONObject(0).getLong("stat_time"));
  274. statisticsTotal.setNewChatCnt(data.getInteger("new_chat_cnt"));
  275. statisticsTotal.setChatTotal(data.getInteger("chat_total"));
  276. statisticsTotal.setChatHasMsg(data.getInteger("chat_has_msg"));
  277. statisticsTotal.setNewMemberCnt(data.getInteger("new_member_cnt"));
  278. statisticsTotal.setMemberTotal(data.getInteger("member_total"));
  279. statisticsTotal.setMemberHasMsg(data.getInteger("member_has_msg"));
  280. statisticsTotal.setMsgTotal(data.getInteger("msg_total"));
  281. statisticsTotal.setMigrateTraineeChatCnt(data.getInteger("migrate_trainee_chat_cnt"));
  282. statisticsTotal.setDate(date);
  283. statisticsTotal.setCorpId(corpId);
  284. statisticsTotal.setStaffId(staff.getId());
  285. statisticsTotal.setUserId(staff.getCarrierId());
  286. staffGroupStatisticsTotalMapper.insertSelective(statisticsTotal);
  287. }
  288. }
  289. }
  290. }
  291. }