Selaa lähdekoodia

支付发送消息 开屏广告 IM发送map重复key报错

yuhongqi 19 tuntia sitten
vanhempi
commit
0bbf4d6d4b

+ 11 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreProductScrmController.java

@@ -70,6 +70,17 @@ public class FsStoreProductScrmController extends BaseController
         return R.ok();
     }
 
+    /**
+     * 批量修改商品上下架、商城展示、所属公司
+     */
+    @PreAuthorize("@ss.hasPermi('store:storeProduct:edit')")
+    @PostMapping("/bulkUpdate")
+    @Log(title = "商品管理", businessType = BusinessType.UPDATE, isStoreLog = true, logParam = {"商品", "批量修改商品信息"})
+    public R bulkUpdate(@RequestBody ModifyMoreDTO modifyMoreDTO) {
+        fsStoreProductService.batchModify(modifyMoreDTO);
+        return R.ok();
+    }
+
     @PreAuthorize("@ss.hasPermi('store:storeProduct:list')")
     @PostMapping("/batchAudit")
     @Log(title = "商品审核", businessType = BusinessType.AUDIT,isStoreLog = true,logParam = {"商品","批量审核商品信息"},

+ 1 - 1
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -872,7 +872,7 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
 //            String sortLink = domainName + link.getRealLink().replace("/#","");
 //            return R.ok().put("url", sortLink).put("link", random).put("linkId", link.getLinkId());
             //没人用我先注释了,手动发课 直接用 链接带参数
-            if (CloudHostUtils.hasCloudHostName("中康","蒙牛", "鸿森堂")){
+            if (CloudHostUtils.hasCloudHostName("中康","蒙牛", "鸿森堂","北京卓美")){
                 String domainName = getDomainName(param.getCompanyUserId(), config);
                 String encodedCourseJson = URLEncoder.encode(courseJson, "UTF-8");
                 String sortLink = domainName +appRealLink+ encodedCourseJson;

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -508,4 +508,7 @@ public interface FsUserMapper
     List<AppSalesCourseStatisticsVO> selectAppSalesNewUserCountVO(FsCourseWatchLogStatisticsListParam param);
 
     int updateMpOpenIdByUserId(@Param("userId") Long userId, @Param("openId") String openId);
+
+    @Update("update fs_user set password = #{password} where user_id = #{userId}")
+    void updatePasswordByUserId(FsUser user);
 }

+ 45 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/MergedOrderMapper.java

@@ -66,7 +66,7 @@ public interface MergedOrderMapper
      * @return 订单总数
      */
     long countMergedOrderList(@Param("maps") MergedOrderQueryParam param);
-    
+
     /**
      * 查询合并的售后列表(商城售后+直播售后)
      *
@@ -154,5 +154,49 @@ public interface MergedOrderMapper
             "ORDER BY create_time DESC " +
             "</script>"})
     List<FsMergedOrderListQueryVO> selectMergedOrderListVO(@Param("maps") FsMyStoreOrderQueryParam param);
+
+    /**
+     * 查询合并的订单列表(商城订单+直播订单)(新)
+     *
+     * @param param 查询参数
+     * @return 合并后的订单列表
+     */
+    @Select({"<script> " +
+            "SELECT * FROM ( " +
+            "  SELECT " +
+            "    o.id, " +
+            "    NULL AS order_id, " +
+            "    NULL AS live_id, " +
+            "    NULL AS after_sales_id, " +
+            "    o.order_code, " +
+            "    o.pay_price, " +
+            "    o.status, " +
+            "    o.is_package, " +
+            "    o.package_json, " +
+            "    o.item_json, " +
+            "    o.delivery_id, " +
+            "    o.finish_time, " +
+            "    o.create_time, " +
+            "    NULL AS total_num, " +
+            "    NULL AS discount_money, " +
+            "    o.order_type " +
+            "  FROM fs_store_order_scrm o " +
+            "  WHERE o.is_del = 0 AND o.is_sys_del = 0 " +
+            "  <if test = 'maps.status != null and maps.status != \"\"'> " +
+            "    AND o.status = #{maps.status} " +
+            "  </if> " +
+            "  <if test = 'maps.keyword != null and maps.keyword != \"\"'> " +
+            "    AND o.order_code LIKE CONCAT('%', #{maps.keyword}, '%') " +
+            "  </if> " +
+            "  <if test = 'maps.deliveryStatus != null'> " +
+            "    AND o.delivery_status = #{maps.deliveryStatus} " +
+            "  </if> " +
+            "  <if test = 'maps.userId != null'> " +
+            "    AND o.user_id = #{maps.userId} " +
+            "  </if> " +
+            ") AS merged_orders " +
+            "ORDER BY create_time DESC " +
+            "</script>"})
+    List<FsMergedOrderListQueryVO> selectMergedOrderListNewVO(@Param("maps") FsMyStoreOrderQueryParam param);
 }
 

+ 3 - 1
fs-service/src/main/java/com/fs/hisStore/service/IMergedOrderService.java

@@ -27,7 +27,7 @@ public interface IMergedOrderService
     List<FsMergedOrderListQueryVO> selectMergedOrderListVO(FsMyStoreOrderQueryParam param);
 
     List<MergedOrderVO> selectMergedOrderList(MergedOrderQueryParam param);
-    
+
     /**
      * 统计合并订单总数
      *
@@ -87,5 +87,7 @@ public interface IMergedOrderService
      * @return 结果
      */
     R deleteOrder(String userId, MergedOrderDeleteParam param);
+
+    List<FsMergedOrderListQueryVO> selectMergedOrderListNewVO(FsMyStoreOrderQueryParam param);
 }
 

