Browse Source

对接拼团数据1

master
wangfukang 3 weeks ago
parent
commit
c9d6a751ed
  1. 16
      hiver-admin/test-output/test-report.html
  2. 13
      hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java
  3. 239
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java
  4. 12
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java
  5. 6
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java
  6. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java
  7. 4
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallOrderGroup.java
  8. 34
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java
  9. 12
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeChatService.java
  10. 89
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java
  11. 34
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java
  12. 1
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java
  13. 5
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java
  14. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java
  15. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java
  16. 9
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java
  17. 4
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java
  18. 62
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java
  19. 141
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/ShopGroupOrderCacheUtil.java
  20. 50
      hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml
  21. 10
      hiver-modules/hiver-mall/src/main/resources/mapper/MallOrderGroupMapper.xml

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a> <a href="#"><span class="badge badge-primary">Hiver</span></a>
</li> </li>
<li class="m-r-10"> <li class="m-r-10">
<a href="#"><span class="badge badge-primary">五月 21, 2026 15:07:44</span></a> <a href="#"><span class="badge badge-primary">五月 29, 2026 16:35:42</span></a>
</li> </li>
</ul> </ul>
</div> </div>
@ -84,7 +84,7 @@
<div class="test-detail"> <div class="test-detail">
<span class="meta text-white badge badge-sm"></span> <span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p> <p class="name">passTest</p>
<p class="text-sm"><span>15:07:45 下午</span> / <span>0.024 secs</span></p> <p class="text-sm"><span>16:35:42 下午</span> / <span>0.018 secs</span></p>
</div> </div>
<div class="test-contents d-none"> <div class="test-contents d-none">
<div class="detail-head"> <div class="detail-head">
@ -92,9 +92,9 @@
<div class="info"> <div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div> <div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5> <h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>05.21.2026 15:07:45</span> <span class='badge badge-success'>05.29.2026 16:35:42</span>
<span class='badge badge-danger'>05.21.2026 15:07:45</span> <span class='badge badge-danger'>05.29.2026 16:35:42</span>
<span class='badge badge-default'>0.024 secs</span> <span class='badge badge-default'>0.018 secs</span>
</div> </div>
<div class="m-t-10 m-l-5"></div> <div class="m-t-10 m-l-5"></div>
</div> </div>
@ -104,7 +104,7 @@
<tbody> <tbody>
<tr class="event-row"> <tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td> <td><span class="badge log pass-bg">Pass</span></td>
<td>15:07:45</td> <td>16:35:42</td>
<td> <td>
Test passed Test passed
</td> </td>
@ -128,13 +128,13 @@
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Started</p> <p class="m-b-0">Started</p>
<h3>五月 21, 2026 15:07:44</h3> <h3>五月 29, 2026 16:35:42</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Ended</p> <p class="m-b-0">Ended</p>
<h3>五月 21, 2026 15:07:45</h3> <h3>五月 29, 2026 16:35:43</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

