From c9d6a751edbfc7fec595db21db3ac235723a7b6f Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Fri, 29 May 2026 17:02:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E6=8B=BC=E5=9B=A2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hiver-admin/test-output/test-report.html | 16 +- .../controller/manage/AuthController.java | 13 +- .../AdminMallOrderGroupController.java | 239 +++++++++++++++++- .../MallDeliveryOrderController.java | 12 +- .../mall/controller/MallOrderController.java | 6 +- .../dao/mapper/MallDeliveryOrderMapper.java | 2 + .../cc/hiver/mall/entity/MallOrderGroup.java | 4 + .../mall/ie/controller/IeController.java | 34 +++ .../hiver/mall/ie/service/IeChatService.java | 12 + .../ie/service/impl/IeChatServiceImpl.java | 89 ++++++- .../ie/service/impl/IeMatchServiceImpl.java | 34 ++- .../java/cc/hiver/mall/ie/vo/IeHomeVO.java | 1 + .../java/cc/hiver/mall/ie/vo/IeMatchVO.java | 5 + .../mybatis/MallDeliveryOrderService.java | 2 + .../service/mybatis/MallOrderService.java | 2 +- .../mybatis/MallDeliveryOrderServiceImpl.java | 9 + .../mybatis/MallOrderGroupServiceImpl.java | 4 +- .../mybatis/MallOrderServiceImpl.java | 62 +++-- .../mall/utils/ShopGroupOrderCacheUtil.java | 145 +++++++++-- .../mapper/MallDeliveryOrderMapper.xml | 50 ++++ .../resources/mapper/MallOrderGroupMapper.xml | 10 +- 21 files changed, 667 insertions(+), 84 deletions(-) diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index 5b5db9fa..7c5f6fdd 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • -五月 21, 2026 15:07:44 +五月 29, 2026 16:35:42
  • @@ -84,7 +84,7 @@

    passTest

    -

    15:07:45 下午 / 0.024 secs

    +

    16:35:42 下午 / 0.018 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -05.21.2026 15:07:45 -05.21.2026 15:07:45 -0.024 secs +05.29.2026 16:35:42 +05.29.2026 16:35:42 +0.018 secs
    @@ -104,7 +104,7 @@ Pass - 15:07:45 + 16:35:42 Test passed @@ -128,13 +128,13 @@

    Started

    -

    五月 21, 2026 15:07:44

    +

    五月 29, 2026 16:35:42

    Ended

    -

    五月 21, 2026 15:07:45

    +

    五月 29, 2026 16:35:43

    diff --git a/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java b/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java index 4f148dbb..a7bcba19 100644 --- a/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java +++ b/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java @@ -23,12 +23,13 @@ import cc.hiver.core.service.UserRoleService; import cc.hiver.core.service.UserService; import cc.hiver.mall.debt.service.DebtService; import cc.hiver.mall.entity.Shop; +import cc.hiver.mall.entity.ShopTakeaway; import cc.hiver.mall.entity.ShopUser; import cc.hiver.mall.invitelog.constant.InviteLogConstant; import cc.hiver.mall.invitelog.entity.InviteLog; import cc.hiver.mall.invitelog.service.InviteLogService; -import cc.hiver.mall.pojo.vo.ShopVo; import cc.hiver.mall.service.ShopService; +import cc.hiver.mall.service.ShopTakeawayService; import cc.hiver.mall.service.ShopUserService; import cc.hiver.mall.service.SupplierService; import cc.hiver.mall.service.mybatis.CustomerService; @@ -101,6 +102,9 @@ public class AuthController { @Autowired private ShopService shopService; + @Autowired + private ShopTakeawayService shopTakeawayService; + @Autowired private ShopUserService shopUserService; @@ -526,16 +530,17 @@ public class AuthController { final String token = redisTemplate.get(tokenKey); // 鑾峰彇搴楅摵鐨勫晢鍦 final Shop shop = shopService.get(shopId); + ShopTakeaway takeaway = shopTakeawayService.selectByPrimaryKey(shopId); securityUtil.chooseShop(shopId, shop.getRegionId(), token); - final ShopVo shopVo = new ShopVo(); + /*final ShopVo shopVo = new ShopVo(); shopVo.setShopIcon(shop.getShopIcon()); shopVo.setShopAddress(shop.getShopAddress()); shopVo.setRemark(shop.getRemark()); final ShopUser shopUser = shopUserService.selectByUserIdAndShopId(userId, shopId); shopVo.setUserType(String.valueOf(shopUser.getType())); // 搴楅摵榛樿瑙勬牸搴搃d - shopVo.setAttrId(shop.getAttrId()); - return new ResultUtil().setData(shopVo); + shopVo.setAttrId(shop.getAttrId());*/ + return new ResultUtil().setData(takeaway); } /* diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java index ab2a7abe..7905aadf 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java @@ -1,13 +1,17 @@ package cc.hiver.mall.controller; +import cc.hiver.core.common.redis.RedisTemplateHelper; import cc.hiver.core.common.utils.ResultUtil; import cc.hiver.core.common.vo.Result; import cc.hiver.mall.dao.mapper.MallOrderGoodsMapper; -import cc.hiver.mall.entity.MallOrder; -import cc.hiver.mall.entity.MallOrderGoods; -import cc.hiver.mall.entity.MallOrderGroup; +import cc.hiver.mall.dao.mapper.ShopMapper; +import cc.hiver.mall.dao.mapper.ShopTakeawayMapper; +import cc.hiver.mall.entity.*; +import cc.hiver.mall.pojo.dto.ShopCacheDTO; import cc.hiver.mall.service.mybatis.MallOrderGroupService; import cc.hiver.mall.service.mybatis.MallOrderService; +import cc.hiver.mall.utils.ShopGroupOrderCacheUtil; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.Api; @@ -18,9 +22,8 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; @Slf4j @RestController @@ -37,24 +40,105 @@ public class AdminMallOrderGroupController { @Autowired private MallOrderGoodsMapper mallOrderGoodsMapper; + @Autowired + private ShopGroupOrderCacheUtil shopGroupOrderCacheUtil; + + @Autowired + private RedisTemplateHelper redisTemplateHelper; + + @Autowired + private ShopMapper shopMapper; + + @Autowired + private ShopTakeawayMapper shopTakeawayMapper; + @Data public static class OrderGroupQuery { private String shopId; + private String regionId; private String headUserId; private Integer status; private String productName; + private String keyWord; private Integer isFace; + private Integer merchantType; private int pageNumber = 1; private int pageSize = 10; } + @Data + public static class OrderGroupListVo { + private String id; + private String shopId; + private String shopName; + private String regionId; + private String headUserId; + private String headOrderId; + private String groupOrderIds; + private Integer targetMembers; + private Integer currentMembers; + private Integer isFace; + private Integer status; + private java.math.BigDecimal groupPrice; + private String workerId; + private java.math.BigDecimal workerCommission; + private java.math.BigDecimal totalDeliveryFee; + private java.util.Date createTime; + private java.util.Date expireTime; + private java.util.Date successTime; + private String productName; + private String productPicture; + private String productId; + private Shop shopItem; + } + @PostMapping("/page") @ApiOperation(value = "鍒嗛〉鏌ヨ鎷煎洟鍒楄〃") - public Result> page(@RequestBody OrderGroupQuery query) { + public Result> page(@RequestBody OrderGroupQuery query) { + if (query == null || StringUtils.isBlank(query.getRegionId())) { + return ResultUtil.error("regionId涓嶈兘涓虹┖"); + } + if (query.getStatus() == null) { + query.setStatus(0); + } + if (query.getIsFace() == null) { + query.setIsFace(0); + } + + List groups = shopGroupOrderCacheUtil.getAllByRegion(query.getRegionId()); + if (groups == null) { + groups = listGroupsFromDb(query); + shopGroupOrderCacheUtil.putAllByRegion(query.getRegionId(), groups); + } + + groups = filterGroups(groups, query); + Map shopMap = buildShopMap(groups, query.getRegionId()); + groups = filterByShop(groups, shopMap, query); + groups.sort(Comparator.comparing(MallOrderGroup::getCreateTime, + Comparator.nullsLast(Comparator.naturalOrder())).reversed()); + + long total = groups.size(); + int pageNumber = Math.max(query.getPageNumber(), 1); + int pageSize = Math.max(query.getPageSize(), 1); + int fromIndex = Math.min((pageNumber - 1) * pageSize, groups.size()); + int toIndex = Math.min(fromIndex + pageSize, groups.size()); + List records = groups.subList(fromIndex, toIndex).stream() + .map(group -> toListVo(group, shopMap.get(group.getShopId()))) + .collect(Collectors.toList()); + + Page result = new Page<>(pageNumber, pageSize, total); + result.setRecords(records); + return new ResultUtil>().setData(result); + } + + private List listGroupsFromDb(OrderGroupQuery query) { LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); if (StringUtils.isNotBlank(query.getShopId())) { qw.eq(MallOrderGroup::getShopId, query.getShopId()); } + if (StringUtils.isNotBlank(query.getRegionId())) { + qw.eq(MallOrderGroup::getRegionId, query.getRegionId()); + } if (StringUtils.isNotBlank(query.getHeadUserId())) { qw.eq(MallOrderGroup::getHeadUserId, query.getHeadUserId()); } @@ -68,10 +152,145 @@ public class AdminMallOrderGroupController { qw.eq(MallOrderGroup::getIsFace, query.getIsFace()); } qw.orderByDesc(MallOrderGroup::getCreateTime); + return mallOrderGroupService.list(qw); + } + + private List filterGroups(List groups, OrderGroupQuery query) { + if (groups == null || groups.isEmpty()) { + return new ArrayList<>(); + } + return groups.stream() + .filter(group -> group != null) + .filter(group -> StringUtils.isBlank(query.getShopId()) || query.getShopId().equals(group.getShopId())) + .filter(group -> StringUtils.isBlank(query.getRegionId()) || query.getRegionId().equals(group.getRegionId())) + .filter(group -> StringUtils.isBlank(query.getHeadUserId()) || query.getHeadUserId().equals(group.getHeadUserId())) + .filter(group -> query.getStatus() == null || query.getStatus().equals(group.getStatus())) + .filter(group -> query.getIsFace() == null || query.getIsFace().equals(group.getIsFace())) + .collect(Collectors.toList()); + } + + private Map buildShopMap(List groups, String regionId) { + if (groups == null || groups.isEmpty()) { + return Collections.emptyMap(); + } + Set shopIds = groups.stream() + .map(MallOrderGroup::getShopId) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toCollection(LinkedHashSet::new)); + if (shopIds.isEmpty()) { + return Collections.emptyMap(); + } + + Map result = new HashMap<>(); + List missingShopIds = new ArrayList<>(); + String shopCacheKey = "SHOP_CACHE:" + regionId; + List cacheFields = new ArrayList<>(shopIds); + List cacheValues = redisTemplateHelper.hMultiGet(shopCacheKey, cacheFields); + int index = 0; + for (String shopId : shopIds) { + Object value = cacheValues != null && index < cacheValues.size() ? cacheValues.get(index) : null; + Shop shop = parseShopFromCache(value); + if (shop != null) { + result.put(shopId, shop); + } else { + missingShopIds.add(shopId); + } + index++; + } + + if (!missingShopIds.isEmpty()) { + List dbShops = shopMapper.selectBatchIds(missingShopIds); + if (dbShops != null && !dbShops.isEmpty()) { + List takeawayList = shopTakeawayMapper.selectListByshopId(missingShopIds); + Map takeawayMap = takeawayList == null ? Collections.emptyMap() + : takeawayList.stream().filter(Objects::nonNull) + .filter(item -> StringUtils.isNotBlank(item.getShopId())) + .collect(Collectors.toMap(ShopTakeaway::getShopId, item -> item, (a, b) -> a)); + for (Shop shop : dbShops) { + if (shop != null && StringUtils.isNotBlank(shop.getId())) { + shop.setShopTakeaway(takeawayMap.get(shop.getId())); + result.put(shop.getId(), shop); + } + } + } + } + return result; + } + + private Shop parseShopFromCache(Object value) { + if (value == null) { + return null; + } + try { + ShopCacheDTO dto = JSONUtil.toBean(value.toString(), ShopCacheDTO.class); + if (dto == null || dto.getShop() == null) { + return null; + } + Shop shop = dto.getShop(); + shop.setProducts(dto.getProducts()); + shop.setShopTakeaway(dto.getShopTakeaway()); + return shop; + } catch (Exception e) { + log.info("瑙f瀽搴楅摵缂撳瓨澶辫触", e); + return null; + } + } + + private List filterByShop(List groups, Map shopMap, OrderGroupQuery query) { + String keyword = StringUtils.isNotBlank(query.getKeyWord()) ? query.getKeyWord() : query.getProductName(); + return groups.stream() + .filter(group -> { + Shop shop = shopMap.get(group.getShopId()); + if (query.getMerchantType() != null) { + Integer merchantType = shop == null ? null : shop.getMerchantType(); + if (query.getMerchantType().equals(1)) { + if (merchantType != null && !query.getMerchantType().equals(merchantType)) { + return false; + } + } else if (!query.getMerchantType().equals(merchantType)) { + return false; + } + } + if (StringUtils.isBlank(keyword)) { + return true; + } + String kw = keyword.trim(); + return contains(group.getProductName(), kw) + || contains(group.getShopName(), kw) + || (shop != null && contains(shop.getShopName(), kw)); + }) + .collect(Collectors.toList()); + } + + private boolean contains(String value, String keyword) { + return value != null && keyword != null && value.contains(keyword); + } - Page page = new Page<>(query.getPageNumber(), query.getPageSize()); - Page result = mallOrderGroupService.page(page, qw); - return new ResultUtil>().setData(result); + private OrderGroupListVo toListVo(MallOrderGroup group, Shop shop) { + OrderGroupListVo vo = new OrderGroupListVo(); + vo.setId(group.getId()); + vo.setShopId(group.getShopId()); + vo.setShopName(group.getShopName()); + vo.setRegionId(group.getRegionId()); + vo.setHeadUserId(group.getHeadUserId()); + vo.setHeadOrderId(group.getHeadOrderId()); + vo.setGroupOrderIds(group.getGroupOrderIds()); + vo.setTargetMembers(group.getTargetMembers()); + vo.setCurrentMembers(group.getCurrentMembers()); + vo.setIsFace(group.getIsFace()); + vo.setStatus(group.getStatus()); + vo.setGroupPrice(group.getGroupPrice()); + vo.setWorkerId(group.getWorkerId()); + vo.setWorkerCommission(group.getWorkerCommission()); + vo.setTotalDeliveryFee(group.getTotalDeliveryFee()); + vo.setCreateTime(group.getCreateTime()); + vo.setExpireTime(group.getExpireTime()); + vo.setSuccessTime(group.getSuccessTime()); + vo.setProductName(group.getProductName()); + vo.setProductPicture(group.getProductPicture()); + vo.setProductId(group.getProductId()); + vo.setShopItem(shop); + return vo; } @Data diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java index e7d44c64..d6c3ac40 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java @@ -188,6 +188,14 @@ public class MallDeliveryOrderController { return new ResultUtil().setData(page); } + @PostMapping("/pagebyworkerHistory") + @ApiOperation(value = "鍒嗛〉鏌ヨ閰嶉佸憳閰嶉佸崟") + public Result pagebyworkerHistory(@RequestBody MallDeliveryOrderPageQuery q) { + // 1. 鍏堜粠缂撳瓨鑾峰彇 + IPage page = mallDeliveryOrderService.pageDeliveryByStatusHis(q); + return new ResultUtil().setData(page); + } + /** * 閰嶉佸憳鎺ュ崟 */ @@ -208,7 +216,7 @@ public class MallDeliveryOrderController { //褰撳墠浜烘病鏈夋敞鍐屽吋鑱岋紝鍏堣祴浜堝吋鑱岃韩浠 final User user = securityUtil.getCurrUser(); Worker worker = new Worker(); - worker.setWorkerName(user.getNickname()); + worker.setWorkerName("鍗婂緞楠戝+"); worker.setUserId(user.getId()); worker.setAvgTime(BigDecimal.valueOf(25)); worker.setMobile(user.getMobile()); @@ -228,6 +236,8 @@ public class MallDeliveryOrderController { return ResultUtil.success("閰嶉佸崟宸茶鎺ュ彇鎴栧凡鍙栨秷"); }else if(result == 2){ return ResultUtil.success("璇ュ崟宸叉寚瀹氬叾浠栭厤閫佸憳锛屾棤娉曟姠鍗"); + }else if(result == 5){ + return ResultUtil.success("宸茶绂佹鎺ュ崟锛屾棤娉曟姠鍗"); }else{ return new ResultUtil().setData(worker); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java index 1f41e0d9..fb614bc0 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java @@ -211,9 +211,11 @@ public class MallOrderController { @ApiOperation(value = "鐢ㄦ埛鍙栨秷璁㈠崟") public Result cancelOrder(@RequestParam String orderId, @RequestParam String userId,@RequestParam Integer refundType, - @RequestParam Integer refundTypeStatus) { + @RequestParam Integer refundTypeStatus, + @RequestParam(required = false) String reason, + @RequestParam(required = false) String pictures) { try { - mallOrderService.cancelOrder(orderId, userId, refundType, refundTypeStatus); + mallOrderService.cancelOrder(orderId, userId, refundType, refundTypeStatus, reason, pictures); return ResultUtil.success("宸插彇娑"); } catch (Exception e) { log.error("鍙栨秷澶辫触: {}", e.getMessage(), e); diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java index 6af26329..d6ef3c1b 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java @@ -28,6 +28,8 @@ public interface MallDeliveryOrderMapper extends BaseMapper { */ IPage selectPageVOByStatus(IPage page, @Param("q") MallDeliveryOrderPageQuery q); + IPage selectPageVOByStatusHis(IPage page, @Param("q") MallDeliveryOrderPageQuery q); + /** * 缁熻閰嶉佸憳褰撳墠娲昏穬鍗曢噺锛堝緟鍙栬揣+閰嶉佷腑锛 */ diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallOrderGroup.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallOrderGroup.java index 3009ce0a..f8b2fd1f 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallOrderGroup.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallOrderGroup.java @@ -25,6 +25,10 @@ public class MallOrderGroup implements Serializable { private String id = SnowFlakeUtil.nextId().toString(); @ApiModelProperty(value = "搴楅摵ID") private String shopId; + @ApiModelProperty(value = "搴楅摵鍚嶇О") + private String shopName; + @ApiModelProperty(value = "鍖哄煙ID") + private String regionId; @ApiModelProperty(value = "鍥㈤暱鐢ㄦ埛ID") private String headUserId; @ApiModelProperty(value = "鍥㈤暱璁㈠崟ID") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java index 79e780dd..ed128555 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; @RestController @Api(tags = "i/e闅忔満闄即鎺ュ彛") @@ -59,6 +60,13 @@ public class IeController { return new ResultUtil().setData(matchService.profileByUserId(currentUserId(), targetUserId)); } + @RequestMapping(value = "/rooms/{roomId}/profile", method = RequestMethod.GET) + @ApiOperation("鎸夋埧闂磋幏鍙栧鏂瑰崐鍖垮悕i/e璧勬枡") + public Result roomTargetProfile(@PathVariable Long roomId) { + Long targetUserId = chatService.roomTargetUserId(currentUserId(), roomId); + return new ResultUtil().setData(matchService.profileByUserId(currentUserId(), targetUserId)); + } + @RequestMapping(value = "/profile", method = RequestMethod.POST) @ApiOperation("淇濆瓨i/e璧勬枡") public Result saveProfile(@RequestBody IeProfileDTO dto) { @@ -129,6 +137,32 @@ public class IeController { return ResultUtil.success("宸茶В闄"); } + @RequestMapping(value = "/block/{blockedUserId}/status", method = RequestMethod.GET) + @ApiOperation("鏌ヨ鎷夐粦鐘舵") + public Result> blockStatus(@PathVariable Long blockedUserId) { + return new ResultUtil>().setData(chatService.blockStatus(currentUserId(), blockedUserId)); + } + + @RequestMapping(value = "/rooms/{roomId}/block", method = RequestMethod.POST) + @ApiOperation("鎸夋埧闂存媺榛戦櫔浼村璞") + public Result blockRoomTarget(@PathVariable Long roomId, String reason) { + chatService.blockRoomTarget(currentUserId(), roomId, reason); + return ResultUtil.success("宸叉媺榛"); + } + + @RequestMapping(value = "/rooms/{roomId}/block", method = RequestMethod.DELETE) + @ApiOperation("鎸夋埧闂磋В闄ゆ媺榛戦櫔浼村璞") + public Result unblockRoomTarget(@PathVariable Long roomId) { + chatService.unblockRoomTarget(currentUserId(), roomId); + return ResultUtil.success("宸茶В闄"); + } + + @RequestMapping(value = "/rooms/{roomId}/block/status", method = RequestMethod.GET) + @ApiOperation("鎸夋埧闂存煡璇㈡媺榛戠姸鎬") + public Result> roomBlockStatus(@PathVariable Long roomId) { + return new ResultUtil>().setData(chatService.roomBlockStatus(currentUserId(), roomId)); + } + @RequestMapping(value = "/offline", method = RequestMethod.GET) @ApiOperation("鎷夊彇绂荤嚎娑堟伅") public Result> offline() { diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeChatService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeChatService.java index e599a299..c813d6f2 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeChatService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeChatService.java @@ -7,6 +7,8 @@ import cc.hiver.mall.ie.entity.*; import cc.hiver.mall.ie.vo.IeMessageAckVO; import com.baomidou.mybatisplus.core.metadata.IPage; +import java.util.Map; + public interface IeChatService { IeRoom getRoom(Long roomId); @@ -28,6 +30,16 @@ public interface IeChatService { void unblock(Long userId, Long blockedUserId); + Map blockStatus(Long userId, Long targetUserId); + + void blockRoomTarget(Long userId, Long roomId, String reason); + + void unblockRoomTarget(Long userId, Long roomId); + + Map roomBlockStatus(Long userId, Long roomId); + + Long roomTargetUserId(Long userId, Long roomId); + IPage pageMessages(Long userId, Long roomId, Integer pageNumber, Integer pageSize); void markRead(Long userId, Long roomId); diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java index b795cc58..6c51ac5d 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java @@ -25,9 +25,7 @@ import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Calendar; -import java.util.Date; -import java.util.List; +import java.util.*; @Service public class IeChatServiceImpl implements IeChatService { @@ -185,6 +183,8 @@ public class IeChatServiceImpl implements IeChatService { @Override public void sendPresence(Long senderId, IePresenceDTO dto) { IeRoom room = assertActiveRoom(senderId, dto.getRoomId()); + Long receiverId = room.getUserAId().equals(senderId) ? room.getUserBId() : room.getUserAId(); + assertNotBlocked(senderId, receiverId); IePresenceEvent event = new IePresenceEvent(); event.setRoomId(room.getId()); event.setSenderId(senderId); @@ -192,7 +192,6 @@ public class IeChatServiceImpl implements IeChatService { event.setEventText(dto.getEventText()); event.setCreateTime(new Date()); presenceEventMapper.insert(event); - Long receiverId = room.getUserAId().equals(senderId) ? room.getUserBId() : room.getUserAId(); messagingTemplate.convertAndSendToUser(String.valueOf(receiverId), "/queue/ie/presence", event); } @@ -258,17 +257,11 @@ public class IeChatServiceImpl implements IeChatService { block.setReason(reason); block.setCreateTime(new Date()); blockMapper.insert(block); + broadcastBlockStatus(userId, blockedUserId); } private void assertNotBlocked(Long senderId, Long receiverId) { - Long count = blockMapper.selectCount(new LambdaQueryWrapper() - .and(wrapper -> wrapper - .eq(IeBlock::getUserId, senderId) - .eq(IeBlock::getBlockedUserId, receiverId)) - .or(wrapper -> wrapper - .eq(IeBlock::getUserId, receiverId) - .eq(IeBlock::getBlockedUserId, senderId))); - if (count != null && count > 0) { + if (hasBlock(senderId, receiverId) || hasBlock(receiverId, senderId)) { throw new RuntimeException("浣犱滑涔嬮棿宸叉湁榛戝悕鍗曞叧绯伙紝鏃犳硶缁х画鍙戦佹秷鎭"); } } @@ -278,6 +271,78 @@ public class IeChatServiceImpl implements IeChatService { blockMapper.delete(new LambdaQueryWrapper() .eq(IeBlock::getUserId, userId) .eq(IeBlock::getBlockedUserId, blockedUserId)); + broadcastBlockStatus(userId, blockedUserId); + } + + @Override + public void blockRoomTarget(Long userId, Long roomId, String reason) { + IeRoom room = assertActiveRoom(userId, roomId); + Long targetUserId = room.getUserAId().equals(userId) ? room.getUserBId() : room.getUserAId(); + block(userId, targetUserId, reason); + } + + @Override + public void unblockRoomTarget(Long userId, Long roomId) { + IeRoom room = assertActiveRoom(userId, roomId); + Long targetUserId = room.getUserAId().equals(userId) ? room.getUserBId() : room.getUserAId(); + unblock(userId, targetUserId); + } + + @Override + public Map roomBlockStatus(Long userId, Long roomId) { + IeRoom room = assertActiveRoom(userId, roomId); + Long targetUserId = room.getUserAId().equals(userId) ? room.getUserBId() : room.getUserAId(); + return blockStatus(userId, targetUserId); + } + + @Override + public Long roomTargetUserId(Long userId, Long roomId) { + IeRoom room = assertActiveRoom(userId, roomId); + return room.getUserAId().equals(userId) ? room.getUserBId() : room.getUserAId(); + } + + @Override + public Map blockStatus(Long userId, Long targetUserId) { + boolean blockedByMe = hasBlock(userId, targetUserId); + boolean blockedByOther = hasBlock(targetUserId, userId); + Map status = new HashMap<>(); + status.put("blockedByMe", blockedByMe); + status.put("blockedByOther", blockedByOther); + status.put("blocked", blockedByMe || blockedByOther); + return status; + } + + private boolean hasBlock(Long userId, Long blockedUserId) { + if (userId == null || blockedUserId == null) { + return false; + } + Long count = blockMapper.selectCount(new LambdaQueryWrapper() + .eq(IeBlock::getUserId, userId) + .eq(IeBlock::getBlockedUserId, blockedUserId)); + return count != null && count > 0; + } + + private void broadcastBlockStatus(Long userId, Long targetUserId) { + List rooms = roomMapper.selectList(new LambdaQueryWrapper() + .and(wrapper -> wrapper + .eq(IeRoom::getUserAId, userId) + .eq(IeRoom::getUserBId, targetUserId)) + .or(wrapper -> wrapper + .eq(IeRoom::getUserAId, targetUserId) + .eq(IeRoom::getUserBId, userId))); + for (IeRoom room : rooms) { + if (room == null || room.getId() == null) { + continue; + } + Map payload = new HashMap<>(); + payload.put("type", "blockStatus"); + payload.put("roomId", room.getId()); + payload.put("userId", userId); + payload.put("targetUserId", targetUserId); + payload.put("userStatus", blockStatus(userId, targetUserId)); + payload.put("targetStatus", blockStatus(targetUserId, userId)); + messagingTemplate.convertAndSend("/topic/ie/room/" + room.getId(), payload); + } } @Override diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java index 8be74f22..a4359998 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java @@ -41,6 +41,12 @@ public class IeMatchServiceImpl implements IeMatchService { @Autowired private IeRoomMapper roomMapper; + @Autowired + private IeRecordMapper recordMapper; + + @Autowired + private IeRoomMessageMapper roomMessageMapper; + @Autowired private IeBlockMapper blockMapper; @@ -59,6 +65,7 @@ public class IeMatchServiceImpl implements IeMatchService { vo.setWaitingCount(redisService.waitingCount(profile.getCurrentMode(), "quiet")); vo.setDailyQuota(profile.getDailyQuota()); vo.setUsedQuota((int) redisService.todayUsedQuota(userId)); + vo.setUnreadCount(totalUnreadCount(userId)); vo.setCurrentMode(profile.getCurrentMode()); vo.setCurrentMood("quiet"); vo.setTargetModePreference(profile.getTargetModePreference()); @@ -69,6 +76,25 @@ public class IeMatchServiceImpl implements IeMatchService { return vo; } + private int totalUnreadCount(Long userId) { + List records = recordMapper.selectList(new LambdaQueryWrapper() + .eq(IeRecord::getUserId, userId)); + int total = 0; + for (IeRecord record : records) { + if (record.getRoomId() == null || record.getTargetUserId() == null) { + continue; + } + Long count = roomMessageMapper.selectCount(new LambdaQueryWrapper() + .eq(IeRoomMessage::getRoomId, record.getRoomId()) + .eq(IeRoomMessage::getSenderId, record.getTargetUserId()) + .eq(IeRoomMessage::getReceiverId, userId) + .eq(IeRoomMessage::getIsBlocked, 0) + .gt(record.getLastReadTime() != null, IeRoomMessage::getCreateTime, record.getLastReadTime())); + total += count == null ? 0 : count.intValue(); + } + return total; + } + @Override public IeUserProfileVO profile(Long userId) { return toProfileVO(ensureProfile(userId)); @@ -175,7 +201,7 @@ public class IeMatchServiceImpl implements IeMatchService { Long targetUserId = null; try { if (redisService.todayUsedQuota(userId) >= maxQuota) { - return fail(userId, dto, "浠婃棩闄即鏈轰細宸茬粡鐢ㄥ畬"); + return fail(userId, dto, "浠婃棩闄即鏈轰細宸茬粡鐢ㄥ畬锛屽钩鍙颁笅鍗曞彲澧炲姞鍖归厤娆℃暟"); } IeStatusDTO statusDTO = new IeStatusDTO(); BeanUtils.copyProperties(dto == null ? new IeMatchStartDTO() : dto, statusDTO); @@ -217,7 +243,7 @@ public class IeMatchServiceImpl implements IeMatchService { } long used = redisService.increaseTodayQuota(userId, maxQuota); if (used > maxQuota) { - return fail(userId, dto, "浠婃棩闄即鏈轰細宸茬粡鐢ㄥ畬"); + return fail(userId, dto, "浠婃棩闄即鏈轰細宸茬粡鐢ㄥ畬锛屽钩鍙颁笅鍗曞彲澧炲姞鍖归厤娆℃暟"); } IeUserProfile targetProfile = ensureProfile(targetUserId); @@ -247,6 +273,10 @@ public class IeMatchServiceImpl implements IeMatchService { vo.setRoomId(room.getId()); vo.setRoomNo(room.getRoomNo()); vo.setAvatarUrl(targetProfile.getAvatarUrl()); + vo.setGender(targetProfile.getGender()); + vo.setIntro(targetProfile.getIntro()); + vo.setInterestTags(jsonToTags(targetProfile.getInterestTags())); + vo.setPersonaImages(jsonToTags(targetProfile.getPersonaImages())); return vo; } finally { redisService.unlockMatchUser(userId); diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java index 3a7c7d89..4f5efc60 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java @@ -10,6 +10,7 @@ public class IeHomeVO { private Long waitingCount; private Integer dailyQuota; private Integer usedQuota; + private Integer unreadCount; private String currentMode; private String currentMood; private String targetModePreference; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java index 9d9c7150..5217491e 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java @@ -3,6 +3,7 @@ package cc.hiver.mall.ie.vo; import lombok.Data; import java.util.Date; +import java.util.List; @Data public class IeMatchVO { @@ -12,6 +13,10 @@ public class IeMatchVO { private String anonymousName; private String avatarText; private String avatarUrl; + private String gender; + private String intro; + private List interestTags; + private List personaImages; private String mode; private String mood; private String stateText; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java index b549cc11..e687cecd 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java @@ -27,6 +27,8 @@ public interface MallDeliveryOrderService extends IService { */ IPage pageDeliveryByStatus(MallDeliveryOrderPageQuery q); + IPage pageDeliveryByStatusHis(MallDeliveryOrderPageQuery q); + /** * 閰嶉佸憳鎺ュ崟锛堟姠鍗曞ぇ鍘呮垨鎸囨淳鍗曪級 */ diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java index 72a8a28d..adb8b431 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java @@ -50,7 +50,7 @@ public interface MallOrderService extends IService { /** * 鐢ㄦ埛鍙栨秷璁㈠崟锛堜粎寰呮敮浠/寰呮垚鍥㈢姸鎬佸彲鍙栨秷锛 */ - void cancelOrder(String orderId, String userId,Integer refundType, Integer refundTypeStatus); + void cancelOrder(String orderId, String userId,Integer refundType, Integer refundTypeStatus, String reason, String pictures); /** * 鐢宠閫娆 diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java index 6b2901d4..9652fcb3 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java @@ -170,6 +170,15 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl pageDeliveryByStatusHis(MallDeliveryOrderPageQuery q) { + IPage page = new Page<>(q.getPageNum(), q.getPageSize()); + page = this.baseMapper.selectPageVOByStatusHis(page,q); + // 鎵归噺鏌ヨ璁㈠崟鍟嗗搧鏄庣粏锛岄伩鍏 N+1 闂锛屽鐞嗛潰瀵归潰鎷煎洟瀛愯鍗 + assembleOrderGoodsForDeliveries(page.getRecords()); + return page; + } + /** * 閰嶉佸憳鎺ュ崟 * - 鎶㈠崟澶у巺锛歸orkerId 涓虹┖鐨勫崟锛屼换浣曢厤閫佸憳鍧囧彲鎺 diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java index 98291568..b11a40eb 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java @@ -145,9 +145,7 @@ public class MallOrderGroupServiceImpl extends ServiceImpl waitingOrders = mallOrderService.list(oqw); - boolean isFace2Face = (group.getStatus() == GROUP_STATUS_FACE2FACE - || (group.getStatus() == GROUP_STATUS_SUCCESS - && this.getById(groupId).getStatus() == GROUP_STATUS_FACE2FACE)); + boolean isFace2Face = group.getIsFace() != null && group.getIsFace() == 1; for (MallOrder order : waitingOrders) { int targetStatus = (order.getDeliveryType() != null && order.getDeliveryType() == 1) ? 2 : 3; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java index cc85cf58..96ec442c 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java @@ -420,6 +420,8 @@ public class MallOrderServiceImpl extends ServiceImpl= 1) { - applyMerchantRefund(delivery.getWorkerId(),order, "鐢ㄦ埛鐢宠鍙栨秷璁㈠崟閫娆",refundType,refundTypeStatus); + applyMerchantRefund(delivery.getWorkerId(),order, appendCancelReason("鐢ㄦ埛鐢宠鍙栨秷璁㈠崟閫娆", reason),refundType,refundTypeStatus, pictures); }else{ // 鍏佽鍙栨秷 cancelDeliveryOrderByOrderId(order.getId()); @@ -1004,14 +1008,14 @@ public class MallOrderServiceImpl extends ServiceImpl= 1) { // 閰嶉佸憳宸叉帴鍗 鈫 璧板晢瀹舵垨鑰呴厤閫佸憳鍚屾剰娴佺▼ - applyMerchantRefund(delivery.getWorkerId(),order, "鐢ㄦ埛鐢宠鍙栨秷璁㈠崟", refundType, refundTypeStatus); + applyMerchantRefund(delivery.getWorkerId(),order, appendCancelReason("鐢ㄦ埛鐢宠鍙栨秷璁㈠崟", reason), refundType, refundTypeStatus, pictures); } else { // 鏈帴鍗 鈫 鐩存帴鍙栨秷骞堕娆 cancelDeliveryOrderByOrderId(order.getId()); @@ -1098,7 +1102,7 @@ public class MallOrderServiceImpl extends ServiceImpl - * 搴曞眰浣跨敤 Redis Hash 缁撴瀯锛屼繚璇佹寜 shopId + orderId 缁村害鐨 O(1) 璇诲啓鏁堢巼銆 + * 搴曞眰浣跨敤 Redis Hash 缁撴瀯锛屼繚璇佹寜 shopId / regionId + orderId 缁村害鐨 O(1) 璇诲啓鏁堢巼銆 *
    - *   Key   = SHOP_GROUP_ORDERS:{shopId}
    - *   Field = orderId
    - *   Value = MallOrderGroup 鐨 JSON 搴忓垪鍖
    + *   搴楅摵缁村害 Key   = SHOP_GROUP_ORDERS:{shopId}
    + *   鍖哄煙缁村害 Key   = SHOP_GROUP_ORDERS_REGION:{regionId}
    + *   Field          = orderId
    + *   Value          = MallOrderGroup 鐨 JSON 搴忓垪鍖
      * 
    *

    * 浣跨敤鍦烘櫙锛氳鍗曠姸鎬佸彂鐢熷彉鍖栨椂锛堝垱寤恒佹洿鏂般佸彇娑堛佸畬鎴愮瓑锛夛紝 @@ -34,8 +35,14 @@ public class ShopGroupOrderCacheUtil { /** Redis Key 鍓嶇紑 */ private static final String KEY_PREFIX = "SHOP_GROUP_ORDERS:"; - /** 璁㈠崟涓嶅啀灞炰簬"寰呮垚鍥"鐨勭姸鎬侀泦鍚 */ - private static final int STATUS_DONE = 0; + /** 鍖哄煙寰呮垚鍥 Redis Key 鍓嶇紑 */ + private static final String REGION_KEY_PREFIX = "SHOP_GROUP_ORDERS_REGION:"; + + /** 鍏紑寰呮垚鍥㈢姸鎬 */ + private static final int STATUS_FORMING = 0; + + /** 闈為潰瀵归潰鎷煎洟 */ + private static final int IS_FACE_NORMAL = 0; @Autowired private RedisTemplateHelper redisTemplateHelper; @@ -48,6 +55,10 @@ public class ShopGroupOrderCacheUtil { return KEY_PREFIX + shopId; } + private String buildRegionKey(String regionId) { + return REGION_KEY_PREFIX + regionId; + } + // ================================================================ // 瀛樻斁锛坧ut锛 // ================================================================ @@ -64,10 +75,17 @@ public class ShopGroupOrderCacheUtil { return; } try { - String key = buildKey(shopId); + if (!isPublicPending(orderVO)) { + remove(shopId, orderVO.getRegionId(), orderVO.getId()); + return; + } String json = JSONUtil.toJsonStr(orderVO); - redisTemplateHelper.hPut(key, orderVO.getId(), json); - log.info("缂撳瓨搴楅摵寰呮垚鍥㈣鍗: shopId={}, orderId={}", shopId, orderVO.getId()); + redisTemplateHelper.hPut(buildKey(shopId), orderVO.getId(), json); + if (StringUtils.isNotBlank(orderVO.getRegionId())) { + redisTemplateHelper.hPut(buildRegionKey(orderVO.getRegionId()), orderVO.getId(), json); + } + log.info("缂撳瓨搴楅摵寰呮垚鍥㈣鍗: shopId={}, regionId={}, orderId={}", + shopId, orderVO.getRegionId(), orderVO.getId()); } catch (Exception e) { log.info("缂撳瓨搴楅摵寰呮垚鍥㈣鍗曞け璐: shopId={}, orderId={}", shopId, orderVO.getId(), e); } @@ -84,15 +102,23 @@ public class ShopGroupOrderCacheUtil { return; } try { - String key = buildKey(shopId); Map map = new java.util.LinkedHashMap<>(orders.size()); + Map> regionMap = new java.util.LinkedHashMap<>(); for (MallOrderGroup order : orders) { - if (order != null && StringUtils.isNotBlank(order.getId())) { - map.put(order.getId(), JSONUtil.toJsonStr(order)); + if (order != null && StringUtils.isNotBlank(order.getId()) && isPublicPending(order)) { + String json = JSONUtil.toJsonStr(order); + map.put(order.getId(), json); + if (StringUtils.isNotBlank(order.getRegionId())) { + regionMap.computeIfAbsent(order.getRegionId(), k -> new java.util.LinkedHashMap<>()) + .put(order.getId(), json); + } } } if (!map.isEmpty()) { - redisTemplateHelper.hPutAll(key, map); + redisTemplateHelper.hPutAll(buildKey(shopId), map); + for (Map.Entry> entry : regionMap.entrySet()) { + redisTemplateHelper.hPutAll(buildRegionKey(entry.getKey()), entry.getValue()); + } log.info("鎵归噺缂撳瓨搴楅摵寰呮垚鍥㈣鍗: shopId={}, count={}", shopId, map.size()); } } catch (Exception e) { @@ -118,14 +144,33 @@ public class ShopGroupOrderCacheUtil { return; } try { - String key = buildKey(shopId); - redisTemplateHelper.hDelete(key, orderId); + MallOrderGroup cachedOrder = get(shopId, orderId); + redisTemplateHelper.hDelete(buildKey(shopId), orderId); + if (cachedOrder != null && StringUtils.isNotBlank(cachedOrder.getRegionId())) { + redisTemplateHelper.hDelete(buildRegionKey(cachedOrder.getRegionId()), orderId); + } log.info("鍒犻櫎寰呮垚鍥㈣鍗曠紦瀛: shopId={}, orderId={}", shopId, orderId); } catch (Exception e) { log.info("鍒犻櫎寰呮垚鍥㈣鍗曠紦瀛樺け璐: shopId={}, orderId={}", shopId, orderId, e); } } + public void remove(String shopId, String regionId, String orderId) { + if (StringUtils.isBlank(shopId) || StringUtils.isBlank(orderId)) { + log.info("ShopGroupOrderCacheUtil.remove 鍙傛暟鏃犳晥, shopId={}, orderId={}", shopId, orderId); + return; + } + try { + redisTemplateHelper.hDelete(buildKey(shopId), orderId); + if (StringUtils.isNotBlank(regionId)) { + redisTemplateHelper.hDelete(buildRegionKey(regionId), orderId); + } + log.info("鍒犻櫎寰呮垚鍥㈣鍗曠紦瀛: shopId={}, regionId={}, orderId={}", shopId, regionId, orderId); + } catch (Exception e) { + log.info("鍒犻櫎寰呮垚鍥㈣鍗曠紦瀛樺け璐: shopId={}, regionId={}, orderId={}", shopId, regionId, orderId, e); + } + } + /** * 娓呴櫎鎸囧畾搴楅摵鎵鏈夊緟鎴愬洟璁㈠崟缂撳瓨 *

    @@ -165,8 +210,8 @@ public class ShopGroupOrderCacheUtil { } try { // 濡傛灉璁㈠崟鐘舵佸凡涓嶅睘浜庡緟鎴愬洟锛岀洿鎺ュ垹闄 - /*if (!isTerminalStatus(orderVO.getStatus())) { - remove(shopId, orderVO.getId()); + /*if (!isPublicPending(orderVO)) { + remove(shopId, orderVO.getRegionId(), orderVO.getId()); log.debug("璁㈠崟宸茬粓鎬侊紝浠庣紦瀛樼Щ闄: shopId={}, orderId={}, status={}", shopId, orderVO.getId(), orderVO.getStatus()); return; @@ -213,6 +258,57 @@ public class ShopGroupOrderCacheUtil { } } + /** + * 鑾峰彇鍖哄煙缁村害寰呮垚鍥㈣鍗曠紦瀛樸 + */ + public List getAllByRegion(String regionId) { + if (StringUtils.isBlank(regionId)) { + return null; + } + try { + Map entries = redisTemplateHelper.hGetAll(buildRegionKey(regionId)); + if (entries == null || entries.isEmpty()) { + return null; + } + List result = new ArrayList<>(entries.size()); + for (Object value : entries.values()) { + if (value != null) { + MallOrderGroup order = JSONUtil.toBean(value.toString(), MallOrderGroup.class); + if (isPublicPending(order)) { + result.add(order); + } + } + } + return result; + } catch (Exception e) { + log.info("鑾峰彇鍖哄煙寰呮垚鍥㈣鍗曠紦瀛樺け璐: regionId={}", regionId, e); + return null; + } + } + + /** + * 鎵归噺鍐欏叆鍖哄煙缁村害寰呮垚鍥㈢紦瀛橈紝閫氬父鐢ㄤ簬鍥炴簮鍚庨鐑 + */ + public void putAllByRegion(String regionId, List orders) { + if (StringUtils.isBlank(regionId) || orders == null || orders.isEmpty()) { + return; + } + try { + Map map = new java.util.LinkedHashMap<>(orders.size()); + for (MallOrderGroup order : orders) { + if (order != null && StringUtils.isNotBlank(order.getId()) && isPublicPending(order)) { + map.put(order.getId(), JSONUtil.toJsonStr(order)); + } + } + if (!map.isEmpty()) { + redisTemplateHelper.hPutAll(buildRegionKey(regionId), map); + log.info("鎵归噺缂撳瓨鍖哄煙寰呮垚鍥㈣鍗: regionId={}, count={}", regionId, map.size()); + } + } catch (Exception e) { + log.info("鎵归噺缂撳瓨鍖哄煙寰呮垚鍥㈣鍗曞け璐: regionId={}", regionId, e); + } + } + /** * 鑾峰彇搴楅摵缂撳瓨寰呮垚鍥㈠崟涓鍗 * @@ -251,6 +347,14 @@ public class ShopGroupOrderCacheUtil { return hasKey != null && hasKey; } + public boolean existsRegion(String regionId) { + if (StringUtils.isBlank(regionId)) { + return false; + } + Boolean hasKey = redisTemplateHelper.hasKey(buildRegionKey(regionId)); + return hasKey != null && hasKey; + } + // ================================================================ // 鍐呴儴宸ュ叿 // ================================================================ @@ -258,10 +362,11 @@ public class ShopGroupOrderCacheUtil { /** * 鍒ゆ柇璁㈠崟鐘舵佹槸鍚︿负缁堟侊紙涓嶅啀灞炰簬"寰呮垚鍥"锛 */ - private boolean isTerminalStatus(Integer status) { - if (status == null) { + public boolean isPublicPending(MallOrderGroup order) { + if (order == null || order.getStatus() == null) { return false; } - return status == STATUS_DONE; + return order.getStatus() == STATUS_FORMING + && (order.getIsFace() == null || order.getIsFace() == IS_FACE_NORMAL); } } diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml index 495f93c9..46ade5a3 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml @@ -167,6 +167,56 @@ ORDER BY (CASE WHEN d.must_finish_time IS NULL THEN 1 ELSE 0 END) ASC + + SELECT id,shop_id,head_user_id,head_order_id,group_order_ids,target_members, current_members,status,group_price,worker_id,worker_commission,total_delivery_fee, - create_time,expire_time,is_face,product_name,product_picture,product_id,success_time + create_time,expire_time,is_face,product_name,product_picture,product_id,success_time,region_id,shop_name FROM mall_order_group @@ -41,6 +43,12 @@ AND status = #{group.status} + + AND region_id = #{group.regionId} + + + AND shop_name = #{group.shopName} + order by create_time asc