+ 44 - 9
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -139,9 +139,11 @@ import com.fs.wx.order.service.ExpressToWxService;
 import com.fs.wx.order.service.ShippingService;
 import com.fs.wxwork.dto.WxWorkResponseDTO;
 import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
+import com.fs.wxwork.dto.WxWorkSendTextMsgRespDTO;
 import com.fs.wxwork.dto.WxWorkUserId2VidDTO;
 import com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO;
 import com.fs.wxwork.dto.WxwSendCDNImgMsgDTO;
+import com.fs.wxwork.dto.WxwSendCDNImgMsgRespDTO;
 import com.fs.wxwork.dto.WxwUploadCdnLinkImgDTO;
 import com.fs.wxwork.dto.WxwUploadCdnLinkImgRespDTO;
 import com.fs.wxwork.service.WxWorkService;
@@ -506,6 +508,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             "尊敬的VIP,感谢您的信任与购买~若后续遇到任何售后相关问题,欢迎您第一时间联系专属销售对接处理或拨打客服电话400-0909-575。我们将竭诚为您高效解决问题,保障您的权益。";
 
     private static final String PAY_SUCCESS_MSG_REDIS_KEY = "fs:pay:success:msg:send:";
+
+    /** 同一企微账号 + 外部联系人,一天内只发一次支付成功消息 */
+    private static final String PAY_SUCCESS_MSG_CONTACT_REDIS_KEY = "fs:pay:success:msg:contact:";
     @PostConstruct
     public void initErpServiceMap() {
         erpServiceMap = new HashMap<>();
@@ -7526,6 +7531,15 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     || qwUser.getServerStatus() != 1 || qwUser.getIpadStatus() != 1) {
                 continue;
             }
+            String externalUserId = externalContact.getExternalUserId();
+            if (StringUtils.isEmpty(externalUserId)) {
+                continue;
+            }
+            if (isPaySuccessMsgSentToday(qwUserId, externalUserId)) {
+                log.info("支付成功企微消息今日已发送,跳过,qwUserId={},externalUserId={},orderId={}",
+                        qwUserId, externalUserId, orderId);
+                continue;
+            }
             WxWorkUserId2VidDTO wxWorkUserId2VidDTO = new WxWorkUserId2VidDTO();
             wxWorkUserId2VidDTO.setOpenid(Collections.singletonList(externalContact.getExternalUserId()));
             wxWorkUserId2VidDTO.setUuid(qwUser.getUid());
