WeGroupFissionServiceImpl.java 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. package com.linkwechat.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.baomidou.mybatisplus.core.metadata.IPage;
  6. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  7. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8. import com.google.gson.JsonArray;
  9. import com.google.gson.JsonObject;
  10. import com.google.gson.JsonParser;
  11. import com.linkwechat.common.core.domain.AjaxResult;
  12. import com.linkwechat.common.core.domain.entity.SysUser;
  13. import com.linkwechat.common.core.domain.model.LoginUser;
  14. import com.linkwechat.common.core.page.TableDataInfo;
  15. import com.linkwechat.common.enums.WeErrorCodeEnum;
  16. import com.linkwechat.common.exception.CustomException;
  17. import com.linkwechat.common.utils.WxMiniProgramSchemeUtil;
  18. import com.linkwechat.domain.groupchat.vo.LinkGroupChatListVo;
  19. import com.linkwechat.domain.weGroupFission.bdsh.LocalMerchantInfo;
  20. import com.linkwechat.domain.weGroupFission.bdsh.LocalRightsInfo;
  21. import com.linkwechat.domain.weGroupFission.bdsh.LotteryActivity;
  22. import com.linkwechat.domain.weGroupFission.dto.DistDto;
  23. import com.linkwechat.domain.weGroupFission.dto.WeGroupFissionDetailDto;
  24. import com.linkwechat.domain.weGroupFission.dto.WeGroupFissionDto;
  25. import com.linkwechat.domain.weGroupFission.entity.*;
  26. import com.linkwechat.domain.weGroupFission.vo.*;
  27. import com.linkwechat.domain.wecom.query.WeBaseQuery;
  28. import com.linkwechat.domain.wecom.query.customer.WeCustomerQuery;
  29. import com.linkwechat.domain.wecom.query.customer.groupchat.WeGroupChatDetailQuery;
  30. import com.linkwechat.domain.wecom.query.customer.groupchat.WeGroupChatListQuery;
  31. import com.linkwechat.domain.wecom.vo.customer.WeCustomerDetailVo;
  32. import com.linkwechat.domain.wecom.vo.customer.WeFollowUserListVo;
  33. import com.linkwechat.domain.wecom.vo.customer.groupchat.WeGroupChatDetailVo;
  34. import com.linkwechat.domain.wecom.vo.customer.groupchat.WeGroupChatListVo;
  35. import com.linkwechat.fegin.QwCustomerClient;
  36. import com.linkwechat.framework.service.TokenService;
  37. import com.linkwechat.mapper.WeGroupFissionMapper;
  38. import com.linkwechat.service.*;
  39. import me.chanjar.weixin.common.error.WxErrorException;
  40. import me.chanjar.weixin.cp.api.WxCpExternalContactService;
  41. import me.chanjar.weixin.cp.api.WxCpService;
  42. import me.chanjar.weixin.cp.api.WxCpUserService;
  43. import me.chanjar.weixin.cp.bean.WxCpUser;
  44. import me.chanjar.weixin.cp.bean.external.WxCpContactWayInfo;
  45. import me.chanjar.weixin.cp.bean.external.WxCpContactWayResult;
  46. import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatInfo;
  47. import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatList;
  48. import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
  49. import org.apache.commons.lang3.StringUtils;
  50. import org.springframework.beans.BeanUtils;
  51. import org.springframework.beans.factory.annotation.Autowired;
  52. import org.springframework.stereotype.Service;
  53. import javax.annotation.Resource;
  54. import java.math.BigDecimal;
  55. import java.util.*;
  56. import java.util.stream.Collectors;
  57. /**
  58. * @Description: 群裂变活动表
  59. * @Author: jeecg-boot
  60. * @Date: 2026-01-28
  61. * @Version: V1.0
  62. */
  63. @Service
  64. public class WeGroupFissionServiceImpl extends ServiceImpl<WeGroupFissionMapper, WeGroupFission> implements IWeGroupFissionService {
  65. @Autowired
  66. private IWeGroupFissionExtraRecordService weGroupFissionExtraRecordService;
  67. @Autowired
  68. private IWeGroupFissionStepRecordService weGroupFissionStepRecordService;
  69. @Resource
  70. private WxMiniProgramSchemeUtil wxMiniProgramSchemeUtil;
  71. @Autowired
  72. private LocalMerchantInfoService localMerchantInfoService;
  73. @Resource
  74. private TokenService tokenService;
  75. @Autowired
  76. private ILotteryActivityService lotteryActivityService;
  77. @Autowired
  78. private LocalRightsInfoService localRightsInfoService;
  79. @Autowired
  80. private WxCpService wxCpService;
  81. @Autowired
  82. private IWeExternalChatService weExternalChatService;
  83. @Autowired
  84. private IWeGroupFissionQrCodeRecordService weGroupFissionQrCodeRecordService;
  85. /**
  86. * @version
  87. * @author: hxl
  88. * @Date: 2026/1/28 10:59
  89. * @Description: 群裂变列表+分页
  90. */
  91. @Override
  92. public TableDataInfo<?> getPageList(WeGroupFissionVo weGroupFissionVo) {
  93. TableDataInfo rspData = new TableDataInfo();
  94. if(weGroupFissionVo.getPageNum() == null){
  95. rspData.setCode(500);
  96. rspData.setMsg("当前页码不能为空");
  97. return rspData;
  98. }
  99. if(weGroupFissionVo.getPageSize() == null){
  100. rspData.setCode(500);
  101. rspData.setMsg("页数不能为空");
  102. return rspData;
  103. }
  104. Page<WeGroupFissionDto> page = new Page<WeGroupFissionDto>(weGroupFissionVo.getPageNum(), weGroupFissionVo.getPageSize());
  105. IPage<WeGroupFissionDto> pageList = this.getBaseMapper().getPageList(page, weGroupFissionVo);
  106. List<WeGroupFissionDto> records = pageList.getRecords();
  107. if(records==null || records.isEmpty()){
  108. records =new ArrayList<>();
  109. }
  110. rspData.setCode(200);
  111. rspData.setMsg("查询成功");
  112. rspData.setRows(records);
  113. rspData.setPageNum(weGroupFissionVo.getPageNum());
  114. rspData.setPageSize(weGroupFissionVo.getPageSize());
  115. rspData.setTotal(pageList.getTotal());
  116. return rspData;
  117. }
  118. /**
  119. * @version
  120. * @author: hxl
  121. * @Date: 2026/1/28 11:30
  122. * @Description: 群裂变添加或者修改
  123. */
  124. @Override
  125. public void addOrUpdate(WeGroupFissionAddVo weGroupFissionAddVo) {
  126. try{
  127. //获取平台用户登录id
  128. LoginUser loginUser = tokenService.getLoginUser();
  129. //验证数据正确性
  130. checkData(weGroupFissionAddVo);
  131. //判断是否有id 新增
  132. String id ="";
  133. if (StringUtils.isNotBlank(weGroupFissionAddVo.getId())) {
  134. WeGroupFission weGroupFissionUpdate = this.getById(weGroupFissionAddVo.getId());
  135. if(weGroupFissionUpdate==null){
  136. throw new CustomException("数据不存在");
  137. }
  138. id = weGroupFissionUpdate.getId();
  139. BeanUtil.copyProperties(weGroupFissionAddVo, weGroupFissionUpdate);
  140. //修改创建时间、创建人
  141. weGroupFissionUpdate.setUpdateTime(new Date());
  142. weGroupFissionUpdate.setUpdateUserId(String.valueOf(loginUser.getUserId()));
  143. this.updateById(weGroupFissionUpdate);
  144. }else{
  145. WeGroupFission weGroupFissionAdd =new WeGroupFission();
  146. BeanUtil.copyProperties(weGroupFissionAddVo, weGroupFissionAdd);
  147. //添加创建时间、创建人
  148. weGroupFissionAdd.setCreateTime(new Date());
  149. weGroupFissionAdd.setCreateUserId(String.valueOf(loginUser.getUserId()));
  150. //1.插入群打卡表
  151. this.save(weGroupFissionAdd);
  152. id = weGroupFissionAdd.getId();
  153. }
  154. //2.插入阶段记录表 先通过id删除再添加
  155. List<WeGroupFissionStepVo> weGroupFissionStepList = weGroupFissionAddVo.getWeGroupFissionStepList();
  156. if(weGroupFissionStepList!=null && !weGroupFissionStepList.isEmpty()) {
  157. weGroupFissionStepRecordService.deleteByGroupFissionId(id);
  158. List<WeGroupFissionStepRecord> list =new ArrayList<WeGroupFissionStepRecord>();
  159. String weGroupFissionId = id;
  160. for (WeGroupFissionStepVo weGroupFissionStepVo : weGroupFissionStepList) {
  161. WeGroupFissionStepRecord add = new WeGroupFissionStepRecord();
  162. add.setGroupFissionId(weGroupFissionId);
  163. add.setInvitationCount(weGroupFissionStepVo.getInvitationCount());
  164. add.setSortNum(weGroupFissionStepVo.getSortNum());
  165. add.setRewardAmount(weGroupFissionStepVo.getRewardAmount());
  166. add.setCreateTime(new Date());
  167. list.add(add);
  168. }
  169. weGroupFissionStepRecordService.saveBatch(list);
  170. }
  171. //2.插入额外奖励记录表 先通过id删除再添加
  172. List<WeGroupFissionExtraVo> weGroupFissionExtraList = weGroupFissionAddVo.getWeGroupFissionExtraList();
  173. if(weGroupFissionExtraList!=null && !weGroupFissionExtraList.isEmpty()) {
  174. weGroupFissionExtraRecordService.deleteByGroupFissionId(id);
  175. List<WeGroupFissionExtraRecord> list =new ArrayList<WeGroupFissionExtraRecord>();
  176. String weGroupFissionId = id;
  177. for (WeGroupFissionExtraVo weGroupFissionExtraVo : weGroupFissionExtraList) {
  178. WeGroupFissionExtraRecord add = new WeGroupFissionExtraRecord();
  179. add.setGroupFissionId(weGroupFissionId);
  180. add.setSortNum(weGroupFissionExtraVo.getSortNum());
  181. add.setRewardType(weGroupFissionExtraVo.getRewardType());
  182. add.setRewardAmount(weGroupFissionExtraVo.getRewardAmount());
  183. add.setRightInfoId(weGroupFissionExtraVo.getRightInfoId());
  184. add.setLotteryActivityId(weGroupFissionExtraVo.getLotteryActivityId());
  185. add.setCreateTime(new Date());
  186. list.add(add);
  187. }
  188. weGroupFissionExtraRecordService.saveBatch(list);
  189. }
  190. }catch (Exception e){
  191. throw new CustomException(e.getMessage());
  192. }
  193. }
  194. /**
  195. * @version
  196. * @author: hxl
  197. * @Date: 2026/1/28 14:34
  198. * @Description: 验证数据准确性
  199. */
  200. public void checkData(WeGroupFissionAddVo weGroupFissionAddVo){
  201. //1.触发条件判断 注:≥1,≤200(邀请新客户进群人数)
  202. if(weGroupFissionAddVo.getInvitationCount() <1 || weGroupFissionAddVo.getInvitationCount()>200){
  203. throw new CustomException("邀请新客户进群人数必须>=1且<=200");
  204. }
  205. //2.验证阶梯集合对象
  206. if (weGroupFissionAddVo.getWeGroupFissionStepList() == null || weGroupFissionAddVo.getWeGroupFissionStepList().isEmpty()) {
  207. throw new CustomException("阶梯列表不能为空!");
  208. }else{
  209. //验证每行数据不能为空
  210. validateStepList(weGroupFissionAddVo.getWeGroupFissionStepList());
  211. }
  212. //3.验证额外奖励集合对象
  213. if(weGroupFissionAddVo.getWeGroupFissionExtraList() == null || weGroupFissionAddVo.getWeGroupFissionExtraList().isEmpty()){
  214. throw new CustomException("额外奖励列表不能为空!");
  215. }else{
  216. //验证每行数据不能为空
  217. validateExtraList(weGroupFissionAddVo.getWeGroupFissionExtraList(),weGroupFissionAddVo.getWeGroupFissionStepList().size());
  218. }
  219. }
  220. /**
  221. * @version
  222. * @author: hxl
  223. * @Date: 2026/1/28 14:23
  224. * @Description: 验证额外奖励数据
  225. */
  226. private void validateExtraList(List<WeGroupFissionExtraVo> weGroupFissionExtraList, int size) {
  227. Set<Integer> sortNumSet = new HashSet<>();
  228. for (int i = 0; i < weGroupFissionExtraList.size(); i++) {
  229. WeGroupFissionExtraVo weGroupFissionExtraVo = weGroupFissionExtraList.get(i);
  230. String indexTip = "第" + (i + 1) + "条额外奖励记录:";
  231. if (weGroupFissionExtraVo == null) {
  232. throw new CustomException(indexTip + "额外奖励记录对象不能为空");
  233. }
  234. if (weGroupFissionExtraVo.getSortNum() == null) {
  235. throw new CustomException(indexTip + "阶梯序号不能为空");
  236. }
  237. if (weGroupFissionExtraVo.getSortNum()>size) {
  238. throw new CustomException(indexTip + "阶梯序号不能大于阶梯的数量");
  239. }
  240. if (sortNumSet.contains(weGroupFissionExtraVo.getSortNum())) {
  241. throw new CustomException("阶梯序号[" + weGroupFissionExtraVo.getSortNum() + "]重复");
  242. }
  243. sortNumSet.add(weGroupFissionExtraVo.getSortNum());
  244. if (weGroupFissionExtraVo.getRewardType() == null || weGroupFissionExtraVo.getRewardType().trim().isEmpty()) {
  245. throw new CustomException(indexTip + "奖励类型不能为空");
  246. }
  247. String rewardType = weGroupFissionExtraVo.getRewardType().trim();
  248. if (!"1".equals(rewardType) && !"2".equals(rewardType) && !"3".equals(rewardType)) {
  249. throw new CustomException(indexTip + "奖励类型不正确");
  250. }
  251. if ("1".equals(rewardType)) {
  252. if (weGroupFissionExtraVo.getRewardAmount() == null) {
  253. throw new CustomException(indexTip + "奖励金额不能为空");
  254. }
  255. if (weGroupFissionExtraVo.getRewardAmount().compareTo(BigDecimal.ZERO) <= 0) {
  256. throw new CustomException(indexTip + "奖励金额数值必须大于0");
  257. }
  258. }else if ("2".equals(rewardType)) {
  259. if (StringUtils.isBlank(weGroupFissionExtraVo.getRightInfoId())) {
  260. throw new CustomException(indexTip + "权益券id不能为空");
  261. }
  262. }else if ("3".equals(rewardType)) {
  263. if (StringUtils.isBlank(weGroupFissionExtraVo.getLotteryActivityId())) {
  264. throw new CustomException(indexTip + "大转盘或者九宫格活动id不能为空");
  265. }
  266. }
  267. }
  268. }
  269. /**
  270. * @version
  271. * @author: hxl
  272. * @Date: 2026/1/28 14:13
  273. * @Description: 验证数据
  274. */
  275. public static void validateStepList(List<WeGroupFissionStepVo> stepVoList) {
  276. // 验证数据
  277. WeGroupFissionStepVo prevStep = null;
  278. for (int i = 0; i < stepVoList.size(); i++) {
  279. WeGroupFissionStepVo currentStep = stepVoList.get(i);
  280. if (currentStep.getSortNum() == null) {
  281. throw new IllegalArgumentException("第" + (i + 1) + "条阶梯数据的序号不能为空");
  282. }
  283. if (currentStep.getInvitationCount() == null) {
  284. throw new IllegalArgumentException("第" + (i + 1) + "条阶梯数据的邀请人数不能为空");
  285. }
  286. if (currentStep.getRewardAmount() == null) {
  287. throw new IllegalArgumentException("第" + (i + 1) + "条阶梯数据的奖励金额不能为空");
  288. }
  289. if (i > 0 && prevStep != null) {
  290. if (currentStep.getInvitationCount() <= prevStep.getInvitationCount()) {
  291. throw new IllegalArgumentException(
  292. "第" + (i + 1) + "条阶梯数据的邀请人数(" + currentStep.getInvitationCount() + ")" +
  293. "必须大于第" + i + "条的邀请人数(" + prevStep.getInvitationCount() + ")"
  294. );
  295. }
  296. }
  297. prevStep = currentStep;
  298. }
  299. }
  300. /**
  301. * @version
  302. * @author: hxl
  303. * @Date: 2026/1/28 11:30
  304. * @Description: 通过id查询群裂变信息
  305. * @param type 1.后台结构 2.app结构
  306. */
  307. @Override
  308. public WeGroupFissionDetailDto queryDetailById(String id, String type) {
  309. WeGroupFission weGroupFission = this.getById(id);
  310. if(weGroupFission==null){
  311. throw new CustomException("群裂变活动不存在");
  312. }
  313. //1.基础数据赋值
  314. WeGroupFissionDetailDto dto =new WeGroupFissionDetailDto();
  315. BeanUtils.copyProperties(weGroupFission, dto);
  316. //2.关联阶梯奖励赋值
  317. List<WeGroupFissionStepRecord> stepList = weGroupFissionStepRecordService.findListByGroupCheckInId(id);
  318. if(stepList!=null && !stepList.isEmpty()) {
  319. if("1".equals(type)){
  320. List<WeGroupFissionStepVo> weGroupFissionStepList = new ArrayList<WeGroupFissionStepVo>();
  321. stepList.forEach(reward -> {
  322. WeGroupFissionStepVo weGroupFissionStepVo = new WeGroupFissionStepVo();
  323. BeanUtils.copyProperties(reward, weGroupFissionStepVo);
  324. weGroupFissionStepList.add(weGroupFissionStepVo);
  325. });
  326. dto.setWeGroupFissionStepList(weGroupFissionStepList);
  327. }
  328. }
  329. //3.关联额外奖励赋值
  330. List<WeGroupFissionExtraRecord> extraList = weGroupFissionExtraRecordService.findListByGroupFissionId(id);
  331. HashMap<String, WeGroupFissionExtraRecord> extraMap = new HashMap<>();
  332. if(extraList!=null && !extraList.isEmpty()) {
  333. List<WeGroupFissionExtraVo> weGroupFissionExtraList = new ArrayList<WeGroupFissionExtraVo>();
  334. extraList.forEach(reward -> {
  335. WeGroupFissionExtraVo weGroupFissionExtraVo = new WeGroupFissionExtraVo();
  336. BeanUtils.copyProperties(reward, weGroupFissionExtraVo);
  337. if(StringUtils.isNotBlank(reward.getRightInfoId())){
  338. LocalRightsInfo localRightsInfo = localRightsInfoService.getById(reward.getRightInfoId());
  339. weGroupFissionExtraVo.setRightInfoName(localRightsInfo!=null?localRightsInfo.getRightsName():null);
  340. }
  341. if(StringUtils.isNotBlank(reward.getLotteryActivityId())){
  342. LotteryActivity lotteryActivity = lotteryActivityService.getById(reward.getLotteryActivityId());
  343. weGroupFissionExtraVo.setLotteryActivityName(lotteryActivity!=null?lotteryActivity.getActivityName():null);
  344. }
  345. extraMap.put(reward.getSortNum()+"", reward);
  346. weGroupFissionExtraList.add(weGroupFissionExtraVo);
  347. });
  348. if("1".equals(type)){
  349. dto.setWeGroupFissionExtraList(weGroupFissionExtraList);
  350. }else if("2".equals(type)){
  351. //APP对象
  352. if(stepList!=null && !stepList.isEmpty()) {
  353. List<WeGroupFissionStepAppVo> weGroupFissionStepAppList = new ArrayList<WeGroupFissionStepAppVo>();
  354. stepList.forEach(reward -> {
  355. WeGroupFissionStepAppVo weGroupFissionStepVo = new WeGroupFissionStepAppVo();
  356. BeanUtils.copyProperties(reward, weGroupFissionStepVo);
  357. WeGroupFissionExtraRecord weGroupFissionExtraRecord = extraMap.get(reward.getSortNum() + "");
  358. if(weGroupFissionExtraRecord!=null){
  359. weGroupFissionStepVo.setExtraRewardAmount(weGroupFissionExtraRecord.getRewardAmount());
  360. weGroupFissionStepVo.setRewardType(weGroupFissionExtraRecord.getRewardType());
  361. }
  362. weGroupFissionStepAppList.add(weGroupFissionStepVo);
  363. });
  364. dto.setWeGroupFissionStepAppList(weGroupFissionStepAppList);
  365. }
  366. }
  367. }
  368. //4.查询商户名称
  369. LocalMerchantInfo merchantInfo = localMerchantInfoService.getById(weGroupFission.getMerchantId());
  370. dto.setMerchantName(merchantInfo!=null?merchantInfo.getStoreName():null);
  371. return dto;
  372. }
  373. /**
  374. * @version
  375. * @author: hxl
  376. * @Date: 2026/1/28 11:32
  377. * @Description: 通过id删除数据
  378. */
  379. @Override
  380. public void deleteByWeGroupFissionId(String id) {
  381. WeGroupFission weGroupFission = getStatusDetailsById(id);
  382. if("进行中".equals(weGroupFission.getActivityStatus())
  383. || "已结束".equals(weGroupFission.getActivityStatus())){
  384. throw new CustomException("活动进行中或已结束,不能删除");
  385. }else{
  386. this.removeById(id);
  387. //删除阶梯表
  388. weGroupFissionStepRecordService.deleteByGroupFissionId(id);
  389. //刪除关联额外奖励务表
  390. weGroupFissionExtraRecordService.deleteByGroupFissionId(id);
  391. }
  392. }
  393. /**
  394. * @version
  395. * @author: hxl
  396. * @Date: 2026/1/28 15:05
  397. * @Description: 生成小程序的短连接
  398. */
  399. @Override
  400. public String getWechatGroupFissionUrl(CreateWechatGroupFissionUrlVo createWechatGroupFissionUrlVo) {
  401. String queryParam = "groupFissionId="+createWechatGroupFissionUrlVo.getGroupFissionId()+"&source=poster";
  402. //添加分享人id
  403. if(StringUtils.isNotBlank(createWechatGroupFissionUrlVo.getShareUserId())){
  404. queryParam = queryParam + "&shareUserId="+createWechatGroupFissionUrlVo.getShareUserId();
  405. }
  406. String url ="";
  407. try{
  408. url = wxMiniProgramSchemeUtil.generateScheme(createWechatGroupFissionUrlVo.getUrl(), queryParam, 0,createWechatGroupFissionUrlVo.getVersion());
  409. }catch (Exception e){
  410. throw new CustomException("生成群打卡的短链失败");
  411. }
  412. return url;
  413. }
  414. /**
  415. * @version
  416. * @author: hxl
  417. * @Date: 2026/1/28 16:42
  418. * @Description: 获取企业微信群列表 优化
  419. */
  420. @Override
  421. public List<DistDto> getWecomGroupList() {
  422. List<DistDto> list = new ArrayList<>();
  423. List<WeExternalChat> chatList = weExternalChatService.list(new QueryWrapper<WeExternalChat>().eq("dismiss_flag", "0").orderByDesc("create_time"));
  424. if(chatList!=null && !chatList.isEmpty()){
  425. for (WeExternalChat weExternalChat : chatList) {
  426. DistDto dto = new DistDto();
  427. dto.setVal(weExternalChat.getChatId());
  428. dto.setName(weExternalChat.getChatName());
  429. list.add(dto);
  430. }
  431. }
  432. /* //获取企业微信群列表
  433. WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
  434. try{
  435. // 调用获取客户群列表接口
  436. WxCpUserExternalGroupChatList wxCpUserExternalGroupChatList = externalContactService.listGroupChat(0, 100, 0, null, null);
  437. if(wxCpUserExternalGroupChatList!=null && wxCpUserExternalGroupChatList.getGroupChatList()!=null && !wxCpUserExternalGroupChatList.getGroupChatList().isEmpty()){
  438. List<WxCpUserExternalGroupChatList.ChatStatus> groupChatList = wxCpUserExternalGroupChatList.getGroupChatList();
  439. for (WxCpUserExternalGroupChatList.ChatStatus chat : groupChatList) {
  440. WxCpUserExternalGroupChatInfo groupChat = externalContactService.getGroupChat(chat.getChatId());
  441. if (groupChat == null) {
  442. continue;
  443. }
  444. DistDto dto = new DistDto();
  445. dto.setVal(chat.getChatId());
  446. dto.setName(groupChat.getGroupChat().getName());
  447. list.add(dto);
  448. }
  449. }
  450. }catch (Exception e){
  451. log.error(e.getMessage());
  452. return new ArrayList<>();
  453. }*/
  454. return list;
  455. }
  456. // 企微原生API - 用户详情
  457. private static final String API_USER_DETAIL_GET = "https://qyapi.weixin.qq.com/cgi-bin/user/get?userid=%s";
  458. /**
  459. * @version
  460. * @author: hxl
  461. * @Date: 2026/1/28 16:42
  462. * @Description: 获取企业微信员工列表
  463. */
  464. @Override
  465. public List<DistDto> getWecomEmployeeList() {
  466. /* List<DistDto> list = new ArrayList<>();
  467. //获取外部联系人列表
  468. WxCpExternalContactService externalContactService = wxCpService.getExternalContactService();
  469. try{
  470. List<String> followerUserIdList = externalContactService.listFollowers();
  471. // 4. 补充成员详情(沿用 4.1.0 版本支持的 getUserService())
  472. WxCpUserService userService = wxCpService.getUserService();
  473. String accessToken = wxCpService.getAccessToken();
  474. for (String userId : followerUserIdList) {
  475. // WxCpUser userDetail = userService.getById(userId);
  476. String requestUrl = String.format(API_USER_DETAIL_GET, userId);
  477. String response = wxCpService.get(requestUrl,null);
  478. JsonObject userDetail = JsonParser.parseString(response).getAsJsonObject();
  479. if (userDetail == null) {
  480. continue;
  481. }
  482. DistDto dto = new DistDto();
  483. dto.setVal(userId);
  484. dto.setName(userDetail.get("name").getAsString());
  485. dto.setUnionid(userDetail.get("unionid")!=null ?userDetail.get("unionid").getAsString():null);
  486. list.add(dto);
  487. }
  488. }catch (Exception e){
  489. log.error(e.getMessage());
  490. return new ArrayList<>();
  491. }*/
  492. return getUserDictDtos();
  493. }
  494. /**
  495. * @version
  496. * @author: hxl
  497. * @Date: 2026/2/2 11:10
  498. * @Description: 获取用户列表
  499. */
  500. @Override
  501. public List<DistDto> getUserDictDtos() {
  502. List<DistDto> list = new ArrayList<>();
  503. List<SysUser> userList = this.getBaseMapper().getUserDictList();
  504. if(userList != null && userList.size() > 0){
  505. for(SysUser sysUser : userList){
  506. DistDto dto = new DistDto();
  507. dto.setVal(sysUser.getUserId()+"");
  508. dto.setName(sysUser.getUserName());
  509. list.add(dto);
  510. }
  511. }
  512. return list;
  513. }
  514. /**
  515. * @version
  516. * @author: hxl
  517. * @Date: 2026/2/11 17:26
  518. * @Description: 获取群二维码链接
  519. */
  520. @Override
  521. public String getChartQrCodeByChatId(String chatId, String activityId) {
  522. WeGroupFissionQrCodeRecord weGroupFissionQrCodeRecord = weGroupFissionQrCodeRecordService.findEntityByActivityIdAndChatId(activityId,chatId);
  523. WxCpExternalContactService service = wxCpService.getExternalContactService();
  524. WxCpContactWayInfo contactWayInfo = new WxCpContactWayInfo();
  525. WxCpContactWayInfo.ContactWay contactWay = new WxCpContactWayInfo.ContactWay();
  526. // 类型:MULTI(2) 表示群聊(SINGLE(1)是单人)
  527. contactWay.setType(WxCpContactWayInfo.TYPE.MULTI);
  528. // 场景:QRCODE(2) 对应接口的「链接入群」场景
  529. contactWay.setScene(WxCpContactWayInfo.SCENE.QRCODE);
  530. // 自定义状态值(关联你的裂变记录ID)
  531. contactWay.setState(weGroupFissionQrCodeRecord.getId().toString());
  532. // 跳过验证:用户扫码直接入群
  533. contactWay.setSkipVerify(Boolean.TRUE);
  534. contactWayInfo.setContactWay(contactWay);
  535. String baseJson = contactWayInfo.toJson();
  536. JsonObject jsonObject = JsonParser.parseString(baseJson).getAsJsonObject();
  537. JsonObject contactWayJson = jsonObject.getAsJsonObject("contact_way");
  538. DistDto distDto = querySingleChatDetail(chatId);
  539. String roomBaseName = distDto.getName();
  540. // 群聊基础名称
  541. contactWayJson.addProperty("room_base_name", roomBaseName);
  542. // 固定传0
  543. contactWayJson.addProperty("room_base_id", 0);
  544. // 关闭自动建群(用已有群)
  545. contactWayJson.addProperty("auto_create_room", 0);
  546. // 群聊ID列表
  547. List<String> chatIdList = new ArrayList<>();
  548. chatIdList.add(chatId);
  549. contactWayJson.add("chat_id_list", JsonParser.parseString(com.alibaba.fastjson.JSON.toJSONString(chatIdList)).getAsJsonArray());
  550. //添加部门权限为5 暂定为开发部 不能为空
  551. JsonArray partyArray = new JsonArray();
  552. partyArray.add(5);
  553. contactWayJson.add("party", partyArray);
  554. String finalJson = jsonObject.toString();
  555. try{
  556. WxCpContactWayResult result = service.addContactWay(WxCpContactWayInfo.fromJson(finalJson));
  557. WxCpContactWayInfo contactWayCode = service.getContactWay(result.getConfigId());
  558. String qrCode = contactWayCode.getContactWay().getQrCode();
  559. return qrCode;
  560. }catch (Exception e){
  561. }
  562. return null;
  563. }
  564. /**
  565. * @version
  566. * @author: hxl
  567. * @Date: 2026/2/10 19:00
  568. * @Description: 查询单个群详情
  569. */
  570. private DistDto querySingleChatDetail(String chatId) {
  571. try {
  572. WxCpUserExternalGroupChatInfo groupChat =
  573. wxCpService.getExternalContactService().getGroupChat(chatId);
  574. WxCpUserExternalGroupChatInfo.GroupChat detail = groupChat.getGroupChat();
  575. DistDto dto = new DistDto();
  576. dto.setVal(detail.getChatId());
  577. dto.setName(detail.getName());
  578. return dto;
  579. } catch (WxErrorException e) {
  580. return null;
  581. }
  582. }
  583. /**
  584. * @version
  585. * @author: hxl
  586. * @Date: 2026/1/31 16:16
  587. * @Description: 获取九宫格活动列表
  588. */
  589. public List<DistDto> getActivityDictDtos() {
  590. List<DistDto> list = new ArrayList<>();
  591. List<LotteryActivity> activityList = lotteryActivityService.findListType(null);
  592. if(activityList != null && activityList.size() > 0){
  593. for(LotteryActivity info : activityList){
  594. DistDto dto = new DistDto();
  595. dto.setVal(info.getId());
  596. dto.setName(info.getActivityName());
  597. list.add(dto);
  598. }
  599. }
  600. return list;
  601. }
  602. /**
  603. * @version
  604. * @author: hxl
  605. * @Date: 2026/1/31 16:16
  606. * @Description: 获取权益券列表
  607. */
  608. public List<DistDto> getRightInfoDictDtos() {
  609. List<DistDto> list = new ArrayList<>();
  610. List<LocalRightsInfo> localRightsInfoList = localRightsInfoService.getRightInfoList();
  611. if(localRightsInfoList != null && localRightsInfoList.size() > 0){
  612. for(LocalRightsInfo info : localRightsInfoList){
  613. DistDto dto = new DistDto();
  614. dto.setVal(info.getId());
  615. dto.setName(info.getRightsName());
  616. list.add(dto);
  617. }
  618. }
  619. return list;
  620. }
  621. /**
  622. * @version
  623. * @author: hxl
  624. * @Date: 2026/1/31 16:15
  625. * @Description: 获取启用的商户
  626. */
  627. public List<DistDto> getLocalMerchantInfoDictDtos() {
  628. List<DistDto> list = new ArrayList<>();
  629. List<LocalMerchantInfo> merchantInfoList = localMerchantInfoService.getMerchantInfoList();
  630. if(merchantInfoList != null && merchantInfoList.size() > 0){
  631. for(LocalMerchantInfo info : merchantInfoList){
  632. DistDto dto = new DistDto();
  633. dto.setVal(info.getId());
  634. dto.setName(info.getStoreName());
  635. list.add(dto);
  636. }
  637. }
  638. return list;
  639. }
  640. /**
  641. * @version
  642. * @author: hxl
  643. * @Date: 2026/1/28 14:53
  644. * @Description: 查询状态
  645. */
  646. public WeGroupFission getStatusDetailsById(String id) {
  647. return this.getBaseMapper().getStatusDetailsById(id);
  648. }
  649. }