13
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.core.service.UserService;
import cc.hiver.mall.debt.service.DebtService; import cc.hiver.mall.debt.service.DebtService;
import cc.hiver.mall.entity.Shop; import cc.hiver.mall.entity.Shop;
import cc.hiver.mall.entity.ShopTakeaway;
import cc.hiver.mall.entity.ShopUser; import cc.hiver.mall.entity.ShopUser;
import cc.hiver.mall.invitelog.constant.InviteLogConstant; import cc.hiver.mall.invitelog.constant.InviteLogConstant;
import cc.hiver.mall.invitelog.entity.InviteLog; import cc.hiver.mall.invitelog.entity.InviteLog;
import cc.hiver.mall.invitelog.service.InviteLogService; 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.ShopService;
import cc.hiver.mall.service.ShopTakeawayService;
import cc.hiver.mall.service.ShopUserService; import cc.hiver.mall.service.ShopUserService;
import cc.hiver.mall.service.SupplierService; import cc.hiver.mall.service.SupplierService;
import cc.hiver.mall.service.mybatis.CustomerService; import cc.hiver.mall.service.mybatis.CustomerService;
@ -101,6 +102,9 @@ public class AuthController {
@Autowired @Autowired
private ShopService shopService; private ShopService shopService;
@Autowired
private ShopTakeawayService shopTakeawayService;
@Autowired @Autowired
private ShopUserService shopUserService; private ShopUserService shopUserService;
@ -526,16 +530,17 @@ public class AuthController {
final String token = redisTemplate.get(tokenKey); final String token = redisTemplate.get(tokenKey);
// 获取店铺的商圈 // 获取店铺的商圈
final Shop shop = shopService.get(shopId); final Shop shop = shopService.get(shopId);
ShopTakeaway takeaway = shopTakeawayService.selectByPrimaryKey(shopId);
securityUtil.chooseShop(shopId, shop.getRegionId(), token); securityUtil.chooseShop(shopId, shop.getRegionId(), token);
final ShopVo shopVo = new ShopVo(); /*final ShopVo shopVo = new ShopVo();
shopVo.setShopIcon(shop.getShopIcon()); shopVo.setShopIcon(shop.getShopIcon());
shopVo.setShopAddress(shop.getShopAddress()); shopVo.setShopAddress(shop.getShopAddress());
shopVo.setRemark(shop.getRemark()); shopVo.setRemark(shop.getRemark());
final ShopUser shopUser = shopUserService.selectByUserIdAndShopId(userId, shopId); final ShopUser shopUser = shopUserService.selectByUserIdAndShopId(userId, shopId);
shopVo.setUserType(String.valueOf(shopUser.getType())); shopVo.setUserType(String.valueOf(shopUser.getType()));
// 店铺默认规格库id // 店铺默认规格库id
shopVo.setAttrId(shop.getAttrId()); shopVo.setAttrId(shop.getAttrId());*/
return new ResultUtil<ShopVo>().setData(shopVo); return new ResultUtil<ShopTakeaway>().setData(takeaway);
} }
/* /*

239
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminMallOrderGroupController.java

@ -1,13 +1,17 @@
package cc.hiver.mall.controller; package cc.hiver.mall.controller;
import cc.hiver.core.common.redis.RedisTemplateHelper;
import cc.hiver.core.common.utils.ResultUtil; import cc.hiver.core.common.utils.ResultUtil;
import cc.hiver.core.common.vo.Result; import cc.hiver.core.common.vo.Result;
import cc.hiver.mall.dao.mapper.MallOrderGoodsMapper; import cc.hiver.mall.dao.mapper.MallOrderGoodsMapper;
import cc.hiver.mall.entity.MallOrder; import cc.hiver.mall.dao.mapper.ShopMapper;
import cc.hiver.mall.entity.MallOrderGoods; import cc.hiver.mall.dao.mapper.ShopTakeawayMapper;
import cc.hiver.mall.entity.MallOrderGroup; 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.MallOrderGroupService;
import cc.hiver.mall.service.mybatis.MallOrderService; 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.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; 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.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.List;
@Slf4j @Slf4j
@RestController @RestController
@ -37,24 +40,105 @@ public class AdminMallOrderGroupController {
@Autowired @Autowired
private MallOrderGoodsMapper mallOrderGoodsMapper; private MallOrderGoodsMapper mallOrderGoodsMapper;
@Autowired
private ShopGroupOrderCacheUtil shopGroupOrderCacheUtil;
@Autowired
private RedisTemplateHelper redisTemplateHelper;
@Autowired
private ShopMapper shopMapper;
@Autowired
private ShopTakeawayMapper shopTakeawayMapper;
@Data @Data
public static class OrderGroupQuery { public static class OrderGroupQuery {
private String shopId; private String shopId;
private String regionId;
private String headUserId; private String headUserId;
private Integer status; private Integer status;
private String productName; private String productName;
private String keyWord;
private Integer isFace; private Integer isFace;
private Integer merchantType;
private int pageNumber = 1; private int pageNumber = 1;
private int pageSize = 10; 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") @PostMapping("/page")
@ApiOperation(value = "分页查询拼团列表") @ApiOperation(value = "分页查询拼团列表")
public Result<Page<MallOrderGroup>> page(@RequestBody OrderGroupQuery query) { public Result<Page<OrderGroupListVo>> 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<MallOrderGroup> groups = shopGroupOrderCacheUtil.getAllByRegion(query.getRegionId());
if (groups == null) {
groups = listGroupsFromDb(query);
shopGroupOrderCacheUtil.putAllByRegion(query.getRegionId(), groups);
}
groups = filterGroups(groups, query);
Map<String, Shop> 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<OrderGroupListVo> records = groups.subList(fromIndex, toIndex).stream()
.map(group -> toListVo(group, shopMap.get(group.getShopId())))
.collect(Collectors.toList());
Page<OrderGroupListVo> result = new Page<>(pageNumber, pageSize, total);
result.setRecords(records);
return new ResultUtil<Page<OrderGroupListVo>>().setData(result);
}
private List<MallOrderGroup> listGroupsFromDb(OrderGroupQuery query) {
LambdaQueryWrapper<MallOrderGroup> qw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<MallOrderGroup> qw = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(query.getShopId())) { if (StringUtils.isNotBlank(query.getShopId())) {
qw.eq(MallOrderGroup::getShopId, query.getShopId()); qw.eq(MallOrderGroup::getShopId, query.getShopId());
} }
if (StringUtils.isNotBlank(query.getRegionId())) {
qw.eq(MallOrderGroup::getRegionId, query.getRegionId());
}
if (StringUtils.isNotBlank(query.getHeadUserId())) { if (StringUtils.isNotBlank(query.getHeadUserId())) {
qw.eq(MallOrderGroup::getHeadUserId, query.getHeadUserId()); qw.eq(MallOrderGroup::getHeadUserId, query.getHeadUserId());
} }
@ -68,10 +152,145 @@ public class AdminMallOrderGroupController {
qw.eq(MallOrderGroup::getIsFace, query.getIsFace()); qw.eq(MallOrderGroup::getIsFace, query.getIsFace());
} }
qw.orderByDesc(MallOrderGroup::getCreateTime); qw.orderByDesc(MallOrderGroup::getCreateTime);
return mallOrderGroupService.list(qw);
}
private List<MallOrderGroup> filterGroups(List<MallOrderGroup> 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<String, Shop> buildShopMap(List<MallOrderGroup> groups, String regionId) {
if (groups == null || groups.isEmpty()) {
return Collections.emptyMap();
}
Set<String> shopIds = groups.stream()
.map(MallOrderGroup::getShopId)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(LinkedHashSet::new));
if (shopIds.isEmpty()) {
return Collections.emptyMap();
}
Map<String, Shop> result = new HashMap<>();
List<String> missingShopIds = new ArrayList<>();
String shopCacheKey = "SHOP_CACHE:" + regionId;
List<Object> cacheFields = new ArrayList<>(shopIds);
List<Object> 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<Shop> dbShops = shopMapper.selectBatchIds(missingShopIds);
if (dbShops != null && !dbShops.isEmpty()) {
List<ShopTakeaway> takeawayList = shopTakeawayMapper.selectListByshopId(missingShopIds);
Map<String, ShopTakeaway> 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("解析店铺缓存失败", e);
return null;
}
}
private List<MallOrderGroup> filterByShop(List<MallOrderGroup> groups, Map<String, Shop> 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<MallOrderGroup> page = new Page<>(query.getPageNumber(), query.getPageSize()); private OrderGroupListVo toListVo(MallOrderGroup group, Shop shop) {
Page<MallOrderGroup> result = mallOrderGroupService.page(page, qw); OrderGroupListVo vo = new OrderGroupListVo();
return new ResultUtil<Page<MallOrderGroup>>().setData(result); 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 @Data

12
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java

@ -188,6 +188,14 @@ public class MallDeliveryOrderController {
return new ResultUtil<Object>().setData(page); return new ResultUtil<Object>().setData(page);
} }
@PostMapping("/pagebyworkerHistory")
@ApiOperation(value = "分页查询配送员配送单")
public Result<Object> pagebyworkerHistory(@RequestBody MallDeliveryOrderPageQuery q) {
// 1. 先从缓存获取
IPage<MallDeliveryOrder> page = mallDeliveryOrderService.pageDeliveryByStatusHis(q);
return new ResultUtil<Object>().setData(page);
}
/** /**
* 配送员接单 * 配送员接单
*/ */
@ -208,7 +216,7 @@ public class MallDeliveryOrderController {
//当前人没有注册兼职,先赋予兼职身份 //当前人没有注册兼职,先赋予兼职身份
final User user = securityUtil.getCurrUser(); final User user = securityUtil.getCurrUser();
Worker worker = new Worker(); Worker worker = new Worker();
worker.setWorkerName(user.getNickname()); worker.setWorkerName("半径骑士");
worker.setUserId(user.getId()); worker.setUserId(user.getId());
worker.setAvgTime(BigDecimal.valueOf(25)); worker.setAvgTime(BigDecimal.valueOf(25));
worker.setMobile(user.getMobile()); worker.setMobile(user.getMobile());
@ -228,6 +236,8 @@ public class MallDeliveryOrderController {
return ResultUtil.success("配送单已被接取或已取消"); return ResultUtil.success("配送单已被接取或已取消");
}else if(result == 2){ }else if(result == 2){
return ResultUtil.success("该单已指定其他配送员,无法抢单"); return ResultUtil.success("该单已指定其他配送员,无法抢单");
}else if(result == 5){
return ResultUtil.success("已被禁止接单,无法抢单");
}else{ }else{
return new ResultUtil<Worker>().setData(worker); return new ResultUtil<Worker>().setData(worker);
} }

6
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallOrderController.java