@@ -7540,26 +7554,24 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             textMsgDto.setUuid(qwUser.getUid());
             textMsgDto.setContent(PAY_SUCCESS_MSG);
             textMsgDto.setIsRoom(false);
-            wxWorkService.SendTextMsg(textMsgDto, qwUser.getServerId());
+            WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> textResp = wxWorkService.SendTextMsg(textMsgDto, qwUser.getServerId());
             /** 支付成功企微消息配图,在配置文件中设置 store.pay-success.image-url */
             String paySuccessImageUrl = "https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/vip-ele.jpg";
-            if (StringUtils.isNotEmpty(paySuccessImageUrl)) {
-                sendWxImageMsg(sendId, qwUser.getUid(), qwUser.getServerId(), paySuccessImageUrl);
-            } else {
-                log.warn("支付成功企微配图未配置,跳过图片发送,orderId:{}", orderId);
-            }
+            sendWxImageMsg(sendId, qwUser.getUid(), qwUser.getServerId(), paySuccessImageUrl);
+
+            markPaySuccessMsgSentToday(qwUserId, externalUserId);
             return;
         }
     }
 
-    private void sendWxImageMsg(Long sendId, String uuid, Long serverId, String imageUrl) {
+    private boolean sendWxImageMsg(Long sendId, String uuid, Long serverId, String imageUrl) {
         WxwUploadCdnLinkImgDTO uploadDto = new WxwUploadCdnLinkImgDTO();
         uploadDto.setUuid(uuid);
         uploadDto.setUrl(imageUrl);
         WxWorkResponseDTO<WxwUploadCdnLinkImgRespDTO> uploadResp = wxWorkService.uploadCdnLinkImg(uploadDto, serverId);
         if (uploadResp == null || !"成功".equals(uploadResp.getErrmsg()) || uploadResp.getData() == null) {
             log.warn("支付成功消息图片上传CDN失败,sendId:{},imageUrl:{}", sendId, imageUrl);
-            return;
+            return false;
         }
         WxwUploadCdnLinkImgRespDTO imgData = uploadResp.getData();
         WxwSendCDNImgMsgDTO imgMsgDto = new WxwSendCDNImgMsgDTO();
@@ -7570,7 +7582,30 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         imgMsgDto.setAeskey(imgData.getAes_key());
         imgMsgDto.setMd5(imgData.getMd5());
         imgMsgDto.setFileSize(imgData.getSize());
-        wxWorkService.SendCDNImgMsg(imgMsgDto, serverId);
+        WxWorkResponseDTO<WxwSendCDNImgMsgRespDTO> imgResp = wxWorkService.SendCDNImgMsg(imgMsgDto, serverId);
+        return isWxWorkSuccess(imgResp);
+    }
+
+    private String buildPaySuccessMsgContactKey(Long qwUserId, String externalUserId) {
+        return PAY_SUCCESS_MSG_CONTACT_REDIS_KEY + qwUserId + ":" + externalUserId;
+    }
+
+    private boolean isPaySuccessMsgSentToday(Long qwUserId, String externalUserId) {
+        return redisCache.getCacheObject(buildPaySuccessMsgContactKey(qwUserId, externalUserId)) != null;
+    }
+
+    private void markPaySuccessMsgSentToday(Long qwUserId, String externalUserId) {
+        redisCache.setCacheObject(buildPaySuccessMsgContactKey(qwUserId, externalUserId), "1", 1, TimeUnit.DAYS);
+    }
+
+    private boolean isWxWorkSuccess(WxWorkResponseDTO<?> resp) {
+        if (resp == null) {
+            return false;
+        }
+        if (resp.getErrcode() != null && resp.getErrcode() == 0) {
+            return true;
+        }
+        return "成功".equals(resp.getErrmsg()) || "ok".equalsIgnoreCase(resp.getErrmsg());
     }
 
     @Override

+ 68 - 12
fs-service/src/main/java/com/fs/hisStore/service/impl/MergedOrderServiceImpl.java

@@ -103,7 +103,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
 
         return list;
     }
