# Conflicts:
#	yudao-dependencies/pom.xml
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareCreateReqVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareUpdateReqVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/record/IotOtaUpgradeRecordPageReqVO.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/task/IotOtaUpgradeTaskPageReqVO.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java
#	yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImplTest.java
#	yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java
This commit is contained in:
YunaiV
2025-04-30 00:11:24 +08:00
71 changed files with 2342 additions and 246 deletions

View File

@@ -5,6 +5,9 @@ import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 商品 SKU API 接口
@@ -30,6 +33,16 @@ public interface ProductSkuApi {
*/
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
/**
* 批量查询 SKU MAP
*
* @param ids SKU 编号列表
* @return SKU MAP
*/
default Map<Long, ProductSkuRespDTO> getSkuMap(Collection<Long> ids) {
return convertMap(getSkuList(ids), ProductSkuRespDTO::getId);
}
/**
* 批量查询 SKU 数组
*

View File

@@ -30,7 +30,7 @@ public interface ProductSpuApi {
* @param ids SPU 编号列表
* @return SPU MAP
*/
default Map<Long, ProductSpuRespDTO> getSpusMap(Collection<Long> ids) {
default Map<Long, ProductSpuRespDTO> getSpuMap(Collection<Long> ids) {
return convertMap(getSpuList(ids), ProductSpuRespDTO::getId);
}

View File

@@ -4,17 +4,15 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "管理后台 - 商品浏览记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ProductBrowseHistoryRespVO {
@Schema(description = "编号", requiredMode = REQUIRED, example = "1")
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
private Long spuId;
// ========== 商品相关字段 ==========
@@ -34,4 +32,4 @@ public class ProductBrowseHistoryRespVO {
@Schema(description = "库存", example = "100")
private Integer stock;
}
}

View File

@@ -6,13 +6,11 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 APP - 商品收藏的批量 Request VO") // 用于收藏、取消收藏、获取收藏
@Data
public class AppFavoriteBatchReqVO {
@Schema(description = "商品 SPU 编号数组", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
@NotEmpty(message = "商品 SPU 编号数组不能为空")
private List<Long> spuIds;

View File

@@ -5,13 +5,11 @@ import lombok.Data;
import javax.validation.constraints.NotNull;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 APP - 商品收藏的单个 Request VO") // 用于收藏、取消收藏、获取收藏
@Data
public class AppFavoriteReqVO {
@Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;

View File

@@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 App - 商品收藏 Response VO")
@Data
public class AppFavoriteRespVO {
@Schema(description = "编号", requiredMode = REQUIRED, example = "1")
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
private Long spuId;
// ========== 商品相关字段 ==========

View File

@@ -6,13 +6,11 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 APP - 删除商品浏览记录的 Request VO")
@Data
public class AppProductBrowseHistoryDeleteReqVO {
@Schema(description = "商品 SPU 编号数组", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
@NotEmpty(message = "商品 SPU 编号数组不能为空")
private List<Long> spuIds;

View File

@@ -3,33 +3,31 @@ package cn.iocoder.yudao.module.product.controller.app.history.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 App - 商品浏览记录 Response VO")
@Data
public class AppProductBrowseHistoryRespVO {
@Schema(description = "编号", requiredMode = REQUIRED, example = "1")
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "29502")
private Long spuId;
// ========== 商品相关字段 ==========
@Schema(description = "商品 SPU 名称", requiredMode = REQUIRED, example = "赵六")
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
private String spuName;
@Schema(description = "商品封面图", requiredMode = REQUIRED, example = "https://www.iocoder.cn/pic.png")
@Schema(description = "商品封面图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/pic.png")
private String picUrl;
@Schema(description = "商品单价", requiredMode = REQUIRED, example = "50")
@Schema(description = "商品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
private Integer price;
@Schema(description = "商品销量", requiredMode = REQUIRED, example = "60")
@Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "60")
private Integer salesCount;
@Schema(description = "库存", requiredMode = REQUIRED, example = "80")
@Schema(description = "库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "80")
private Integer stock;
}

View File

@@ -124,7 +124,7 @@ public class PointActivityController {
List<PointProductDO> products = pointActivityService.getPointProductListByActivityIds(
convertSet(activityList, PointActivityDO::getId));
Map<Long, List<PointProductDO>> productsMap = convertMultiMap(products, PointProductDO::getActivityId);
Map<Long, ProductSpuRespDTO> spuMap = productSpuApi.getSpusMap(
Map<Long, ProductSpuRespDTO> spuMap = productSpuApi.getSpuMap(
convertSet(activityList, PointActivityDO::getSpuId));
List<PointActivityRespVO> result = BeanUtils.toBean(activityList, PointActivityRespVO.class);
result.forEach(activity -> {

View File

@@ -104,7 +104,7 @@ public class AppPointActivityController {
List<PointProductDO> products = pointActivityService.getPointProductListByActivityIds(
convertSet(activityList, PointActivityDO::getId));
Map<Long, List<PointProductDO>> productsMap = convertMultiMap(products, PointProductDO::getActivityId);
Map<Long, ProductSpuRespDTO> spuMap = productSpuApi.getSpusMap(
Map<Long, ProductSpuRespDTO> spuMap = productSpuApi.getSpuMap(
convertSet(activityList, PointActivityDO::getSpuId));
List<AppPointActivityRespVO> result = BeanUtils.toBean(activityList, AppPointActivityRespVO.class);
result.forEach(activity -> {

View File

@@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -180,7 +181,7 @@ public class CouponServiceImpl implements CouponService {
* @param couponId 模版编号
* @param userId 用户编号
*/
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) // 每次调用开启一个新的事务,避免在一个大的事务里面
public void invalidateCoupon(Long couponId, Long userId) {
if (couponId == null || couponId <= 0) {
return;
@@ -270,13 +271,17 @@ public class CouponServiceImpl implements CouponService {
if (CollUtil.isEmpty(userIds)) {
throw exception(COUPON_TEMPLATE_USER_ALREADY_TAKE);
}
// 校验模板
if (couponTemplate == null) {
throw exception(COUPON_TEMPLATE_NOT_EXISTS);
}
// 校验剩余数量
if (ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
// 校验领取方式
if (ObjUtil.notEqual(couponTemplate.getTakeType(), takeType.getType())) {
throw exception(COUPON_TEMPLATE_CANNOT_TAKE);
}
// 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时)
if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType())
&& ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
&& couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
throw exception(COUPON_TEMPLATE_NOT_ENOUGH);
}
@@ -286,10 +291,6 @@ public class CouponServiceImpl implements CouponService {
throw exception(COUPON_TEMPLATE_EXPIRED);
}
}
// 校验领取方式
if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getType())) {
throw exception(COUPON_TEMPLATE_CANNOT_TAKE);
}
}
/**

View File

@@ -1,12 +1,13 @@
package cn.iocoder.yudao.module.trade.controller.app.aftersale;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleRespVO;
import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -32,16 +33,17 @@ public class AppAfterSaleController {
@GetMapping(value = "/page")
@Operation(summary = "获得售后分页")
public CommonResult<PageResult<AppAfterSaleRespVO>> getAfterSalePage(PageParam pageParam) {
return success(AfterSaleConvert.INSTANCE.convertPage02(
afterSaleService.getAfterSalePage(getLoginUserId(), pageParam)));
public CommonResult<PageResult<AppAfterSaleRespVO>> getAfterSalePage(AppAfterSalePageReqVO pageReqVO) {
PageResult<AfterSaleDO> pageResult = afterSaleService.getAfterSalePage(getLoginUserId(), pageReqVO);
return success(BeanUtils.toBean(pageResult, AppAfterSaleRespVO.class));
}
@GetMapping(value = "/get")
@Operation(summary = "获得售后订单")
@Parameter(name = "id", description = "售后编号", required = true, example = "1")
public CommonResult<AppAfterSaleRespVO> getAfterSale(@RequestParam("id") Long id) {
return success(AfterSaleConvert.INSTANCE.convert(afterSaleService.getAfterSale(getLoginUserId(), id)));
AfterSaleDO afterSale = afterSaleService.getAfterSale(getLoginUserId(), id);
return success(BeanUtils.toBean(afterSale, AppAfterSaleRespVO.class));
}
@PostMapping(value = "/create")

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Set;
@Schema(description = "用户 App - 交易售后分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppAfterSalePageReqVO extends PageParam {
@Schema(description = "售后状态", example = "10, 20")
private Set<Integer> statuses;
}

View File

@@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.trade.controller.app.base.spu;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* 商品 SPU 基础 Response VO
*
@@ -25,4 +23,10 @@ public class AppProductSpuBaseRespVO {
@Schema(description = "商品分类编号", example = "1")
private Long categoryId;
@Schema(description = "商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
private Integer stock;
@Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
}

View File

@@ -1,8 +1,12 @@
package cn.iocoder.yudao.module.trade.controller.app.delivery.vo.pickup;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalTime;
@Schema(description = "用户 App - 自提门店 Response VO")
@Data
public class AppDeliveryPickUpStoreRespVO {
@@ -28,6 +32,16 @@ public class AppDeliveryPickUpStoreRespVO {
@Schema(description = "门店详细地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "复旦大学路 188 号")
private String detailAddress;
@Schema(description = "营业开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "营业开始时间不能为空")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm")
private LocalTime openingTime;
@Schema(description = "营业结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "营业结束时间不能为空")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm")
private LocalTime closingTime;
@Schema(description = "纬度", requiredMode = Schema.RequiredMode.REQUIRED, example = "5.88")
private Double latitude;

View File

@@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUse
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderBaseVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleRespVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -63,10 +62,6 @@ public interface AfterSaleConvert {
ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
AppAfterSaleRespVO convert(AfterSaleDO bean);
PageResult<AppAfterSaleRespVO> convertPage02(PageResult<AfterSaleDO> page);
default AfterSaleDetailRespVO convert(AfterSaleDO afterSale, TradeOrderDO order, TradeOrderItemDO orderItem,
MemberUserRespDTO user, List<AfterSaleLogDO> logs) {
AfterSaleDetailRespVO respVO = convert02(afterSale);

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.trade.convert.cart;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
@@ -33,21 +34,18 @@ public interface TradeCartConvert {
cartVO.setId(cart.getId()).setCount(cart.getCount()).setSelected(cart.getSelected());
ProductSpuRespDTO spu = spuMap.get(cart.getSpuId());
ProductSkuRespDTO sku = skuMap.get(cart.getSkuId());
cartVO.setSpu(convert(spu)).setSku(convert(sku));
cartVO.setSpu(BeanUtils.toBean(spu, AppProductSpuBaseRespVO.class))
.setSku(BeanUtils.toBean(sku, AppProductSkuBaseRespVO.class));
// 如果 SPU 不存在,或者下架,或者库存不足,说明是无效的
if (spu == null
|| !ProductSpuStatusEnum.isEnable(spu.getStatus())
|| spu.getStock() <= 0) {
cartVO.setSelected(false); // 强制设置成不可选中
invalidList.add(cartVO);
} else {
// 虽然 SKU 可能也会不存在,但是可以通过购物车重新选择
validList.add(cartVO);
}
});
return new AppCartListRespVO().setValidList(validList).setInvalidList(invalidList);
}
AppProductSpuBaseRespVO convert(ProductSpuRespDTO spu);
AppProductSkuBaseRespVO convert(ProductSkuRespDTO sku);
}

View File

@@ -1,10 +1,10 @@
package cn.iocoder.yudao.module.trade.dal.mysql.aftersale;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
@@ -27,9 +27,10 @@ public interface AfterSaleMapper extends BaseMapperX<AfterSaleDO> {
.orderByDesc(AfterSaleDO::getId));
}
default PageResult<AfterSaleDO> selectPage(Long userId, PageParam pageParam) {
return selectPage(pageParam, new LambdaQueryWrapperX<AfterSaleDO>()
.eqIfPresent(AfterSaleDO::getUserId, userId)
default PageResult<AfterSaleDO> selectPage(Long userId, AppAfterSalePageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<AfterSaleDO>()
.eq(AfterSaleDO::getUserId, userId)
.inIfPresent(AfterSaleDO::getStatus, pageReqVO.getStatuses())
.orderByDesc(AfterSaleDO::getId));
}

View File

@@ -1,12 +1,12 @@
package cn.iocoder.yudao.module.trade.service.aftersale;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
/**
@@ -28,10 +28,10 @@ public interface AfterSaleService {
* 【会员】获得售后订单分页
*
* @param userId 用户编号
* @param pageParam 分页参数
* @param pageReqVO 分页参数
* @return 售后订单分页
*/
PageResult<AfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam);
PageResult<AfterSaleDO> getAfterSalePage(Long userId, AppAfterSalePageReqVO pageReqVO);
/**
* 【会员】获得售后单

View File

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.aftersale;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
@@ -16,6 +15,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePage
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
@@ -36,6 +36,7 @@ import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -44,7 +45,6 @@ import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -87,8 +87,8 @@ public class AfterSaleServiceImpl implements AfterSaleService {
}
@Override
public PageResult<AfterSaleDO> getAfterSalePage(Long userId, PageParam pageParam) {
return tradeAfterSaleMapper.selectPage(userId, pageParam);
public PageResult<AfterSaleDO> getAfterSalePage(Long userId, AppAfterSalePageReqVO pageReqVO) {
return tradeAfterSaleMapper.selectPage(userId, pageReqVO);
}
@Override
@@ -386,7 +386,7 @@ public class AfterSaleServiceImpl implements AfterSaleService {
public void afterCommit() {
// 创建退款单
PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties)
.setReason(StrUtil.format("退款【{}】", afterSale.getSpuName()));;
.setReason(StrUtil.format("退款【{}】", afterSale.getSpuName()));
Long payRefundId = payRefundApi.createRefund(createReqDTO);
// 更新售后单的退款单号
tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId));

View File

@@ -135,7 +135,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
private Long createPayTransfer(BrokerageWithdrawDO withdraw) {
// 1.1 获取微信 openid
SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(
UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType());
UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType());
// TODO @luchi这里需要校验非空。如果空的话要有业务异常哈
// 1.2 构建请求
PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO()

View File

@@ -545,6 +545,14 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) {
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
}
// 1.3 校验是否支持延迟(不允许取消)
if (TradeOrderStatusEnum.isUnpaid(order.getStatus())) {
PayOrderRespDTO payOrder = payOrderApi.getOrder(order.getPayOrderId());
if (payOrder != null && PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
log.warn("[cancelOrderByMember][order({}) 支付单已支付(支付回调延迟),不支持取消]", order.getId());
throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
}
}
// 2. 取消订单
cancelOrder0(order, TradeOrderCancelTypeEnum.MEMBER_CANCEL);
@@ -581,6 +589,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Transactional(rollbackFor = Exception.class)
@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_CANCEL)
public void cancelOrderBySystem(TradeOrderDO order) {
// 校验是否支持延迟(不允许取消)
if (TradeOrderStatusEnum.isUnpaid(order.getStatus())) {
PayOrderRespDTO payOrder = payOrderApi.getOrder(order.getPayOrderId());
if (payOrder != null && PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
log.warn("[cancelOrderBySystem][order({}) 支付单已支付(支付回调延迟),不支持取消]", order.getId());
return;
}
}
cancelOrder0(order, TradeOrderCancelTypeEnum.PAY_TIMEOUT);
}
@@ -895,12 +912,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
if (order == null) {
throw exception(ORDER_NOT_FOUND);
}
// 1.3 校验订单是否支付
if (!order.getPayStatus()) {
throw exception(ORDER_CANCEL_PAID_FAIL, "已支付");
}
// 1.3 校验订单是否未退款
// 1.4 校验订单是否未退款
if (ObjUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
throw exception(ORDER_CANCEL_PAID_FAIL, "未退款");
}

View File

@@ -20,6 +20,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -101,13 +102,17 @@ public class TradeBrokerageOrderHandler implements TradeOrderHandler {
protected void addBrokerage(Long userId, List<TradeOrderItemDO> orderItems) {
MemberUserRespDTO user = memberUserApi.getUser(userId);
Assert.notNull(user);
ProductSpuRespDTO spu = productSpuApi.getSpu(orderItems.get(0).getSpuId());
Assert.notNull(spu);
ProductSkuRespDTO sku = productSkuApi.getSku(orderItems.get(0).getSkuId());
Map<Long, ProductSpuRespDTO> spusMap = productSpuApi.getSpuMap(convertList(orderItems, TradeOrderItemDO::getSpuId));
Map<Long, ProductSkuRespDTO> skusMap = productSkuApi.getSkuMap(convertList(orderItems, TradeOrderItemDO::getSkuId));
// 每一个订单项,都会去生成分销记录
List<BrokerageAddReqBO> addList = convertList(orderItems,
item -> TradeOrderConvert.INSTANCE.convert(user, item, spu, sku));
List<BrokerageAddReqBO> addList = convertList(orderItems, item -> {
ProductSpuRespDTO spu = spusMap.get(item.getSpuId());
Assert.notNull(spu);
ProductSkuRespDTO sku = skusMap.get(item.getSkuId());
Assert.notNull(sku);
return TradeOrderConvert.INSTANCE.convert(user, item, spu, sku);
});
brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList);
}