@ -211,9 +211,11 @@ public class MallOrderController {
@ApiOperation(value = "用户取消订单") @ApiOperation(value = "用户取消订单")
public Result cancelOrder(@RequestParam String orderId, public Result cancelOrder(@RequestParam String orderId,
@RequestParam String userId,@RequestParam Integer refundType, @RequestParam String userId,@RequestParam Integer refundType,
@RequestParam Integer refundTypeStatus) { @RequestParam Integer refundTypeStatus,
@RequestParam(required = false) String reason,
@RequestParam(required = false) String pictures) {
try { try {
mallOrderService.cancelOrder(orderId, userId, refundType, refundTypeStatus); mallOrderService.cancelOrder(orderId, userId, refundType, refundTypeStatus, reason, pictures);
return ResultUtil.success("已取消"); return ResultUtil.success("已取消");
} catch (Exception e) { } catch (Exception e) {
log.error("取消失败: {}", e.getMessage(), e); log.error("取消失败: {}", e.getMessage(), e);

2
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/MallDeliveryOrderMapper.java

@ -28,6 +28,8 @@ public interface MallDeliveryOrderMapper extends BaseMapper<MallDeliveryOrder> {
*/ */
IPage<MallDeliveryOrder> selectPageVOByStatus(IPage<?> page, @Param("q") MallDeliveryOrderPageQuery q); IPage<MallDeliveryOrder> selectPageVOByStatus(IPage<?> page, @Param("q") MallDeliveryOrderPageQuery q);
IPage<MallDeliveryOrder> selectPageVOByStatusHis(IPage<?> page, @Param("q") MallDeliveryOrderPageQuery q);
/** /**
* 统计配送员当前活跃单量待取货+配送中 * 统计配送员当前活跃单量待取货+配送中
*/ */

4
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(); private String id = SnowFlakeUtil.nextId().toString();
@ApiModelProperty(value = "店铺ID") @ApiModelProperty(value = "店铺ID")
private String shopId; private String shopId;
@ApiModelProperty(value = "店铺名称")
private String shopName;
@ApiModelProperty(value = "区域ID")
private String regionId;
@ApiModelProperty(value = "团长用户ID") @ApiModelProperty(value = "团长用户ID")
private String headUserId; private String headUserId;
@ApiModelProperty(value = "团长订单ID") @ApiModelProperty(value = "团长订单ID")

34
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 org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.Map;
@RestController @RestController
@Api(tags = "i/e随机陪伴接口") @Api(tags = "i/e随机陪伴接口")
@ -59,6 +60,13 @@ public class IeController {
return new ResultUtil<IeUserProfileVO>().setData(matchService.profileByUserId(currentUserId(), targetUserId)); return new ResultUtil<IeUserProfileVO>().setData(matchService.profileByUserId(currentUserId(), targetUserId));
} }
@RequestMapping(value = "/rooms/{roomId}/profile", method = RequestMethod.GET)
@ApiOperation("按房间获取对方半匿名i/e资料")
public Result<IeUserProfileVO> roomTargetProfile(@PathVariable Long roomId) {
Long targetUserId = chatService.roomTargetUserId(currentUserId(), roomId);
return new ResultUtil<IeUserProfileVO>().setData(matchService.profileByUserId(currentUserId(), targetUserId));
}
@RequestMapping(value = "/profile", method = RequestMethod.POST) @RequestMapping(value = "/profile", method = RequestMethod.POST)
@ApiOperation("保存i/e资料") @ApiOperation("保存i/e资料")
public Result<IeUserProfileVO> saveProfile(@RequestBody IeProfileDTO dto) { public Result<IeUserProfileVO> saveProfile(@RequestBody IeProfileDTO dto) {
@ -129,6 +137,32 @@ public class IeController {
return ResultUtil.success("已解除"); return ResultUtil.success("已解除");
} }
@RequestMapping(value = "/block/{blockedUserId}/status", method = RequestMethod.GET)
@ApiOperation("查询拉黑状态")
public Result<Map<String, Boolean>> blockStatus(@PathVariable Long blockedUserId) {
return new ResultUtil<Map<String, Boolean>>().setData(chatService.blockStatus(currentUserId(), blockedUserId));
}
@RequestMapping(value = "/rooms/{roomId}/block", method = RequestMethod.POST)
@ApiOperation("按房间拉黑陪伴对象")
public Result<Object> 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<Object> unblockRoomTarget(@PathVariable Long roomId) {
chatService.unblockRoomTarget(currentUserId(), roomId);
return ResultUtil.success("已解除");
}
@RequestMapping(value = "/rooms/{roomId}/block/status", method = RequestMethod.GET)
@ApiOperation("按房间查询拉黑状态")
public Result<Map<String, Boolean>> roomBlockStatus(@PathVariable Long roomId) {
return new ResultUtil<Map<String, Boolean>>().setData(chatService.roomBlockStatus(currentUserId(), roomId));
}
@RequestMapping(value = "/offline", method = RequestMethod.GET) @RequestMapping(value = "/offline", method = RequestMethod.GET)
@ApiOperation("拉取离线消息") @ApiOperation("拉取离线消息")
public Result<List<String>> offline() { public Result<List<String>> offline() {

12
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 cc.hiver.mall.ie.vo.IeMessageAckVO;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.Map;
public interface IeChatService { public interface IeChatService {
IeRoom getRoom(Long roomId); IeRoom getRoom(Long roomId);
@ -28,6 +30,16 @@ public interface IeChatService {
void unblock(Long userId, Long blockedUserId); void unblock(Long userId, Long blockedUserId);
Map<String, Boolean> blockStatus(Long userId, Long targetUserId);
void blockRoomTarget(Long userId, Long roomId, String reason);
void unblockRoomTarget(Long userId, Long roomId);
Map<String, Boolean> roomBlockStatus(Long userId, Long roomId);
Long roomTargetUserId(Long userId, Long roomId);
IPage<IeRoomMessage> pageMessages(Long userId, Long roomId, Integer pageNumber, Integer pageSize); IPage<IeRoomMessage> pageMessages(Long userId, Long roomId, Integer pageNumber, Integer pageSize);
void markRead(Long userId, Long roomId); void markRead(Long userId, Long roomId);

89
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar; import java.util.*;
import java.util.Date;
import java.util.List;
@Service @Service
public class IeChatServiceImpl implements IeChatService { public class IeChatServiceImpl implements IeChatService {
@ -185,6 +183,8 @@ public class IeChatServiceImpl implements IeChatService {
@Override @Override
public void sendPresence(Long senderId, IePresenceDTO dto) { public void sendPresence(Long senderId, IePresenceDTO dto) {
IeRoom room = assertActiveRoom(senderId, dto.getRoomId()); IeRoom room = assertActiveRoom(senderId, dto.getRoomId());
Long receiverId = room.getUserAId().equals(senderId) ? room.getUserBId() : room.getUserAId();
assertNotBlocked(senderId, receiverId);
IePresenceEvent event = new IePresenceEvent(); IePresenceEvent event = new IePresenceEvent();
event.setRoomId(room.getId()); event.setRoomId(room.getId());
event.setSenderId(senderId); event.setSenderId(senderId);
@ -192,7 +192,6 @@ public class IeChatServiceImpl implements IeChatService {
event.setEventText(dto.getEventText()); event.setEventText(dto.getEventText());
event.setCreateTime(new Date()); event.setCreateTime(new Date());
presenceEventMapper.insert(event); presenceEventMapper.insert(event);
Long receiverId = room.getUserAId().equals(senderId) ? room.getUserBId() : room.getUserAId();
messagingTemplate.convertAndSendToUser(String.valueOf(receiverId), "/queue/ie/presence", event); messagingTemplate.convertAndSendToUser(String.valueOf(receiverId), "/queue/ie/presence", event);
} }
@ -258,17 +257,11 @@ public class IeChatServiceImpl implements IeChatService {
block.setReason(reason); block.setReason(reason);
block.setCreateTime(new Date()); block.setCreateTime(new Date());
blockMapper.insert(block); blockMapper.insert(block);
broadcastBlockStatus(userId, blockedUserId);
} }
private void assertNotBlocked(Long senderId, Long receiverId) { private void assertNotBlocked(Long senderId, Long receiverId) {
Long count = blockMapper.selectCount(new LambdaQueryWrapper<IeBlock>() if (hasBlock(senderId, receiverId) || hasBlock(receiverId, senderId)) {
.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) {
throw new RuntimeException("你们之间已有黑名单关系,无法继续发送消息"); throw new RuntimeException("你们之间已有黑名单关系,无法继续发送消息");
} }
} }
@ -278,6 +271,78 @@ public class IeChatServiceImpl implements IeChatService {
blockMapper.delete(new LambdaQueryWrapper<IeBlock>() blockMapper.delete(new LambdaQueryWrapper<IeBlock>()
.eq(IeBlock::getUserId, userId) .eq(IeBlock::getUserId, userId)
.eq(IeBlock::getBlockedUserId, blockedUserId)); .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<String, Boolean> 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<String, Boolean> blockStatus(Long userId, Long targetUserId) {
boolean blockedByMe = hasBlock(userId, targetUserId);
boolean blockedByOther = hasBlock(targetUserId, userId);
Map<String, Boolean> 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<IeBlock>()
.eq(IeBlock::getUserId, userId)
.eq(IeBlock::getBlockedUserId, blockedUserId));
return count != null && count > 0;
}
private void broadcastBlockStatus(Long userId, Long targetUserId) {
List<IeRoom> rooms = roomMapper.selectList(new LambdaQueryWrapper<IeRoom>()
.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<String, Object> 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 @Override

34
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 @Autowired
private IeRoomMapper roomMapper; private IeRoomMapper roomMapper;
@Autowired
private IeRecordMapper recordMapper;
@Autowired
private IeRoomMessageMapper roomMessageMapper;
@Autowired @Autowired
private IeBlockMapper blockMapper; private IeBlockMapper blockMapper;
@ -59,6 +65,7 @@ public class IeMatchServiceImpl implements IeMatchService {
vo.setWaitingCount(redisService.waitingCount(profile.getCurrentMode(), "quiet")); vo.setWaitingCount(redisService.waitingCount(profile.getCurrentMode(), "quiet"));
vo.setDailyQuota(profile.getDailyQuota()); vo.setDailyQuota(profile.getDailyQuota());
vo.setUsedQuota((int) redisService.todayUsedQuota(userId)); vo.setUsedQuota((int) redisService.todayUsedQuota(userId));
vo.setUnreadCount(totalUnreadCount(userId));
vo.setCurrentMode(profile.getCurrentMode()); vo.setCurrentMode(profile.getCurrentMode());
vo.setCurrentMood("quiet"); vo.setCurrentMood("quiet");
vo.setTargetModePreference(profile.getTargetModePreference()); vo.setTargetModePreference(profile.getTargetModePreference());
@ -69,6 +76,25 @@ public class IeMatchServiceImpl implements IeMatchService {
return vo; return vo;
} }
private int totalUnreadCount(Long userId) {
List<IeRecord> records = recordMapper.selectList(new LambdaQueryWrapper<IeRecord>()
.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<IeRoomMessage>()
.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 @Override
public IeUserProfileVO profile(Long userId) { public IeUserProfileVO profile(Long userId) {
return toProfileVO(ensureProfile(userId)); return toProfileVO(ensureProfile(userId));
@ -175,7 +201,7 @@ public class IeMatchServiceImpl implements IeMatchService {
Long targetUserId = null; Long targetUserId = null;
try { try {
if (redisService.todayUsedQuota(userId) >= maxQuota) { if (redisService.todayUsedQuota(userId) >= maxQuota) {
return fail(userId, dto, "今日陪伴机会已经用完"); return fail(userId, dto, "今日陪伴机会已经用完,平台下单可增加匹配次数");
} }
IeStatusDTO statusDTO = new IeStatusDTO(); IeStatusDTO statusDTO = new IeStatusDTO();
BeanUtils.copyProperties(dto == null ? new IeMatchStartDTO() : dto, statusDTO); BeanUtils.copyProperties(dto == null ? new IeMatchStartDTO() : dto, statusDTO);
@ -217,7 +243,7 @@ public class IeMatchServiceImpl implements IeMatchService {
} }
long used = redisService.increaseTodayQuota(userId, maxQuota); long used = redisService.increaseTodayQuota(userId, maxQuota);
if (used > maxQuota) { if (used > maxQuota) {
return fail(userId, dto, "今日陪伴机会已经用完"); return fail(userId, dto, "今日陪伴机会已经用完,平台下单可增加匹配次数");
} }
IeUserProfile targetProfile = ensureProfile(targetUserId); IeUserProfile targetProfile = ensureProfile(targetUserId);
@ -247,6 +273,10 @@ public class IeMatchServiceImpl implements IeMatchService {
vo.setRoomId(room.getId()); vo.setRoomId(room.getId());
vo.setRoomNo(room.getRoomNo()); vo.setRoomNo(room.getRoomNo());
vo.setAvatarUrl(targetProfile.getAvatarUrl()); vo.setAvatarUrl(targetProfile.getAvatarUrl());
vo.setGender(targetProfile.getGender());
vo.setIntro(targetProfile.getIntro());
vo.setInterestTags(jsonToTags(targetProfile.getInterestTags()));
vo.setPersonaImages(jsonToTags(targetProfile.getPersonaImages()));
return vo; return vo;
} finally { } finally {
redisService.unlockMatchUser(userId); redisService.unlockMatchUser(userId);

1
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 Long waitingCount;
private Integer dailyQuota; private Integer dailyQuota;
private Integer usedQuota; private Integer usedQuota;
private Integer unreadCount;
private String currentMode; private String currentMode;
private String currentMood; private String currentMood;
private String targetModePreference; private String targetModePreference;

5
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 lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List;
@Data @Data
public class IeMatchVO { public class IeMatchVO {
@ -12,6 +13,10 @@ public class IeMatchVO {
private String anonymousName; private String anonymousName;
private String avatarText; private String avatarText;
private String avatarUrl; private String avatarUrl;
private String gender;
private String intro;
private List<String> interestTags;
private List<String> personaImages;
private String mode; private String mode;
private String mood; private String mood;
private String stateText; private String stateText;

2
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallDeliveryOrderService.java

@ -27,6 +27,8 @@ public interface MallDeliveryOrderService extends IService<MallDeliveryOrder> {
*/ */
IPage<MallDeliveryOrder> pageDeliveryByStatus(MallDeliveryOrderPageQuery q); IPage<MallDeliveryOrder> pageDeliveryByStatus(MallDeliveryOrderPageQuery q);
IPage<MallDeliveryOrder> pageDeliveryByStatusHis(MallDeliveryOrderPageQuery q);
/** /**
* 配送员接单抢单大厅或指派单 * 配送员接单抢单大厅或指派单
*/ */

2
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/MallOrderService.java

@ -50,7 +50,7 @@ public interface MallOrderService extends IService<MallOrder> {
/** /**
* 用户取消订单仅待支付/待成团状态可取消 * 用户取消订单仅待支付/待成团状态可取消
*/ */
void cancelOrder(String orderId, String userId,Integer refundType, Integer refundTypeStatus); void cancelOrder(String orderId, String userId,Integer refundType, Integer refundTypeStatus, String reason, String pictures);
/** /**
* 申请退款 * 申请退款

9
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java

@ -170,6 +170,15 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
return page; return page;
} }
@Override
public IPage<MallDeliveryOrder> pageDeliveryByStatusHis(MallDeliveryOrderPageQuery q) {
IPage<MallDeliveryOrder> page = new Page<>(q.getPageNum(), q.getPageSize());
page = this.baseMapper.selectPageVOByStatusHis(page,q);
// 批量查询订单商品明细,避免 N+1 问题,处理面对面拼团子订单
assembleOrderGoodsForDeliveries(page.getRecords());
return page;
}
/** /**
* 配送员接单 * 配送员接单
* - 抢单大厅workerId 为空的单任何配送员均可接 * - 抢单大厅workerId 为空的单任何配送员均可接

4
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java

@ -145,9 +145,7 @@ public class MallOrderGroupServiceImpl extends ServiceImpl<MallOrderGroupMapper,
.in(MallOrder::getId, orderIdList); .in(MallOrder::getId, orderIdList);
List<MallOrder> waitingOrders = mallOrderService.list(oqw); List<MallOrder> waitingOrders = mallOrderService.list(oqw);
boolean isFace2Face = (group.getStatus() == GROUP_STATUS_FACE2FACE boolean isFace2Face = group.getIsFace() != null && group.getIsFace() == 1;
|| (group.getStatus() == GROUP_STATUS_SUCCESS
&& this.getById(groupId).getStatus() == GROUP_STATUS_FACE2FACE));
for (MallOrder order : waitingOrders) { for (MallOrder order : waitingOrders) {
int targetStatus = (order.getDeliveryType() != null && order.getDeliveryType() == 1) ? 2 : 3; int targetStatus = (order.getDeliveryType() != null && order.getDeliveryType() == 1) ? 2 : 3;

62
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java

@ -420,6 +420,8 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
group.setIsFace(STATUS_WAIT_PAY); group.setIsFace(STATUS_WAIT_PAY);
} }
group.setShopId(dto.getShopId()); group.setShopId(dto.getShopId());
group.setRegionId(dto.getRegionId());
group.setShopName(order.getShopName());
group.setHeadUserId(dto.getUserId()); group.setHeadUserId(dto.getUserId());
group.setTargetMembers(gp.getTargetMembers()); group.setTargetMembers(gp.getTargetMembers());
//group.setCurrentMembers(1); //group.setCurrentMembers(1);
@ -681,6 +683,8 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
//普通拼团团长发起拼团进缓存 //普通拼团团长发起拼团进缓存
if(order.getOrderType() == ORDER_TYPE_GROUP){ if(order.getOrderType() == ORDER_TYPE_GROUP){
group.setCurrentMembers(newMembers); group.setCurrentMembers(newMembers);
group.setStatus(GROUP_STATUS_FORMING);
group.setIsFace(0);
shopGroupOrderCacheUtil.put(order.getShopId(), group); shopGroupOrderCacheUtil.put(order.getShopId(), group);
} }
}else{ }else{
@ -775,7 +779,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void cancelOrder(String orderId, String userId,Integer refundType,Integer refundTypeStatus) { public void cancelOrder(String orderId, String userId,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
MallOrder order = getById(orderId); MallOrder order = getById(orderId);
if (order == null) throw new RuntimeException("订单不存在"); if (order == null) throw new RuntimeException("订单不存在");
if (!userId.equals(order.getUserId())) throw new RuntimeException("无权操作该订单"); if (!userId.equals(order.getUserId())) throw new RuntimeException("无权操作该订单");
@ -788,10 +792,10 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
// 拼团 / 面对面团 // 拼团 / 面对面团
if (order.getOrderType() == ORDER_TYPE_GROUP || order.getOrderType() == 3) { if (order.getOrderType() == ORDER_TYPE_GROUP || order.getOrderType() == 3) {
handleGroupCancel(order,refundType,refundTypeStatus); handleGroupCancel(order,refundType,refundTypeStatus, reason, pictures);
} else { } else {
// 直接购买 // 直接购买
handleDirectCancel(order, refundType,refundTypeStatus); handleDirectCancel(order, refundType,refundTypeStatus, reason, pictures);
} }
} }
@ -802,22 +806,22 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
/** /**
* 拼团取消总调度判断团长/团员后分流 * 拼团取消总调度判断团长/团员后分流
*/ */
private void handleGroupCancel(MallOrder order,Integer refundType,Integer refundTypeStatus) { private void handleGroupCancel(MallOrder order,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
MallOrderGroup group = findGroupByOrderId(order.getId()); MallOrderGroup group = findGroupByOrderId(order.getId());
if (group == null) throw new RuntimeException("拼团信息不存在"); if (group == null) throw new RuntimeException("拼团信息不存在");
boolean isHead = order.getId().equals(group.getHeadOrderId()); boolean isHead = order.getId().equals(group.getHeadOrderId());
if (isHead) { if (isHead) {
handleGroupHeadCancel(order, group,refundType,refundTypeStatus); handleGroupHeadCancel(order, group,refundType,refundTypeStatus, reason, pictures);
} else { } else {
handleGroupMemberCancel(order, group,refundType,refundTypeStatus); handleGroupMemberCancel(order, group,refundType,refundTypeStatus, reason, pictures);
} }
} }
/** /**
* 团长取消订单 * 团长取消订单
*/ */
private void handleGroupHeadCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus) { private void handleGroupHeadCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
boolean isFace2Face = (order.getOrderType() == 3); boolean isFace2Face = (order.getOrderType() == 3);
// ---- 1. 未支付 ---- // ---- 1. 未支付 ----
@ -909,13 +913,13 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
} }
// ---- 3. 已成团后 ---- // ---- 3. 已成团后 ----
handlePostGroupCancel(order, group,refundType,refundTypeStatus); handlePostGroupCancel(order, group,refundType,refundTypeStatus, reason, pictures);
} }
/** /**
* 团员取消订单 * 团员取消订单
*/ */
private void handleGroupMemberCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus) { private void handleGroupMemberCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
// ---- 1. 未支付 ---- // ---- 1. 未支付 ----
if (order.getStatus() == STATUS_WAIT_PAY) { if (order.getStatus() == STATUS_WAIT_PAY) {
updateOrderStatus(order.getId(), STATUS_CANCELLED); updateOrderStatus(order.getId(), STATUS_CANCELLED);
@ -955,13 +959,13 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
} }
// ---- 3. 已成团后 ---- // ---- 3. 已成团后 ----
handlePostGroupCancel(order, group,refundType,refundTypeStatus); handlePostGroupCancel(order, group,refundType,refundTypeStatus, reason, pictures);
} }
/** /**
* 成团后取消逻辑团长和团员共用 * 成团后取消逻辑团长和团员共用
*/ */
private void handlePostGroupCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus) { private void handlePostGroupCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
boolean isFace2Face = (order.getOrderType() == 3); boolean isFace2Face = (order.getOrderType() == 3);
boolean isHead = order.getId().equals(group.getHeadOrderId()); boolean isHead = order.getId().equals(group.getHeadOrderId());
@ -977,7 +981,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
if (!isHead) { if (!isHead) {
throw new RuntimeException("面对面配送团只有团长可以取消订单"); throw new RuntimeException("面对面配送团只有团长可以取消订单");
} }
handleFace2FaceDeliveryCancel(order, group, refundType,refundTypeStatus); handleFace2FaceDeliveryCancel(order, group, refundType,refundTypeStatus, reason, pictures);
return; return;
} }
@ -993,7 +997,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
} }
} }
if (delivery != null && delivery.getStatus() != null && delivery.getStatus() >= 1) { if (delivery != null && delivery.getStatus() != null && delivery.getStatus() >= 1) {
applyMerchantRefund(delivery.getWorkerId(),order, "用户申请取消订单退款",refundType,refundTypeStatus); applyMerchantRefund(delivery.getWorkerId(),order, appendCancelReason("用户申请取消订单退款", reason),refundType,refundTypeStatus, pictures);
}else{ }else{
// 允许取消 // 允许取消
cancelDeliveryOrderByOrderId(order.getId()); cancelDeliveryOrderByOrderId(order.getId());
@ -1004,14 +1008,14 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
} }
} else { } else {
// 自取(待消费)→ 待商家同意退款 // 自取(待消费)→ 待商家同意退款
applyMerchantRefund(null,order, "用户申请取消订单退款",refundType,refundTypeStatus); applyMerchantRefund(null,order, appendCancelReason("用户申请取消订单退款", reason),refundType,refundTypeStatus, pictures);
} }
} }
/** /**
* 面对面团 + 配送 成团后团长取消批量操作所有子订单 * 面对面团 + 配送 成团后团长取消批量操作所有子订单
*/ */
private void handleFace2FaceDeliveryCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus) { private void handleFace2FaceDeliveryCancel(MallOrder order, MallOrderGroup group,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
MallDeliveryOrder delivery = findDeliveryByOrderId(order.getId()); MallDeliveryOrder delivery = findDeliveryByOrderId(order.getId());
if (delivery != null && delivery.getStatus() != null && delivery.getStatus() == 0) { if (delivery != null && delivery.getStatus() != null && delivery.getStatus() == 0) {
@ -1044,7 +1048,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
if (subOrder != null && subOrder.getStatus() != STATUS_CANCELLED if (subOrder != null && subOrder.getStatus() != STATUS_CANCELLED
&& subOrder.getStatus() != STATUS_REFUNDED) { && subOrder.getStatus() != STATUS_REFUNDED) {
subOrder.setGroupOrderIds(group.getGroupOrderIds()); subOrder.setGroupOrderIds(group.getGroupOrderIds());
applyMerchantRefund(delivery.getWorkerId(),subOrder, "面对面团团长申请取消",refundType,refundTypeStatus); applyMerchantRefund(delivery.getWorkerId(),subOrder, appendCancelReason("面对面团团长申请取消", reason),refundType,refundTypeStatus, pictures);
} }
} }
} }
@ -1057,7 +1061,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
/** /**
* 直接购买订单取消 * 直接购买订单取消
*/ */
private void handleDirectCancel(MallOrder order,Integer refundType,Integer refundTypeStatus) { private void handleDirectCancel(MallOrder order,Integer refundType,Integer refundTypeStatus, String reason, String pictures) {
// ---- 1. 未支付 ---- // ---- 1. 未支付 ----
if (order.getStatus() == STATUS_WAIT_PAY) { if (order.getStatus() == STATUS_WAIT_PAY) {
updateOrderStatus(order.getId(), STATUS_CANCELLED); updateOrderStatus(order.getId(), STATUS_CANCELLED);
@ -1083,7 +1087,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
MallDeliveryOrder delivery = findDeliveryByOrderId(order.getId()); MallDeliveryOrder delivery = findDeliveryByOrderId(order.getId());
if (delivery != null && delivery.getStatus() != null && delivery.getStatus() >= 1) { if (delivery != null && delivery.getStatus() != null && delivery.getStatus() >= 1) {
// 配送员已接单 → 走商家或者配送员同意流程 // 配送员已接单 → 走商家或者配送员同意流程
applyMerchantRefund(delivery.getWorkerId(),order, "用户申请取消订单", refundType, refundTypeStatus); applyMerchantRefund(delivery.getWorkerId(),order, appendCancelReason("用户申请取消订单", reason), refundType, refundTypeStatus, pictures);
} else { } else {
// 未接单 → 直接取消并退款 // 未接单 → 直接取消并退款
cancelDeliveryOrderByOrderId(order.getId()); cancelDeliveryOrderByOrderId(order.getId());
@ -1098,7 +1102,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
autoRefund(order, "用户取消订单,系统退款"); autoRefund(order, "用户取消订单,系统退款");
restoreStock(order.getId()); restoreStock(order.getId());
}else{ }else{
applyMerchantRefund(null,order, "用户申请取消订单", refundType, refundTypeStatus); applyMerchantRefund(null,order, appendCancelReason("用户申请取消订单", reason), refundType, refundTypeStatus, pictures);
} }
} }
} }
@ -1703,12 +1707,19 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
* 创建退款记录 * 创建退款记录
*/ */
private void createRefundRecord(String workerId,MallOrder order, BigDecimal amount, String reason,Integer refundType,Integer refundTypeStatus) { private void createRefundRecord(String workerId,MallOrder order, BigDecimal amount, String reason,Integer refundType,Integer refundTypeStatus) {
createRefundRecord(workerId, order, amount, reason, refundType, refundTypeStatus, null);
}
private void createRefundRecord(String workerId,MallOrder order, BigDecimal amount, String reason,Integer refundType,Integer refundTypeStatus, String pictures) {
MallRefundRecord record = new MallRefundRecord(); MallRefundRecord record = new MallRefundRecord();
record.setOrderId(order.getId()); record.setOrderId(order.getId());
record.setUserId(order.getUserId()); record.setUserId(order.getUserId());
record.setRefundAmount(amount); record.setRefundAmount(amount);
record.setRegionId(order.getRegionId()); record.setRegionId(order.getRegionId());
record.setReason(reason); record.setReason(reason);
if (StringUtils.isNotBlank(pictures)) {
record.setPictures(pictures);
}
if(order.getGroupOrderIds() != null){ if(order.getGroupOrderIds() != null){
record.setGroupOrderIds(order.getGroupOrderIds()); record.setGroupOrderIds(order.getGroupOrderIds());
} }
@ -1967,6 +1978,10 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
* 申请商家同意退款订单状态 待商家同意退款(7)退款记录状态 待商家同意(0) * 申请商家同意退款订单状态 待商家同意退款(7)退款记录状态 待商家同意(0)
*/ */
private void applyMerchantRefund(String workerId, MallOrder order, String reason,Integer refundType,Integer refundTypeStatus) { private void applyMerchantRefund(String workerId, MallOrder order, String reason,Integer refundType,Integer refundTypeStatus) {
applyMerchantRefund(workerId, order, reason, refundType, refundTypeStatus, null);
}
private void applyMerchantRefund(String workerId, MallOrder order, String reason,Integer refundType,Integer refundTypeStatus, String pictures) {
updateOrderStatus(order.getId(), STATUS_WAIT_REFUND); updateOrderStatus(order.getId(), STATUS_WAIT_REFUND);
//更新缓存 //更新缓存
MallOrderVO vo = userPendingOrderCacheUtil.get(order.getUserId(), order.getId()); MallOrderVO vo = userPendingOrderCacheUtil.get(order.getUserId(), order.getId());
@ -1981,7 +1996,14 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
.set(MallDeliveryOrder::getIsReturn, IS_RETURN_EXPRESS); .set(MallDeliveryOrder::getIsReturn, IS_RETURN_EXPRESS);
mallDeliveryOrderMapper.update(null, duw); mallDeliveryOrderMapper.update(null, duw);
} }
createRefundRecord(workerId,order, order.getTotalAmount(), reason,refundType,refundTypeStatus); createRefundRecord(workerId,order, order.getTotalAmount(), reason,refundType,refundTypeStatus, pictures);
}
private String appendCancelReason(String baseReason, String reason) {
if (StringUtils.isBlank(reason)) {
return baseReason;
}
return baseReason + ":" + reason;
} }
/** /**

141
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/ShopGroupOrderCacheUtil.java

@ -15,9 +15,10 @@ import java.util.Map;
/** /**
* 商家待成团订单缓存工具类 * 商家待成团订单缓存工具类
* <p> * <p>
* 底层使用 Redis Hash 结构保证按 shopId + orderId 维度的 O(1) 读写效率 * 底层使用 Redis Hash 结构保证按 shopId / regionId + orderId 维度的 O(1) 读写效率
* <pre> * <pre>
* Key = SHOP_GROUP_ORDERS:{shopId} * 店铺维度 Key = SHOP_GROUP_ORDERS:{shopId}
* 区域维度 Key = SHOP_GROUP_ORDERS_REGION:{regionId}
* Field = orderId * Field = orderId
* Value = MallOrderGroup JSON 序列化 * Value = MallOrderGroup JSON 序列化
* </pre> * </pre>
@ -34,8 +35,14 @@ public class ShopGroupOrderCacheUtil {
/** Redis Key 前缀 */ /** Redis Key 前缀 */
private static final String KEY_PREFIX = "SHOP_GROUP_ORDERS:"; private static final String KEY_PREFIX = "SHOP_GROUP_ORDERS:";
/** 订单不再属于"待成团"的状态集合 */ /** 区域待成团 Redis Key 前缀 */
private static final int STATUS_DONE = 0; 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 @Autowired
private RedisTemplateHelper redisTemplateHelper; private RedisTemplateHelper redisTemplateHelper;
@ -48,6 +55,10 @@ public class ShopGroupOrderCacheUtil {
return KEY_PREFIX + shopId; return KEY_PREFIX + shopId;
} }
private String buildRegionKey(String regionId) {
return REGION_KEY_PREFIX + regionId;
}
// ================================================================ // ================================================================
// 存放(put) // 存放(put)
// ================================================================ // ================================================================
@ -64,10 +75,17 @@ public class ShopGroupOrderCacheUtil {
return; return;
} }
try { try {
String key = buildKey(shopId); if (!isPublicPending(orderVO)) {
remove(shopId, orderVO.getRegionId(), orderVO.getId());
return;
}
String json = JSONUtil.toJsonStr(orderVO); String json = JSONUtil.toJsonStr(orderVO);
redisTemplateHelper.hPut(key, orderVO.getId(), json); redisTemplateHelper.hPut(buildKey(shopId), orderVO.getId(), json);
log.info("缓存店铺待成团订单: shopId={}, orderId={}", shopId, orderVO.getId()); 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) { } catch (Exception e) {
log.info("缓存店铺待成团订单失败: shopId={}, orderId={}", shopId, orderVO.getId(), e); log.info("缓存店铺待成团订单失败: shopId={}, orderId={}", shopId, orderVO.getId(), e);
} }
@ -84,15 +102,23 @@ public class ShopGroupOrderCacheUtil {
return; return;
} }
try { try {
String key = buildKey(shopId);
Map<String, String> map = new java.util.LinkedHashMap<>(orders.size()); Map<String, String> map = new java.util.LinkedHashMap<>(orders.size());
Map<String, Map<String, String>> regionMap = new java.util.LinkedHashMap<>();
for (MallOrderGroup order : orders) { for (MallOrderGroup order : orders) {
if (order != null && StringUtils.isNotBlank(order.getId())) { if (order != null && StringUtils.isNotBlank(order.getId()) && isPublicPending(order)) {
map.put(order.getId(), JSONUtil.toJsonStr(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()) { if (!map.isEmpty()) {
redisTemplateHelper.hPutAll(key, map); redisTemplateHelper.hPutAll(buildKey(shopId), map);
for (Map.Entry<String, Map<String, String>> entry : regionMap.entrySet()) {
redisTemplateHelper.hPutAll(buildRegionKey(entry.getKey()), entry.getValue());
}
log.info("批量缓存店铺待成团订单: shopId={}, count={}", shopId, map.size()); log.info("批量缓存店铺待成团订单: shopId={}, count={}", shopId, map.size());
} }
} catch (Exception e) { } catch (Exception e) {
@ -118,14 +144,33 @@ public class ShopGroupOrderCacheUtil {
return; return;
} }
try { try {
String key = buildKey(shopId); MallOrderGroup cachedOrder = get(shopId, orderId);
redisTemplateHelper.hDelete(key, 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); log.info("删除待成团订单缓存: shopId={}, orderId={}", shopId, orderId);
} catch (Exception e) { } catch (Exception e) {
log.info("删除待成团订单缓存失败: shopId={}, orderId={}", shopId, orderId, 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);
}
}
/** /**
* 清除指定店铺所有待成团订单缓存 * 清除指定店铺所有待成团订单缓存
* <p> * <p>
@ -165,8 +210,8 @@ public class ShopGroupOrderCacheUtil {
} }
try { try {
// 如果订单状态已不属于待成团,直接删除 // 如果订单状态已不属于待成团,直接删除
/*if (!isTerminalStatus(orderVO.getStatus())) { /*if (!isPublicPending(orderVO)) {
remove(shopId, orderVO.getId()); remove(shopId, orderVO.getRegionId(), orderVO.getId());
log.debug("订单已终态,从缓存移除: shopId={}, orderId={}, status={}", log.debug("订单已终态,从缓存移除: shopId={}, orderId={}, status={}",
shopId, orderVO.getId(), orderVO.getStatus()); shopId, orderVO.getId(), orderVO.getStatus());
return; return;
@ -213,6 +258,57 @@ public class ShopGroupOrderCacheUtil {
} }
} }
/**
* 获取区域维度待成团订单缓存
*/
public List<MallOrderGroup> getAllByRegion(String regionId) {
if (StringUtils.isBlank(regionId)) {
return null;
}
try {
Map<Object, Object> entries = redisTemplateHelper.hGetAll(buildRegionKey(regionId));
if (entries == null || entries.isEmpty()) {
return null;
}
List<MallOrderGroup> 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<MallOrderGroup> orders) {
if (StringUtils.isBlank(regionId) || orders == null || orders.isEmpty()) {
return;
}
try {
Map<String, String> 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; 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) { public boolean isPublicPending(MallOrderGroup order) {
if (status == null) { if (order == null || order.getStatus() == null) {
return false; return false;
} }
return status == STATUS_DONE; return order.getStatus() == STATUS_FORMING
&& (order.getIsFace() == null || order.getIsFace() == IS_FACE_NORMAL);
} }
} }

50
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 ORDER BY (CASE WHEN d.must_finish_time IS NULL THEN 1 ELSE 0 END) ASC
</select> </select>
<select id="selectPageVOByStatusHis" resultMap="deliveryMap">
SELECT
d.id, d.order_id, d.group_id, d.worker_id, d.shop_id,
d.get_area_id, d.put_area_id, d.delivery_fee, d.delivery_fee_marketplace,
d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.finish_time,
d.receiver_name, d.receiver_phone, d.receiver_address,
d.shop_name, d.shop_phone, d.shop_address, d.delivery_type, d.number_code,
d.region_id,d.remark, d.all_count, d.phone_number, d.get_codes, d.get_pictures,
d.is_big,d.is_return,d.worker_name,d.arrive_time,d.new_worker,d.worker_phone
FROM mall_delivery_order d
<where>
d.status not in (-1,4)
<if test="q.regionId != null and q.regionId != ''">
AND d.region_id = #{q.regionId}
</if>
<if test="q.workerId != null and q.workerId != ''">
AND d.worker_id = #{q.workerId}
</if>
<if test="q.newWorker != null and q.newWorker != ''">
AND d.new_worker = #{q.newWorker}
</if>
<if test="q.shopId != null and q.shopId != ''">
AND d.shop_id = #{q.shopId}
</if>
<if test="q.status != null">
AND d.status = #{q.status}
</if>
<if test="q.getAreaId != null and q.getAreaId != ''">
AND d.get_area_id = #{q.getAreaId}
</if>
<if test="q.putAreaId != null and q.putAreaId != ''">
AND d.put_area_id = #{q.putAreaId}
</if>
<if test="q.hallOnly != null and q.hallOnly == true">
AND (d.worker_id IS NULL OR d.worker_id = '')
AND d.status = 0
</if>
<if test="q.startDate != null and q.startDate != ''">
AND DATE(d.create_time) &gt;= #{q.startDate}
</if>
<if test="q.endDate != null and q.endDate != ''">
AND DATE(d.create_time) &lt;= #{q.endDate}
</if>
<if test="q.deliveryType != null">
AND d.delivery_type = #{q.deliveryType}
</if>
</where>
ORDER BY d.finish_time desc
</select>
<select id="selectByGroupId" resultMap="deliveryMap"> <select id="selectByGroupId" resultMap="deliveryMap">
SELECT SELECT
d.id, d.order_id, d.group_id, d.worker_id, d.shop_id, d.id, d.order_id, d.group_id, d.worker_id, d.shop_id,

10
hiver-modules/hiver-mall/src/main/resources/mapper/MallOrderGroupMapper.xml

@ -23,13 +23,15 @@
<result column="product_picture" property="productPicture"/> <result column="product_picture" property="productPicture"/>
<result column="product_id" property="productId"/> <result column="product_id" property="productId"/>
<result column="success_time" property="successTime"/> <result column="success_time" property="successTime"/>
<result column="region_id" property="regionId"/>
<result column="shop_name" property="shopName"/>
</resultMap> </resultMap>
<select id="selectMallGroup" resultMap="groupMap"> <select id="selectMallGroup" resultMap="groupMap">
SELECT id,shop_id,head_user_id,head_order_id,group_order_ids,target_members, 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, 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 FROM mall_order_group
<where> <where>
<if test="group.shopId != null and group.shopId != ''"> <if test="group.shopId != null and group.shopId != ''">
@ -41,6 +43,12 @@
<if test="group.status != null"> <if test="group.status != null">
AND status = #{group.status} AND status = #{group.status}
</if> </if>
<if test="group.regionId != null and group.regionId != ''">
AND region_id = #{group.regionId}
</if>
<if test="group.shopName != null and group.shopName != ''">
AND shop_name = #{group.shopName}
</if>
</where> </where>
order by create_time asc order by create_time asc
</select> </select>

Loading…
Cancel
Save