Răsfoiți Sursa

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

dujian 2 zile în urmă
părinte
comite
7f6db7fe4f

+ 15 - 1
alien-entity/src/main/java/shop/alien/entity/result/R.java

@@ -63,7 +63,7 @@ public class R<T> implements Serializable {
      */
     public static boolean isSuccess(@Nullable R<?> result) {
         return Optional.ofNullable(result)
-                .map(x -> ObjectUtils.nullSafeEquals(ResultCode.SUCCESS.code, x.code))
+                .map(x -> ObjectUtils.nullSafeEquals(ResultCode.SUCCESS.code, x.code) && x.isSuccess())
                 .orElse(Boolean.FALSE);
     }
 
@@ -158,6 +158,20 @@ public class R<T> implements Serializable {
         return new R<>(ResultCode.FAILURE, msg);
     }
 
+    /**
+     * 业务失败但 body 中 {@code code} 仍为 HTTP 200({@link APPConstant#SC_OK}),与部分移动端约定一致:
+     * 仅当 {@code success=false} 时表示失败;拦截器在 {@code code==200} 时仍 resolve 整包 JSON,便于展示 {@code msg}。
+     *
+     * @param msg 提示文案(如「当前店铺已删除。」)
+     */
+    public static <T> R<T> failWithOkStatus(String msg) {
+        R<T> r = new R<>();
+        r.setCode(APPConstant.SC_OK);
+        r.setSuccess(false);
+        r.setData(null);
+        r.setMsg(msg);
+        return r;
+    }
 
     /**
      * 返回R

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeDiscountCouponVo.java

@@ -54,6 +54,9 @@ public class LifeDiscountCouponVo {
     @ApiModelProperty(value = "已领取数量")
     private Integer quantityClaimed;
 
+    @ApiModelProperty(value = "好友赠券场景下,本店作为送出方已向好友发放的合计张数(life_discount_coupon_store_friend.single_qty;friend_store_user_id 归属本店、release_type=1)")
+    private Integer ownedQuantity;
+
     @ApiModelProperty(value = "券名称")
     private String name;
 

+ 23 - 0
alien-store/src/main/java/shop/alien/store/controller/LifeDiscountCouponController.java

@@ -114,6 +114,29 @@ public class LifeDiscountCouponController {
         return R.success("切换成功");
     }
 
+    @ApiOperation("获取优惠券详情(含好友赠券本店铺已送出数量)")
+    @ApiOperationSupport(order = 55)
+    @GetMapping("/getCouponDetailWithOwnedQty")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "couponId", value = "优惠券id(life_discount_coupon.id)", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "storeId", value = "店铺id(store_info.id)", dataType = "String", paramType = "query", required = true)
+    })
+    public R<LifeDiscountCouponVo> getCouponDetailWithOwnedQty(@ApiIgnore @TokenInfo UserLoginInfo userLoginInfo,
+                                                               @RequestParam(value = "couponId") String couponId,
+                                                               @RequestParam(value = "storeId") String storeId) {
+        log.info("LifeDiscountCouponController.getCouponDetailWithOwnedQty?couponId={}, storeId={}", couponId, storeId);
+        try {
+            LifeDiscountCouponVo vo = lifeDiscountCouponService.getCouponDetailWithFriendOwnedQty(couponId, storeId);
+            if (vo == null) {
+                return R.fail("优惠券不存在或参数无效");
+            }
+            return R.data(vo);
+        } catch (Exception e) {
+            log.error("LifeDiscountCouponController.getCouponDetailWithOwnedQty ERROR Msg={}", e.getMessage(), e);
+            return R.fail("查询失败");
+        }
+    }
+
     @ApiOperation("获取该优惠券的明细信息")
     @ApiOperationSupport(order = 5)
     @GetMapping("/getCounponDetailById")

+ 5 - 1
alien-store/src/main/java/shop/alien/store/controller/StoreClockInController.java

@@ -114,7 +114,11 @@ public class StoreClockInController {
     public R<StoreClockInVo> getStoreClockInById(@ApiIgnore @TokenInfo UserLoginInfo userLoginInfo, Integer id) {
         Integer userId = userLoginInfo != null ? userLoginInfo.getUserId() : null;
         log.info("StoreClockInController.getStoreClockInById?userId={},id={}", userId, id);
-        return R.data(storeClockInService.getStoreClockInById(id, userId));
+        try {
+            return R.data(storeClockInService.getStoreClockInById(id, userId));
+        } catch (IllegalArgumentException e) {
+            return R.failWithOkStatus(e.getMessage());
+        }
     }
 
     @ApiOperation("打卡记录筛选校验(年份各月是否有打卡、可选城市过滤、用户打卡涉及城市列表)")

+ 37 - 18
alien-store/src/main/java/shop/alien/store/controller/StoreImgController.java

@@ -90,6 +90,25 @@ public class StoreImgController {
         }
         Integer imgType = storeImgInfoVo.getImgType();
         Integer storeId = storeImgInfoVo.getStoreId();
+        // imgType=38:仅落库 store_img,不走环境相册、门店图片模式、异步取色、头图审核状态等分支
+        if (Integer.valueOf(38).equals(imgType)) {
+            int deleteCount = storeImgService.saveOrUpdateImg(storeId, imgType);
+            log.info("StoreImgController.saveOrUpdateImg imgType=38 store_img only, deleteCount={}", deleteCount);
+            for (StoreImg storeImg : storeImgList) {
+                if (storeImg != null) {
+                    storeImg.setStoreId(storeId);
+                    storeImg.setImgType(imgType);
+                }
+            }
+            Integer id = storeImgList.get(0).getId();
+            if (storeImgService.saveOrUpdateBatch(storeImgList)) {
+                if (id != null) {
+                    return R.success("修改成功");
+                }
+                return R.success("新增成功");
+            }
+            return R.fail("失败");
+        }
         // 图片由前端直连 AI 审核;服务端不再对门店图调用 moderate,避免保存被误拦截(仅与环境相册查询并行占位)
         CompletableFuture<AiContentModerationUtil.AuditResult> auditFuture = CompletableFuture
                 .completedFuture(new AiContentModerationUtil.AuditResult(true, null));
@@ -104,24 +123,24 @@ public class StoreImgController {
         if (!auditResult.isPassed()) {
             return R.fail(auditResult.getFailureReason());
         }
-        if (imgType != null && imgType == 4) {
-            List<StoreOfficialAlbum> albumList;
-            try {
-                albumList = albumFuture.get(10, TimeUnit.SECONDS);
-            } catch (Exception e) {
-                log.error("查询环境相册异常", e);
-                return R.fail("查询环境相册失败");
-            }
-            if (albumList == null || albumList.isEmpty()) {
-                return R.fail("没有默认环境相册");
-            }
-            StoreOfficialAlbum album = albumList.get(0);
-            storeImgList.forEach(storeImg -> storeImg.setBusinessId(album.getId()));
-            storeOfficialAlbumService.lambdaUpdate()
-                    .eq(StoreOfficialAlbum::getId, album.getId())
-                    .setSql("img_count = img_count + " + storeImgList.size())
-                    .update();
-        }
+//        if (imgType != null && imgType == 4) {
+//            List<StoreOfficialAlbum> albumList;
+//            try {
+//                albumList = albumFuture.get(10, TimeUnit.SECONDS);
+//            } catch (Exception e) {
+//                log.error("查询环境相册异常", e);
+//                return R.fail("查询环境相册失败");
+//            }
+//            if (albumList == null || albumList.isEmpty()) {
+//                return R.fail("没有默认环境相册");
+//            }
+//            StoreOfficialAlbum album = albumList.get(0);
+//            storeImgList.forEach(storeImg -> storeImg.setBusinessId(album.getId()));
+//            storeOfficialAlbumService.lambdaUpdate()
+//                    .eq(StoreOfficialAlbum::getId, album.getId())
+//                    .setSql("img_count = img_count + " + storeImgList.size())
+//                    .update();
+//        }
         boolean isHeadImage = imgType != null && (imgType == 20 || imgType == 21);
         // 清空storeid,imgType下图片
         int deleteCount = storeImgService.saveOrUpdateImg(storeImgInfoVo.getStoreId(),storeImgInfoVo.getImgType());

+ 10 - 0
alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponService.java

@@ -52,6 +52,16 @@ public interface LifeDiscountCouponService extends IService<LifeDiscountCoupon>
     LifeDiscountCouponVo getCounponDetailById(String counponId, UserLoginInfo userLoginInfo);
 
     /**
+     * 优惠券详情 + 好友赠券场景下本店铺作为送出方已向好友发放的合计数量(release_type=1):
+     * 对 life_discount_coupon_store_friend 中 friend_store_user_id 为本店任一 store_user.id 的记录,汇总 single_qty。
+     *
+     * @param couponId 优惠券主键 life_discount_coupon.id
+     * @param storeId  店铺 id(store_info.id)
+     * @return 详情 VO,含 ownedQuantity;券不存在或参数非法时返回 null
+     */
+    LifeDiscountCouponVo getCouponDetailWithFriendOwnedQty(String couponId, String storeId);
+
+    /**
      * 获取该用户该店铺优惠券列表
      * @param couponType 优惠券类型:1=满减券,2=折扣券,null=全部优惠券
      */

+ 2 - 1
alien-store/src/main/java/shop/alien/store/service/StoreClockInService.java

@@ -43,7 +43,8 @@ public interface StoreClockInService extends IService<StoreClockIn> {
      *
      * @param id 主键id
      * @param userId 当前登录用户ID(用于查询收藏状态)
-     * @return 打卡记录
+     * @return 打卡记录;无此打卡时返回 null
+     * @throws IllegalArgumentException 打卡存在但门店不可用(如已逻辑删除)时抛出,消息为「当前店铺已删除。」,由控制层转为 {@code R.fail}
      */
     StoreClockInVo getStoreClockInById(Integer id, Integer userId);
 

+ 51 - 0
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponServiceImpl.java

@@ -67,6 +67,8 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
 
     private final StoreInfoMapper storeInfoMapper;
 
+    private final StoreUserMapper storeUserMapper;
+
     private final LifeDiscountCouponQuantumRulesService lifeDiscountCouponQuantumRulesService;
 
     private final LifeDiscountCouponUserService lifeDiscountCouponUserService;
@@ -430,6 +432,55 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
         return lifeDiscountCouponVo;
     }
 
+    @Override
+    public LifeDiscountCouponVo getCouponDetailWithFriendOwnedQty(String couponId, String storeId) {
+        if (StringUtils.isEmpty(couponId) || StringUtils.isEmpty(storeId)) {
+            return null;
+        }
+        int couponIdInt;
+        int storeIdInt;
+        try {
+            couponIdInt = Integer.parseInt(couponId.trim());
+            storeIdInt = Integer.parseInt(storeId.trim());
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        if (lifeDiscountCouponMapper.selectById(couponIdInt) == null) {
+            return null;
+        }
+
+        LifeDiscountCouponVo vo = getCounponDetailById(String.valueOf(couponIdInt), null);
+
+        // ownedQuantity:本店(storeId=store_info.id)作为发放方已向好友送出的合计张数。
+        // 关系表语义:store_user_id=接收方店员 store_user.id,friend_store_user_id=送出方店员 store_user.id。
+        int owned = 0;
+        List<StoreUser> storeUsers = storeUserMapper.selectList(new LambdaQueryWrapper<StoreUser>()
+                .eq(StoreUser::getStoreId, storeIdInt)
+                .eq(StoreUser::getDeleteFlag, 0));
+        if (CollectionUtils.isNotEmpty(storeUsers)) {
+            List<Integer> senderStoreUserIds = storeUsers.stream()
+                    .map(StoreUser::getId)
+                    .filter(Objects::nonNull)
+                    .distinct()
+                    .collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(senderStoreUserIds)) {
+                List<LifeDiscountCouponStoreFriend> rows = lifeDiscountCouponStoreFriendMapper.selectList(
+                        new LambdaQueryWrapper<LifeDiscountCouponStoreFriend>()
+                                .eq(LifeDiscountCouponStoreFriend::getCouponId, couponIdInt)
+                                .in(LifeDiscountCouponStoreFriend::getFriendStoreUserId, senderStoreUserIds)
+                                .eq(LifeDiscountCouponStoreFriend::getReleaseType, 1));
+                for (LifeDiscountCouponStoreFriend row : rows) {
+                    if (row.getSingleQty() != null) {
+                        owned += row.getSingleQty();
+                    }
+                }
+            }
+        }
+
+        vo.setOwnedQuantity(owned);
+        return vo;
+    }
+
     public static Date addDaysToDateJava8(Date date, int days) {
         // 将Date转换为Instant
         Instant instant = date.toInstant();

+ 4 - 1
alien-store/src/main/java/shop/alien/store/service/impl/StoreClockInServiceImpl.java

@@ -482,12 +482,15 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
     @Override
     public StoreClockInVo getStoreClockInById(Integer id, Integer userId) {
         StoreClockIn storeClockIn = storeClockInMapper.selectById(id);
-        StoreClockInVo storeClockInVo = BeanUtil.copyProperties(storeClockIn, StoreClockInVo.class);
         if (null == storeClockIn) {
             return null;
         }
+        StoreClockInVo storeClockInVo = BeanUtil.copyProperties(storeClockIn, StoreClockInVo.class);
 
         StoreInfo storeInfo = storeInfoMapper.selectById(storeClockIn.getStoreId());
+        if (storeInfo == null) {
+            throw new IllegalArgumentException("当前店铺已删除");
+        }
         // 店铺名称
         storeClockInVo.setStoreName(storeInfo.getStoreName());
         storeClockInVo.setStoreBlurb(storeInfo.getStoreBlurb());

+ 8 - 7
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -1288,14 +1288,14 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         environmentAlbum.setAlbumName("环境");
         environmentAlbum.setImgCount(0);
         environmentAlbum.setIsFixed(1); // 1-固定相册
-        storeOfficialAlbumMapper.insert(environmentAlbum);
+        //storeOfficialAlbumMapper.insert(environmentAlbum);
         // 创建视频相册
         StoreOfficialAlbum videoAlbum = new StoreOfficialAlbum();
         videoAlbum.setStoreId(storeInfo.getId());
         videoAlbum.setAlbumName("视频");
         videoAlbum.setImgCount(0);
         videoAlbum.setIsFixed(1); // 1-固定相册
-        storeOfficialAlbumMapper.insert(videoAlbum);
+        //storeOfficialAlbumMapper.insert(videoAlbum);
         if (StringUtils.isNotEmpty(storeInfoDto.getStorePositionLongitude()) && StringUtils.isNotEmpty(storeInfoDto.getStorePositionLatitude())) {
             nearMeService.inGeolocation(new Point(Double.parseDouble(storeInfoDto.getStorePositionLongitude()), Double.parseDouble(storeInfoDto.getStorePositionLatitude())), storeInfo.getId().toString(), Boolean.TRUE);
         }
@@ -5996,11 +5996,12 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
 
         // 获取店铺相册
         List<StoreImg> storeAlbumList = new ArrayList<>();
-        if (storeInfo.getImgMode() != null && storeInfo.getImgMode() == 0) {
-            storeAlbumList = storeImgService.getStoreImg(Integer.parseInt(storeId), 20);
-        } else {
-            storeAlbumList = storeImgService.getStoreImg(Integer.parseInt(storeId), 21);
-        }
+//        if (storeInfo.getImgMode() != null && storeInfo.getImgMode() == 0) {
+//            storeAlbumList = storeImgService.getStoreImg(Integer.parseInt(storeId), 20);
+//        } else {
+//            storeAlbumList = storeImgService.getStoreImg(Integer.parseInt(storeId), 21);
+//        }
+         storeAlbumList = storeImgService.getStoreImg(Integer.parseInt(storeId), 38);
 
         if (!CollectionUtils.isEmpty(storeAlbumList)) {
             List<String> storeAlbumUrlList = storeAlbumList.stream().map(StoreImg::getImgUrl)  // 假设 StoreImg 有 getStoreUrl() 方法

+ 3 - 1
alien-store/src/main/java/shop/alien/store/service/impl/StoreOfficialAlbumServiceImpl.java

@@ -111,7 +111,9 @@ public class StoreOfficialAlbumServiceImpl extends ServiceImpl<StoreOfficialAlbu
         if(StringUtils.isNotBlank(storeId)) {
             //查询出店铺官方相册img数量并更新
             List<StoreOfficialAlbum> storeOfficialAlbumList = storeOfficialAlbumMapper.getStoreOfficialAlbumImgCount(Integer.parseInt(storeId));
-            this.updateBatchById(storeOfficialAlbumList);
+            if(CollectionUtils.isNotEmpty(storeOfficialAlbumList)) {
+                this.updateBatchById(storeOfficialAlbumList);
+            }
 
             // 查询官方相册列表
             List<StoreOfficialAlbumVo> albumVoList = storeOfficialAlbumMapper.getStoreOfficialAlbumList(Integer.parseInt(storeId));