first commit
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
# 交易中心模块 (ruoyi-mall-trade)
|
||||
|
||||
## 模块简介
|
||||
|
||||
`ruoyi-mall-trade` 是商城系统的交易中心模块,负责交易流程的核心功能,包括购物车、订单、售后等。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 购物车管理
|
||||
|
||||
- ✅ 添加/删除购物车
|
||||
- ✅ 购物车数量修改
|
||||
- ✅ 购物车选中状态管理
|
||||
- ✅ 购物车详情查询
|
||||
|
||||
### 2. 订单管理
|
||||
|
||||
- ✅ 订单创建
|
||||
- ✅ 订单查询(列表、详情)
|
||||
- ✅ 订单取消
|
||||
- ✅ 订单状态管理
|
||||
- ✅ 订单支付集成
|
||||
|
||||
### 3. 售后管理 ✅
|
||||
|
||||
- ✅ 订单退款申请
|
||||
- ✅ 退货申请
|
||||
- ✅ 换货申请
|
||||
- ✅ 售后审核(同意/拒绝)
|
||||
- ✅ 售后状态跟踪
|
||||
- ✅ 退货物流信息填写
|
||||
- ✅ 商家确认收货
|
||||
- ✅ 完成售后处理
|
||||
- ✅ 取消售后申请
|
||||
|
||||
### 4. 订单评价 ✅
|
||||
|
||||
- ✅ 订单评价提交
|
||||
- ✅ 评价列表查询(支持按订单、商品查询)
|
||||
- ✅ 评价审核(通过/驳回)
|
||||
- ✅ 评价回复(商家回复)
|
||||
- ✅ 评价导出功能
|
||||
|
||||
### 5. 地址管理 ✅
|
||||
|
||||
- ✅ 收货地址CRUD操作
|
||||
- ✅ 用户地址列表查询
|
||||
- ✅ 默认地址查询
|
||||
- ✅ 设置默认地址
|
||||
- ✅ 地址导出功能(管理端)
|
||||
|
||||
## 数据库表
|
||||
|
||||
- `mall_cart` - 购物车表
|
||||
- `mall_order` - 订单表
|
||||
- `mall_order_item` - 订单明细表
|
||||
- `mall_after_sale` - 售后申请表
|
||||
- `mall_order_evaluate` - 订单评价表
|
||||
- `mall_order_coupon` - 订单优惠券使用记录表
|
||||
- `mall_address` - 收货地址表
|
||||
|
||||
详细表结构请参考:`script/sql/ry_mall.sql`
|
||||
|
||||
## 模块结构
|
||||
|
||||
```
|
||||
org.dromara.mall.trade
|
||||
├── controller
|
||||
│ ├── admin // 管理端API
|
||||
│ └── app // 用户端API
|
||||
├── domain
|
||||
│ ├── bo // 业务对象
|
||||
│ └── vo // 视图对象
|
||||
├── mapper // MyBatis Mapper
|
||||
├── service // 业务逻辑层
|
||||
│ └── impl
|
||||
├── enums // 枚举类
|
||||
└── config // 配置类
|
||||
```
|
||||
|
||||
## 依赖模块
|
||||
|
||||
- `ruoyi-mall-product` - 商品中心模块
|
||||
- `ruoyi-pay` - 支付中心模块
|
||||
- `ruoyi-common-*` - 通用工具模块
|
||||
|
||||
## 业务流程
|
||||
|
||||
### 订单提交流程
|
||||
|
||||
1. 用户选择商品(从购物车或直接购买)
|
||||
2. 调用订单提交接口
|
||||
3. 系统创建订单和订单明细
|
||||
4. 调用支付中心创建支付单
|
||||
5. 返回支付参数给前端
|
||||
6. 前端调起支付
|
||||
7. 支付成功后,支付中心回调
|
||||
8. 系统更新订单状态并扣减库存
|
||||
|
||||
## 模块结构
|
||||
|
||||
```
|
||||
org.dromara.mall.trade
|
||||
├── controller
|
||||
│ ├── admin // 管理端API
|
||||
│ │ ├── AdminMallAfterSaleController.java
|
||||
│ │ ├── AdminMallOrderEvaluateController.java
|
||||
│ │ └── AdminMallAddressController.java
|
||||
│ └── app // 用户端API
|
||||
│ ├── AppMallAfterSaleController.java
|
||||
│ ├── AppMallOrderEvaluateController.java
|
||||
│ └── AppMallAddressController.java
|
||||
├── domain
|
||||
│ ├── MallAfterSale.java
|
||||
│ ├── MallOrderEvaluate.java
|
||||
│ ├── MallOrderCoupon.java
|
||||
│ ├── MallAddress.java
|
||||
│ ├── bo // 业务对象
|
||||
│ │ ├── MallAfterSaleBo.java
|
||||
│ │ ├── MallOrderEvaluateBo.java
|
||||
│ │ ├── MallOrderCouponBo.java
|
||||
│ │ └── MallAddressBo.java
|
||||
│ └── vo // 视图对象
|
||||
│ ├── MallAfterSaleVo.java
|
||||
│ ├── MallOrderEvaluateVo.java
|
||||
│ ├── MallOrderCouponVo.java
|
||||
│ └── MallAddressVo.java
|
||||
├── mapper
|
||||
│ ├── MallAfterSaleMapper.java
|
||||
│ ├── MallOrderEvaluateMapper.java
|
||||
│ ├── MallOrderCouponMapper.java
|
||||
│ └── MallAddressMapper.java
|
||||
├── service
|
||||
│ ├── MallAfterSaleService.java
|
||||
│ ├── MallOrderEvaluateService.java
|
||||
│ ├── MallOrderCouponService.java
|
||||
│ ├── MallAddressService.java
|
||||
│ ├── SeckillOrderService.java
|
||||
│ └── impl
|
||||
│ ├── MallAfterSaleServiceImpl.java
|
||||
│ ├── MallOrderEvaluateServiceImpl.java
|
||||
│ ├── MallOrderCouponServiceImpl.java
|
||||
│ ├── MallAddressServiceImpl.java
|
||||
│ └── SeckillOrderServiceImpl.java
|
||||
├── utils
|
||||
│ └── CouponCalculator.java
|
||||
└── config
|
||||
└── MallTradeAutoConfiguration.java
|
||||
```
|
||||
|
||||
## API接口
|
||||
|
||||
### 管理端接口
|
||||
|
||||
#### 售后申请管理 (`/mall/order/after-sale`)
|
||||
|
||||
- `GET /mall/order/after-sale/list` - 查询售后申请列表(分页)
|
||||
- `GET /mall/order/after-sale/{id}` - 获取售后申请详情
|
||||
- `DELETE /mall/order/after-sale/{ids}` - 删除售后申请
|
||||
- `POST /mall/order/after-sale/export` - 导出售后申请列表
|
||||
- `PUT /mall/order/after-sale/audit/{id}` - 审核售后申请(同意/拒绝)
|
||||
- `PUT /mall/order/after-sale/receive/{id}` - 确认收货(商家确认收到退货)
|
||||
- `PUT /mall/order/after-sale/complete/{id}` - 完成售后
|
||||
|
||||
#### 订单评价管理 (`/mall/order/evaluate`)
|
||||
|
||||
- `GET /mall/order/evaluate/list` - 查询订单评价列表(分页)
|
||||
- `GET /mall/order/evaluate/{id}` - 获取订单评价详情
|
||||
- `DELETE /mall/order/evaluate/{ids}` - 删除订单评价
|
||||
- `POST /mall/order/evaluate/export` - 导出订单评价列表
|
||||
- `PUT /mall/order/evaluate/audit/{id}` - 审核评价(通过/驳回)
|
||||
- `PUT /mall/order/evaluate/reply/{id}` - 回复评价
|
||||
|
||||
### 移动端接口
|
||||
|
||||
#### 售后申请 (`/app/mall/order/after-sale`)
|
||||
|
||||
- `GET /app/mall/order/after-sale/list` - 查询售后申请列表
|
||||
- `GET /app/mall/order/after-sale/order/{orderId}` - 根据订单ID查询售后申请列表
|
||||
- `GET /app/mall/order/after-sale/{id}` - 获取售后申请详情
|
||||
- `POST /app/mall/order/after-sale` - 新增售后申请(退款/退货/换货)
|
||||
- `PUT /app/mall/order/after-sale/logistics/{id}` - 填写退货物流信息
|
||||
- `PUT /app/mall/order/after-sale/cancel/{id}` - 取消售后申请
|
||||
|
||||
#### 订单评价 (`/app/mall/order/evaluate`)
|
||||
|
||||
- `GET /app/mall/order/evaluate/list` - 查询订单评价列表
|
||||
- `GET /app/mall/order/evaluate/order/{orderId}` - 根据订单ID查询评价列表
|
||||
- `GET /app/mall/order/evaluate/product/{productId}` - 根据商品ID查询评价列表(仅已审核)
|
||||
- `GET /app/mall/order/evaluate/{id}` - 获取订单评价详情
|
||||
- `POST /app/mall/order/evaluate` - 提交订单评价
|
||||
|
||||
#### 收货地址 (`/app/mall/address`)
|
||||
|
||||
- `GET /app/mall/address/list` - 查询收货地址列表
|
||||
- `GET /app/mall/address/default` - 获取默认收货地址
|
||||
- `GET /app/mall/address/{id}` - 获取收货地址详情
|
||||
- `POST /app/mall/address` - 新增收货地址
|
||||
- `PUT /app/mall/address` - 修改收货地址
|
||||
- `DELETE /app/mall/address/{ids}` - 删除收货地址
|
||||
- `PUT /app/mall/address/default/{id}` - 设置默认地址
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-mall</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-mall-trade</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-mall-trade 交易中心模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-doc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-log</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-idempotent</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-satoken</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 商品中心模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-mall-product</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 支付模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-pay</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 营销中心模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-mall-promotion</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 优惠券中心模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-mall-coupon</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package org.dromara.mall.trade.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 交易中心自动配置类
|
||||
* 主要用于扫描交易中心模块的组件
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "org.dromara.mall.trade")
|
||||
@ConditionalOnProperty(prefix = "ruoyi.mall.trade", name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class MallTradeAutoConfiguration {
|
||||
|
||||
public MallTradeAutoConfiguration() {
|
||||
log.info("交易中心模块已启用");
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package org.dromara.mall.trade.controller.admin;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.trade.domain.bo.MallAddressBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAddressVo;
|
||||
import org.dromara.mall.trade.service.MallAddressService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收货地址管理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "管理端-收货地址管理", description = "收货地址管理接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/mall/address")
|
||||
public class AdminMallAddressController extends BaseController {
|
||||
|
||||
private final MallAddressService mallAddressService;
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
@Operation(summary = "查询收货地址列表", description = "分页查询收货地址列表")
|
||||
@SaCheckPermission("mall:address:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallAddressVo> list(@Parameter(description = "收货地址查询条件") MallAddressBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallAddressService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出收货地址列表
|
||||
*/
|
||||
@Operation(summary = "导出收货地址列表", description = "导出收货地址到Excel")
|
||||
@SaCheckPermission("mall:address:export")
|
||||
@Log(title = "收货地址", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "收货地址查询条件") MallAddressBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallAddressVo> list = mallAddressService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "收货地址", MallAddressVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址详细信息
|
||||
*/
|
||||
@Operation(summary = "获取收货地址详情", description = "根据地址ID获取详细信息")
|
||||
@SaCheckPermission("mall:address:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallAddressVo> getInfo(@Parameter(description = "地址ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallAddressService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增收货地址
|
||||
*/
|
||||
@Operation(summary = "新增收货地址", description = "创建新的收货地址")
|
||||
@SaCheckPermission("mall:address:add")
|
||||
@Log(title = "收货地址", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "收货地址信息") @Validated @RequestBody MallAddressBo bo) {
|
||||
return toAjax(mallAddressService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改收货地址
|
||||
*/
|
||||
@Operation(summary = "修改收货地址", description = "更新收货地址信息")
|
||||
@SaCheckPermission("mall:address:edit")
|
||||
@Log(title = "收货地址", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "收货地址信息") @Validated @RequestBody MallAddressBo bo) {
|
||||
return toAjax(mallAddressService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
*/
|
||||
@Operation(summary = "删除收货地址", description = "删除收货地址")
|
||||
@SaCheckPermission("mall:address:remove")
|
||||
@Log(title = "收货地址", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "地址ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallAddressService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package org.dromara.mall.trade.controller.admin;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.trade.domain.bo.MallAfterSaleBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAfterSaleVo;
|
||||
import org.dromara.mall.trade.service.MallAfterSaleService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后申请管理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "管理端-售后申请管理", description = "售后申请管理接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/mall/order/after-sale")
|
||||
public class AdminMallAfterSaleController extends BaseController {
|
||||
|
||||
private final MallAfterSaleService mallAfterSaleService;
|
||||
|
||||
/**
|
||||
* 查询售后申请列表
|
||||
*/
|
||||
@Operation(summary = "查询售后申请列表", description = "分页查询售后申请列表")
|
||||
@SaCheckPermission("mall:order:after-sale:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallAfterSaleVo> list(@Parameter(description = "售后申请查询条件") MallAfterSaleBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallAfterSaleService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出售后申请列表
|
||||
*/
|
||||
@Operation(summary = "导出售后申请列表", description = "导出售后申请到Excel")
|
||||
@SaCheckPermission("mall:order:after-sale:export")
|
||||
@Log(title = "售后申请", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "售后申请查询条件") MallAfterSaleBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallAfterSaleVo> list = mallAfterSaleService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "售后申请", MallAfterSaleVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取售后申请详细信息
|
||||
*/
|
||||
@Operation(summary = "获取售后申请详情", description = "根据售后申请ID获取详细信息")
|
||||
@SaCheckPermission("mall:order:after-sale:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallAfterSaleVo> getInfo(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallAfterSaleService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除售后申请
|
||||
*/
|
||||
@Operation(summary = "删除售后申请", description = "删除售后申请")
|
||||
@SaCheckPermission("mall:order:after-sale:remove")
|
||||
@Log(title = "售后申请", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "售后申请ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallAfterSaleService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核售后申请(同意/拒绝)
|
||||
*/
|
||||
@Operation(summary = "审核售后申请", description = "审核售后申请,1-同意,2-拒绝")
|
||||
@SaCheckPermission("mall:order:after-sale:audit")
|
||||
@Log(title = "售后申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/audit/{id}")
|
||||
public R<Void> audit(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "审核状态", required = true)
|
||||
@NotNull(message = "审核状态不能为空")
|
||||
@RequestParam Integer status,
|
||||
@Parameter(description = "拒绝原因")
|
||||
@RequestParam(required = false) String refuseReason) {
|
||||
return toAjax(mallAfterSaleService.audit(id, status, refuseReason));
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认收货(商家确认收到退货)
|
||||
*/
|
||||
@Operation(summary = "确认收货", description = "商家确认收到退货商品")
|
||||
@SaCheckPermission("mall:order:after-sale:receive")
|
||||
@Log(title = "售后申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/receive/{id}")
|
||||
public R<Void> confirmReceive(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return toAjax(mallAfterSaleService.confirmReceive(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成售后(退款完成或换货完成)
|
||||
*/
|
||||
@Operation(summary = "完成售后", description = "完成售后申请(退款完成或换货完成)")
|
||||
@SaCheckPermission("mall:order:after-sale:complete")
|
||||
@Log(title = "售后申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/complete/{id}")
|
||||
public R<Void> complete(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return toAjax(mallAfterSaleService.complete(id));
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package org.dromara.mall.trade.controller.admin;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderEvaluateBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderEvaluateVo;
|
||||
import org.dromara.mall.trade.service.MallOrderEvaluateService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单评价管理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "管理端-订单评价管理", description = "订单评价管理接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/mall/order/evaluate")
|
||||
public class AdminMallOrderEvaluateController extends BaseController {
|
||||
|
||||
private final MallOrderEvaluateService mallOrderEvaluateService;
|
||||
|
||||
/**
|
||||
* 查询订单评价列表
|
||||
*/
|
||||
@Operation(summary = "查询订单评价列表", description = "分页查询订单评价列表")
|
||||
@SaCheckPermission("mall:order:evaluate:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallOrderEvaluateVo> list(@Parameter(description = "评价查询条件") MallOrderEvaluateBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallOrderEvaluateService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出订单评价列表
|
||||
*/
|
||||
@Operation(summary = "导出订单评价列表", description = "导出订单评价到Excel")
|
||||
@SaCheckPermission("mall:order:evaluate:export")
|
||||
@Log(title = "订单评价", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "评价查询条件") MallOrderEvaluateBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallOrderEvaluateVo> list = mallOrderEvaluateService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "订单评价", MallOrderEvaluateVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单评价详细信息
|
||||
*/
|
||||
@Operation(summary = "获取订单评价详情", description = "根据评价ID获取详细信息")
|
||||
@SaCheckPermission("mall:order:evaluate:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallOrderEvaluateVo> getInfo(@Parameter(description = "评价ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallOrderEvaluateService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单评价
|
||||
*/
|
||||
@Operation(summary = "删除订单评价", description = "删除订单评价")
|
||||
@SaCheckPermission("mall:order:evaluate:remove")
|
||||
@Log(title = "订单评价", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "评价ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallOrderEvaluateService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核评价(通过/驳回)
|
||||
*/
|
||||
@Operation(summary = "审核评价", description = "审核评价,1-通过,2-驳回")
|
||||
@SaCheckPermission("mall:order:evaluate:audit")
|
||||
@Log(title = "订单评价", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/audit/{id}")
|
||||
public R<Void> audit(@Parameter(description = "评价ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "审核状态", required = true)
|
||||
@NotNull(message = "审核状态不能为空")
|
||||
@RequestParam Integer status) {
|
||||
return toAjax(mallOrderEvaluateService.audit(id, status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 回复评价
|
||||
*/
|
||||
@Operation(summary = "回复评价", description = "商家回复评价")
|
||||
@SaCheckPermission("mall:order:evaluate:reply")
|
||||
@Log(title = "订单评价", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/reply/{id}")
|
||||
public R<Void> reply(@Parameter(description = "评价ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "回复内容", required = true)
|
||||
@NotNull(message = "回复内容不能为空")
|
||||
@RequestParam String replyContent) {
|
||||
return toAjax(mallOrderEvaluateService.reply(id, replyContent));
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package org.dromara.mall.trade.controller.app;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.trade.domain.bo.MallAddressBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAddressVo;
|
||||
import org.dromara.mall.trade.service.MallAddressService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收货地址(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-收货地址", description = "收货地址接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/address")
|
||||
public class AppMallAddressController extends BaseController {
|
||||
|
||||
private final MallAddressService mallAddressService;
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
@Operation(summary = "查询收货地址列表", description = "查询用户的收货地址列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<MallAddressVo>> list() {
|
||||
Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
|
||||
List<MallAddressVo> list = mallAddressService.queryListByUserId(userId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认收货地址
|
||||
*/
|
||||
@Operation(summary = "获取默认收货地址", description = "查询用户的默认收货地址")
|
||||
@GetMapping("/default")
|
||||
public R<MallAddressVo> getDefault() {
|
||||
Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
|
||||
MallAddressVo address = mallAddressService.queryDefaultByUserId(userId);
|
||||
return R.ok(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收货地址详细信息
|
||||
*/
|
||||
@Operation(summary = "获取收货地址详情", description = "根据地址ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallAddressVo> getInfo(@Parameter(description = "地址ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallAddressService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增收货地址
|
||||
*/
|
||||
@Operation(summary = "新增收货地址", description = "创建新的收货地址")
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "收货地址信息") @Validated @RequestBody MallAddressBo bo) {
|
||||
return toAjax(mallAddressService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改收货地址
|
||||
*/
|
||||
@Operation(summary = "修改收货地址", description = "更新收货地址信息")
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "收货地址信息") @Validated @RequestBody MallAddressBo bo) {
|
||||
return toAjax(mallAddressService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
*/
|
||||
@Operation(summary = "删除收货地址", description = "删除收货地址")
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "地址ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallAddressService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认地址
|
||||
*/
|
||||
@Operation(summary = "设置默认地址", description = "将指定地址设置为默认收货地址")
|
||||
@PutMapping("/default/{id}")
|
||||
public R<Void> setDefault(@Parameter(description = "地址ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return toAjax(mallAddressService.setDefault(id));
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package org.dromara.mall.trade.controller.app;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.trade.domain.bo.MallAfterSaleBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAfterSaleVo;
|
||||
import org.dromara.mall.trade.service.MallAfterSaleService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后申请(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-售后申请", description = "售后申请接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/order/after-sale")
|
||||
public class AppMallAfterSaleController {
|
||||
|
||||
private final MallAfterSaleService mallAfterSaleService;
|
||||
|
||||
/**
|
||||
* 查询售后申请列表(移动端)
|
||||
*/
|
||||
@Operation(summary = "查询售后申请列表", description = "查询用户的售后申请列表")
|
||||
@GetMapping("/list")
|
||||
public R<TableDataInfo<MallAfterSaleVo>> list(@Parameter(description = "售后申请查询条件") MallAfterSaleBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
TableDataInfo<MallAfterSaleVo> result = mallAfterSaleService.queryPageList(bo, pageQuery);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID查询售后申请列表
|
||||
*/
|
||||
@Operation(summary = "查询订单售后申请列表", description = "根据订单ID查询售后申请列表")
|
||||
@GetMapping("/order/{orderId}")
|
||||
public R<List<MallAfterSaleVo>> listByOrderId(@Parameter(description = "订单ID", required = true)
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
@PathVariable Long orderId) {
|
||||
MallAfterSaleBo bo = new MallAfterSaleBo();
|
||||
bo.setOrderId(orderId);
|
||||
List<MallAfterSaleVo> list = mallAfterSaleService.queryList(bo);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取售后申请详细信息
|
||||
*/
|
||||
@Operation(summary = "获取售后申请详情", description = "根据售后申请ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallAfterSaleVo> getInfo(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallAfterSaleService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增售后申请
|
||||
*/
|
||||
@Operation(summary = "新增售后申请", description = "提交售后申请(退款/退货/换货)")
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "售后申请信息") @Validated @RequestBody MallAfterSaleBo bo) {
|
||||
return R.ok(mallAfterSaleService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户填写退货物流信息
|
||||
*/
|
||||
@Operation(summary = "填写退货物流信息", description = "用户填写退货物流信息(仅退货和换货类型)")
|
||||
@PutMapping("/logistics/{id}")
|
||||
public R<Void> fillLogistics(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "物流公司", required = true)
|
||||
@NotBlank(message = "物流公司不能为空")
|
||||
@RequestParam String logisticsCompany,
|
||||
@Parameter(description = "物流单号", required = true)
|
||||
@NotBlank(message = "物流单号不能为空")
|
||||
@RequestParam String logisticsNo) {
|
||||
return R.ok(mallAfterSaleService.fillLogistics(id, logisticsCompany, logisticsNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消售后申请
|
||||
*/
|
||||
@Operation(summary = "取消售后申请", description = "用户取消售后申请")
|
||||
@PutMapping("/cancel/{id}")
|
||||
public R<Void> cancel(@Parameter(description = "售后申请ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallAfterSaleService.cancel(id));
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package org.dromara.mall.trade.controller.app;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderEvaluateBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderEvaluateVo;
|
||||
import org.dromara.mall.trade.service.MallOrderEvaluateService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单评价(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-订单评价", description = "订单评价接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/order/evaluate")
|
||||
public class AppMallOrderEvaluateController {
|
||||
|
||||
private final MallOrderEvaluateService mallOrderEvaluateService;
|
||||
|
||||
/**
|
||||
* 查询订单评价列表(移动端)
|
||||
*/
|
||||
@Operation(summary = "查询订单评价列表", description = "查询订单评价列表")
|
||||
@GetMapping("/list")
|
||||
public R<TableDataInfo<MallOrderEvaluateVo>> list(@Parameter(description = "评价查询条件") MallOrderEvaluateBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
TableDataInfo<MallOrderEvaluateVo> result = mallOrderEvaluateService.queryPageList(bo, pageQuery);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID查询评价列表
|
||||
*/
|
||||
@Operation(summary = "查询订单评价列表", description = "根据订单ID查询评价列表")
|
||||
@GetMapping("/order/{orderId}")
|
||||
public R<List<MallOrderEvaluateVo>> listByOrderId(@Parameter(description = "订单ID", required = true)
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
@PathVariable Long orderId) {
|
||||
MallOrderEvaluateBo bo = new MallOrderEvaluateBo();
|
||||
bo.setOrderId(orderId);
|
||||
List<MallOrderEvaluateVo> list = mallOrderEvaluateService.queryList(bo);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商品ID查询评价列表
|
||||
*/
|
||||
@Operation(summary = "查询商品评价列表", description = "根据商品ID查询评价列表(仅已通过审核的)")
|
||||
@GetMapping("/product/{productId}")
|
||||
public R<TableDataInfo<MallOrderEvaluateVo>> listByProductId(@Parameter(description = "商品ID", required = true)
|
||||
@NotNull(message = "商品ID不能为空")
|
||||
@PathVariable Long productId,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
MallOrderEvaluateBo bo = new MallOrderEvaluateBo();
|
||||
bo.setProductId(productId);
|
||||
bo.setStatus(1); // 只查询已通过审核的评价
|
||||
TableDataInfo<MallOrderEvaluateVo> result = mallOrderEvaluateService.queryPageList(bo, pageQuery);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单评价详细信息
|
||||
*/
|
||||
@Operation(summary = "获取订单评价详情", description = "根据评价ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallOrderEvaluateVo> getInfo(@Parameter(description = "评价ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallOrderEvaluateService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单评价
|
||||
*/
|
||||
@Operation(summary = "新增订单评价", description = "提交订单评价")
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "评价信息") @Validated @RequestBody MallOrderEvaluateBo bo) {
|
||||
return R.ok(mallOrderEvaluateService.insertByBo(bo));
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package org.dromara.mall.trade.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 收货地址对象 mall_address
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_address")
|
||||
public class MallAddress implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 地址ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
private String receiverName;
|
||||
|
||||
/**
|
||||
* 收货人电话
|
||||
*/
|
||||
private String receiverPhone;
|
||||
|
||||
/**
|
||||
* 省份
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 是否默认地址(0否 1是)
|
||||
*/
|
||||
private Integer isDefault;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package org.dromara.mall.trade.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 售后申请对象 mall_after_sale
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_after_sale")
|
||||
public class MallAfterSale implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 售后ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 售后单号
|
||||
*/
|
||||
private String afterSaleNo;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 售后类型(0退款 1退货 2换货)
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 申请原因
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 凭证图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 退款金额(分)
|
||||
*/
|
||||
private Integer refundAmount;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已同意 2已拒绝 3待退货 4待收货 5已完成 6已取消)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 拒绝原因
|
||||
*/
|
||||
private String refuseReason;
|
||||
|
||||
/**
|
||||
* 退款单号
|
||||
*/
|
||||
private String refundOrderNo;
|
||||
|
||||
/**
|
||||
* 物流公司
|
||||
*/
|
||||
private String logisticsCompany;
|
||||
|
||||
/**
|
||||
* 物流单号
|
||||
*/
|
||||
private String logisticsNo;
|
||||
|
||||
/**
|
||||
* 申请时间
|
||||
*/
|
||||
private Date applyTime;
|
||||
|
||||
/**
|
||||
* 审核时间
|
||||
*/
|
||||
private Date auditTime;
|
||||
|
||||
/**
|
||||
* 退货时间
|
||||
*/
|
||||
private Date returnTime;
|
||||
|
||||
/**
|
||||
* 收货时间
|
||||
*/
|
||||
private Date receiveTime;
|
||||
|
||||
/**
|
||||
* 退款时间
|
||||
*/
|
||||
private Date refundTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package org.dromara.mall.trade.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录对象 mall_order_coupon
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_order_coupon")
|
||||
public class MallOrderCoupon implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 优惠券ID
|
||||
*/
|
||||
private Long couponId;
|
||||
|
||||
/**
|
||||
* 用户优惠券ID
|
||||
*/
|
||||
private Long couponUserId;
|
||||
|
||||
/**
|
||||
* 优惠金额(分)
|
||||
*/
|
||||
private Integer discountAmount;
|
||||
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
package org.dromara.mall.trade.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单评价对象 mall_order_evaluate
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_order_evaluate")
|
||||
public class MallOrderEvaluate implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 评价ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 评分(1-5)
|
||||
*/
|
||||
private Integer score;
|
||||
|
||||
/**
|
||||
* 评价内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 评价图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 回复内容
|
||||
*/
|
||||
private String replyContent;
|
||||
|
||||
/**
|
||||
* 回复时间
|
||||
*/
|
||||
private Date replyTime;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已通过 2已驳回)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package org.dromara.mall.trade.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.trade.domain.MallAddress;
|
||||
|
||||
/**
|
||||
* 收货地址业务对象 mall_address
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallAddress.class, reverseConvertGenerate = false)
|
||||
public class MallAddressBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 地址ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
@NotBlank(message = "收货人姓名不能为空")
|
||||
@Size(max = 64, message = "收货人姓名长度不能超过64个字符")
|
||||
private String receiverName;
|
||||
|
||||
/**
|
||||
* 收货人电话
|
||||
*/
|
||||
@NotBlank(message = "收货人电话不能为空")
|
||||
@Size(max = 32, message = "收货人电话长度不能超过32个字符")
|
||||
private String receiverPhone;
|
||||
|
||||
/**
|
||||
* 省份
|
||||
*/
|
||||
@Size(max = 64, message = "省份长度不能超过64个字符")
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市
|
||||
*/
|
||||
@Size(max = 64, message = "城市长度不能超过64个字符")
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
@Size(max = 64, message = "区/县长度不能超过64个字符")
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
@NotBlank(message = "详细地址不能为空")
|
||||
@Size(max = 512, message = "详细地址长度不能超过512个字符")
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 是否默认地址(0否 1是)
|
||||
*/
|
||||
private Integer isDefault;
|
||||
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package org.dromara.mall.trade.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.trade.domain.MallAfterSale;
|
||||
|
||||
/**
|
||||
* 售后申请业务对象 mall_after_sale
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallAfterSale.class, reverseConvertGenerate = false)
|
||||
public class MallAfterSaleBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 售后ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 售后单号
|
||||
*/
|
||||
private String afterSaleNo;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
@NotNull(message = "订单明细ID不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 售后类型(0退款 1退货 2换货)
|
||||
*/
|
||||
@NotNull(message = "售后类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 申请原因
|
||||
*/
|
||||
@NotBlank(message = "申请原因不能为空")
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 凭证图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 退款金额(分)
|
||||
*/
|
||||
private Integer refundAmount;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已同意 2已拒绝 3待退货 4待收货 5已完成 6已取消)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 拒绝原因
|
||||
*/
|
||||
private String refuseReason;
|
||||
|
||||
/**
|
||||
* 退款单号
|
||||
*/
|
||||
private String refundOrderNo;
|
||||
|
||||
/**
|
||||
* 物流公司
|
||||
*/
|
||||
private String logisticsCompany;
|
||||
|
||||
/**
|
||||
* 物流单号
|
||||
*/
|
||||
private String logisticsNo;
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.dromara.mall.trade.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.trade.domain.MallOrderCoupon;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录业务对象 mall_order_coupon
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallOrderCoupon.class, reverseConvertGenerate = false)
|
||||
public class MallOrderCouponBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 优惠券ID
|
||||
*/
|
||||
@NotNull(message = "优惠券ID不能为空")
|
||||
private Long couponId;
|
||||
|
||||
/**
|
||||
* 用户优惠券ID
|
||||
*/
|
||||
@NotNull(message = "用户优惠券ID不能为空")
|
||||
private Long couponUserId;
|
||||
|
||||
/**
|
||||
* 优惠金额(分)
|
||||
*/
|
||||
@NotNull(message = "优惠金额不能为空")
|
||||
@Min(value = 0, message = "优惠金额不能为负数")
|
||||
private Integer discountAmount;
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package org.dromara.mall.trade.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.trade.domain.MallOrderEvaluate;
|
||||
|
||||
/**
|
||||
* 订单评价业务对象 mall_order_evaluate
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallOrderEvaluate.class, reverseConvertGenerate = false)
|
||||
public class MallOrderEvaluateBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 评价ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
@NotNull(message = "订单明细ID不能为空")
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 评分(1-5)
|
||||
*/
|
||||
@NotNull(message = "评分不能为空")
|
||||
@Min(value = 1, message = "评分不能小于1")
|
||||
@Max(value = 5, message = "评分不能大于5")
|
||||
private Integer score;
|
||||
|
||||
/**
|
||||
* 评价内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 评价图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 回复内容
|
||||
*/
|
||||
private String replyContent;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已通过 2已驳回)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package org.dromara.mall.trade.domain.vo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.trade.domain.MallAddress;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 收货地址视图对象 mall_address
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = MallAddress.class)
|
||||
public class MallAddressVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 地址ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 收货人姓名
|
||||
*/
|
||||
private String receiverName;
|
||||
|
||||
/**
|
||||
* 收货人电话
|
||||
*/
|
||||
private String receiverPhone;
|
||||
|
||||
/**
|
||||
* 省份
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 区/县
|
||||
*/
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 是否默认地址(0否 1是)
|
||||
*/
|
||||
private Integer isDefault;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 完整地址(省份+城市+区/县+详细地址)
|
||||
*/
|
||||
public String getFullAddress() {
|
||||
StringBuilder fullAddress = new StringBuilder();
|
||||
if (province != null && !province.isEmpty()) {
|
||||
fullAddress.append(province);
|
||||
}
|
||||
if (city != null && !city.isEmpty()) {
|
||||
fullAddress.append(city);
|
||||
}
|
||||
if (district != null && !district.isEmpty()) {
|
||||
fullAddress.append(district);
|
||||
}
|
||||
if (address != null && !address.isEmpty()) {
|
||||
fullAddress.append(address);
|
||||
}
|
||||
return fullAddress.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package org.dromara.mall.trade.domain.vo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.trade.domain.MallAfterSale;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 售后申请视图对象 mall_after_sale
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = MallAfterSale.class)
|
||||
public class MallAfterSaleVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 售后ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 售后单号
|
||||
*/
|
||||
private String afterSaleNo;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 售后类型(0退款 1退货 2换货)
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 申请原因
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 凭证图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 退款金额(分)
|
||||
*/
|
||||
private Integer refundAmount;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已同意 2已拒绝 3待退货 4待收货 5已完成 6已取消)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 拒绝原因
|
||||
*/
|
||||
private String refuseReason;
|
||||
|
||||
/**
|
||||
* 退款单号
|
||||
*/
|
||||
private String refundOrderNo;
|
||||
|
||||
/**
|
||||
* 物流公司
|
||||
*/
|
||||
private String logisticsCompany;
|
||||
|
||||
/**
|
||||
* 物流单号
|
||||
*/
|
||||
private String logisticsNo;
|
||||
|
||||
/**
|
||||
* 申请时间
|
||||
*/
|
||||
private Date applyTime;
|
||||
|
||||
/**
|
||||
* 审核时间
|
||||
*/
|
||||
private Date auditTime;
|
||||
|
||||
/**
|
||||
* 退货时间
|
||||
*/
|
||||
private Date returnTime;
|
||||
|
||||
/**
|
||||
* 收货时间
|
||||
*/
|
||||
private Date receiveTime;
|
||||
|
||||
/**
|
||||
* 退款时间
|
||||
*/
|
||||
private Date refundTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package org.dromara.mall.trade.domain.vo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.trade.domain.MallOrderCoupon;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录视图对象 mall_order_coupon
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = MallOrderCoupon.class)
|
||||
public class MallOrderCouponVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 优惠券ID
|
||||
*/
|
||||
private Long couponId;
|
||||
|
||||
/**
|
||||
* 用户优惠券ID
|
||||
*/
|
||||
private Long couponUserId;
|
||||
|
||||
/**
|
||||
* 优惠金额(分)
|
||||
*/
|
||||
private Integer discountAmount;
|
||||
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package org.dromara.mall.trade.domain.vo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.trade.domain.MallOrderEvaluate;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单评价视图对象 mall_order_evaluate
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@AutoMapper(target = MallOrderEvaluate.class)
|
||||
public class MallOrderEvaluateVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 评价ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 订单号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单明细ID
|
||||
*/
|
||||
private Long orderItemId;
|
||||
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long productId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 评分(1-5)
|
||||
*/
|
||||
private Integer score;
|
||||
|
||||
/**
|
||||
* 评价内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 评价图片(JSON数组)
|
||||
*/
|
||||
private String images;
|
||||
|
||||
/**
|
||||
* 回复内容
|
||||
*/
|
||||
private String replyContent;
|
||||
|
||||
/**
|
||||
* 回复时间
|
||||
*/
|
||||
private Date replyTime;
|
||||
|
||||
/**
|
||||
* 状态(0待审核 1已通过 2已驳回)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.trade.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.trade.domain.MallAddress;
|
||||
import org.dromara.mall.trade.domain.vo.MallAddressVo;
|
||||
|
||||
/**
|
||||
* 收货地址Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallAddressMapper extends BaseMapperPlus<MallAddress, MallAddressVo> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.trade.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.trade.domain.MallAfterSale;
|
||||
import org.dromara.mall.trade.domain.vo.MallAfterSaleVo;
|
||||
|
||||
/**
|
||||
* 售后申请Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallAfterSaleMapper extends BaseMapperPlus<MallAfterSale, MallAfterSaleVo> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.trade.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.trade.domain.MallOrderCoupon;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderCouponVo;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallOrderCouponMapper extends BaseMapperPlus<MallOrderCoupon, MallOrderCouponVo> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.trade.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.trade.domain.MallOrderEvaluate;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderEvaluateVo;
|
||||
|
||||
/**
|
||||
* 订单评价Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallOrderEvaluateMapper extends BaseMapperPlus<MallOrderEvaluate, MallOrderEvaluateVo> {
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.dromara.mall.trade.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.trade.domain.bo.MallAddressBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAddressVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收货地址Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallAddressService {
|
||||
|
||||
/**
|
||||
* 查询收货地址
|
||||
*/
|
||||
MallAddressVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
TableDataInfo<MallAddressVo> queryPageList(MallAddressBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
List<MallAddressVo> queryList(MallAddressBo bo);
|
||||
|
||||
/**
|
||||
* 查询用户的收货地址列表
|
||||
*/
|
||||
List<MallAddressVo> queryListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 查询用户的默认地址
|
||||
*/
|
||||
MallAddressVo queryDefaultByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 新增收货地址
|
||||
*/
|
||||
Boolean insertByBo(MallAddressBo bo);
|
||||
|
||||
/**
|
||||
* 修改收货地址
|
||||
*/
|
||||
Boolean updateByBo(MallAddressBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除收货地址信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 设置默认地址
|
||||
*/
|
||||
Boolean setDefault(Long id);
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package org.dromara.mall.trade.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.trade.domain.bo.MallAfterSaleBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAfterSaleVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后申请Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallAfterSaleService {
|
||||
|
||||
/**
|
||||
* 查询售后申请
|
||||
*/
|
||||
MallAfterSaleVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 根据售后单号查询
|
||||
*/
|
||||
MallAfterSaleVo queryByAfterSaleNo(String afterSaleNo);
|
||||
|
||||
/**
|
||||
* 查询售后申请列表
|
||||
*/
|
||||
TableDataInfo<MallAfterSaleVo> queryPageList(MallAfterSaleBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询售后申请列表
|
||||
*/
|
||||
List<MallAfterSaleVo> queryList(MallAfterSaleBo bo);
|
||||
|
||||
/**
|
||||
* 新增售后申请
|
||||
*/
|
||||
Boolean insertByBo(MallAfterSaleBo bo);
|
||||
|
||||
/**
|
||||
* 修改售后申请
|
||||
*/
|
||||
Boolean updateByBo(MallAfterSaleBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除售后申请信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 审核售后申请(同意/拒绝)
|
||||
*/
|
||||
Boolean audit(Long id, Integer status, String refuseReason);
|
||||
|
||||
/**
|
||||
* 用户填写退货物流信息
|
||||
*/
|
||||
Boolean fillLogistics(Long id, String logisticsCompany, String logisticsNo);
|
||||
|
||||
/**
|
||||
* 确认收货(商家确认收到退货)
|
||||
*/
|
||||
Boolean confirmReceive(Long id);
|
||||
|
||||
/**
|
||||
* 完成售后(退款完成或换货完成)
|
||||
*/
|
||||
Boolean complete(Long id);
|
||||
|
||||
/**
|
||||
* 取消售后申请
|
||||
*/
|
||||
Boolean cancel(Long id);
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package org.dromara.mall.trade.service;
|
||||
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderCouponBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderCouponVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallOrderCouponService {
|
||||
|
||||
/**
|
||||
* 查询订单优惠券使用记录
|
||||
*/
|
||||
MallOrderCouponVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 根据订单ID查询订单优惠券使用记录列表
|
||||
*/
|
||||
List<MallOrderCouponVo> queryListByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单优惠券使用记录列表
|
||||
*/
|
||||
List<MallOrderCouponVo> queryListByOrderNo(String orderNo);
|
||||
|
||||
/**
|
||||
* 新增订单优惠券使用记录
|
||||
*/
|
||||
Boolean insertByBo(MallOrderCouponBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除订单优惠券使用记录信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 计算并使用优惠券(订单创建时调用)
|
||||
* 计算优惠券折扣金额,创建订单优惠券使用记录,并标记用户优惠券为已使用
|
||||
*
|
||||
* @param couponUserId 用户优惠券ID
|
||||
* @param orderId 订单ID
|
||||
* @param orderNo 订单号
|
||||
* @param orderAmount 订单金额(单位:分)
|
||||
* @return 优惠金额(单位:分)
|
||||
*/
|
||||
Long calculateAndUseCoupon(Long couponUserId, Long orderId, String orderNo, Long orderAmount);
|
||||
|
||||
/**
|
||||
* 根据订单ID统计优惠金额
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 优惠金额总和(单位:分)
|
||||
*/
|
||||
Long sumDiscountAmountByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据订单号统计优惠金额
|
||||
*
|
||||
* @param orderNo 订单号
|
||||
* @return 优惠金额总和(单位:分)
|
||||
*/
|
||||
Long sumDiscountAmountByOrderNo(String orderNo);
|
||||
|
||||
/**
|
||||
* 根据优惠券ID统计核销金额
|
||||
*
|
||||
* @param couponId 优惠券ID
|
||||
* @return 核销金额总和(单位:分)
|
||||
*/
|
||||
Long sumDiscountAmountByCouponId(Long couponId);
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package org.dromara.mall.trade.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderEvaluateBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderEvaluateVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单评价Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallOrderEvaluateService {
|
||||
|
||||
/**
|
||||
* 查询订单评价
|
||||
*/
|
||||
MallOrderEvaluateVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询订单评价列表
|
||||
*/
|
||||
TableDataInfo<MallOrderEvaluateVo> queryPageList(MallOrderEvaluateBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询订单评价列表
|
||||
*/
|
||||
List<MallOrderEvaluateVo> queryList(MallOrderEvaluateBo bo);
|
||||
|
||||
/**
|
||||
* 新增订单评价
|
||||
*/
|
||||
Boolean insertByBo(MallOrderEvaluateBo bo);
|
||||
|
||||
/**
|
||||
* 修改订单评价
|
||||
*/
|
||||
Boolean updateByBo(MallOrderEvaluateBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除订单评价信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 审核评价(通过/驳回)
|
||||
*/
|
||||
Boolean audit(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 回复评价(商家回复)
|
||||
*/
|
||||
Boolean reply(Long id, String replyContent);
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package org.dromara.mall.trade.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 秒杀订单处理Service接口
|
||||
* 提供秒杀订单创建、验证、库存管理等核心业务逻辑
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface SeckillOrderService {
|
||||
|
||||
/**
|
||||
* 验证秒杀活动是否可用
|
||||
*
|
||||
* @param seckillId 秒杀活动ID
|
||||
* @param quantity 购买数量
|
||||
* @return 验证结果信息(包含是否可用、错误信息等)
|
||||
*/
|
||||
SeckillValidationResult validateSeckillActivity(Long seckillId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 验证秒杀限购
|
||||
*
|
||||
* @param seckillId 秒杀活动ID
|
||||
* @param userId 用户ID
|
||||
* @param skuId SKU ID
|
||||
* @return 是否允许购买
|
||||
*/
|
||||
Boolean validatePurchaseLimit(Long seckillId, Long userId, Long skuId);
|
||||
|
||||
/**
|
||||
* 预扣秒杀库存
|
||||
*
|
||||
* @param seckillId 秒杀活动ID
|
||||
* @param quantity 购买数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean preDeductSeckillStock(Long seckillId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 恢复秒杀库存(订单取消时调用)
|
||||
*
|
||||
* @param seckillId 秒杀活动ID
|
||||
* @param quantity 恢复数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean restoreSeckillStock(Long seckillId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 获取秒杀价格
|
||||
*
|
||||
* @param seckillId 秒杀活动ID
|
||||
* @return 秒杀价(分)
|
||||
*/
|
||||
Integer getSeckillPrice(Long seckillId);
|
||||
|
||||
/**
|
||||
* 秒杀验证结果
|
||||
*/
|
||||
class SeckillValidationResult {
|
||||
private Boolean valid;
|
||||
private String errorMessage;
|
||||
private Map<String, Object> data;
|
||||
|
||||
public SeckillValidationResult(Boolean valid, String errorMessage) {
|
||||
this.valid = valid;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public SeckillValidationResult(Boolean valid, String errorMessage, Map<String, Object> data) {
|
||||
this.valid = valid;
|
||||
this.errorMessage = errorMessage;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Boolean getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(Boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public Map<String, Object> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Map<String, Object> data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
package org.dromara.mall.trade.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.mall.trade.domain.MallAddress;
|
||||
import org.dromara.mall.trade.domain.bo.MallAddressBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAddressVo;
|
||||
import org.dromara.mall.trade.mapper.MallAddressMapper;
|
||||
import org.dromara.mall.trade.service.MallAddressService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收货地址Service业务层处理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class MallAddressServiceImpl implements MallAddressService {
|
||||
|
||||
private final MallAddressMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询收货地址
|
||||
*/
|
||||
@Override
|
||||
public MallAddressVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallAddressVo> queryPageList(MallAddressBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallAddress> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询收货地址列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallAddressVo> queryList(MallAddressBo bo) {
|
||||
LambdaQueryWrapper<MallAddress> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户的收货地址列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallAddressVo> queryListByUserId(Long userId) {
|
||||
LambdaQueryWrapper<MallAddress> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallAddress::getUserId, userId);
|
||||
lqw.orderByDesc(MallAddress::getIsDefault);
|
||||
lqw.orderByDesc(MallAddress::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户的默认地址
|
||||
*/
|
||||
@Override
|
||||
public MallAddressVo queryDefaultByUserId(Long userId) {
|
||||
LambdaQueryWrapper<MallAddress> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallAddress::getUserId, userId);
|
||||
lqw.eq(MallAddress::getIsDefault, 1);
|
||||
lqw.last("LIMIT 1");
|
||||
List<MallAddressVo> list = baseMapper.selectVoList(lqw);
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallAddress> buildQueryWrapper(MallAddressBo bo) {
|
||||
LambdaQueryWrapper<MallAddress> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(bo.getUserId() != null, MallAddress::getUserId, bo.getUserId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getReceiverName()), MallAddress::getReceiverName, bo.getReceiverName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getReceiverPhone()), MallAddress::getReceiverPhone, bo.getReceiverPhone());
|
||||
lqw.eq(bo.getIsDefault() != null, MallAddress::getIsDefault, bo.getIsDefault());
|
||||
lqw.orderByDesc(MallAddress::getIsDefault);
|
||||
lqw.orderByDesc(MallAddress::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增收货地址
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallAddressBo bo) {
|
||||
MallAddress add = MapstructUtils.convert(bo, MallAddress.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置用户ID(移动端用户)
|
||||
if (add.getUserId() == null) {
|
||||
add.setUserId(LoginHelper.getUserId());
|
||||
}
|
||||
|
||||
// 如果设置为默认地址,则取消其他默认地址
|
||||
if (add.getIsDefault() != null && add.getIsDefault() == 1) {
|
||||
cancelOtherDefaultAddress(add.getUserId());
|
||||
} else {
|
||||
add.setIsDefault(0);
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改收货地址
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallAddressBo bo) {
|
||||
MallAddress update = MapstructUtils.convert(bo, MallAddress.class);
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
// 如果设置为默认地址,则取消其他默认地址
|
||||
if (update.getIsDefault() != null && update.getIsDefault() == 1) {
|
||||
cancelOtherDefaultAddress(update.getUserId(), update.getId());
|
||||
}
|
||||
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallAddress entity) {
|
||||
// 可以添加业务校验逻辑,如手机号格式校验等
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消其他默认地址
|
||||
*/
|
||||
private void cancelOtherDefaultAddress(Long userId) {
|
||||
cancelOtherDefaultAddress(userId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消其他默认地址(排除指定地址ID)
|
||||
*/
|
||||
private void cancelOtherDefaultAddress(Long userId, Long excludeId) {
|
||||
LambdaUpdateWrapper<MallAddress> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(MallAddress::getUserId, userId);
|
||||
updateWrapper.eq(MallAddress::getIsDefault, 1);
|
||||
if (excludeId != null) {
|
||||
updateWrapper.ne(MallAddress::getId, excludeId);
|
||||
}
|
||||
updateWrapper.set(MallAddress::getIsDefault, 0);
|
||||
baseMapper.update(null, updateWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除收货地址信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认地址
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean setDefault(Long id) {
|
||||
MallAddress address = baseMapper.selectById(id);
|
||||
if (address == null) {
|
||||
throw new ServiceException("收货地址不存在");
|
||||
}
|
||||
|
||||
Long userId = address.getUserId();
|
||||
if (userId == null) {
|
||||
userId = LoginHelper.getUserId();
|
||||
}
|
||||
|
||||
// 取消其他默认地址
|
||||
cancelOtherDefaultAddress(userId, id);
|
||||
|
||||
// 设置当前地址为默认地址
|
||||
address.setIsDefault(1);
|
||||
return baseMapper.updateById(address) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
package org.dromara.mall.trade.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.mall.trade.domain.MallAfterSale;
|
||||
import org.dromara.mall.trade.domain.bo.MallAfterSaleBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallAfterSaleVo;
|
||||
import org.dromara.mall.trade.mapper.MallAfterSaleMapper;
|
||||
import org.dromara.mall.trade.service.MallAfterSaleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后申请Service业务层处理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class MallAfterSaleServiceImpl implements MallAfterSaleService {
|
||||
|
||||
private final MallAfterSaleMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询售后申请
|
||||
*/
|
||||
@Override
|
||||
public MallAfterSaleVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据售后单号查询
|
||||
*/
|
||||
@Override
|
||||
public MallAfterSaleVo queryByAfterSaleNo(String afterSaleNo) {
|
||||
LambdaQueryWrapper<MallAfterSale> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallAfterSale::getAfterSaleNo, afterSaleNo);
|
||||
return baseMapper.selectVoOne(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询售后申请列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallAfterSaleVo> queryPageList(MallAfterSaleBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallAfterSale> lqw = buildQueryWrapper(bo);
|
||||
Page<MallAfterSaleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询售后申请列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallAfterSaleVo> queryList(MallAfterSaleBo bo) {
|
||||
LambdaQueryWrapper<MallAfterSale> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallAfterSale> buildQueryWrapper(MallAfterSaleBo bo) {
|
||||
LambdaQueryWrapper<MallAfterSale> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getAfterSaleNo()), MallAfterSale::getAfterSaleNo, bo.getAfterSaleNo());
|
||||
lqw.eq(bo.getOrderId() != null, MallAfterSale::getOrderId, bo.getOrderId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), MallAfterSale::getOrderNo, bo.getOrderNo());
|
||||
lqw.eq(bo.getOrderItemId() != null, MallAfterSale::getOrderItemId, bo.getOrderItemId());
|
||||
lqw.eq(bo.getUserId() != null, MallAfterSale::getUserId, bo.getUserId());
|
||||
lqw.eq(bo.getType() != null, MallAfterSale::getType, bo.getType());
|
||||
lqw.eq(bo.getStatus() != null, MallAfterSale::getStatus, bo.getStatus());
|
||||
lqw.orderByDesc(MallAfterSale::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成售后单号
|
||||
*/
|
||||
private String generateAfterSaleNo() {
|
||||
return "AS" + System.currentTimeMillis() + IdUtil.fastSimpleUUID().substring(0, 6).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增售后申请
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallAfterSaleBo bo) {
|
||||
MallAfterSale add = MapstructUtils.convert(bo, MallAfterSale.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置用户ID(移动端用户)
|
||||
if (add.getUserId() == null) {
|
||||
add.setUserId(LoginHelper.getUserId());
|
||||
}
|
||||
|
||||
// 生成售后单号
|
||||
if (StringUtils.isBlank(add.getAfterSaleNo())) {
|
||||
add.setAfterSaleNo(generateAfterSaleNo());
|
||||
}
|
||||
|
||||
// 设置默认状态为待审核
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0);
|
||||
}
|
||||
|
||||
// 设置申请时间
|
||||
if (add.getApplyTime() == null) {
|
||||
add.setApplyTime(new Date());
|
||||
}
|
||||
|
||||
// 设置默认数量
|
||||
if (add.getQuantity() == null) {
|
||||
add.setQuantity(1);
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改售后申请
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallAfterSaleBo bo) {
|
||||
MallAfterSale update = MapstructUtils.convert(bo, MallAfterSale.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallAfterSale entity) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除售后申请
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核售后申请(同意/拒绝)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean audit(Long id, Integer status, String refuseReason) {
|
||||
MallAfterSale afterSale = baseMapper.selectById(id);
|
||||
if (afterSale == null) {
|
||||
throw new ServiceException("售后申请不存在");
|
||||
}
|
||||
if (afterSale.getStatus() != 0) {
|
||||
throw new ServiceException("售后申请已审核,不能重复审核");
|
||||
}
|
||||
if (status == null || (status != 1 && status != 2)) {
|
||||
throw new ServiceException("审核状态不正确");
|
||||
}
|
||||
|
||||
afterSale.setStatus(status);
|
||||
afterSale.setAuditTime(new Date());
|
||||
|
||||
if (status == 2) {
|
||||
// 拒绝
|
||||
if (StringUtils.isBlank(refuseReason)) {
|
||||
throw new ServiceException("拒绝原因不能为空");
|
||||
}
|
||||
afterSale.setRefuseReason(refuseReason);
|
||||
} else if (status == 1) {
|
||||
// 同意
|
||||
if (afterSale.getType() == 1 || afterSale.getType() == 2) {
|
||||
// 退货或换货,状态变为待退货
|
||||
afterSale.setStatus(3);
|
||||
}
|
||||
// 退款类型,状态保持为已同意,等待退款处理
|
||||
}
|
||||
|
||||
return baseMapper.updateById(afterSale) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户填写退货物流信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean fillLogistics(Long id, String logisticsCompany, String logisticsNo) {
|
||||
MallAfterSale afterSale = baseMapper.selectById(id);
|
||||
if (afterSale == null) {
|
||||
throw new ServiceException("售后申请不存在");
|
||||
}
|
||||
if (afterSale.getStatus() != 3) {
|
||||
throw new ServiceException("当前状态不能填写物流信息");
|
||||
}
|
||||
if (afterSale.getType() == 0) {
|
||||
throw new ServiceException("退款类型不需要填写物流信息");
|
||||
}
|
||||
|
||||
afterSale.setLogisticsCompany(logisticsCompany);
|
||||
afterSale.setLogisticsNo(logisticsNo);
|
||||
afterSale.setReturnTime(new Date());
|
||||
afterSale.setStatus(4); // 待收货
|
||||
|
||||
return baseMapper.updateById(afterSale) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认收货(商家确认收到退货)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean confirmReceive(Long id) {
|
||||
MallAfterSale afterSale = baseMapper.selectById(id);
|
||||
if (afterSale == null) {
|
||||
throw new ServiceException("售后申请不存在");
|
||||
}
|
||||
if (afterSale.getStatus() != 4) {
|
||||
throw new ServiceException("当前状态不能确认收货");
|
||||
}
|
||||
|
||||
afterSale.setReceiveTime(new Date());
|
||||
// 状态变为已完成(退款或换货完成需要调用支付中心退款接口或换货接口)
|
||||
// 这里暂时设置为已完成,实际业务中需要调用支付中心退款接口
|
||||
afterSale.setStatus(5);
|
||||
|
||||
return baseMapper.updateById(afterSale) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成售后(退款完成或换货完成)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean complete(Long id) {
|
||||
MallAfterSale afterSale = baseMapper.selectById(id);
|
||||
if (afterSale == null) {
|
||||
throw new ServiceException("售后申请不存在");
|
||||
}
|
||||
if (afterSale.getStatus() == 5 || afterSale.getStatus() == 6) {
|
||||
throw new ServiceException("售后申请已完成或已取消");
|
||||
}
|
||||
|
||||
afterSale.setStatus(5);
|
||||
if (afterSale.getType() == 0 || afterSale.getType() == 1) {
|
||||
// 退款或退货,设置退款时间
|
||||
afterSale.setRefundTime(new Date());
|
||||
}
|
||||
|
||||
return baseMapper.updateById(afterSale) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消售后申请
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean cancel(Long id) {
|
||||
MallAfterSale afterSale = baseMapper.selectById(id);
|
||||
if (afterSale == null) {
|
||||
throw new ServiceException("售后申请不存在");
|
||||
}
|
||||
if (afterSale.getStatus() == 5 || afterSale.getStatus() == 6) {
|
||||
throw new ServiceException("售后申请已完成或已取消");
|
||||
}
|
||||
if (afterSale.getStatus() == 4) {
|
||||
throw new ServiceException("商家已收货,不能取消");
|
||||
}
|
||||
|
||||
afterSale.setStatus(6);
|
||||
return baseMapper.updateById(afterSale) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
package org.dromara.mall.trade.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.mall.coupon.domain.vo.MallCouponVo;
|
||||
import org.dromara.mall.coupon.service.MallCouponService;
|
||||
import org.dromara.mall.coupon.service.MallCouponUserService;
|
||||
import org.dromara.mall.trade.domain.MallOrderCoupon;
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderCouponBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderCouponVo;
|
||||
import org.dromara.mall.trade.mapper.MallOrderCouponMapper;
|
||||
import org.dromara.mall.trade.service.MallOrderCouponService;
|
||||
import org.dromara.mall.trade.utils.CouponCalculator;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单优惠券使用记录Service业务层处理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class MallOrderCouponServiceImpl implements MallOrderCouponService {
|
||||
|
||||
private final MallOrderCouponMapper baseMapper;
|
||||
private final MallCouponService couponService;
|
||||
private final MallCouponUserService couponUserService;
|
||||
|
||||
/**
|
||||
* 查询订单优惠券使用记录
|
||||
*/
|
||||
@Override
|
||||
public MallOrderCouponVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID查询订单优惠券使用记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallOrderCouponVo> queryListByOrderId(Long orderId) {
|
||||
LambdaQueryWrapper<MallOrderCoupon> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallOrderCoupon::getOrderId, orderId);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单优惠券使用记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallOrderCouponVo> queryListByOrderNo(String orderNo) {
|
||||
LambdaQueryWrapper<MallOrderCoupon> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallOrderCoupon::getOrderNo, orderNo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单优惠券使用记录
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallOrderCouponBo bo) {
|
||||
MallOrderCoupon add = MapstructUtils.convert(bo, MallOrderCoupon.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置使用时间
|
||||
if (add.getCreateTime() == null) {
|
||||
add.setCreateTime(new Date());
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallOrderCoupon entity) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除订单优惠券使用记录信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算并使用优惠券(订单创建时调用)
|
||||
* 计算优惠券折扣金额,创建订单优惠券使用记录,并标记用户优惠券为已使用
|
||||
*
|
||||
* @param couponUserId 用户优惠券ID
|
||||
* @param orderId 订单ID
|
||||
* @param orderNo 订单号
|
||||
* @param orderAmount 订单金额(单位:分)
|
||||
* @return 优惠金额(单位:分)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long calculateAndUseCoupon(Long couponUserId, Long orderId, String orderNo, Long orderAmount) {
|
||||
if (couponUserId == null) {
|
||||
throw new ServiceException("用户优惠券ID不能为空");
|
||||
}
|
||||
if (orderId == null) {
|
||||
throw new ServiceException("订单ID不能为空");
|
||||
}
|
||||
if (orderNo == null || orderNo.trim().isEmpty()) {
|
||||
throw new ServiceException("订单号不能为空");
|
||||
}
|
||||
if (orderAmount == null || orderAmount <= 0) {
|
||||
throw new ServiceException("订单金额必须大于0");
|
||||
}
|
||||
|
||||
// 查询用户优惠券信息
|
||||
org.dromara.mall.coupon.domain.vo.MallCouponUserVo couponUser = couponUserService.queryById(couponUserId);
|
||||
if (couponUser == null) {
|
||||
throw new ServiceException("用户优惠券不存在");
|
||||
}
|
||||
if (couponUser.getStatus() != 0) {
|
||||
throw new ServiceException("优惠券已使用或已过期");
|
||||
}
|
||||
|
||||
// 查询优惠券信息
|
||||
MallCouponVo coupon = couponService.queryById(couponUser.getCouponId());
|
||||
if (coupon == null) {
|
||||
throw new ServiceException("优惠券不存在");
|
||||
}
|
||||
|
||||
// 计算优惠金额
|
||||
Long discountAmount = CouponCalculator.calculateDiscountAmount(coupon, orderAmount);
|
||||
if (discountAmount <= 0) {
|
||||
throw new ServiceException("订单金额不满足优惠券使用门槛");
|
||||
}
|
||||
|
||||
// 标记用户优惠券为已使用(调用优惠券服务的useCoupon方法)
|
||||
couponUserService.useCoupon(couponUserId, orderId);
|
||||
|
||||
// 创建订单优惠券使用记录
|
||||
MallOrderCouponBo orderCouponBo = new MallOrderCouponBo();
|
||||
orderCouponBo.setOrderId(orderId);
|
||||
orderCouponBo.setOrderNo(orderNo);
|
||||
orderCouponBo.setCouponId(coupon.getId());
|
||||
orderCouponBo.setCouponUserId(couponUserId);
|
||||
orderCouponBo.setDiscountAmount(discountAmount.intValue());
|
||||
|
||||
boolean flag = insertByBo(orderCouponBo);
|
||||
if (!flag) {
|
||||
throw new ServiceException("创建订单优惠券使用记录失败");
|
||||
}
|
||||
|
||||
log.info("优惠券使用成功 - 用户优惠券ID: {}, 订单ID: {}, 订单号: {}, 优惠金额: {}",
|
||||
couponUserId, orderId, orderNo, discountAmount);
|
||||
return discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID统计优惠金额
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 优惠金额总和(单位:分)
|
||||
*/
|
||||
@Override
|
||||
public Long sumDiscountAmountByOrderId(Long orderId) {
|
||||
if (orderId == null) {
|
||||
return 0L;
|
||||
}
|
||||
List<MallOrderCouponVo> list = queryListByOrderId(orderId);
|
||||
return list.stream()
|
||||
.mapToLong(vo -> vo.getDiscountAmount() != null ? vo.getDiscountAmount().longValue() : 0L)
|
||||
.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单号统计优惠金额
|
||||
*
|
||||
* @param orderNo 订单号
|
||||
* @return 优惠金额总和(单位:分)
|
||||
*/
|
||||
@Override
|
||||
public Long sumDiscountAmountByOrderNo(String orderNo) {
|
||||
if (orderNo == null || orderNo.trim().isEmpty()) {
|
||||
return 0L;
|
||||
}
|
||||
List<MallOrderCouponVo> list = queryListByOrderNo(orderNo);
|
||||
return list.stream()
|
||||
.mapToLong(vo -> vo.getDiscountAmount() != null ? vo.getDiscountAmount().longValue() : 0L)
|
||||
.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据优惠券ID统计核销金额
|
||||
*
|
||||
* @param couponId 优惠券ID
|
||||
* @return 核销金额总和(单位:分)
|
||||
*/
|
||||
@Override
|
||||
public Long sumDiscountAmountByCouponId(Long couponId) {
|
||||
if (couponId == null) {
|
||||
return 0L;
|
||||
}
|
||||
LambdaQueryWrapper<MallOrderCoupon> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(MallOrderCoupon::getCouponId, couponId);
|
||||
List<MallOrderCouponVo> list = baseMapper.selectVoList(lqw);
|
||||
return list.stream()
|
||||
.mapToLong(vo -> vo.getDiscountAmount() != null ? vo.getDiscountAmount().longValue() : 0L)
|
||||
.sum();
|
||||
}
|
||||
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
package org.dromara.mall.trade.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.mall.trade.domain.MallOrderEvaluate;
|
||||
import org.dromara.mall.trade.domain.bo.MallOrderEvaluateBo;
|
||||
import org.dromara.mall.trade.domain.vo.MallOrderEvaluateVo;
|
||||
import org.dromara.mall.trade.mapper.MallOrderEvaluateMapper;
|
||||
import org.dromara.mall.trade.service.MallOrderEvaluateService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单评价Service业务层处理
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class MallOrderEvaluateServiceImpl implements MallOrderEvaluateService {
|
||||
|
||||
private final MallOrderEvaluateMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询订单评价
|
||||
*/
|
||||
@Override
|
||||
public MallOrderEvaluateVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单评价列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallOrderEvaluateVo> queryPageList(MallOrderEvaluateBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallOrderEvaluate> lqw = buildQueryWrapper(bo);
|
||||
Page<MallOrderEvaluateVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单评价列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallOrderEvaluateVo> queryList(MallOrderEvaluateBo bo) {
|
||||
LambdaQueryWrapper<MallOrderEvaluate> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallOrderEvaluate> buildQueryWrapper(MallOrderEvaluateBo bo) {
|
||||
LambdaQueryWrapper<MallOrderEvaluate> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(bo.getOrderId() != null, MallOrderEvaluate::getOrderId, bo.getOrderId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), MallOrderEvaluate::getOrderNo, bo.getOrderNo());
|
||||
lqw.eq(bo.getOrderItemId() != null, MallOrderEvaluate::getOrderItemId, bo.getOrderItemId());
|
||||
lqw.eq(bo.getProductId() != null, MallOrderEvaluate::getProductId, bo.getProductId());
|
||||
lqw.eq(bo.getSkuId() != null, MallOrderEvaluate::getSkuId, bo.getSkuId());
|
||||
lqw.eq(bo.getUserId() != null, MallOrderEvaluate::getUserId, bo.getUserId());
|
||||
lqw.eq(bo.getScore() != null, MallOrderEvaluate::getScore, bo.getScore());
|
||||
lqw.eq(bo.getStatus() != null, MallOrderEvaluate::getStatus, bo.getStatus());
|
||||
lqw.orderByDesc(MallOrderEvaluate::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增订单评价
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallOrderEvaluateBo bo) {
|
||||
MallOrderEvaluate add = MapstructUtils.convert(bo, MallOrderEvaluate.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置用户ID(移动端用户)
|
||||
if (add.getUserId() == null) {
|
||||
add.setUserId(LoginHelper.getUserId());
|
||||
}
|
||||
|
||||
// 设置默认状态为待审核
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0);
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单评价
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallOrderEvaluateBo bo) {
|
||||
MallOrderEvaluate update = MapstructUtils.convert(bo, MallOrderEvaluate.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallOrderEvaluate entity) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除订单评价
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// 可以添加业务校验逻辑
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核评价(通过/驳回)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean audit(Long id, Integer status) {
|
||||
MallOrderEvaluate evaluate = baseMapper.selectById(id);
|
||||
if (evaluate == null) {
|
||||
throw new ServiceException("评价不存在");
|
||||
}
|
||||
if (evaluate.getStatus() != 0) {
|
||||
throw new ServiceException("评价已审核,不能重复审核");
|
||||
}
|
||||
if (status == null || (status != 1 && status != 2)) {
|
||||
throw new ServiceException("审核状态不正确");
|
||||
}
|
||||
|
||||
evaluate.setStatus(status);
|
||||
return baseMapper.updateById(evaluate) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回复评价(商家回复)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean reply(Long id, String replyContent) {
|
||||
MallOrderEvaluate evaluate = baseMapper.selectById(id);
|
||||
if (evaluate == null) {
|
||||
throw new ServiceException("评价不存在");
|
||||
}
|
||||
if (evaluate.getStatus() != 1) {
|
||||
throw new ServiceException("只有已通过审核的评价才能回复");
|
||||
}
|
||||
|
||||
evaluate.setReplyContent(replyContent);
|
||||
evaluate.setReplyTime(new Date());
|
||||
return baseMapper.updateById(evaluate) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
package org.dromara.mall.trade.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
import org.dromara.mall.promotion.mapper.MallPromotionMapper;
|
||||
import org.dromara.mall.promotion.service.MallSeckillService;
|
||||
import org.dromara.mall.trade.service.SeckillOrderService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 秒杀订单处理Service业务层实现
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SeckillOrderServiceImpl implements SeckillOrderService {
|
||||
|
||||
private final MallSeckillService mallSeckillService;
|
||||
private final MallPromotionMapper promotionMapper;
|
||||
|
||||
/**
|
||||
* 活动类型:秒杀
|
||||
*/
|
||||
private static final Integer PROMOTION_TYPE_SECKILL = 2;
|
||||
|
||||
/**
|
||||
* 默认限购数量
|
||||
*/
|
||||
private static final Integer DEFAULT_PURCHASE_LIMIT = 1;
|
||||
|
||||
/**
|
||||
* 验证秒杀活动是否可用
|
||||
*/
|
||||
@Override
|
||||
public SeckillValidationResult validateSeckillActivity(Long seckillId, Integer quantity) {
|
||||
// 查询秒杀活动
|
||||
MallSeckillVo seckillVo = mallSeckillService.queryById(seckillId);
|
||||
if (seckillVo == null) {
|
||||
return new SeckillValidationResult(false, "秒杀活动不存在");
|
||||
}
|
||||
|
||||
// 验证秒杀活动状态
|
||||
if (seckillVo.getStatus() != 0) {
|
||||
return new SeckillValidationResult(false, "秒杀活动已禁用");
|
||||
}
|
||||
|
||||
// 验证秒杀活动时间
|
||||
Date now = new Date();
|
||||
if (seckillVo.getStartTime() != null && seckillVo.getStartTime().after(now)) {
|
||||
return new SeckillValidationResult(false, "秒杀活动尚未开始");
|
||||
}
|
||||
if (seckillVo.getEndTime() != null && seckillVo.getEndTime().before(now)) {
|
||||
return new SeckillValidationResult(false, "秒杀活动已结束");
|
||||
}
|
||||
|
||||
// 验证秒杀库存
|
||||
if (seckillVo.getSeckillStock() == null || seckillVo.getSeckillStock() < quantity) {
|
||||
return new SeckillValidationResult(false, "秒杀库存不足");
|
||||
}
|
||||
|
||||
// 验证关联的营销活动
|
||||
if (seckillVo.getPromotionId() != null) {
|
||||
MallPromotionVo promotionVo = promotionMapper.selectVoById(seckillVo.getPromotionId());
|
||||
if (promotionVo == null) {
|
||||
return new SeckillValidationResult(false, "关联的营销活动不存在");
|
||||
}
|
||||
if (promotionVo.getStatus() != 0) {
|
||||
return new SeckillValidationResult(false, "关联的营销活动已禁用");
|
||||
}
|
||||
if (!PROMOTION_TYPE_SECKILL.equals(promotionVo.getType())) {
|
||||
return new SeckillValidationResult(false, "关联的营销活动类型不正确");
|
||||
}
|
||||
}
|
||||
|
||||
// 返回验证通过的结果,包含秒杀信息
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("seckillPrice", seckillVo.getSeckillPrice());
|
||||
data.put("promotionId", seckillVo.getPromotionId());
|
||||
data.put("skuId", seckillVo.getSkuId());
|
||||
|
||||
return new SeckillValidationResult(true, null, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证秒杀限购
|
||||
*/
|
||||
@Override
|
||||
public Boolean validatePurchaseLimit(Long seckillId, Long userId, Long skuId) {
|
||||
// 查询秒杀活动信息
|
||||
MallSeckillVo seckillVo = mallSeckillService.queryById(seckillId);
|
||||
if (seckillVo == null) {
|
||||
throw new ServiceException("秒杀活动不存在");
|
||||
}
|
||||
|
||||
// 获取限购数量(从营销活动的rules JSON中读取,或使用默认值)
|
||||
Integer purchaseLimit = DEFAULT_PURCHASE_LIMIT;
|
||||
if (seckillVo.getPromotionId() != null) {
|
||||
MallPromotion promotion = promotionMapper.selectById(seckillVo.getPromotionId());
|
||||
if (promotion != null && promotion.getRules() != null) {
|
||||
try {
|
||||
Dict rules = JsonUtils.parseMap(promotion.getRules());
|
||||
if (rules != null && rules.containsKey("purchaseLimit")) {
|
||||
Object limitObj = rules.get("purchaseLimit");
|
||||
if (limitObj instanceof Number) {
|
||||
purchaseLimit = ((Number) limitObj).intValue();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析营销活动规则JSON失败,使用默认限购数量: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 查询用户已购买的秒杀订单数量
|
||||
// 注意:由于订单实体类和服务尚未实现,这里暂时返回true(允许购买)
|
||||
// 后续需要在订单服务中实现此逻辑:
|
||||
// 1. 查询用户已购买的秒杀订单数量(同一秒杀活动、同一SKU,仅统计已支付的订单)
|
||||
// 2. 校验是否超过限购数量
|
||||
// 示例代码(需要等订单服务实现后):
|
||||
// LambdaQueryWrapper<MallOrder> lqw = new LambdaQueryWrapper<>();
|
||||
// lqw.eq(MallOrder::getUserId, userId);
|
||||
// lqw.eq(MallOrder::getSeckillId, seckillId);
|
||||
// lqw.eq(MallOrder::getPayStatus, PAY_STATUS_PAID);
|
||||
// lqw.ne(MallOrder::getOrderStatus, 4);
|
||||
// Long purchasedCount = orderMapper.selectCount(lqw);
|
||||
// return purchasedCount == null || purchasedCount < purchaseLimit;
|
||||
|
||||
log.info("秒杀限购校验 - 秒杀ID: {}, 用户ID: {}, SKU ID: {}, 限购数量: {} (待订单服务实现后完善)", seckillId, userId, skuId, purchaseLimit);
|
||||
return true; // 临时返回true,待订单服务实现后完善
|
||||
}
|
||||
|
||||
/**
|
||||
* 预扣秒杀库存
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean preDeductSeckillStock(Long seckillId, Integer quantity) {
|
||||
return mallSeckillService.reduceStock(seckillId, quantity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复秒杀库存(订单取消时调用)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean restoreSeckillStock(Long seckillId, Integer quantity) {
|
||||
return mallSeckillService.restoreStock(seckillId, quantity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒杀价格
|
||||
*/
|
||||
@Override
|
||||
public Integer getSeckillPrice(Long seckillId) {
|
||||
MallSeckillVo seckillVo = mallSeckillService.queryById(seckillId);
|
||||
if (seckillVo == null) {
|
||||
throw new ServiceException("秒杀活动不存在");
|
||||
}
|
||||
return seckillVo.getSeckillPrice();
|
||||
}
|
||||
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
package org.dromara.mall.trade.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.mall.coupon.domain.vo.MallCouponVo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* 优惠券计算工具类
|
||||
* 用于计算优惠券的折扣金额
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
public class CouponCalculator {
|
||||
|
||||
/**
|
||||
* 计算优惠券的折扣金额(单位:分)
|
||||
*
|
||||
* @param coupon 优惠券信息
|
||||
* @param orderAmount 订单金额(单位:分)
|
||||
* @return 折扣金额(单位:分),如果订单金额不满足使用门槛,返回0
|
||||
*/
|
||||
public static Long calculateDiscountAmount(MallCouponVo coupon, Long orderAmount) {
|
||||
if (coupon == null) {
|
||||
throw new ServiceException("优惠券信息不能为空");
|
||||
}
|
||||
if (orderAmount == null || orderAmount <= 0) {
|
||||
throw new ServiceException("订单金额必须大于0");
|
||||
}
|
||||
|
||||
// 检查使用门槛
|
||||
Integer minAmount = coupon.getMinAmount();
|
||||
if (minAmount != null && minAmount > 0 && orderAmount < minAmount) {
|
||||
log.debug("订单金额{}不满足优惠券{}的使用门槛{}", orderAmount, coupon.getId(), minAmount);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
Integer type = coupon.getType();
|
||||
if (type == null) {
|
||||
throw new ServiceException("优惠券类型不能为空");
|
||||
}
|
||||
|
||||
Long discountAmount = 0L;
|
||||
|
||||
// 0-满减,1-折扣,2-现金
|
||||
if (type == 0 || type == 2) {
|
||||
// 满减券或现金券:直接使用 discountAmount
|
||||
Integer couponDiscountAmount = coupon.getDiscountAmount();
|
||||
if (couponDiscountAmount == null || couponDiscountAmount <= 0) {
|
||||
throw new ServiceException("优惠券优惠金额配置错误");
|
||||
}
|
||||
discountAmount = couponDiscountAmount.longValue();
|
||||
// 确保折扣金额不超过订单金额
|
||||
if (discountAmount > orderAmount) {
|
||||
discountAmount = orderAmount;
|
||||
}
|
||||
} else if (type == 1) {
|
||||
// 折扣券:使用 discountRate(百分比)
|
||||
BigDecimal discountRate = coupon.getDiscountRate();
|
||||
if (discountRate == null || discountRate.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException("优惠券折扣率配置错误");
|
||||
}
|
||||
if (discountRate.compareTo(new BigDecimal("100")) > 0) {
|
||||
throw new ServiceException("折扣率不能大于100%");
|
||||
}
|
||||
// 计算折扣金额:订单金额 * (折扣率 / 100)
|
||||
BigDecimal orderAmountDecimal = new BigDecimal(orderAmount);
|
||||
BigDecimal discountAmountDecimal = orderAmountDecimal
|
||||
.multiply(discountRate)
|
||||
.divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
|
||||
discountAmount = discountAmountDecimal.setScale(0, RoundingMode.HALF_UP).longValue();
|
||||
// 确保折扣金额不超过订单金额
|
||||
if (discountAmount > orderAmount) {
|
||||
discountAmount = orderAmount;
|
||||
}
|
||||
} else {
|
||||
throw new ServiceException("不支持的优惠券类型: " + type);
|
||||
}
|
||||
|
||||
log.debug("优惠券{}计算折扣金额: 订单金额={}, 折扣金额={}", coupon.getId(), orderAmount, discountAmount);
|
||||
return discountAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算优惠券的折扣金额(单位:分)
|
||||
* 使用优惠券ID和订单金额,需要传入优惠券查询方法
|
||||
*
|
||||
* @param couponService 优惠券服务,用于查询优惠券信息
|
||||
* @param couponId 优惠券ID
|
||||
* @param orderAmount 订单金额(单位:分)
|
||||
* @return 折扣金额(单位:分),如果订单金额不满足使用门槛或优惠券不存在,返回0
|
||||
*/
|
||||
public static Long calculateDiscountAmount(
|
||||
org.dromara.mall.coupon.service.MallCouponService couponService,
|
||||
Long couponId,
|
||||
Long orderAmount) {
|
||||
if (couponService == null) {
|
||||
throw new ServiceException("优惠券服务不能为空");
|
||||
}
|
||||
if (couponId == null) {
|
||||
throw new ServiceException("优惠券ID不能为空");
|
||||
}
|
||||
|
||||
org.dromara.mall.coupon.domain.vo.MallCouponVo coupon = couponService.queryById(couponId);
|
||||
if (coupon == null) {
|
||||
log.warn("优惠券{}不存在", couponId);
|
||||
return 0L;
|
||||
}
|
||||
|
||||
return calculateDiscountAmount(coupon, orderAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证优惠券是否可用
|
||||
*
|
||||
* @param coupon 优惠券信息
|
||||
* @param orderAmount 订单金额(单位:分)
|
||||
* @return true表示可用,false表示不可用
|
||||
*/
|
||||
public static boolean isValidCoupon(MallCouponVo coupon, Long orderAmount) {
|
||||
if (coupon == null) {
|
||||
return false;
|
||||
}
|
||||
// 检查状态
|
||||
if (coupon.getStatus() != null && coupon.getStatus() != 0) {
|
||||
return false;
|
||||
}
|
||||
// 检查使用门槛
|
||||
Integer minAmount = coupon.getMinAmount();
|
||||
if (minAmount != null && minAmount > 0 && orderAmount < minAmount) {
|
||||
return false;
|
||||
}
|
||||
// 检查有效期(如果订单服务需要,可以添加时间校验)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.dromara.mall.trade.config.MallTradeAutoConfiguration
|
||||
Reference in New Issue
Block a user