浏览代码

Merge remote-tracking branch 'origin/sit' into uat-20260202

dujian 12 小时之前
父节点
当前提交
5072633475

+ 16 - 1
alien-lawyer/src/main/java/shop/alien/lawyer/config/WebSocketProcess.java

@@ -22,6 +22,8 @@ import shop.alien.util.common.safe.TextReviewServiceEnum;
 import javax.websocket.*;
 import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
+import java.io.EOFException;
+import java.nio.channels.ClosedChannelException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -190,13 +192,26 @@ public class WebSocketProcess implements ApplicationContextAware {
         }
     }
 
+    private static boolean isBenignSocketDisconnect(Throwable error) {
+        for (Throwable t = error; t != null; t = t.getCause()) {
+            if (t instanceof EOFException || t instanceof ClosedChannelException) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * 连接发生异常时候触发
      */
     @OnError
     public void onError(@PathParam("sendId") String id, Throwable error) {
         try {
-            log.error("WebSocketProcess.onError() Error,id={}, Msg=", id, error);
+            if (isBenignSocketDisconnect(error)) {
+                log.warn("WebSocketProcess.onError() 连接已关闭或读流结束(可忽略), id={}, summary={}", id, error.toString());
+            } else {
+                log.error("WebSocketProcess.onError() Error,id={}, Msg=", id, error);
+            }
             // 发生错误时主动移除,防止僵尸连接
             concurrentHashMap.remove(id, this);
         } catch (Exception e) {

+ 33 - 31
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/LicenseServiceImpl.java

@@ -7,17 +7,15 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import shop.alien.entity.second.vo.StoreImgDTO;
-import shop.alien.entity.store.*;
-import shop.alien.entity.store.vo.StoreImgVo;
-import shop.alien.entity.storePlatform.vo.StoreLicenseHistoryDto;
-import shop.alien.entity.storePlatform.vo.StoreLicenseHistoryVO;
+import shop.alien.entity.store.StoreImg;
+import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.storePlatform.StoreLicenseHistory;
+import shop.alien.entity.storePlatform.vo.StoreLicenseHistoryDto;
 import shop.alien.mapper.StoreImgMapper;
 import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.storePlantform.StoreLicenseHistoryMapper;
 import shop.alien.storeplatform.service.LicenseService;
 
-import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
@@ -37,10 +35,14 @@ import java.util.*;
 @RequiredArgsConstructor
 public class LicenseServiceImpl implements LicenseService {
 
-    /** 商户图片数据访问对象 */
+    /**
+     * 商户图片数据访问对象
+     */
     private final StoreImgMapper storeImgMapper;
 
-    /** 商户证照历史记录数据访问对象 */
+    /**
+     * 商户证照历史记录数据访问对象
+     */
     private final StoreLicenseHistoryMapper licenseHistoryMapper;
 
     private final StoreInfoMapper storeInfoMapper;
@@ -48,7 +50,7 @@ public class LicenseServiceImpl implements LicenseService {
 
     @Override
     public int uploadfoodLicence(StoreImg storeImg) {
-        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType,24).eq(StoreImg::getStoreId,storeImg.getStoreId()));
+        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType, 24).eq(StoreImg::getStoreId, storeImg.getStoreId()));
         storeImg.setImgType(24);
         storeImg.setImgDescription("经营许可证审核通过前图片");
         storeImgMapper.insert(storeImg);
@@ -80,7 +82,7 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 营业执照图片列表
      */
     @Override
-    public List<StoreImg> getbusinessLicenseList (Integer id) {
+    public List<StoreImg> getbusinessLicenseList(Integer id) {
         // 查询图片类型为14(营业执照)的图片列表
         return storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>()
                 .eq(StoreImg::getImgType, 14)
@@ -97,11 +99,11 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 合同图片列表
      */
     @Override
-    public List<StoreImgDTO> getContractList (Integer id) {
+    public List<StoreImgDTO> getContractList(Integer id) {
 
 
         StoreInfo storeInfo = storeInfoMapper.selectOne(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, id));
-        
+
 
         log.info("getEntertainmentLicenseList - 查询商户ID为 {} 的娱乐经营许可证图片列表", id);
         List<StoreImg> storeImgList = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>()
@@ -132,11 +134,11 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 食品经营许可证图片列表
      */
     @Override
-    public List<StoreImgDTO> getFoodLicenceList (Integer id) {
-         log.info("getEntertainmentLicenseList - 查询商户ID为 {} 的娱乐经营许可证图片列表", id);
-        
+    public List<StoreImgDTO> getFoodLicenceList(Integer id) {
+        log.info("getEntertainmentLicenseList - 查询商户ID为 {} 的娱乐经营许可证图片列表", id);
+
         StoreInfo storeInfo = storeInfoMapper.selectOne(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, id));
-        
+
         // 查询图片类型为25(食品经营许可证)的图片列表
         List<StoreImg> storeImgList = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>()
                 .eq(StoreImg::getImgType, 25)
@@ -167,7 +169,7 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 证照历史记录VO列表
      */
     @Override
-    public List<StoreLicenseHistoryDto> queryLicenceByStatusList (Integer storeId) {
+    public List<StoreLicenseHistoryDto> queryLicenceByStatusList(Integer storeId) {
 
         List<StoreLicenseHistory> licenseList = licenseHistoryMapper.queryLicenceByStatusList(storeId, 2, 1);
 
@@ -224,7 +226,7 @@ public class LicenseServiceImpl implements LicenseService {
 
         Date date = new Date();
         //先清除数据
-        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType,22).eq(StoreImg::getStoreId,value));
+        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType, 22).eq(StoreImg::getStoreId, value));
         for (StoreImg renewContract : storeImgList) {
             StoreImg storeImg = new StoreImg();
             storeImg.setStoreId(renewContract.getStoreId());
@@ -322,7 +324,7 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 按时间分组的证照历史记录列表
      */
     @Override
-    public List<StoreLicenseHistoryDto> queryContractByStatusList (Integer storeId) {
+    public List<StoreLicenseHistoryDto> queryContractByStatusList(Integer storeId) {
 
         // 查询证照类型为1(合同管理)的记录
         List<StoreLicenseHistory> licenseList = licenseHistoryMapper.queryLicenceByStatusList(storeId, 1, 1);
@@ -394,29 +396,29 @@ public class LicenseServiceImpl implements LicenseService {
         // 第三步:将分组后的数据转换为列表结构
         // 每个时间节点创建一个父对象,将该时间的所有记录存储到 licenseList 中
         List<StoreLicenseHistoryDto> resultList = new ArrayList<>();
-        
+
         for (Map.Entry<String, List<StoreLicenseHistoryDto>> entry : timeGroupMap.entrySet()) {
             String timeKey = entry.getKey();
             List<StoreLicenseHistoryDto> sameTimeList = entry.getValue();
-            
+
             // 创建一个父对象,代表这个时间节点
             StoreLicenseHistoryDto parentVo = new StoreLicenseHistoryDto();
-            
+
             // 使用第一条记录的基本信息作为父对象的信息(ID最小的那条)
             if (!sameTimeList.isEmpty()) {
                 StoreLicenseHistoryDto firstItem = sameTimeList.get(0);
                 BeanUtils.copyProperties(firstItem, parentVo);
-                
+
                 // 将相同时间的所有记录存储到 licenseList 中(已按ID升序排列)
                 parentVo.setLicenseList(sameTimeList);
                 parentVo.setCreatedDateFormat(timeKey);
-                
+
                 resultList.add(parentVo);
             }
         }
 
-        log.info("queryContractByStatusList - 共查询到 {} 条记录,按时间分组后 {} 个时间节点", 
-                 licenseList.size(), resultList.size());
+        log.info("queryContractByStatusList - 共查询到 {} 条记录,按时间分组后 {} 个时间节点",
+                licenseList.size(), resultList.size());
 
         return resultList;
     }
@@ -431,10 +433,10 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 营业执照图片列表
      */
     @Override
-    public List<StoreImgDTO> getEntertainmentLicenseList (Integer id) {
+    public List<StoreImgDTO> getEntertainmentLicenseList(Integer id) {
 
         StoreInfo storeInfo = storeInfoMapper.selectOne(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, id));
-        
+
         log.info("getEntertainmentLicenseList - 查询商户ID为 {} 的娱乐经营许可证图片列表", id);
         List<StoreImg> storeImgList = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>()
                 .eq(StoreImg::getImgType, 31)
@@ -454,7 +456,7 @@ public class LicenseServiceImpl implements LicenseService {
 
     @Override
     public int uploadEntertainmentLicence(StoreImg storeImg) {
-        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType,32).eq(StoreImg::getStoreId,storeImg.getStoreId()));
+        storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType, 32).eq(StoreImg::getStoreId, storeImg.getStoreId()));
         storeImg.setImgType(32);
         storeImg.setImgDescription("经营许可证审核通过前图片");
         storeImgMapper.insert(storeImg);
@@ -464,14 +466,14 @@ public class LicenseServiceImpl implements LicenseService {
         StoreLicenseHistory licenseHistory = new StoreLicenseHistory();
         licenseHistory.setStoreId(storeImg.getStoreId());
         licenseHistory.setLicenseStatus(3);
-        licenseHistory.setLicenseExecuteStatus(2);
+        licenseHistory.setLicenseExecuteStatus(1);
         licenseHistory.setImgUrl(storeImg.getImgUrl());
         licenseHistory.setDeleteFlag(0);
         licenseHistoryMapper.insert(licenseHistory);
 
         //更新店铺
         StoreInfo storeInfo = new StoreInfo();
-        storeInfo.setEntertainmentLicenceStatus(2);
+        storeInfo.setEntertainmentLicenceStatus(1);
         storeInfo.setId(storeImg.getStoreId());
         storeInfo.setUpdateEntertainmentLicenceTime(new Date());
         return storeInfoMapper.updateById(storeInfo);
@@ -488,7 +490,7 @@ public class LicenseServiceImpl implements LicenseService {
      * @return 证照历史记录VO列表
      */
     @Override
-    public List<StoreLicenseHistoryDto> queryEntertainmentByStatusList (Integer storeId) {
+    public List<StoreLicenseHistoryDto> queryEntertainmentByStatusList(Integer storeId) {
 
         List<StoreLicenseHistory> licenseList = licenseHistoryMapper.queryLicenceByStatusList(storeId, 3, 1);
 

+ 16 - 1
alien-store/src/main/java/shop/alien/store/config/WebSocketProcess.java

@@ -30,6 +30,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import javax.websocket.*;
 import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
+import java.io.EOFException;
+import java.nio.channels.ClosedChannelException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -256,13 +258,26 @@ public class WebSocketProcess implements ApplicationContextAware {
         }
     }
 
+    private static boolean isBenignSocketDisconnect(Throwable error) {
+        for (Throwable t = error; t != null; t = t.getCause()) {
+            if (t instanceof EOFException || t instanceof ClosedChannelException) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * 连接发生异常时候触发
      */
     @OnError
     public void onError(@PathParam("sendId") String id, Throwable error) {
         try {
-            log.error("WebSocketProcess.onError() Error,id={}, Msg=", id, error);
+            if (isBenignSocketDisconnect(error)) {
+                log.warn("WebSocketProcess.onError() 连接已关闭或读流结束(可忽略), id={}, summary={}", id, error.toString());
+            } else {
+                log.error("WebSocketProcess.onError() Error,id={}, Msg=", id, error);
+            }
             // 发生错误时主动移除,防止僵尸连接
             concurrentHashMap.remove(id, this);
             connectionInfoMap.remove(id);

+ 20 - 19
alien-store/src/main/java/shop/alien/store/service/LifeUserService.java

@@ -19,22 +19,13 @@ import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import shop.alien.config.properties.RiskControlProperties;
-import shop.alien.entity.result.R;
 import shop.alien.entity.second.LifeUserLog;
 import shop.alien.entity.second.SecondRiskControlRecord;
-import shop.alien.entity.store.LifeFans;
-import shop.alien.entity.store.LifeNotice;
-import shop.alien.entity.store.LifeUser;
-import shop.alien.entity.store.PushDeviceOwnerType;
-import shop.alien.entity.store.StoreUser;
+import shop.alien.entity.store.*;
 import shop.alien.entity.store.vo.LifeMessageVo;
 import shop.alien.entity.store.vo.LifeUserVo;
 import shop.alien.entity.store.vo.WebSocketVo;
-import shop.alien.mapper.LifeFansMapper;
-import shop.alien.mapper.LifeMessageMapper;
-import shop.alien.mapper.LifeNoticeMapper;
-import shop.alien.mapper.LifeUserMapper;
-import shop.alien.mapper.StoreUserMapper;
+import shop.alien.mapper.*;
 import shop.alien.mapper.second.LifeUserLogMapper;
 import shop.alien.mapper.second.SecondRiskControlRecordMapper;
 import shop.alien.mapper.second.SecondUserCreditMapper;
@@ -57,7 +48,9 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
 
-    /** App 点击推送后跳转页面(与动态点赞通知一致) */
+    /**
+     * App 点击推送后跳转页面(与动态点赞通知一致)
+     */
     private static final String FOLLOW_APP_PUSH_OPEN_PATH =
             "pages/secondHandTransactions/pages/message/noticesAndMessage";
 
@@ -127,7 +120,15 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
 
     public int addFans(LifeFans fans) {
         fans.setCreatedTime(new Date());
-        int num = lifeFansMapper.insert(fans);
+        LambdaQueryWrapper<LifeFans> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(LifeFans::getFollowedId, fans.getFollowedId())
+                .eq(LifeFans::getFansId, fans.getFansId())
+                .eq(LifeFans::getDeleteFlag, 0);
+        int num = lifeFansMapper.selectCount(lambdaQueryWrapper);
+        if (num != 0) {
+            return 1;
+        }
+        lifeFansMapper.insert(fans);
 
         if (num == 1) {
             LifeNotice notice = new LifeNotice();
@@ -156,7 +157,7 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
                 lifeNoticeMapper.insert(notice);
 
                 // 发送系统通知开关
-                if(uniPushOn) {
+                if (uniPushOn) {
                     try {
                         sendFollowRelationAppPush(fans.getFollowedId());
                     } catch (Exception e) {
@@ -248,11 +249,11 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
         QueryWrapper<LifeUserVo> queryWrapper = new QueryWrapper<>();
         if (StringUtils.isNotEmpty(vo.getSearchName())) {
             queryWrapper.and(wrapper -> wrapper
-                .like("a.storeUserName", vo.getSearchName())
-                .or()
-                .like("a.phoneId", vo.getSearchName())
-                .or()
-                .like("a.accountName", vo.getSearchName())
+                    .like("a.storeUserName", vo.getSearchName())
+                    .or()
+                    .like("a.phoneId", vo.getSearchName())
+                    .or()
+                    .like("a.accountName", vo.getSearchName())
             );
         }
         IPage<LifeUserVo> voList = lifeUserMapper.getStoreAndUserByName(new Page<>(vo.getPage(), vo.getSize()), queryWrapper);

+ 8 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreStaffTitleServiceImpl.java

@@ -1,6 +1,7 @@
 package shop.alien.store.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -106,6 +107,13 @@ public class StoreStaffTitleServiceImpl extends ServiceImpl<StoreStaffTitleMappe
             throw new IllegalArgumentException("标题名称不能为空");
         }
 
+        // TODO 去重
+        List<StoreStaffTitle> titleName = storeStaffTitleMapper.selectList(new QueryWrapper<StoreStaffTitle>().eq("store_id",storeStaffTitle.getStoreId()).eq("title_name", storeStaffTitle.getTitleName()));
+        if ( !titleName.isEmpty() ) {
+            log.warn("新增员工标题失败,标题名称重复");
+            throw new IllegalArgumentException("标题名称不能重复");
+        }
+
         try {
             // 自动计算员工数量
             int staffCount = calculateStaffCount(storeStaffTitle.getStaffIds());

+ 3 - 3
alien-store/src/main/java/shop/alien/store/strategy/merchantPayment/impl/MerchantAlipayPaymentStrategyImpl.java

@@ -252,9 +252,9 @@ public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrateg
             return R.fail("门店ID和商户订单号不能为空");
         }
         StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
-        if (config == null) {
-            return R.fail("该门店未配置支付参数");
-        }
+//        if (config == null) {
+//            return R.fail("该门店未配置支付参数");
+//        }
         MerchantPaymentOrder paymentOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
         if (paymentOrder == null) {
             return R.fail("支付单不存在");