-    
+
     /**
      * 统计合并订单总数
      */
@@ -204,7 +204,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
     @Override
     public List<MergedAfterSalesVO> selectMergedAfterSalesList(MergedAfterSalesQueryParam param) {
         List<MergedAfterSalesVO> list = mergedOrderMapper.selectMergedAfterSalesList(param);
-        
+
         // 填充售后商品列表
         for (MergedAfterSalesVO vo : list) {
             if (vo.getAfterSalesType() != null && vo.getAfterSalesType() == 1) {
@@ -219,7 +219,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
                 vo.setItems(items);
             }
         }
-        
+
         return list;
     }
 
@@ -238,7 +238,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
         } catch (Exception e) {
             // 商城订单不存在,继续尝试直播订单
         }
-        
+
         // 尝试查询直播订单
         com.fs.live.domain.LiveOrder liveOrder = liveOrderService.selectLiveOrderByOrderCode(param.getOrderCode());
         if (liveOrder != null) {
@@ -263,7 +263,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
             }
             return liveAfterSalesService.applyForAfterSales(userId, liveParam);
         }
-        
+
         return R.error("订单不存在");
     }
 
@@ -306,7 +306,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
     @Override
     public MergedAfterSalesVO selectMergedAfterSalesById(Long salesId, Integer afterSalesType) {
         MergedAfterSalesVO vo = new MergedAfterSalesVO();
-        
+
         if (afterSalesType != null && afterSalesType == 1) {
             // 商城售后
             FsStoreAfterSalesScrm storeAfterSales = storeAfterSalesService.selectFsStoreAfterSalesById(salesId);
@@ -315,7 +315,7 @@ public class MergedOrderServiceImpl implements IMergedOrderService
                 vo.setAfterSalesType(1);
                 vo.setAfterSalesTypeName("商城售后");
                 vo.setOrderCode(storeAfterSales.getOrderCode());
-                
+
                 // 填充商品列表
                 FsStoreAfterSalesItemScrm itemParam = new FsStoreAfterSalesItemScrm();
                 itemParam.setStoreAfterSalesId(salesId);
@@ -329,19 +329,19 @@ public class MergedOrderServiceImpl implements IMergedOrderService
                 BeanUtils.copyProperties(liveAfterSales, vo);
                 vo.setAfterSalesType(2);
                 vo.setAfterSalesTypeName("直播售后");
-                
+
                 // 查询订单号
                 com.fs.live.domain.LiveOrder liveOrder = liveOrderService.selectLiveOrderByOrderId(String.valueOf(liveAfterSales.getOrderId()));
                 if (liveOrder != null) {
                     vo.setOrderCode(liveOrder.getOrderCode());
                 }
-                
+
                 // 填充商品列表
                 List<LiveAfterSalesItem> items = liveAfterSalesItemService.selectLiveAfterSalesItemByAfterId(salesId);
                 vo.setItems(items);
             }
         }
-        
+
         return vo;
     }
 
@@ -349,11 +349,11 @@ public class MergedOrderServiceImpl implements IMergedOrderService
     public R deleteOrder(String userId, MergedOrderDeleteParam param) {
         Long orderId = param.getOrderId();
         Integer orderType = param.getOrderType();
-        
+
         if (orderType == null) {
             return R.error("订单类型不能为空");
         }
-        
+
         if (orderType == 1) {
             // 商城订单
             com.fs.hisStore.domain.FsStoreOrderScrm storeOrder = storeOrderService.selectFsStoreOrderById(orderId);
@@ -394,5 +394,61 @@ public class MergedOrderServiceImpl implements IMergedOrderService
             return R.error("订单类型错误");
         }
     }
