|
|
@@ -0,0 +1,303 @@
|
|
|
+package com.jzg.organization.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.jzg.commons.core.base.BaseController;
|
|
|
+import com.jzg.commons.entity.po.SysUploadFiles;
|
|
|
+import com.jzg.commons.entity.vo.SysUserAccountVo;
|
|
|
+import com.jzg.commons.exception.SystemException;
|
|
|
+import com.jzg.commons.util.MinioUtils;
|
|
|
+import com.jzg.organization.entity.WechatCustomerService;
|
|
|
+import com.jzg.organization.entity.WechatCustomerServiceDuty;
|
|
|
+import com.jzg.organization.entity.WechatCustomerServiceRecording;
|
|
|
+import com.jzg.organization.entity.vo.*;
|
|
|
+import com.jzg.organization.mapper.SysUploadFilesMapper;
|
|
|
+import com.jzg.organization.service.*;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
|
|
+import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
|
|
|
+import me.chanjar.weixin.cp.api.*;
|
|
|
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
|
|
|
+import me.chanjar.weixin.cp.bean.WxCpDepart;
|
|
|
+import me.chanjar.weixin.cp.bean.WxCpUser;
|
|
|
+import me.chanjar.weixin.cp.bean.kf.*;
|
|
|
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
|
|
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
|
|
+import me.chanjar.weixin.cp.message.WxCpMessageRouter;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.LocalTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class WechatCustomerServiceManageServiceImpl implements WechatCustomerServiceManageService {
|
|
|
+
|
|
|
+ private final IWechatCustomerServiceService wechatCustomerServiceService;
|
|
|
+
|
|
|
+ private final IWechatCustomerServiceDutyService wechatCustomerServiceDutyService;
|
|
|
+
|
|
|
+ private final IWechatCustomerServiceRecordingService wechatCustomerServiceRecordingService;
|
|
|
+
|
|
|
+ private final MinioUtils minioUtils;
|
|
|
+
|
|
|
+ private final SysUserService sysUserService;
|
|
|
+
|
|
|
+ private final WxCpService wxCpService;
|
|
|
+
|
|
|
+ private final WxCpMessageRouter wxCpMessageRouter;
|
|
|
+
|
|
|
+ private final WxCpMediaService wxCpMediaService;
|
|
|
+
|
|
|
+ private final WxCpKfService wxCpKfService;
|
|
|
+
|
|
|
+ private final WxCpUserService wxCpUserService;
|
|
|
+
|
|
|
+ private final WxCpDepartmentService wxCpDepartmentService;
|
|
|
+
|
|
|
+ private final SysUploadFilesMapper sysUploadFilesMapper;
|
|
|
+
|
|
|
+ private final BaseController baseController;
|
|
|
+
|
|
|
+ @Value("${minio.bucket-name}")
|
|
|
+ private String bucketName;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public WechatCustomerServiceVo getWechatCustomer(Long customerServiceId) {
|
|
|
+ WechatCustomerService wechatCustomerService = wechatCustomerServiceService.getById(customerServiceId);
|
|
|
+ return Optional.ofNullable(wechatCustomerService).map(WechatCustomerServiceVo::new).orElse(new WechatCustomerServiceVo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addWechatCustomer(WechatCustomerServiceVo sysWechatCustomerAddVo) throws WxErrorException {
|
|
|
+ String userName = baseController.getUserName();
|
|
|
+ // 判断昵称是否重复
|
|
|
+ wechatCustomerServiceService.isNicknameRepeat(sysWechatCustomerAddVo.getNickname());
|
|
|
+ // 判断员工账号是否在职
|
|
|
+ sysUserService.isOnTheJob(sysWechatCustomerAddVo.getUserId());
|
|
|
+ // 判断员工账号是否与其他客服账号关联
|
|
|
+ wechatCustomerServiceService.isUserIdRepeat(sysWechatCustomerAddVo.getUserId());
|
|
|
+
|
|
|
+ WxCpKfAccountAdd wxCpKfAccountAdd = new WxCpKfAccountAdd();
|
|
|
+ wxCpKfAccountAdd.setName(sysWechatCustomerAddVo.getNickname());
|
|
|
+ // 头像
|
|
|
+ WechatCustomerService wechatCustomerService = sysWechatCustomerAddVo.buildWechatCustomerService(userName);
|
|
|
+
|
|
|
+ if (StringUtils.hasLength(sysWechatCustomerAddVo.getAvatar())) {
|
|
|
+ SysUploadFiles sysUploadFiles = sysUploadFilesMapper.selectById(sysWechatCustomerAddVo.getAvatar());
|
|
|
+ Optional.ofNullable(sysUploadFiles).map(SysUploadFiles::getFileName).ifPresent(fileName -> {
|
|
|
+ InputStream inputStream = minioUtils.getObject(bucketName, fileName);
|
|
|
+ // 上传素材
|
|
|
+ WxMediaUploadResult image;
|
|
|
+ try {
|
|
|
+ image = wxCpMediaService.upload("image", inputStream, fileName);
|
|
|
+ } catch (WxErrorException e) {
|
|
|
+ throw new SystemException("图片上传失败");
|
|
|
+ }
|
|
|
+ String mediaId = image.getMediaId();
|
|
|
+ wxCpKfAccountAdd.setMediaId(mediaId);
|
|
|
+ wechatCustomerService.setAvatar(sysUploadFiles.getId());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 添加
|
|
|
+ WxCpKfAccountAddResp wxCpKfAccountAddResp = wxCpKfService.addAccount(wxCpKfAccountAdd);
|
|
|
+ wechatCustomerService.setOpenKfId(wxCpKfAccountAddResp.getOpenKfid());
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ list.add(sysWechatCustomerAddVo.getReceptionistId());
|
|
|
+ WxCpKfServicerOpResp wxCpKfServicerOpResp = wxCpKfService.addServicer(wxCpKfAccountAddResp.getOpenKfid(), list);
|
|
|
+ if (wxCpKfServicerOpResp.getErrcode() == 0) {
|
|
|
+ wechatCustomerServiceService.save(wechatCustomerService);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteWechatCustomer(Long customerServiceId) throws WxErrorException {
|
|
|
+ WechatCustomerService wechatCustomerService = wechatCustomerServiceService.getByIdExist(customerServiceId, "客服不存在");
|
|
|
+ WxCpKfAccountDel wxCpKfAccountDel = new WxCpKfAccountDel();
|
|
|
+ wxCpKfAccountDel.setOpenKfid(wechatCustomerService.getOpenKfId());
|
|
|
+ WxCpBaseResp wxCpBaseResp;
|
|
|
+ wxCpBaseResp = wxCpKfService.delAccount(wxCpKfAccountDel);
|
|
|
+ if (wxCpBaseResp.getErrcode() == 0) {
|
|
|
+ wechatCustomerServiceService.deleteAllInfo(customerServiceId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateWechatCustomer(Long customerServiceId, WechatCustomerServiceVo wechatCustomerServiceVo) throws WxErrorException {
|
|
|
+ WechatCustomerService wechatCustomerService = wechatCustomerServiceService.getByIdExist(customerServiceId, "客服不存在");
|
|
|
+ if (!wechatCustomerService.getNickname().equals(wechatCustomerServiceVo.getNickname())) {
|
|
|
+ wechatCustomerServiceService.isNicknameRepeat(wechatCustomerServiceVo.getNickname());
|
|
|
+ }
|
|
|
+
|
|
|
+ WxCpKfAccountUpd wxCpKfAccountUpd = new WxCpKfAccountUpd();
|
|
|
+ wxCpKfAccountUpd.setOpenKfid(wechatCustomerService.getOpenKfId());
|
|
|
+ boolean isAvatarSame = StringUtils.hasLength(wechatCustomerServiceVo.getAvatar()) && !wechatCustomerServiceVo.getAvatar().equals(wechatCustomerService.getAvatar());
|
|
|
+
|
|
|
+ // 头像是否更换
|
|
|
+ if (isAvatarSame) {
|
|
|
+ SysUploadFiles sysUploadFiles = sysUploadFilesMapper.selectById(wechatCustomerServiceVo.getAvatar());
|
|
|
+ InputStream inputStream = minioUtils.getObject(bucketName, sysUploadFiles.getFileName());
|
|
|
+ WxMediaUploadResult image = wxCpMediaService.upload("image", inputStream, sysUploadFiles.getFileName());
|
|
|
+ String mediaId = image.getMediaId();
|
|
|
+ wxCpKfAccountUpd.setMediaId(mediaId);
|
|
|
+ wechatCustomerService.setAvatar(wechatCustomerServiceVo.getAvatar());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 昵称是否相同
|
|
|
+ boolean isNicknameSame = !wechatCustomerService.getNickname().equals(wechatCustomerServiceVo.getNickname());
|
|
|
+ if (isNicknameSame) {
|
|
|
+ wxCpKfAccountUpd.setName(wechatCustomerServiceVo.getNickname());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 客服人员是否替换
|
|
|
+ if (!wechatCustomerService.getReceptionistId().equals(wechatCustomerServiceVo.getReceptionistId())) {
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ list.add(wechatCustomerService.getReceptionistId());
|
|
|
+ wxCpKfService.delServicer(wechatCustomerService.getOpenKfId(), list);
|
|
|
+ list = new ArrayList<>();
|
|
|
+ list.add(wechatCustomerServiceVo.getReceptionistId());
|
|
|
+ wxCpKfService.addServicer(wechatCustomerService.getOpenKfId(), list);
|
|
|
+ wechatCustomerService.setReceptionistId(wechatCustomerServiceVo.getReceptionistId());
|
|
|
+ wechatCustomerService.setReceptionist(wechatCustomerServiceVo.getReceptionist());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 昵称和头像是否跟换
|
|
|
+ if (isNicknameSame || isAvatarSame) {
|
|
|
+ wxCpKfService.updAccount(wxCpKfAccountUpd);
|
|
|
+ }
|
|
|
+
|
|
|
+ wechatCustomerService.setNickname(wechatCustomerServiceVo.getNickname());
|
|
|
+ wechatCustomerService.setAvatar(wechatCustomerServiceVo.getAvatar());
|
|
|
+ wechatCustomerService.setUserId(wechatCustomerServiceVo.getUserId());
|
|
|
+ String userName = baseController.getUserName();
|
|
|
+ wechatCustomerService.setUpdateBy(userName);
|
|
|
+ wechatCustomerService.setUpdateTime(LocalDateTime.now());
|
|
|
+ wechatCustomerServiceService.updateById(wechatCustomerService);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<WeComDeptVo> getDeptByDeptId() throws WxErrorException {
|
|
|
+ List<WxCpDepart> list = wxCpDepartmentService.list(null);
|
|
|
+ List<WeComDeptVo> deptVos = list.stream()
|
|
|
+ .map(WeComDeptVo::new)
|
|
|
+ .toList();
|
|
|
+ Map<String, List<WeComDeptVo>> parentGroup = deptVos.stream()
|
|
|
+ .collect(Collectors.groupingBy(WeComDeptVo::getParentId));
|
|
|
+ List<String> collect = deptVos.stream().map(WeComDeptVo::getDeptId).toList();
|
|
|
+ deptVos.forEach(node -> node.setChildDept(parentGroup.getOrDefault(node.getDeptId(), Collections.emptyList())));
|
|
|
+ return deptVos.stream()
|
|
|
+ .filter(node -> node.getParentId() != null && !collect.contains(node.getParentId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<WeComUserVo> getUser() throws WxErrorException {
|
|
|
+ List<WxCpUser> wxCpUsers = wxCpUserService.listSimpleByDepartment(9L, true, 0);
|
|
|
+ return wxCpUsers.stream().map(x -> new WeComUserVo(x.getUserId(), x.getName())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void saveOrUpdateCustomerServiceDutyRules(WechatCustomerServiceDutyRulesVo sysWechatCustomerDutyRules) {
|
|
|
+ // 删除之前的排班信息
|
|
|
+ wechatCustomerServiceDutyService.clearCustomerDuty(sysWechatCustomerDutyRules.getCustomerId());
|
|
|
+ List<WechatCustomerServiceDuty> wechatCustomerServiceDuties = sysWechatCustomerDutyRules.getDutyList()
|
|
|
+ .stream()
|
|
|
+ .flatMap(duty -> duty.getDutyConfig().stream()
|
|
|
+ .map(config -> {
|
|
|
+ WechatCustomerServiceDuty dutyEntity = new WechatCustomerServiceDuty();
|
|
|
+ dutyEntity.setCustomerServiceId(sysWechatCustomerDutyRules.getCustomerId());
|
|
|
+ dutyEntity.setDutyCustomerServiceId(config.getDutyCustomerServiceId());
|
|
|
+ dutyEntity.setDate(duty.getDutyDate());
|
|
|
+ dutyEntity.setStartTime(config.getStartTime());
|
|
|
+ dutyEntity.setEndTime(config.getEndTime());
|
|
|
+ return dutyEntity;
|
|
|
+ }))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ // 保存排班信息
|
|
|
+ wechatCustomerServiceDutyService.saveBatch(wechatCustomerServiceDuties);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getWeChatCustomer() throws WxErrorException {
|
|
|
+// String userName = baseController.getUserName();
|
|
|
+ WechatCustomerService wechatCustomerService = null;
|
|
|
+// String leaderId = sysUserService.getLeaderId(userName);
|
|
|
+ String userName = "1930514052662677506";
|
|
|
+ String leaderId = "1930514052662677506";
|
|
|
+ if (StringUtils.hasLength(leaderId)) {
|
|
|
+ wechatCustomerService = wechatCustomerServiceService.getByUserId(leaderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ObjectUtils.isEmpty(wechatCustomerService)) {
|
|
|
+ // 获取最近一次的客服记录
|
|
|
+ List<WechatCustomerService> sysWechatCustomerList = wechatCustomerServiceService.list();
|
|
|
+ List<Long> sysWechatCustomerIdList = sysWechatCustomerList.stream()
|
|
|
+ .map(WechatCustomerService::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ WechatCustomerServiceRecording wechatCustomerServiceRecording = wechatCustomerServiceRecordingService.lambdaQuery()
|
|
|
+ .in(!sysWechatCustomerIdList.isEmpty(), WechatCustomerServiceRecording::getCustomerServiceId, sysWechatCustomerIdList)
|
|
|
+ .eq(WechatCustomerServiceRecording::getUserId, userName)
|
|
|
+ .orderByDesc(WechatCustomerServiceRecording::getCreateTime)
|
|
|
+ .last("limit 1")
|
|
|
+ .one();
|
|
|
+ if (ObjectUtils.isEmpty(wechatCustomerServiceRecording)) {
|
|
|
+ wechatCustomerService = wechatCustomerServiceService.getCacheCustomerId(wechatCustomerService);
|
|
|
+ } else {
|
|
|
+ // 使用上一次的客服
|
|
|
+ wechatCustomerService = wechatCustomerServiceService.lambdaQuery()
|
|
|
+ .eq(WechatCustomerService::getId, wechatCustomerServiceRecording.getCustomerServiceId())
|
|
|
+ .one();
|
|
|
+ if (ObjectUtils.isEmpty(wechatCustomerService)) {
|
|
|
+ wechatCustomerService = wechatCustomerServiceService.getCacheCustomerId(wechatCustomerService);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ WechatCustomerServiceRecording customerRecording = new WechatCustomerServiceRecording();
|
|
|
+ customerRecording.setCustomerServiceId(wechatCustomerService.getId());
|
|
|
+ customerRecording.setUserId(userName);
|
|
|
+ wechatCustomerServiceRecordingService.save(customerRecording);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<WechatCustomerServiceDuty> list = wechatCustomerServiceDutyService.lambdaQuery()
|
|
|
+ .eq(WechatCustomerServiceDuty::getDutyCustomerServiceId, wechatCustomerService.getId())
|
|
|
+ .eq(WechatCustomerServiceDuty::getDate, LocalDate.now())
|
|
|
+ .le(WechatCustomerServiceDuty::getStartTime, LocalTime.now())
|
|
|
+ .ge(WechatCustomerServiceDuty::getEndTime, LocalTime.now())
|
|
|
+ .list();
|
|
|
+ if (list != null && !list.isEmpty()) {
|
|
|
+ WechatCustomerServiceDuty wechatCustomerServiceDuty = list.get(0);
|
|
|
+ wechatCustomerService = wechatCustomerServiceService.getById(wechatCustomerServiceDuty.getDutyCustomerServiceId());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ObjectUtils.isEmpty(wechatCustomerService)) {
|
|
|
+ throw new SystemException("请联系管理员,配置客服");
|
|
|
+ }
|
|
|
+
|
|
|
+ String openKfId = wechatCustomerService.getOpenKfId();
|
|
|
+ WxCpKfAccountLink wxCpKfAccountLink = new WxCpKfAccountLink();
|
|
|
+ wxCpKfAccountLink.setOpenKfid(openKfId);
|
|
|
+ wxCpKfAccountLink.setScene(userName);
|
|
|
+ WxCpKfAccountLinkResp accountLink = wxCpKfService.getAccountLink(wxCpKfAccountLink);
|
|
|
+ return accountLink.getUrl();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void callbackSendMsgOnEvent(WxCpXmlMessage wechatEncrypt) {
|
|
|
+ WxCpXmlOutMessage route = wxCpMessageRouter.route(wechatEncrypt);
|
|
|
+ System.out.println(route.toString());
|
|
|
+ }
|
|
|
+}
|