Forráskód Böngészése

修改值班时间

wks 10 hónapja
szülő
commit
fae9e1a8fd

+ 78 - 0
src/main/java/com/ydtech/components/DistributedLockComponent.java

@@ -0,0 +1,78 @@
+package com.ydtech.components;
+
+import lombok.RequiredArgsConstructor;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+/**
+ * @description: 分布式锁封装
+ * @author: wenks
+ * @date: 2025/3/24 15:08
+ **/
+@Component
+@RequiredArgsConstructor
+public class DistributedLockComponent {
+
+    private final RedissonClient redissonClient;
+
+    // 默认配置(单位:秒)
+    private static final int DEFAULT_WAIT_TIME = 3;
+
+    private static final int DEFAULT_LEASE_TIME = 30;
+
+    /**
+     * 带返回值的锁操作
+     *
+     * @param lockName  锁名称
+     * @param supplier  业务逻辑
+     * @param waitTime  获取锁等待时间
+     * @param leaseTime 锁持有时间
+     * @return 业务执行结果
+     */
+    public <T> T executeWithLock(String lockName, Supplier<T> supplier, long waitTime, long leaseTime) throws Exception {
+        RLock lock = redissonClient.getLock(lockName);
+        boolean isLocked = false;
+        try {
+            // 尝试获取锁
+            isLocked = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
+            if (isLocked) {
+                // 执行业务逻辑
+                return supplier.get();
+            }
+            throw new RuntimeException("Acquire lock failed: " + lockName);
+        } finally {
+            if (isLocked && lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+    }
+
+    /**
+     * 快速失败(带默认参数)
+     */
+    public <T> T fastFailExecute(String lockName, Supplier<T> supplier) throws Exception {
+        return executeWithLock(lockName, supplier, 0, DEFAULT_LEASE_TIME);
+    }
+
+    /**
+     * 阻塞等待锁(带默认参数)
+     */
+    public <T> T blockingExecute(String lockName, Supplier<T> supplier) throws Exception {
+        return executeWithLock(lockName, supplier, DEFAULT_WAIT_TIME, -1);
+    }
+
+    /**
+     * 无返回值操作
+     */
+    public void executeWithLock(String lockName, Runnable runnable, long waitTime, long leaseTime) throws Exception {
+        executeWithLock(lockName, () -> {
+            runnable.run();
+            return null;
+        }, waitTime, leaseTime);
+    }
+}
+

+ 1 - 1
src/main/java/com/ydtech/modules/admin/controller/wechat/WechatCustomerController.java

@@ -36,7 +36,7 @@ public class WechatCustomerController {
 
     @PostMapping(path = "/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
     @ApiOperation(value = "客服回调(处理事件发送欢迎语)")
-    public HttpResult<String> customerCallback(@RequestBody String wechatEncrypt) throws JsonProcessingException, WxErrorException {
+    public HttpResult<String> customerCallback(@RequestBody String wechatEncrypt) throws Exception {
         customerService.callbackSendMsgOnEvent(wechatEncrypt);
         return HttpResult.ok();
     }

+ 1 - 1
src/main/java/com/ydtech/modules/admin/service/WechatCustomerService.java

@@ -25,7 +25,7 @@ public interface WechatCustomerService {
      *
      * @param wechatEncrypt
      */
-    void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException, WxErrorException;
+    void callbackSendMsgOnEvent(String wechatEncrypt) throws Exception;
 
 
     /**

+ 77 - 71
src/main/java/com/ydtech/modules/admin/service/impl/WechatCustomerServiceImpl.java

@@ -2,6 +2,7 @@ package com.ydtech.modules.admin.service.impl;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.ydtech.components.DistributedLockComponent;
 import com.ydtech.modules.admin.components.WechatCustomerComponents;
 import com.ydtech.modules.admin.components.wechat.customer.request.CustomerAddContactWayRequest;
 import com.ydtech.modules.admin.components.wechat.customer.request.CustomerListRequest;
@@ -53,7 +54,7 @@ public class WechatCustomerServiceImpl implements WechatCustomerService {
 
     private final SysWechatCustomerDutyService sysWechatCustomerDutyService;
 
-    private final StringRedisTemplate redisTemplate;
+    private final DistributedLockComponent distributedLockComponent;
 
     @Override
     public String customerCallback(String msgSignature, String timestamp, String nonce, String echoStr) {
@@ -62,7 +63,7 @@ public class WechatCustomerServiceImpl implements WechatCustomerService {
     }
 
     @Override
-    public void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException, WxErrorException {
+    public void callbackSendMsgOnEvent(String wechatEncrypt) throws Exception {
         log.info("回调参数为{}", wechatEncrypt);
         WechatEncryptVo wechatEncryptVo = xmlMapper.readValue(wechatEncrypt, WechatEncryptVo.class);
         WxCryptUtil wxCryptUtil = wechatCustomerComponents.getWxCryptUtil();
@@ -89,85 +90,87 @@ public class WechatCustomerServiceImpl implements WechatCustomerService {
                 .ge(SysWechatCustomerDuty::getEndTime, LocalDateTime.now())
                 .list();
 
-        // 改变会话状态
-        if (wxCpKfMsgItem.getOrigin() == 3) {
-            // 1 管理人是否一致
-            // 2 休息日
-            // 3 工作时间内 安排了值班客服
-            if (!sysWechatCustomerService.whetherTheManagersAreConsistent(wxCpKfMsgItem.getExternalUserId(), sysWechatCustomer) || !workingHours || !sysWechatCustomerDuties.isEmpty()) {
-                WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId());
+        distributedLockComponent.executeWithLock(wxCpKfMsgItem.getMsgId(), () -> {
+            // 改变会话状态
+            if (wxCpKfMsgItem.getOrigin() == 3) {
+                // 1 管理人是否一致
+                // 2 休息日
+                // 3 工作时间内 安排了值班客服
+                boolean unanimous = !sysWechatCustomerService.whetherTheManagersAreConsistent(wxCpKfMsgItem.getExternalUserId(), sysWechatCustomer);
+                WxCpKfServiceStateResp serviceState;
+                try {
+                    serviceState = wxCpKfService.getServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId());
+                } catch (WxErrorException e) {
+                    throw new RuntimeException(e);
+                }
                 Integer state1 = serviceState.getServiceState();
-                if (state1 == 0) {
-                    state1 = 1;
-                    wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
-                    restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
-                } else if (state1 == 1) {
-                    String s = redisTemplate.opsForValue().get(wxCpKfMsgItem.getMsgId());
-                    if (!ObjectUtils.isEmpty(s)) {
-                        return;
+                if (unanimous || !workingHours || !sysWechatCustomerDuties.isEmpty()) {
+                    if (state1 == 0) {
+                        state1 = 1;
+                        try {
+                            wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
+                        } catch (WxErrorException e) {
+                            throw new RuntimeException(e);
+                        }
+                        restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
+                    } else if (state1 == 1) {
+                        restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
+                    } else if (state1 == 3) {
+                        state1 = 4;
+                        try {
+                            wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
+                        } catch (WxErrorException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                } else {
+                    if (state1 == 0 || state1 == 1) {
+                        state1 = 3;
+                        try {
+                            wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
+                        } catch (WxErrorException e) {
+                            throw new RuntimeException(e);
+                        }
                     }
-                    restTimeSendMsg(wxCpKfMsgItem.getExternalUserId(), wxCpKfMsgItem.getOpenKfid());
-                    redisTemplate.opsForValue().set(wxCpKfMsgItem.getMsgId(), wxCpKfMsgItem.getMsgId(), 1, TimeUnit.MINUTES);
-                } else if (state1 == 3) {
-                    state1 = 4;
-                    wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
                 }
-            } else {
-                WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId());
-                Integer state1 = serviceState.getServiceState();
-                if (state1 == 0 || state1 == 1) {
-                    state1 = 3;
-                    wxCpKfService.transServiceState(wxCpKfMsgItem.getOpenKfid(), wxCpKfMsgItem.getExternalUserId(), state1, sysWechatCustomer.getReceptionistId());
+            } else if (wxCpKfMsgItem.getOrigin() == 4) {
+                // 发送欢迎语
+                WxCpKfEventMsg event = wxCpKfMsgItem.getEvent();
+                WxCpKfServiceStateResp serviceState = null;
+                try {
+                    serviceState = wxCpKfService.getServiceState(event.getOpenKfid(), event.getExternalUserId());
+                } catch (WxErrorException e) {
+                    throw new RuntimeException(e);
+                }
+                Integer state = serviceState.getServiceState();
+                if (ObjectUtils.isEmpty(event)) {
+                    return;
+                }
+                String scene = event.getScene();
+                if (state != 4 && !StringUtils.isEmpty(scene)) {
+                    SysUser sysUser = sysUserService.getById(scene);
+                    sysUser.setExternalUserId(event.getExternalUserId());
+                    sysUserService.updateById(sysUser);
+                    CustomerSendMsgOnEventRequest customerSendMsgOnEventRequest = CustomerSendMsgOnEventRequest.sendMsgOnEvent(sysUser, event.getWelcomeCode(), workingHours);
+                    wechatCustomerComponents.sendMsgOnEvent(customerSendMsgOnEventRequest);
                 }
-            }
-        } else if (wxCpKfMsgItem.getOrigin() == 4) {
-            // 发送欢迎语
-            WxCpKfEventMsg event = wxCpKfMsgItem.getEvent();
-            if (ObjectUtils.isEmpty(event)) {
-                return;
-            }
-            String scene = event.getScene();
-            if (!StringUtils.isEmpty(scene)) {
-                SysUser sysUser = sysUserService.getById(scene);
-                sysUser.setExternalUserId(event.getExternalUserId());
-                sysUserService.updateById(sysUser);
-                CustomerSendMsgOnEventRequest customerSendMsgOnEventRequest = CustomerSendMsgOnEventRequest.sendMsgOnEvent(sysUser, event.getWelcomeCode(), workingHours);
-                wechatCustomerComponents.sendMsgOnEvent(customerSendMsgOnEventRequest);
-            }
-
-            WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(event.getOpenKfid(), event.getExternalUserId());
-            Integer state = serviceState.getServiceState();
-            if (workingHours && (state == 0 || state == 1)) {
-                state = 3;
-                List<SysWechatCustomer> list = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, wxCpKfMsgItem.getEvent().getOpenKfid()).list();
-                String receptionistId = list.get(0).getReceptionistId();
-                wxCpKfService.transServiceState(wxCpKfMsgItem.getEvent().getOpenKfid(), wxCpKfMsgItem.getEvent().getExternalUserId(), state, receptionistId);
-            }
-        }
-
-        List<WxCpKfMsgListResp.WxCpKfMsgItem> msgListDTOList = msgList.stream().filter(x -> "event".equals(x.getMsgType())).collect(Collectors.toList());
-        msgListDTOList.forEach(x -> {
-            try {
-                WxCpKfEventMsg xEvent = x.getEvent();
-                WxCpKfServiceStateResp wxCpKfServiceStateResp = wxCpKfService.getServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId());
-                Integer state = wxCpKfServiceStateResp.getServiceState();
 
                 if (workingHours && (state == 0 || state == 1)) {
                     state = 3;
-                    // 休息时间
-                    List<SysWechatCustomer> list = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, xEvent.getOpenKfid()).list();
+                    List<SysWechatCustomer> list = sysWechatCustomerService.lambdaQuery().eq(SysWechatCustomer::getOpenKfId, wxCpKfMsgItem.getEvent().getOpenKfid()).list();
                     String receptionistId = list.get(0).getReceptionistId();
-                    wxCpKfService.transServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId(), state, receptionistId);
+                    try {
+                        wxCpKfService.transServiceState(wxCpKfMsgItem.getEvent().getOpenKfid(), wxCpKfMsgItem.getEvent().getExternalUserId(), state, receptionistId);
+                    } catch (WxErrorException e) {
+                        throw new RuntimeException(e);
+                    }
                 }
-            } catch (WxErrorException e) {
-                throw new RuntimeException(e);
             }
-        });
-
+        }, 2, 2);
     }
 
-    private void restTimeSendMsg(String externalUserId, String openKfId) throws WxErrorException {
-        String message = "您咨询的客服目前暂时不在服务时间,请您前往“晋掌柜App”点击“微信客服”,将为您安排新的客服为您提供服务~(客服服务时间:周一至周五  8:30-18:30,周六至周日  9:00-18:00,午间 12:00-14:00 休息)";
+    private void restTimeSendMsg(String externalUserId, String openKfId) {
+        String message = "您咨询的客服目前暂时不在服务时间,请您前往“晋掌柜App”点击“微信客服”,将为您安排新的客服为您提供服务~(客服服务时间:周一至周五  8:30-18:30,周六至周日  8:30-18:30,午间 12:00-14:00 休息)";
         WxCpKfMsgSendRequest wxCpKfMsgSendRequest = new WxCpKfMsgSendRequest();
         wxCpKfMsgSendRequest.setToUser(externalUserId);
         wxCpKfMsgSendRequest.setOpenKfid(openKfId);
@@ -175,10 +178,13 @@ public class WechatCustomerServiceImpl implements WechatCustomerService {
         WxCpKfTextMsg wxCpKfTextMsg = new WxCpKfTextMsg();
         wxCpKfTextMsg.setContent(message);
         wxCpKfMsgSendRequest.setText(wxCpKfTextMsg);
-        wxCpKfService.sendMsg(wxCpKfMsgSendRequest);
+        try {
+            wxCpKfService.sendMsg(wxCpKfMsgSendRequest);
+        } catch (WxErrorException e) {
+            throw new RuntimeException(e);
+        }
     }
 
-
     @Override
     public List<CustomerListResponse.AccountListDTO> list() {
         CustomerListRequest customerListResponse = new CustomerListRequest(0, 100);