+
+    @Override
+    public List<FsMergedOrderListQueryVO> selectMergedOrderListNewVO(FsMyStoreOrderQueryParam param) {
+        List<FsMergedOrderListQueryVO> list = mergedOrderMapper.selectMergedOrderListNewVO(param);
+
+        for (FsMergedOrderListQueryVO vo : list)
+        {
+
+            // 处理商品JSON
+            if (StringUtils.isNotEmpty(vo.getItemJson()))
+            {
+                List<FsStoreOrderItemVO> items = new ArrayList<>();
+                JSONArray jsonArray = JSONUtil.parseArray(vo.getItemJson());
+                items = JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
+                if (items != null && items.size() > 0)
+                {
+                    vo.setItems(items);
+                }
+
+
+            }
+
+            // 处理是否可以申请售后
+            vo.setIsAfterSales(0);
+            if (vo.getStatus() != null && vo.getStatus().equals(OrderInfoEnum.STATUS_3.getValue()))
+            {
+                // 已完成订单
+                vo.setIsAfterSales(1);
+                if (vo.getFinishTime() != null)
+                {
+                    String json = configService.selectConfigByKey("his.store");
+                    if (StringUtils.isNotEmpty(json))
+                    {
+                        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+                        if (storeConfig != null && storeConfig.getStoreAfterSalesDay() != null && storeConfig.getStoreAfterSalesDay() > 0)
+                        {
+                            // 判断完成时间是否超过指定时间
+                            Calendar calendar = new GregorianCalendar();
+                            calendar.setTime(vo.getFinishTime());
+                            calendar.add(Calendar.DATE, storeConfig.getStoreAfterSalesDay());
+                            if (calendar.getTime().getTime() < new Date().getTime())
+                            {
+                                vo.setIsAfterSales(0);
+                            }
+                        }
+                    }
+                }
+            }
+            else if (vo.getStatus() != null && (vo.getStatus() == 1 || vo.getStatus() == 2))
+            {
+                vo.setIsAfterSales(1);
+            }
+        }
+
+        return list;
+    }
 }
 

+ 32 - 11
fs-service/src/main/java/com/fs/im/service/impl/OpenIMServiceImpl.java

@@ -1648,17 +1648,38 @@ public class OpenIMServiceImpl implements OpenIMService {
             // 发送成功的
             if(openImBatchResponseDataDTO != null){
                 List<OpenImBatchResponseDataDTO.Results> results = openImBatchResponseDataDTO.getResults();
-                Map<String, OpenImBatchResponseDataDTO.Results> resultsMap = results.stream().collect(Collectors.toMap(OpenImBatchResponseDataDTO.Results::getRecvID, v -> v));
-                List<String> actualRecvIdList = openImBatchResponseDataDTO.getResults().stream().map(OpenImBatchResponseDataDTO.Results::getRecvID).collect(Collectors.toList());
-                List<FsImMsgSendDetail> successList = imMsgSendDetailList.stream().filter(v -> actualRecvIdList.contains("U" + v.getUserId())).map(v -> {
-                    v.setActualSendTime(new Date(resultsMap.get("U" + v.getUserId()).getSendTime()))
-                            .setSendStatus(1).setParamJson(JSON.toJSONString(openImBatchMsgDTO))
-                            .setStatus(0)
-                            .setResultMessage(JSON.toJSONString(openImBatchResponseDataDTO))
-                            .setUpdateTime(new Date());
-                    return v;
-                }).collect(Collectors.toList());
-                updateList.addAll(successList);
+                if (results != null && !results.isEmpty()) {
+                    Map<String, OpenImBatchResponseDataDTO.Results> resultsMap = results.stream()
+                            .filter(r -> StringUtils.isNotBlank(r.getRecvID()))
+                            .collect(Collectors.toMap(
+                                    OpenImBatchResponseDataDTO.Results::getRecvID,
+                                    v -> v,
+                                    (exist, replace) -> {
+                                        if (exist.getSendTime() == null) {
+                                            return replace;
+                                        }
+                                        if (replace.getSendTime() == null) {
+                                            return exist;
+                                        }
+                                        return replace.getSendTime() >= exist.getSendTime() ? replace : exist;
+                                    }
+                            ));
+                    List<String> actualRecvIdList = new ArrayList<>(resultsMap.keySet());
+                    List<FsImMsgSendDetail> successList = imMsgSendDetailList.stream()
+                            .filter(v -> actualRecvIdList.contains("U" + v.getUserId()))
+                            .map(v -> {
+                                OpenImBatchResponseDataDTO.Results result = resultsMap.get("U" + v.getUserId());
+                                if (result != null && result.getSendTime() != null) {
+                                    v.setActualSendTime(new Date(result.getSendTime()));
+                                }
+                                v.setSendStatus(1).setParamJson(JSON.toJSONString(openImBatchMsgDTO))
+                                        .setStatus(0)
+                                        .setResultMessage(JSON.toJSONString(openImBatchResponseDataDTO))
+                                        .setUpdateTime(new Date());
+                                return v;
+                            }).collect(Collectors.toList());
+                    updateList.addAll(successList);
+                }
             }
             fsImMsgSendDetailServiceImpl.updateBatchById(updateList);
         }

+ 5 - 0
fs-service/src/main/java/com/fs/statis/dto/ModifyMoreDTO.java

@@ -27,5 +27,10 @@ public class ModifyMoreDTO implements Serializable {
      */
     private String companyIds;
 
+    /**
+     * 是否更新所属公司(含清空)
+     */
+    private Boolean updateCompanyIds;
+
     private String isAudit;
 }

+ 1 - 1
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -462,7 +462,7 @@
             <if test="goodsIsShow != null">
                 is_display = #{goodsIsShow},
             </if>
-            <if test="companyIds != null and companyIds != ''">
+            <if test="updateCompanyIds != null and updateCompanyIds">
                 company_ids = #{companyIds},
             </if>
             <if test="isAudit != null and isAudit != ''">

+ 42 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppLoginController.java

@@ -11,6 +11,7 @@ import com.fs.common.VerifyCodeUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.enums.BusinessType;
@@ -37,6 +38,7 @@ import com.fs.his.vo.FsUserRegisterParam;
 import com.fs.im.dto.OpenImResponseDTO;
 import com.fs.im.service.OpenIMService;
 import com.fs.qw.service.ILuckyBagService;
+import com.fs.system.service.ISysDictTypeService;
 import com.fs.utils.ContentCheckUtil;
 import io.netty.util.internal.StringUtil;
 import io.swagger.annotations.Api;
@@ -62,6 +64,9 @@ import static com.fs.his.utils.PhoneUtil.encryptPhoneOldKey;
 @RequestMapping(value="/app/app")
 @Slf4j
 public class AppLoginController extends AppBaseController{
+    private static final String USER_DEFAULT_PASSWORD_DICT_TYPE = "user-default-password";
+    private static final String USER_DEFAULT_PASSWORD_FALLBACK = "zm12345678";
+
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
     @Autowired
     private IFsUserService userService;
@@ -95,6 +100,9 @@ public class AppLoginController extends AppBaseController{
 
     @Autowired
     private FsUserWxMapper fsUserWxMapper;
+
+    @Autowired
+    private ISysDictTypeService dictTypeService;
     @ApiOperation("注册app用户")
     @PostMapping("/register")
     @RepeatSubmit
@@ -159,6 +167,9 @@ public class AppLoginController extends AppBaseController{
         if(CollectionUtil.isEmpty(user)){
             user = userService.selectFsUserListByPhone(encryptPhoneOldKey(phone));
         }
+        if (CollectionUtil.isEmpty(user)){
+            user = userService.selectFsUserListByPhone(phone);
+        }
         if (!CollectionUtil.isEmpty(user)){
             return R.error("此电话号码已注册");
         }
@@ -199,6 +210,9 @@ public class AppLoginController extends AppBaseController{
             String s = encryptPhoneOldKey(phone);
             users = userService.selectFsUserListByPhone(s);
         }
+        if (CollectionUtil.isEmpty(users)){
+            users = userService.selectFsUserListByPhone(phone);
+        }
         if (!CollectionUtil.isEmpty(users)){
             return R.error("此账号已经注册");
         }
@@ -671,6 +685,9 @@ public class AppLoginController extends AppBaseController{
         if (CollectionUtil.isEmpty(user)){
             user = userService.selectFsUserListByPhone(encryptPhoneOldKey(phone));
         }
+        if (CollectionUtil.isEmpty(user)){
+            user = userService.selectFsUserListByPhone(phone);
+        }
         if (CollectionUtil.isEmpty(user)){
             return R.error("此电话号码未绑定用户");
         }
@@ -876,6 +893,9 @@ public class AppLoginController extends AppBaseController{
                     keepUser.setLoginDevice(param.getLoginDevice() != null ? param.getLoginDevice() : null);
                     keepUser.setNickName(nickname);
                     keepUser.setAvatar(avatar);
+                    if (keepUser.getPassword() == null && deleteUser.getPassword() != null) {
+                        keepUser.setPassword(deleteUser.getPassword());
+                    }
                     keepUser.setSex(sex);
                     String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
                     keepUser.setLastIp(ipAddr);
@@ -979,6 +999,13 @@ public class AppLoginController extends AppBaseController{
         if (usersByPhone.size()==1){
             user = usersByPhone.get(0);
             // 校验用户是否存在及账号状态
+            // 卓美 设置默认密码
+            if (StringUtils.isEmpty(user.getPassword())) {
+                user.setPassword(Md5Utils.hash(getUserDefaultPassword()));
+                if (user.getPassword() != null) {
+                    userMapper.updatePasswordByUserId(user);
+                }
+            }
             if (user == null) {
                 return R.error("账号不存在,请先注册账号");
             } else if (user.getStatus() == 0&&StringUtils.isNotEmpty(param.getSource())&&!param.getSource().equals("iOS")) {
@@ -1379,4 +1406,19 @@ public class AppLoginController extends AppBaseController{
         map.put("user", fsUser);
         return R.ok(map);
     }
+
+    /**
+     * 从字典 user-default-password 读取用户默认明文密码,未配置时使用 zm12345678
+     */
+    private String getUserDefaultPassword() {
+        List<SysDictData> dictList = dictTypeService.selectDictDataByType(USER_DEFAULT_PASSWORD_DICT_TYPE);
+        if (CollectionUtil.isNotEmpty(dictList)) {
+            for (SysDictData dictData : dictList) {
+                if (dictData != null && StringUtils.isNotBlank(dictData.getDictValue())) {
+                    return dictData.getDictValue().trim();
+                }
+            }
+        }
+        return null;
+    }
 }

+ 60 - 0
fs-user-app/src/main/java/com/fs/app/controller/StoreActivityController.java

@@ -2,12 +2,14 @@ package com.fs.app.controller;
 
 
 import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.utils.StringUtils;
 import com.fs.his.domain.FsPackage;
 import com.fs.his.service.IFsPackageService;
 import com.fs.his.service.IFsStoreProductService;
 import com.fs.store.domain.FsStoreActivity;
 import com.fs.store.service.IFsStoreActivityService;
+import com.fs.system.service.ISysDictTypeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,7 +19,10 @@ import com.fs.store.vo.FsStoreProductActivityListVO;
 import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 
 @Api("活动接口")
@@ -25,6 +30,14 @@ import java.util.List;
 @RequestMapping(value="/app/activity")
 public class StoreActivityController extends  AppBaseController {
 
+    private static final String ACTIVITY_GUIDE_VIEWED_KEY = "fs:store:activity:guide:viewed:";
+
+    /** 活动引导弹窗缓存时长:30天 */
+    private static final int ACTIVITY_GUIDE_CACHE_DAYS = 30;
+
+    /** 活动引导字典类型:dict_sort 为展示顺序,dict_value 为引导内容(如图片地址/跳转链接) */
+    private static final String ACTIVITY_GUIDE_DICT_TYPE = "store_activity_guide";
+
     @Autowired
     private IFsStoreActivityService activityService;
 
@@ -34,6 +47,9 @@ public class StoreActivityController extends  AppBaseController {
     @Autowired
     private IFsStoreProductService productService;
 
+    @Autowired
+    private ISysDictTypeService dictTypeService;
+
     @ApiOperation("获取活动")
     @GetMapping("/getStoreActivity")
     public R getStoreActivity( HttpServletRequest request){
@@ -74,6 +90,50 @@ public class StoreActivityController extends  AppBaseController {
         return R.ok();
     }
 
+    @ApiOperation("获取活动引导弹窗")
+    @GetMapping("/getStoreActivityGuide")
+    public R getStoreActivityGuide() {
+        String userId = getUserId();
+        if (StringUtils.isEmpty(userId)) {
+            return R.error("用户未登录");
+        }
+        String cacheKey = ACTIVITY_GUIDE_VIEWED_KEY + userId;
+        if (redisCache.getCacheObject(cacheKey) != null) {
+            return R.ok().put("viewed", true);
+        }
+
+        // 按字典 dict_sort 顺序组装引导数组
+        List<Map<String, Object>> guideData = loadActivityGuideData();
+        if (guideData.isEmpty()) {
+            return R.ok().put("viewed", true);
+        }
+
+        redisCache.setCacheObject(cacheKey, "1", ACTIVITY_GUIDE_CACHE_DAYS, TimeUnit.DAYS);
+        return R.ok().put("viewed", false).put("guideData", guideData);
+    }
+
+    /**
+     * 从字典 store_activity_guide 读取引导数据,按 dict_sort 升序返回数组
+     */
+    private List<Map<String, Object>> loadActivityGuideData() {
+        List<Map<String, Object>> guideData = new ArrayList<>();
+        List<SysDictData> dictList = dictTypeService.selectDictDataByType(ACTIVITY_GUIDE_DICT_TYPE);
+        if (dictList == null || dictList.isEmpty()) {
+            return guideData;
+        }
+        for (SysDictData dictData : dictList) {
+            if (dictData == null || StringUtils.isBlank(dictData.getDictValue())) {
+                continue;
+            }
+            Map<String, Object> item = new HashMap<>(3);
+            item.put("sort", dictData.getDictSort());
+            item.put("label", dictData.getDictLabel());
+            item.put("value", dictData.getDictValue());
+            guideData.add(item);
+        }
+        return guideData;
+    }
+
 
 
 }

+ 34 - 5
fs-user-app/src/main/java/com/fs/app/controller/live/OrderController.java

@@ -42,18 +42,47 @@ public class OrderController extends AppBaseController {
         {
             param.setPageSize(10);
         }
-        
+
         PageHelper.startPage(param.getPage(), param.getPageSize());
-        
+
         // 设置用户ID
         param.setUserId(Long.parseLong(getUserId()));
-        
+
         // 查询合并订单列表
         List<FsMergedOrderListQueryVO> list = mergedOrderService.selectMergedOrderListVO(param);
-        
+
         // 封装分页信息
         PageInfo<FsMergedOrderListQueryVO> listPageInfo = new PageInfo<>(list);
-        
+
+        return R.ok().put("data", listPageInfo);
+    }
+
+    @Login
+    @ApiOperation("获取我的合并订单列表(商城订单+直播订单)")
+    @GetMapping("/getMyMergedOrderListNew")
+    public R getMyMergedOrderListNew(FsMyStoreOrderQueryParam param, HttpServletRequest request)
+    {
+        // 设置分页参数
+        if (param.getPage() == null || param.getPage() < 1)
+        {
+            param.setPage(1);
+        }
+        if (param.getPageSize() == null || param.getPageSize() < 1)
+        {
+            param.setPageSize(10);
+        }
+
+        PageHelper.startPage(param.getPage(), param.getPageSize());
+
+        // 设置用户ID
+        param.setUserId(Long.parseLong(getUserId()));
+
+        // 查询合并订单列表
+        List<FsMergedOrderListQueryVO> list = mergedOrderService.selectMergedOrderListNewVO(param);
+
+        // 封装分页信息
+        PageInfo<FsMergedOrderListQueryVO> listPageInfo = new PageInfo<>(list);
+
         return R.ok().put("data", listPageInfo);
     }