first commit
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
# 营销中心模块 (ruoyi-mall-promotion)
|
||||
|
||||
## 模块简介
|
||||
|
||||
`ruoyi-mall-promotion` 是商城系统的营销中心模块,提供多样化的营销活动功能,包括活动、拼团、秒杀、砍价等。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 营销活动管理 ✅
|
||||
|
||||
- ✅ 活动CRUD操作
|
||||
- ✅ 活动类型管理(普通活动、拼团、秒杀、砍价)
|
||||
- ✅ 活动规则配置(JSON格式)
|
||||
- ✅ 活动时间管理
|
||||
- ✅ 活动状态管理(启用/禁用)
|
||||
- ✅ 活动导出功能
|
||||
|
||||
### 2. 拼团功能 ✅
|
||||
|
||||
- ✅ 拼团活动创建
|
||||
- ✅ 拼团活动查询(按SKU、可用列表)
|
||||
- ✅ 拼团活动状态管理
|
||||
- ⏳ 拼团订单管理(需在交易中心模块集成)
|
||||
- ⏳ 拼团成团处理(需在交易中心模块集成)
|
||||
- ⏳ 拼团过期处理(需定时任务支持)
|
||||
|
||||
### 3. 秒杀功能 ✅
|
||||
|
||||
- ✅ 秒杀活动创建
|
||||
- ✅ 秒杀库存管理(扣减、恢复)
|
||||
- ✅ 秒杀活动查询(按SKU、可用列表)
|
||||
- ✅ 秒杀活动状态管理
|
||||
- ✅ 秒杀活动状态自动更新(定时任务)
|
||||
|
||||
### 4. 砍价功能 ✅
|
||||
|
||||
- ✅ 砍价活动创建
|
||||
- ✅ 砍价活动查询(按SKU、可用列表)
|
||||
- ✅ 砍价活动状态管理
|
||||
- ⏳ 砍价记录管理(需在交易中心模块集成)
|
||||
- ⏳ 砍价助力记录(需在交易中心模块集成)
|
||||
- ⏳ 砍价订单处理(需在交易中心模块集成)
|
||||
|
||||
## 数据库表
|
||||
|
||||
- `mall_promotion` - 营销活动表
|
||||
- `mall_group_buy` - 拼团表
|
||||
- `mall_group_buy_order` - 拼团订单表
|
||||
- `mall_seckill` - 秒杀表
|
||||
- `mall_bargain` - 砍价活动表
|
||||
- `mall_bargain_record` - 砍价记录表
|
||||
- `mall_bargain_help` - 砍价助力记录表
|
||||
|
||||
详细表结构请参考:`script/sql/ry_mall.sql`
|
||||
|
||||
## 模块结构
|
||||
|
||||
```
|
||||
org.dromara.mall.promotion
|
||||
├── controller
|
||||
│ ├── admin // 管理端API
|
||||
│ └── app // 用户端API
|
||||
├── domain
|
||||
│ ├── bo // 业务对象
|
||||
│ └── vo // 视图对象
|
||||
├── mapper // MyBatis Mapper
|
||||
├── service // 业务逻辑层
|
||||
│ └── impl
|
||||
├── job // 定时任务
|
||||
│ └── MallPromotionJob.java
|
||||
├── enums // 枚举类
|
||||
└── config // 配置类
|
||||
```
|
||||
|
||||
## 依赖模块
|
||||
|
||||
- `ruoyi-mall-product` - 商品中心模块
|
||||
- `ruoyi-mall-coupon` - 优惠券中心模块
|
||||
- `ruoyi-common-*` - 通用工具模块
|
||||
|
||||
## API接口
|
||||
|
||||
### 管理端接口
|
||||
|
||||
#### 营销活动管理 (`/mall/promotion`)
|
||||
|
||||
- `GET /mall/promotion/list` - 查询营销活动列表(分页)
|
||||
- `GET /mall/promotion/{id}` - 获取营销活动详情
|
||||
- `POST /mall/promotion` - 新增营销活动
|
||||
- `PUT /mall/promotion` - 修改营销活动
|
||||
- `DELETE /mall/promotion/{ids}` - 删除营销活动
|
||||
- `POST /mall/promotion/export` - 导出营销活动列表
|
||||
- `PUT /mall/promotion/changeStatus/{id}` - 启用/禁用营销活动
|
||||
|
||||
### 移动端接口
|
||||
|
||||
#### 营销活动 (`/app/mall/promotion`)
|
||||
|
||||
- `GET /app/mall/promotion/list` - 查询营销活动列表(可按类型筛选)
|
||||
- `GET /app/mall/promotion/{id}` - 获取营销活动详情
|
||||
|
||||
#### 秒杀活动管理 (`/mall/seckill`)
|
||||
|
||||
- `GET /mall/seckill/list` - 查询秒杀活动列表(分页)
|
||||
- `GET /mall/seckill/{id}` - 获取秒杀活动详情
|
||||
- `POST /mall/seckill` - 新增秒杀活动
|
||||
- `PUT /mall/seckill` - 修改秒杀活动
|
||||
- `DELETE /mall/seckill/{ids}` - 删除秒杀活动
|
||||
- `POST /mall/seckill/export` - 导出秒杀活动列表
|
||||
- `PUT /mall/seckill/changeStatus/{id}` - 启用/禁用秒杀活动
|
||||
|
||||
#### 秒杀活动 (`/app/mall/seckill`)
|
||||
|
||||
- `GET /app/mall/seckill/list` - 查询可用秒杀活动列表
|
||||
- `GET /app/mall/seckill/{id}` - 获取秒杀活动详情
|
||||
- `GET /app/mall/seckill/sku/{skuId}` - 根据SKU ID查询秒杀活动
|
||||
|
||||
#### 拼团活动管理 (`/mall/groupbuy`)
|
||||
|
||||
- `GET /mall/groupbuy/list` - 查询拼团活动列表(分页)
|
||||
- `GET /mall/groupbuy/{id}` - 获取拼团活动详情
|
||||
- `POST /mall/groupbuy` - 新增拼团活动
|
||||
- `PUT /mall/groupbuy` - 修改拼团活动
|
||||
- `DELETE /mall/groupbuy/{ids}` - 删除拼团活动
|
||||
- `POST /mall/groupbuy/export` - 导出拼团活动列表
|
||||
- `PUT /mall/groupbuy/changeStatus/{id}` - 启用/禁用拼团活动
|
||||
|
||||
#### 拼团活动 (`/app/mall/groupbuy`)
|
||||
|
||||
- `GET /app/mall/groupbuy/list` - 查询可用拼团活动列表
|
||||
- `GET /app/mall/groupbuy/{id}` - 获取拼团活动详情
|
||||
- `GET /app/mall/groupbuy/sku/{skuId}` - 根据SKU ID查询拼团活动
|
||||
|
||||
#### 砍价活动管理 (`/mall/bargain`)
|
||||
|
||||
- `GET /mall/bargain/list` - 查询砍价活动列表(分页)
|
||||
- `GET /mall/bargain/{id}` - 获取砍价活动详情
|
||||
- `POST /mall/bargain` - 新增砍价活动
|
||||
- `PUT /mall/bargain` - 修改砍价活动
|
||||
- `DELETE /mall/bargain/{ids}` - 删除砍价活动
|
||||
- `POST /mall/bargain/export` - 导出砍价活动列表
|
||||
- `PUT /mall/bargain/changeStatus/{id}` - 启用/禁用砍价活动
|
||||
|
||||
#### 砍价活动 (`/app/mall/bargain`)
|
||||
|
||||
- `GET /app/mall/bargain/list` - 查询可用砍价活动列表
|
||||
- `GET /app/mall/bargain/{id}` - 获取砍价活动详情
|
||||
- `GET /app/mall/bargain/sku/{skuId}` - 根据SKU ID查询砍价活动
|
||||
|
||||
## 待实现功能
|
||||
|
||||
- [x] 营销活动管理功能 ✅
|
||||
- [x] 拼团功能 ✅(基础功能已完成,订单相关功能需在交易中心模块集成)
|
||||
- [x] 秒杀功能 ✅
|
||||
- [x] 砍价功能 ✅(基础功能已完成,记录和订单相关功能需在交易中心模块集成)
|
||||
- [ ] 活动统计功能
|
||||
- [ ] 拼团订单管理和成团处理(需在交易中心模块集成)
|
||||
- [ ] 砍价记录和助力记录管理(需在交易中心模块集成)
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 秒杀库存管理
|
||||
|
||||
秒杀库存使用独立的库存字段 `seckill_stock`,与商品SKU库存分离。在创建秒杀订单时,需要:
|
||||
|
||||
1. 调用 `reduceStock` 方法扣减秒杀库存
|
||||
2. 如果订单取消,调用 `restoreStock` 方法恢复秒杀库存
|
||||
3. 秒杀库存扣减失败表示库存不足,订单创建失败
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 秒杀库存管理
|
||||
|
||||
秒杀库存使用独立的库存字段 `seckill_stock`,与商品SKU库存分离。在创建秒杀订单时,需要:
|
||||
|
||||
1. 调用 `reduceStock` 方法扣减秒杀库存
|
||||
2. 如果订单取消,调用 `restoreStock` 方法恢复秒杀库存
|
||||
3. 秒杀库存扣减失败表示库存不足,订单创建失败
|
||||
|
||||
### 拼团活动管理
|
||||
|
||||
拼团活动配置包括:
|
||||
- `groupPrice`: 拼团价格(分)
|
||||
- `groupSize`: 成团人数(至少2人)
|
||||
- `durationHours`: 拼团有效期(小时,默认24小时)
|
||||
|
||||
注意:拼团功能只实现了活动管理,实际的拼团订单创建、成团处理等逻辑需要在交易中心模块(ruoyi-mall-trade)中集成。
|
||||
|
||||
### 砍价活动管理
|
||||
|
||||
砍价活动配置包括:
|
||||
- `originalPrice`: 原价(分)
|
||||
- `bargainPrice`: 砍后价(分)
|
||||
- `minPrice`: 最低价(分)
|
||||
- `helpCount`: 需要助力人数(可选,默认0)
|
||||
- `bargainStock`: 砍价库存
|
||||
- `durationHours`: 砍价有效期(小时,默认24小时)
|
||||
|
||||
价格校验规则:
|
||||
- 砍后价必须小于原价
|
||||
- 砍后价不能小于最低价
|
||||
- 最低价必须小于原价
|
||||
|
||||
注意:砍价功能只实现了活动管理,实际的砍价记录、助力记录、订单创建等逻辑需要在交易中心模块(ruoyi-mall-trade)中集成。
|
||||
@@ -0,0 +1,81 @@
|
||||
<?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-promotion</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-mall-promotion 营销中心模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-core</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-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-excel</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-mall-coupon</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package org.dromara.mall.promotion.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.promotion")
|
||||
@ConditionalOnProperty(prefix = "ruoyi.mall.promotion", name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class MallPromotionAutoConfiguration {
|
||||
|
||||
public MallPromotionAutoConfiguration() {
|
||||
log.info("营销中心模块已启用");
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.dromara.mall.promotion.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.promotion.domain.bo.MallBargainBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallBargainVo;
|
||||
import org.dromara.mall.promotion.service.MallBargainService;
|
||||
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/bargain")
|
||||
public class AdminMallBargainController extends BaseController {
|
||||
|
||||
private final MallBargainService mallBargainService;
|
||||
|
||||
/**
|
||||
* 查询砍价活动列表
|
||||
*/
|
||||
@Operation(summary = "查询砍价活动列表", description = "分页查询砍价活动列表")
|
||||
@SaCheckPermission("mall:bargain:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallBargainVo> list(@Parameter(description = "砍价活动查询条件") MallBargainBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallBargainService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出砍价活动列表
|
||||
*/
|
||||
@Operation(summary = "导出砍价活动列表", description = "导出砍价活动到Excel")
|
||||
@SaCheckPermission("mall:bargain:export")
|
||||
@Log(title = "砍价活动", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "砍价活动查询条件") MallBargainBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallBargainVo> list = mallBargainService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "砍价活动", MallBargainVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取砍价活动详细信息
|
||||
*/
|
||||
@Operation(summary = "获取砍价活动详情", description = "根据砍价活动ID获取详细信息")
|
||||
@SaCheckPermission("mall:bargain:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallBargainVo> getInfo(@Parameter(description = "砍价活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallBargainService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增砍价活动
|
||||
*/
|
||||
@Operation(summary = "新增砍价活动", description = "创建新的砍价活动")
|
||||
@SaCheckPermission("mall:bargain:add")
|
||||
@Log(title = "砍价活动", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "砍价活动信息") @Validated @RequestBody MallBargainBo bo) {
|
||||
return toAjax(mallBargainService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改砍价活动
|
||||
*/
|
||||
@Operation(summary = "修改砍价活动", description = "更新砍价活动信息")
|
||||
@SaCheckPermission("mall:bargain:edit")
|
||||
@Log(title = "砍价活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "砍价活动信息") @Validated @RequestBody MallBargainBo bo) {
|
||||
return toAjax(mallBargainService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除砍价活动
|
||||
*/
|
||||
@Operation(summary = "删除砍价活动", description = "删除砍价活动")
|
||||
@SaCheckPermission("mall:bargain:remove")
|
||||
@Log(title = "砍价活动", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "砍价活动ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallBargainService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用砍价活动
|
||||
*/
|
||||
@Operation(summary = "启用/禁用砍价活动", description = "更改砍价活动状态")
|
||||
@SaCheckPermission("mall:bargain:edit")
|
||||
@Log(title = "砍价活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus/{id}")
|
||||
public R<Void> changeStatus(@Parameter(description = "砍价活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "状态(0启用 1禁用)", required = true)
|
||||
@RequestParam @NotNull(message = "状态不能为空") Integer status) {
|
||||
return toAjax(mallBargainService.changeStatus(id, status));
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.dromara.mall.promotion.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.promotion.domain.bo.MallGroupBuyBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallGroupBuyVo;
|
||||
import org.dromara.mall.promotion.service.MallGroupBuyService;
|
||||
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/groupbuy")
|
||||
public class AdminMallGroupBuyController extends BaseController {
|
||||
|
||||
private final MallGroupBuyService mallGroupBuyService;
|
||||
|
||||
/**
|
||||
* 查询拼团活动列表
|
||||
*/
|
||||
@Operation(summary = "查询拼团活动列表", description = "分页查询拼团活动列表")
|
||||
@SaCheckPermission("mall:groupbuy:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallGroupBuyVo> list(@Parameter(description = "拼团活动查询条件") MallGroupBuyBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallGroupBuyService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出拼团活动列表
|
||||
*/
|
||||
@Operation(summary = "导出拼团活动列表", description = "导出拼团活动到Excel")
|
||||
@SaCheckPermission("mall:groupbuy:export")
|
||||
@Log(title = "拼团活动", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "拼团活动查询条件") MallGroupBuyBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallGroupBuyVo> list = mallGroupBuyService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "拼团活动", MallGroupBuyVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼团活动详细信息
|
||||
*/
|
||||
@Operation(summary = "获取拼团活动详情", description = "根据拼团活动ID获取详细信息")
|
||||
@SaCheckPermission("mall:groupbuy:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallGroupBuyVo> getInfo(@Parameter(description = "拼团活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallGroupBuyService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增拼团活动
|
||||
*/
|
||||
@Operation(summary = "新增拼团活动", description = "创建新的拼团活动")
|
||||
@SaCheckPermission("mall:groupbuy:add")
|
||||
@Log(title = "拼团活动", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "拼团活动信息") @Validated @RequestBody MallGroupBuyBo bo) {
|
||||
return toAjax(mallGroupBuyService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改拼团活动
|
||||
*/
|
||||
@Operation(summary = "修改拼团活动", description = "更新拼团活动信息")
|
||||
@SaCheckPermission("mall:groupbuy:edit")
|
||||
@Log(title = "拼团活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "拼团活动信息") @Validated @RequestBody MallGroupBuyBo bo) {
|
||||
return toAjax(mallGroupBuyService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除拼团活动
|
||||
*/
|
||||
@Operation(summary = "删除拼团活动", description = "删除拼团活动")
|
||||
@SaCheckPermission("mall:groupbuy:remove")
|
||||
@Log(title = "拼团活动", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "拼团活动ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallGroupBuyService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用拼团活动
|
||||
*/
|
||||
@Operation(summary = "启用/禁用拼团活动", description = "更改拼团活动状态")
|
||||
@SaCheckPermission("mall:groupbuy:edit")
|
||||
@Log(title = "拼团活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus/{id}")
|
||||
public R<Void> changeStatus(@Parameter(description = "拼团活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "状态(0启用 1禁用)", required = true)
|
||||
@RequestParam @NotNull(message = "状态不能为空") Integer status) {
|
||||
return toAjax(mallGroupBuyService.changeStatus(id, status));
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.dromara.mall.promotion.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.promotion.domain.bo.MallPromotionBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
import org.dromara.mall.promotion.service.MallPromotionService;
|
||||
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/promotion")
|
||||
public class AdminMallPromotionController extends BaseController {
|
||||
|
||||
private final MallPromotionService mallPromotionService;
|
||||
|
||||
/**
|
||||
* 查询营销活动列表
|
||||
*/
|
||||
@Operation(summary = "查询营销活动列表", description = "分页查询营销活动列表")
|
||||
@SaCheckPermission("mall:promotion:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallPromotionVo> list(@Parameter(description = "营销活动查询条件") MallPromotionBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallPromotionService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出营销活动列表
|
||||
*/
|
||||
@Operation(summary = "导出营销活动列表", description = "导出营销活动到Excel")
|
||||
@SaCheckPermission("mall:promotion:export")
|
||||
@Log(title = "营销活动", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "营销活动查询条件") MallPromotionBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallPromotionVo> list = mallPromotionService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "营销活动", MallPromotionVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销活动详细信息
|
||||
*/
|
||||
@Operation(summary = "获取营销活动详情", description = "根据营销活动ID获取详细信息")
|
||||
@SaCheckPermission("mall:promotion:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallPromotionVo> getInfo(@Parameter(description = "营销活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallPromotionService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增营销活动
|
||||
*/
|
||||
@Operation(summary = "新增营销活动", description = "创建新的营销活动")
|
||||
@SaCheckPermission("mall:promotion:add")
|
||||
@Log(title = "营销活动", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "营销活动信息") @Validated @RequestBody MallPromotionBo bo) {
|
||||
return toAjax(mallPromotionService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改营销活动
|
||||
*/
|
||||
@Operation(summary = "修改营销活动", description = "更新营销活动信息")
|
||||
@SaCheckPermission("mall:promotion:edit")
|
||||
@Log(title = "营销活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "营销活动信息") @Validated @RequestBody MallPromotionBo bo) {
|
||||
return toAjax(mallPromotionService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除营销活动
|
||||
*/
|
||||
@Operation(summary = "删除营销活动", description = "删除营销活动")
|
||||
@SaCheckPermission("mall:promotion:remove")
|
||||
@Log(title = "营销活动", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "营销活动ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallPromotionService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用营销活动
|
||||
*/
|
||||
@Operation(summary = "启用/禁用营销活动", description = "更改营销活动状态")
|
||||
@SaCheckPermission("mall:promotion:edit")
|
||||
@Log(title = "营销活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus/{id}")
|
||||
public R<Void> changeStatus(@Parameter(description = "营销活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "状态(0启用 1禁用)", required = true)
|
||||
@RequestParam @NotNull(message = "状态不能为空") Integer status) {
|
||||
return toAjax(mallPromotionService.changeStatus(id, status));
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.dromara.mall.promotion.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.promotion.domain.bo.MallSeckillBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
import org.dromara.mall.promotion.service.MallSeckillService;
|
||||
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/seckill")
|
||||
public class AdminMallSeckillController extends BaseController {
|
||||
|
||||
private final MallSeckillService mallSeckillService;
|
||||
|
||||
/**
|
||||
* 查询秒杀活动列表
|
||||
*/
|
||||
@Operation(summary = "查询秒杀活动列表", description = "分页查询秒杀活动列表")
|
||||
@SaCheckPermission("mall:seckill:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<MallSeckillVo> list(@Parameter(description = "秒杀活动查询条件") MallSeckillBo bo,
|
||||
@Parameter(description = "分页参数") PageQuery pageQuery) {
|
||||
return mallSeckillService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出秒杀活动列表
|
||||
*/
|
||||
@Operation(summary = "导出秒杀活动列表", description = "导出秒杀活动到Excel")
|
||||
@SaCheckPermission("mall:seckill:export")
|
||||
@Log(title = "秒杀活动", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Parameter(description = "秒杀活动查询条件") MallSeckillBo bo,
|
||||
@Parameter(description = "响应对象") HttpServletResponse response) {
|
||||
List<MallSeckillVo> list = mallSeckillService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "秒杀活动", MallSeckillVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒杀活动详细信息
|
||||
*/
|
||||
@Operation(summary = "获取秒杀活动详情", description = "根据秒杀活动ID获取详细信息")
|
||||
@SaCheckPermission("mall:seckill:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallSeckillVo> getInfo(@Parameter(description = "秒杀活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallSeckillService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增秒杀活动
|
||||
*/
|
||||
@Operation(summary = "新增秒杀活动", description = "创建新的秒杀活动")
|
||||
@SaCheckPermission("mall:seckill:add")
|
||||
@Log(title = "秒杀活动", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Parameter(description = "秒杀活动信息") @Validated @RequestBody MallSeckillBo bo) {
|
||||
return toAjax(mallSeckillService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改秒杀活动
|
||||
*/
|
||||
@Operation(summary = "修改秒杀活动", description = "更新秒杀活动信息")
|
||||
@SaCheckPermission("mall:seckill:edit")
|
||||
@Log(title = "秒杀活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Parameter(description = "秒杀活动信息") @Validated @RequestBody MallSeckillBo bo) {
|
||||
return toAjax(mallSeckillService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除秒杀活动
|
||||
*/
|
||||
@Operation(summary = "删除秒杀活动", description = "删除秒杀活动")
|
||||
@SaCheckPermission("mall:seckill:remove")
|
||||
@Log(title = "秒杀活动", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@Parameter(description = "秒杀活动ID数组", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(mallSeckillService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用秒杀活动
|
||||
*/
|
||||
@Operation(summary = "启用/禁用秒杀活动", description = "更改秒杀活动状态")
|
||||
@SaCheckPermission("mall:seckill:edit")
|
||||
@Log(title = "秒杀活动", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus/{id}")
|
||||
public R<Void> changeStatus(@Parameter(description = "秒杀活动ID", required = true)
|
||||
@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id,
|
||||
@Parameter(description = "状态(0启用 1禁用)", required = true)
|
||||
@RequestParam @NotNull(message = "状态不能为空") Integer status) {
|
||||
return toAjax(mallSeckillService.changeStatus(id, status));
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package org.dromara.mall.promotion.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 lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.promotion.domain.vo.MallBargainVo;
|
||||
import org.dromara.mall.promotion.service.MallBargainService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 砍价活动(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-砍价活动", description = "砍价活动接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/bargain")
|
||||
public class AppMallBargainController extends BaseController {
|
||||
|
||||
private final MallBargainService mallBargainService;
|
||||
|
||||
/**
|
||||
* 查询可用砍价活动列表
|
||||
*/
|
||||
@Operation(summary = "查询可用砍价活动列表", description = "查询当前可用的砍价活动列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<MallBargainVo>> list() {
|
||||
List<MallBargainVo> list = mallBargainService.queryAvailableList();
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取砍价活动详情
|
||||
*/
|
||||
@Operation(summary = "获取砍价活动详情", description = "根据砍价活动ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallBargainVo> getInfo(@Parameter(description = "砍价活动ID", required = true)
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallBargainService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询砍价活动
|
||||
*/
|
||||
@Operation(summary = "根据SKU ID查询砍价活动", description = "查询指定SKU的砍价活动")
|
||||
@GetMapping("/sku/{skuId}")
|
||||
public R<MallBargainVo> getBySkuId(@Parameter(description = "SKU ID", required = true)
|
||||
@PathVariable Long skuId) {
|
||||
MallBargainVo vo = mallBargainService.queryBySkuId(skuId);
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package org.dromara.mall.promotion.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 lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.promotion.domain.vo.MallGroupBuyVo;
|
||||
import org.dromara.mall.promotion.service.MallGroupBuyService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 拼团活动(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-拼团活动", description = "拼团活动接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/groupbuy")
|
||||
public class AppMallGroupBuyController extends BaseController {
|
||||
|
||||
private final MallGroupBuyService mallGroupBuyService;
|
||||
|
||||
/**
|
||||
* 查询可用拼团活动列表
|
||||
*/
|
||||
@Operation(summary = "查询可用拼团活动列表", description = "查询当前可用的拼团活动列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<MallGroupBuyVo>> list() {
|
||||
List<MallGroupBuyVo> list = mallGroupBuyService.queryAvailableList();
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼团活动详情
|
||||
*/
|
||||
@Operation(summary = "获取拼团活动详情", description = "根据拼团活动ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallGroupBuyVo> getInfo(@Parameter(description = "拼团活动ID", required = true)
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallGroupBuyService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询拼团活动
|
||||
*/
|
||||
@Operation(summary = "根据SKU ID查询拼团活动", description = "查询指定SKU的拼团活动")
|
||||
@GetMapping("/sku/{skuId}")
|
||||
public R<MallGroupBuyVo> getBySkuId(@Parameter(description = "SKU ID", required = true)
|
||||
@PathVariable Long skuId) {
|
||||
MallGroupBuyVo vo = mallGroupBuyService.queryBySkuId(skuId);
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package org.dromara.mall.promotion.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 lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.promotion.domain.bo.MallPromotionBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
import org.dromara.mall.promotion.service.MallPromotionService;
|
||||
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/promotion")
|
||||
public class AppMallPromotionController extends BaseController {
|
||||
|
||||
private final MallPromotionService mallPromotionService;
|
||||
|
||||
/**
|
||||
* 查询营销活动列表(按类型)
|
||||
*/
|
||||
@Operation(summary = "查询营销活动列表", description = "根据活动类型查询启用的营销活动列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<MallPromotionVo>> list(@Parameter(description = "活动类型(0普通活动 1拼团 2秒杀 3砍价)")
|
||||
@RequestParam(required = false) Integer type) {
|
||||
List<MallPromotionVo> list;
|
||||
if (type != null) {
|
||||
list = mallPromotionService.queryListByType(type);
|
||||
} else {
|
||||
list = mallPromotionService.queryList(new MallPromotionBo());
|
||||
}
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销活动详情
|
||||
*/
|
||||
@Operation(summary = "获取营销活动详情", description = "根据营销活动ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallPromotionVo> getInfo(@Parameter(description = "营销活动ID", required = true)
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallPromotionService.queryById(id));
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package org.dromara.mall.promotion.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 lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
import org.dromara.mall.promotion.service.MallSeckillService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀活动(移动端)
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Tag(name = "移动端-秒杀活动", description = "秒杀活动接口")
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/app/mall/seckill")
|
||||
public class AppMallSeckillController extends BaseController {
|
||||
|
||||
private final MallSeckillService mallSeckillService;
|
||||
|
||||
/**
|
||||
* 查询可用秒杀活动列表
|
||||
*/
|
||||
@Operation(summary = "查询可用秒杀活动列表", description = "查询当前可用的秒杀活动列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<MallSeckillVo>> list() {
|
||||
List<MallSeckillVo> list = mallSeckillService.queryAvailableList();
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒杀活动详情
|
||||
*/
|
||||
@Operation(summary = "获取秒杀活动详情", description = "根据秒杀活动ID获取详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public R<MallSeckillVo> getInfo(@Parameter(description = "秒杀活动ID", required = true)
|
||||
@PathVariable Long id) {
|
||||
return R.ok(mallSeckillService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询秒杀活动
|
||||
*/
|
||||
@Operation(summary = "根据SKU ID查询秒杀活动", description = "查询指定SKU的秒杀活动")
|
||||
@GetMapping("/sku/{skuId}")
|
||||
public R<MallSeckillVo> getBySkuId(@Parameter(description = "SKU ID", required = true)
|
||||
@PathVariable Long skuId) {
|
||||
MallSeckillVo vo = mallSeckillService.queryBySkuId(skuId);
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package org.dromara.mall.promotion.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_bargain
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_bargain")
|
||||
public class MallBargain implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 砍价ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 砍后价(分)
|
||||
*/
|
||||
private Integer bargainPrice;
|
||||
|
||||
/**
|
||||
* 原价(分)
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
|
||||
/**
|
||||
* 砍价库存
|
||||
*/
|
||||
private Integer bargainStock;
|
||||
|
||||
/**
|
||||
* 最低价(分)
|
||||
*/
|
||||
private Integer minPrice;
|
||||
|
||||
/**
|
||||
* 需要助力人数
|
||||
*/
|
||||
private Integer helpCount;
|
||||
|
||||
/**
|
||||
* 砍价有效期(小时)
|
||||
*/
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package org.dromara.mall.promotion.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_group_buy
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_group_buy")
|
||||
public class MallGroupBuy implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 拼团ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 拼团价(分)
|
||||
*/
|
||||
private Integer groupPrice;
|
||||
|
||||
/**
|
||||
* 成团人数
|
||||
*/
|
||||
private Integer groupSize;
|
||||
|
||||
/**
|
||||
* 拼团有效期(小时)
|
||||
*/
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package org.dromara.mall.promotion.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_group_buy_order
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_group_buy_order")
|
||||
public class MallGroupBuyOrder implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 拼团ID
|
||||
*/
|
||||
private Long groupBuyId;
|
||||
|
||||
/**
|
||||
* 拼团编号
|
||||
*/
|
||||
private String groupNo;
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 状态(0拼团中 1已成团 2已失败)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 成团时间
|
||||
*/
|
||||
private Date successTime;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package org.dromara.mall.promotion.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_promotion
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_promotion")
|
||||
public class MallPromotion implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 活动类型(0普通活动 1拼团 2秒杀 3砍价)
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 活动规则(JSON)
|
||||
*/
|
||||
private String rules;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package org.dromara.mall.promotion.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_seckill
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@TableName("mall_seckill")
|
||||
public class MallSeckill implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 秒杀ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 秒杀价(分)
|
||||
*/
|
||||
private Integer seckillPrice;
|
||||
|
||||
/**
|
||||
* 秒杀库存
|
||||
*/
|
||||
private Integer seckillStock;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package org.dromara.mall.promotion.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.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.promotion.domain.MallBargain;
|
||||
|
||||
/**
|
||||
* 砍价活动业务对象 mall_bargain
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallBargain.class, reverseConvertGenerate = false)
|
||||
public class MallBargainBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 砍价ID
|
||||
*/
|
||||
@NotNull(message = "砍价ID不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@NotNull(message = "活动ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@NotNull(message = "SKU ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 砍后价(分)
|
||||
*/
|
||||
@NotNull(message = "砍后价不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "砍后价必须大于0")
|
||||
private Integer bargainPrice;
|
||||
|
||||
/**
|
||||
* 原价(分)
|
||||
*/
|
||||
@NotNull(message = "原价不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "原价必须大于0")
|
||||
private Integer originalPrice;
|
||||
|
||||
/**
|
||||
* 砍价库存
|
||||
*/
|
||||
@NotNull(message = "砍价库存不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "砍价库存必须大于0")
|
||||
private Integer bargainStock;
|
||||
|
||||
/**
|
||||
* 最低价(分)
|
||||
*/
|
||||
@NotNull(message = "最低价不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "最低价必须大于0")
|
||||
private Integer minPrice;
|
||||
|
||||
/**
|
||||
* 需要助力人数
|
||||
*/
|
||||
@Min(value = 0, message = "需要助力人数不能为负数")
|
||||
private Integer helpCount;
|
||||
|
||||
/**
|
||||
* 砍价有效期(小时)
|
||||
*/
|
||||
@Min(value = 1, message = "砍价有效期必须大于0")
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package org.dromara.mall.promotion.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.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.promotion.domain.MallGroupBuy;
|
||||
|
||||
/**
|
||||
* 拼团活动业务对象 mall_group_buy
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallGroupBuy.class, reverseConvertGenerate = false)
|
||||
public class MallGroupBuyBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 拼团ID
|
||||
*/
|
||||
@NotNull(message = "拼团ID不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@NotNull(message = "活动ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@NotNull(message = "SKU ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 拼团价(分)
|
||||
*/
|
||||
@NotNull(message = "拼团价不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "拼团价必须大于0")
|
||||
private Integer groupPrice;
|
||||
|
||||
/**
|
||||
* 成团人数
|
||||
*/
|
||||
@NotNull(message = "成团人数不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 2, message = "成团人数至少为2人")
|
||||
private Integer groupSize;
|
||||
|
||||
/**
|
||||
* 拼团有效期(小时)
|
||||
*/
|
||||
@Min(value = 1, message = "拼团有效期必须大于0")
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package org.dromara.mall.promotion.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.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 营销活动业务对象 mall_promotion
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallPromotion.class, reverseConvertGenerate = false)
|
||||
public class MallPromotionBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@NotNull(message = "活动ID不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
@NotBlank(message = "活动名称不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Size(max = 128, message = "活动名称长度不能超过128个字符")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 活动类型(0普通活动 1拼团 2秒杀 3砍价)
|
||||
*/
|
||||
@NotNull(message = "活动类型不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@NotNull(message = "开始时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@NotNull(message = "结束时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 活动规则(JSON)
|
||||
*/
|
||||
private String rules;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Size(max = 512, message = "备注长度不能超过512个字符")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package org.dromara.mall.promotion.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.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.mall.promotion.domain.MallSeckill;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 秒杀活动业务对象 mall_seckill
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = MallSeckill.class, reverseConvertGenerate = false)
|
||||
public class MallSeckillBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 秒杀ID
|
||||
*/
|
||||
@NotNull(message = "秒杀ID不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@NotNull(message = "活动ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@NotNull(message = "SKU ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 秒杀价(分)
|
||||
*/
|
||||
@NotNull(message = "秒杀价不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "秒杀价必须大于0")
|
||||
private Integer seckillPrice;
|
||||
|
||||
/**
|
||||
* 秒杀库存
|
||||
*/
|
||||
@NotNull(message = "秒杀库存不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
@Min(value = 1, message = "秒杀库存必须大于0")
|
||||
private Integer seckillStock;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@NotNull(message = "开始时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@NotNull(message = "结束时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package org.dromara.mall.promotion.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.promotion.domain.MallBargain;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 砍价活动视图对象 mall_bargain
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = MallBargain.class)
|
||||
public class MallBargainVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 砍价ID
|
||||
*/
|
||||
@ExcelProperty(value = "砍价ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@ExcelProperty(value = "活动ID")
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@ExcelProperty(value = "SKU ID")
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 砍后价(分)
|
||||
*/
|
||||
@ExcelProperty(value = "砍后价(分)")
|
||||
private Integer bargainPrice;
|
||||
|
||||
/**
|
||||
* 原价(分)
|
||||
*/
|
||||
@ExcelProperty(value = "原价(分)")
|
||||
private Integer originalPrice;
|
||||
|
||||
/**
|
||||
* 砍价库存
|
||||
*/
|
||||
@ExcelProperty(value = "砍价库存")
|
||||
private Integer bargainStock;
|
||||
|
||||
/**
|
||||
* 最低价(分)
|
||||
*/
|
||||
@ExcelProperty(value = "最低价(分)")
|
||||
private Integer minPrice;
|
||||
|
||||
/**
|
||||
* 需要助力人数
|
||||
*/
|
||||
@ExcelProperty(value = "需要助力人数")
|
||||
private Integer helpCount;
|
||||
|
||||
/**
|
||||
* 砍价有效期(小时)
|
||||
*/
|
||||
@ExcelProperty(value = "砍价有效期(小时)")
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package org.dromara.mall.promotion.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.promotion.domain.MallGroupBuy;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 拼团活动视图对象 mall_group_buy
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = MallGroupBuy.class)
|
||||
public class MallGroupBuyVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 拼团ID
|
||||
*/
|
||||
@ExcelProperty(value = "拼团ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@ExcelProperty(value = "活动ID")
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@ExcelProperty(value = "SKU ID")
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 拼团价(分)
|
||||
*/
|
||||
@ExcelProperty(value = "拼团价(分)")
|
||||
private Integer groupPrice;
|
||||
|
||||
/**
|
||||
* 成团人数
|
||||
*/
|
||||
@ExcelProperty(value = "成团人数")
|
||||
private Integer groupSize;
|
||||
|
||||
/**
|
||||
* 拼团有效期(小时)
|
||||
*/
|
||||
@ExcelProperty(value = "拼团有效期(小时)")
|
||||
private Integer durationHours;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package org.dromara.mall.promotion.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 营销活动视图对象 mall_promotion
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = MallPromotion.class)
|
||||
public class MallPromotionVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@ExcelProperty(value = "活动ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动名称
|
||||
*/
|
||||
@ExcelProperty(value = "活动名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 活动类型(0普通活动 1拼团 2秒杀 3砍价)
|
||||
*/
|
||||
@ExcelProperty(value = "活动类型")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "开始时间")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "结束时间")
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 活动规则(JSON)
|
||||
*/
|
||||
@ExcelProperty(value = "活动规则")
|
||||
private String rules;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package org.dromara.mall.promotion.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.mall.promotion.domain.MallSeckill;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 秒杀活动视图对象 mall_seckill
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = MallSeckill.class)
|
||||
public class MallSeckillVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 秒杀ID
|
||||
*/
|
||||
@ExcelProperty(value = "秒杀ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@ExcelProperty(value = "活动ID")
|
||||
private Long promotionId;
|
||||
|
||||
/**
|
||||
* SKU ID
|
||||
*/
|
||||
@ExcelProperty(value = "SKU ID")
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 秒杀价(分)
|
||||
*/
|
||||
@ExcelProperty(value = "秒杀价(分)")
|
||||
private Integer seckillPrice;
|
||||
|
||||
/**
|
||||
* 秒杀库存
|
||||
*/
|
||||
@ExcelProperty(value = "秒杀库存")
|
||||
private Integer seckillStock;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "开始时间")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "结束时间")
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 状态(0启用 1禁用)
|
||||
*/
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package org.dromara.mall.promotion.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 营销活动类型枚举
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PromotionType {
|
||||
|
||||
/**
|
||||
* 普通活动
|
||||
*/
|
||||
NORMAL(0, "普通活动"),
|
||||
|
||||
/**
|
||||
* 拼团活动
|
||||
*/
|
||||
GROUP_BUY(1, "拼团活动"),
|
||||
|
||||
/**
|
||||
* 秒杀活动
|
||||
*/
|
||||
SECKILL(2, "秒杀活动"),
|
||||
|
||||
/**
|
||||
* 砍价活动
|
||||
*/
|
||||
BARGAIN(3, "砍价活动");
|
||||
|
||||
/**
|
||||
* 类型值
|
||||
*/
|
||||
private final Integer value;
|
||||
|
||||
/**
|
||||
* 类型名称
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* 根据值获取枚举
|
||||
*/
|
||||
public static PromotionType getByValue(Integer value) {
|
||||
for (PromotionType type : values()) {
|
||||
if (type.getValue().equals(value)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package org.dromara.mall.promotion.job;
|
||||
|
||||
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.mall.promotion.domain.MallSeckill;
|
||||
import org.dromara.mall.promotion.mapper.MallSeckillMapper;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 营销活动定时任务
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class MallPromotionJob {
|
||||
|
||||
private final MallSeckillMapper seckillMapper;
|
||||
|
||||
/**
|
||||
* 秒杀活动状态更新任务
|
||||
* 每5分钟执行一次
|
||||
* - 扫描即将开始的活动(start_time <= 当前时间 且 status=1禁用),自动启用(status=0)
|
||||
* - 扫描已结束的活动(end_time < 当前时间 且 status=0启用),自动禁用(status=1)
|
||||
*/
|
||||
@Scheduled(cron = "0 0/5 * * * ?")
|
||||
public void updateSeckillStatus() {
|
||||
Date now = new Date();
|
||||
int updatedCount = 0;
|
||||
|
||||
// 扫描即将开始的活动(start_time <= 当前时间 且 status=1禁用),自动启用
|
||||
LambdaQueryWrapper<MallSeckill> startWrapper = new LambdaQueryWrapper<>();
|
||||
startWrapper.le(MallSeckill::getStartTime, now);
|
||||
startWrapper.gt(MallSeckill::getEndTime, now); // 还未结束
|
||||
startWrapper.eq(MallSeckill::getStatus, 1); // 当前状态为禁用
|
||||
List<MallSeckill> toStart = seckillMapper.selectList(startWrapper);
|
||||
|
||||
if (!toStart.isEmpty()) {
|
||||
for (MallSeckill seckill : toStart) {
|
||||
LambdaUpdateWrapper<MallSeckill> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(MallSeckill::getId, seckill.getId());
|
||||
updateWrapper.set(MallSeckill::getStatus, 0); // 启用
|
||||
seckillMapper.update(null, updateWrapper);
|
||||
updatedCount++;
|
||||
log.info("秒杀活动自动启用: id={}, promotionId={}", seckill.getId(), seckill.getPromotionId());
|
||||
}
|
||||
}
|
||||
|
||||
// 扫描已结束的活动(end_time < 当前时间 且 status=0启用),自动禁用
|
||||
LambdaQueryWrapper<MallSeckill> endWrapper = new LambdaQueryWrapper<>();
|
||||
endWrapper.lt(MallSeckill::getEndTime, now);
|
||||
endWrapper.eq(MallSeckill::getStatus, 0); // 当前状态为启用
|
||||
List<MallSeckill> toEnd = seckillMapper.selectList(endWrapper);
|
||||
|
||||
if (!toEnd.isEmpty()) {
|
||||
for (MallSeckill seckill : toEnd) {
|
||||
LambdaUpdateWrapper<MallSeckill> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(MallSeckill::getId, seckill.getId());
|
||||
updateWrapper.set(MallSeckill::getStatus, 1); // 禁用
|
||||
seckillMapper.update(null, updateWrapper);
|
||||
updatedCount++;
|
||||
log.info("秒杀活动自动禁用: id={}, promotionId={}", seckill.getId(), seckill.getPromotionId());
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedCount > 0) {
|
||||
log.info("秒杀活动状态更新完成,共更新{}个活动", updatedCount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.promotion.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.promotion.domain.MallBargain;
|
||||
import org.dromara.mall.promotion.domain.vo.MallBargainVo;
|
||||
|
||||
/**
|
||||
* 砍价活动Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallBargainMapper extends BaseMapperPlus<MallBargain, MallBargainVo> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.promotion.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.promotion.domain.MallGroupBuy;
|
||||
import org.dromara.mall.promotion.domain.vo.MallGroupBuyVo;
|
||||
|
||||
/**
|
||||
* 拼团活动Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallGroupBuyMapper extends BaseMapperPlus<MallGroupBuy, MallGroupBuyVo> {
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.dromara.mall.promotion.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
|
||||
/**
|
||||
* 营销活动Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallPromotionMapper extends BaseMapperPlus<MallPromotion, MallPromotionVo> {
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package org.dromara.mall.promotion.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.mall.promotion.domain.MallSeckill;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
|
||||
/**
|
||||
* 秒杀活动Mapper接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
@Mapper
|
||||
public interface MallSeckillMapper extends BaseMapperPlus<MallSeckill, MallSeckillVo> {
|
||||
|
||||
/**
|
||||
* 扣减秒杀库存
|
||||
*
|
||||
* @param id 秒杀ID
|
||||
* @param quantity 扣减数量
|
||||
* @return 影响行数
|
||||
*/
|
||||
int reduceStock(@Param("id") Long id, @Param("quantity") Integer quantity);
|
||||
|
||||
/**
|
||||
* 恢复秒杀库存
|
||||
*
|
||||
* @param id 秒杀ID
|
||||
* @param quantity 恢复数量
|
||||
* @return 影响行数
|
||||
*/
|
||||
int restoreStock(@Param("id") Long id, @Param("quantity") Integer quantity);
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.dromara.mall.promotion.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.bo.MallBargainBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallBargainVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 砍价活动Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallBargainService {
|
||||
|
||||
/**
|
||||
* 查询砍价活动
|
||||
*/
|
||||
MallBargainVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询砍价活动列表
|
||||
*/
|
||||
TableDataInfo<MallBargainVo> queryPageList(MallBargainBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询砍价活动列表
|
||||
*/
|
||||
List<MallBargainVo> queryList(MallBargainBo bo);
|
||||
|
||||
/**
|
||||
* 查询可用的砍价活动列表(移动端)
|
||||
*/
|
||||
List<MallBargainVo> queryAvailableList();
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询砍价活动
|
||||
*/
|
||||
MallBargainVo queryBySkuId(Long skuId);
|
||||
|
||||
/**
|
||||
* 新增砍价活动
|
||||
*/
|
||||
Boolean insertByBo(MallBargainBo bo);
|
||||
|
||||
/**
|
||||
* 修改砍价活动
|
||||
*/
|
||||
Boolean updateByBo(MallBargainBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除砍价活动信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 启用/禁用砍价活动
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.dromara.mall.promotion.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.bo.MallGroupBuyBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallGroupBuyVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 拼团活动Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallGroupBuyService {
|
||||
|
||||
/**
|
||||
* 查询拼团活动
|
||||
*/
|
||||
MallGroupBuyVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询拼团活动列表
|
||||
*/
|
||||
TableDataInfo<MallGroupBuyVo> queryPageList(MallGroupBuyBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询拼团活动列表
|
||||
*/
|
||||
List<MallGroupBuyVo> queryList(MallGroupBuyBo bo);
|
||||
|
||||
/**
|
||||
* 查询可用的拼团活动列表(移动端)
|
||||
*/
|
||||
List<MallGroupBuyVo> queryAvailableList();
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询拼团活动
|
||||
*/
|
||||
MallGroupBuyVo queryBySkuId(Long skuId);
|
||||
|
||||
/**
|
||||
* 新增拼团活动
|
||||
*/
|
||||
Boolean insertByBo(MallGroupBuyBo bo);
|
||||
|
||||
/**
|
||||
* 修改拼团活动
|
||||
*/
|
||||
Boolean updateByBo(MallGroupBuyBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除拼团活动信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 启用/禁用拼团活动
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package org.dromara.mall.promotion.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
import org.dromara.mall.promotion.domain.bo.MallPromotionBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 营销活动Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallPromotionService extends IService<MallPromotion> {
|
||||
|
||||
/**
|
||||
* 查询营销活动
|
||||
*/
|
||||
MallPromotionVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询营销活动列表
|
||||
*/
|
||||
TableDataInfo<MallPromotionVo> queryPageList(MallPromotionBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询营销活动列表
|
||||
*/
|
||||
List<MallPromotionVo> queryList(MallPromotionBo bo);
|
||||
|
||||
/**
|
||||
* 新增营销活动
|
||||
*/
|
||||
Boolean insertByBo(MallPromotionBo bo);
|
||||
|
||||
/**
|
||||
* 修改营销活动
|
||||
*/
|
||||
Boolean updateByBo(MallPromotionBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除营销活动信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 启用/禁用营销活动
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 根据活动类型查询活动列表
|
||||
*/
|
||||
List<MallPromotionVo> queryListByType(Integer type);
|
||||
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package org.dromara.mall.promotion.service;
|
||||
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.bo.MallSeckillBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 秒杀活动Service接口
|
||||
*
|
||||
* @author pengles
|
||||
*/
|
||||
public interface MallSeckillService {
|
||||
|
||||
/**
|
||||
* 查询秒杀活动
|
||||
*/
|
||||
MallSeckillVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询秒杀活动列表
|
||||
*/
|
||||
TableDataInfo<MallSeckillVo> queryPageList(MallSeckillBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询秒杀活动列表
|
||||
*/
|
||||
List<MallSeckillVo> queryList(MallSeckillBo bo);
|
||||
|
||||
/**
|
||||
* 查询可用的秒杀活动列表(移动端)
|
||||
*/
|
||||
List<MallSeckillVo> queryAvailableList();
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询秒杀活动
|
||||
*/
|
||||
MallSeckillVo queryBySkuId(Long skuId);
|
||||
|
||||
/**
|
||||
* 新增秒杀活动
|
||||
*/
|
||||
Boolean insertByBo(MallSeckillBo bo);
|
||||
|
||||
/**
|
||||
* 修改秒杀活动
|
||||
*/
|
||||
Boolean updateByBo(MallSeckillBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除秒杀活动信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 启用/禁用秒杀活动
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 扣减秒杀库存
|
||||
*
|
||||
* @param id 秒杀ID
|
||||
* @param quantity 扣减数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean reduceStock(Long id, Integer quantity);
|
||||
|
||||
/**
|
||||
* 恢复秒杀库存
|
||||
*
|
||||
* @param id 秒杀ID
|
||||
* @param quantity 恢复数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean restoreStock(Long id, Integer quantity);
|
||||
|
||||
/**
|
||||
* 检查秒杀活动是否可用
|
||||
*
|
||||
* @param id 秒杀ID
|
||||
* @return 是否可用
|
||||
*/
|
||||
Boolean checkAvailable(Long id);
|
||||
|
||||
}
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
package org.dromara.mall.promotion.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.MallBargain;
|
||||
import org.dromara.mall.promotion.domain.MallPromotion;
|
||||
import org.dromara.mall.promotion.domain.bo.MallBargainBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallBargainVo;
|
||||
import org.dromara.mall.promotion.mapper.MallBargainMapper;
|
||||
import org.dromara.mall.promotion.mapper.MallPromotionMapper;
|
||||
import org.dromara.mall.promotion.service.MallBargainService;
|
||||
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 MallBargainServiceImpl extends ServiceImpl<MallBargainMapper, MallBargain> implements MallBargainService {
|
||||
|
||||
private final MallBargainMapper baseMapper;
|
||||
private final MallPromotionMapper promotionMapper;
|
||||
|
||||
/**
|
||||
* 查询砍价活动
|
||||
*/
|
||||
@Override
|
||||
public MallBargainVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询砍价活动列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallBargainVo> queryPageList(MallBargainBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallBargain> lqw = buildQueryWrapper(bo);
|
||||
Page<MallBargainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询砍价活动列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallBargainVo> queryList(MallBargainBo bo) {
|
||||
LambdaQueryWrapper<MallBargain> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallBargain> buildQueryWrapper(MallBargainBo bo) {
|
||||
LambdaQueryWrapper<MallBargain> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getPromotionId() != null, MallBargain::getPromotionId, bo.getPromotionId());
|
||||
lqw.eq(bo.getSkuId() != null, MallBargain::getSkuId, bo.getSkuId());
|
||||
lqw.eq(bo.getStatus() != null, MallBargain::getStatus, bo.getStatus());
|
||||
lqw.orderByDesc(MallBargain::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可用的砍价活动列表(移动端)
|
||||
*/
|
||||
@Override
|
||||
public List<MallBargainVo> queryAvailableList() {
|
||||
LambdaQueryWrapper<MallBargain> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallBargain::getStatus, 0); // 启用状态
|
||||
lqw.gt(MallBargain::getBargainStock, 0); // 有库存
|
||||
lqw.orderByDesc(MallBargain::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询砍价活动
|
||||
*/
|
||||
@Override
|
||||
public MallBargainVo queryBySkuId(Long skuId) {
|
||||
LambdaQueryWrapper<MallBargain> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallBargain::getSkuId, skuId);
|
||||
lqw.eq(MallBargain::getStatus, 0); // 启用状态
|
||||
lqw.gt(MallBargain::getBargainStock, 0); // 有库存
|
||||
lqw.orderByDesc(MallBargain::getCreateTime);
|
||||
lqw.last("LIMIT 1");
|
||||
return baseMapper.selectVoOne(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增砍价活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallBargainBo bo) {
|
||||
MallBargain add = MapstructUtils.convert(bo, MallBargain.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置默认值
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0); // 默认启用
|
||||
}
|
||||
if (add.getDurationHours() == null) {
|
||||
add.setDurationHours(24); // 默认24小时
|
||||
}
|
||||
if (add.getHelpCount() == null) {
|
||||
add.setHelpCount(0); // 默认0人
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改砍价活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallBargainBo bo) {
|
||||
MallBargain update = MapstructUtils.convert(bo, MallBargain.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallBargain entity) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查活动是否存在、SKU是否存在等
|
||||
if (entity.getOriginalPrice() != null && entity.getBargainPrice() != null) {
|
||||
if (entity.getBargainPrice() >= entity.getOriginalPrice()) {
|
||||
throw new ServiceException("砍后价必须小于原价");
|
||||
}
|
||||
}
|
||||
if (entity.getMinPrice() != null && entity.getBargainPrice() != null) {
|
||||
if (entity.getBargainPrice() < entity.getMinPrice()) {
|
||||
throw new ServiceException("砍后价不能小于最低价");
|
||||
}
|
||||
}
|
||||
if (entity.getMinPrice() != null && entity.getOriginalPrice() != null) {
|
||||
if (entity.getMinPrice() >= entity.getOriginalPrice()) {
|
||||
throw new ServiceException("最低价必须小于原价");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除砍价活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
Date now = new Date();
|
||||
for (Long id : ids) {
|
||||
MallBargain bargain = baseMapper.selectById(id);
|
||||
if (bargain == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查关联的营销活动是否正在进行中
|
||||
if (bargain.getPromotionId() != null) {
|
||||
MallPromotion promotion = promotionMapper.selectById(bargain.getPromotionId());
|
||||
if (promotion != null && promotion.getStartTime() != null && promotion.getEndTime() != null) {
|
||||
// 判断当前时间是否在活动时间范围内(开始时间 <= 当前时间 <= 结束时间)
|
||||
if (!promotion.getStartTime().after(now) && !promotion.getEndTime().before(now)) {
|
||||
throw new ServiceException("砍价活动ID[" + id + "]关联的营销活动正在进行中,不能删除");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:如果有砍价记录表(mall_bargain_record),还可以检查是否有进行中的砍价记录(status=0)
|
||||
// 但由于当前模块中可能还未实现MallBargainRecordMapper,此处暂不添加该检查
|
||||
// 如需添加,可注入MallBargainRecordMapper,然后查询count(bargain_id=? AND status=0) > 0
|
||||
}
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用砍价活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
MallBargain bargain = baseMapper.selectById(id);
|
||||
if (bargain == null) {
|
||||
throw new ServiceException("砍价活动不存在");
|
||||
}
|
||||
|
||||
MallBargain update = new MallBargain();
|
||||
update.setId(id);
|
||||
update.setStatus(status);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
package org.dromara.mall.promotion.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.MallGroupBuy;
|
||||
import org.dromara.mall.promotion.domain.bo.MallGroupBuyBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallGroupBuyVo;
|
||||
import org.dromara.mall.promotion.mapper.MallGroupBuyMapper;
|
||||
import org.dromara.mall.promotion.service.MallGroupBuyService;
|
||||
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 MallGroupBuyServiceImpl extends ServiceImpl<MallGroupBuyMapper, MallGroupBuy> implements MallGroupBuyService {
|
||||
|
||||
private final MallGroupBuyMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询拼团活动
|
||||
*/
|
||||
@Override
|
||||
public MallGroupBuyVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询拼团活动列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallGroupBuyVo> queryPageList(MallGroupBuyBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallGroupBuy> lqw = buildQueryWrapper(bo);
|
||||
Page<MallGroupBuyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询拼团活动列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallGroupBuyVo> queryList(MallGroupBuyBo bo) {
|
||||
LambdaQueryWrapper<MallGroupBuy> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallGroupBuy> buildQueryWrapper(MallGroupBuyBo bo) {
|
||||
LambdaQueryWrapper<MallGroupBuy> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getPromotionId() != null, MallGroupBuy::getPromotionId, bo.getPromotionId());
|
||||
lqw.eq(bo.getSkuId() != null, MallGroupBuy::getSkuId, bo.getSkuId());
|
||||
lqw.eq(bo.getStatus() != null, MallGroupBuy::getStatus, bo.getStatus());
|
||||
lqw.orderByDesc(MallGroupBuy::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可用的拼团活动列表(移动端)
|
||||
*/
|
||||
@Override
|
||||
public List<MallGroupBuyVo> queryAvailableList() {
|
||||
LambdaQueryWrapper<MallGroupBuy> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallGroupBuy::getStatus, 0); // 启用状态
|
||||
lqw.orderByDesc(MallGroupBuy::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询拼团活动
|
||||
*/
|
||||
@Override
|
||||
public MallGroupBuyVo queryBySkuId(Long skuId) {
|
||||
LambdaQueryWrapper<MallGroupBuy> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallGroupBuy::getSkuId, skuId);
|
||||
lqw.eq(MallGroupBuy::getStatus, 0); // 启用状态
|
||||
lqw.orderByDesc(MallGroupBuy::getCreateTime);
|
||||
lqw.last("LIMIT 1");
|
||||
return baseMapper.selectVoOne(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增拼团活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallGroupBuyBo bo) {
|
||||
MallGroupBuy add = MapstructUtils.convert(bo, MallGroupBuy.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置默认值
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0); // 默认启用
|
||||
}
|
||||
if (add.getDurationHours() == null) {
|
||||
add.setDurationHours(24); // 默认24小时
|
||||
}
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改拼团活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallGroupBuyBo bo) {
|
||||
MallGroupBuy update = MapstructUtils.convert(bo, MallGroupBuy.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallGroupBuy entity) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查活动是否存在、SKU是否存在等
|
||||
if (entity.getGroupSize() != null && entity.getGroupSize() < 2) {
|
||||
throw new ServiceException("成团人数至少为2人");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除拼团活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查是否有进行中的拼团活动等
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用拼团活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
MallGroupBuy groupBuy = baseMapper.selectById(id);
|
||||
if (groupBuy == null) {
|
||||
throw new ServiceException("拼团活动不存在");
|
||||
}
|
||||
|
||||
MallGroupBuy update = new MallGroupBuy();
|
||||
update.setId(id);
|
||||
update.setStatus(status);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
package org.dromara.mall.promotion.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
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.mall.promotion.domain.MallPromotion;
|
||||
import org.dromara.mall.promotion.domain.bo.MallPromotionBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallPromotionVo;
|
||||
import org.dromara.mall.promotion.mapper.MallPromotionMapper;
|
||||
import org.dromara.mall.promotion.service.MallPromotionService;
|
||||
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
|
||||
*/
|
||||
@Service
|
||||
public class MallPromotionServiceImpl extends ServiceImpl<MallPromotionMapper, MallPromotion> implements MallPromotionService {
|
||||
|
||||
/**
|
||||
* 查询营销活动
|
||||
*/
|
||||
@Override
|
||||
public MallPromotionVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询营销活动列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallPromotionVo> queryPageList(MallPromotionBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallPromotion> lqw = buildQueryWrapper(bo);
|
||||
Page<MallPromotionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询营销活动列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallPromotionVo> queryList(MallPromotionBo bo) {
|
||||
LambdaQueryWrapper<MallPromotion> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallPromotion> buildQueryWrapper(MallPromotionBo bo) {
|
||||
LambdaQueryWrapper<MallPromotion> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getName()), MallPromotion::getName, bo.getName());
|
||||
lqw.eq(bo.getType() != null, MallPromotion::getType, bo.getType());
|
||||
lqw.eq(bo.getStatus() != null, MallPromotion::getStatus, bo.getStatus());
|
||||
lqw.ge(bo.getStartTime() != null, MallPromotion::getStartTime, bo.getStartTime());
|
||||
lqw.le(bo.getEndTime() != null, MallPromotion::getEndTime, bo.getEndTime());
|
||||
lqw.orderByDesc(MallPromotion::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增营销活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallPromotionBo bo) {
|
||||
MallPromotion add = MapstructUtils.convert(bo, MallPromotion.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置默认状态
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0); // 默认启用
|
||||
}
|
||||
|
||||
// 校验时间
|
||||
validateTimeRange(add.getStartTime(), add.getEndTime());
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改营销活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallPromotionBo bo) {
|
||||
MallPromotion update = MapstructUtils.convert(bo, MallPromotion.class);
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
// 校验时间
|
||||
if (update.getStartTime() != null && update.getEndTime() != null) {
|
||||
validateTimeRange(update.getStartTime(), update.getEndTime());
|
||||
}
|
||||
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallPromotion entity) {
|
||||
// TODO: 可以添加业务校验逻辑,如活动类型校验等
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验时间范围
|
||||
*/
|
||||
private void validateTimeRange(Date startTime, Date endTime) {
|
||||
if (startTime != null && endTime != null) {
|
||||
if (startTime.after(endTime)) {
|
||||
throw new ServiceException("开始时间不能晚于结束时间");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除营销活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查是否有进行中的活动等
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用营销活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
MallPromotion promotion = baseMapper.selectById(id);
|
||||
if (promotion == null) {
|
||||
throw new ServiceException("营销活动不存在");
|
||||
}
|
||||
|
||||
MallPromotion update = new MallPromotion();
|
||||
update.setId(id);
|
||||
update.setStatus(status);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据活动类型查询活动列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallPromotionVo> queryListByType(Integer type) {
|
||||
LambdaQueryWrapper<MallPromotion> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallPromotion::getType, type);
|
||||
lqw.eq(MallPromotion::getStatus, 0); // 只查询启用的活动
|
||||
Date now = new Date();
|
||||
lqw.le(MallPromotion::getStartTime, now); // 开始时间已到
|
||||
lqw.ge(MallPromotion::getEndTime, now); // 结束时间未到
|
||||
lqw.orderByDesc(MallPromotion::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
}
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
package org.dromara.mall.promotion.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
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.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.mall.promotion.domain.MallSeckill;
|
||||
import org.dromara.mall.promotion.domain.bo.MallSeckillBo;
|
||||
import org.dromara.mall.promotion.domain.vo.MallSeckillVo;
|
||||
import org.dromara.mall.promotion.mapper.MallSeckillMapper;
|
||||
import org.dromara.mall.promotion.service.MallSeckillService;
|
||||
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 MallSeckillServiceImpl implements MallSeckillService {
|
||||
|
||||
private final MallSeckillMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询秒杀活动
|
||||
*/
|
||||
@Override
|
||||
public MallSeckillVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询秒杀活动列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<MallSeckillVo> queryPageList(MallSeckillBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<MallSeckill> lqw = buildQueryWrapper(bo);
|
||||
Page<MallSeckillVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询秒杀活动列表
|
||||
*/
|
||||
@Override
|
||||
public List<MallSeckillVo> queryList(MallSeckillBo bo) {
|
||||
LambdaQueryWrapper<MallSeckill> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MallSeckill> buildQueryWrapper(MallSeckillBo bo) {
|
||||
LambdaQueryWrapper<MallSeckill> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getPromotionId() != null, MallSeckill::getPromotionId, bo.getPromotionId());
|
||||
lqw.eq(bo.getSkuId() != null, MallSeckill::getSkuId, bo.getSkuId());
|
||||
lqw.eq(bo.getStatus() != null, MallSeckill::getStatus, bo.getStatus());
|
||||
lqw.ge(bo.getStartTime() != null, MallSeckill::getStartTime, bo.getStartTime());
|
||||
lqw.le(bo.getEndTime() != null, MallSeckill::getEndTime, bo.getEndTime());
|
||||
lqw.orderByDesc(MallSeckill::getCreateTime);
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询可用的秒杀活动列表(移动端)
|
||||
*/
|
||||
@Override
|
||||
public List<MallSeckillVo> queryAvailableList() {
|
||||
LambdaQueryWrapper<MallSeckill> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallSeckill::getStatus, 0); // 启用状态
|
||||
Date now = new Date();
|
||||
lqw.le(MallSeckill::getStartTime, now); // 已开始
|
||||
lqw.ge(MallSeckill::getEndTime, now); // 未结束
|
||||
lqw.gt(MallSeckill::getSeckillStock, 0); // 有库存
|
||||
lqw.orderByDesc(MallSeckill::getCreateTime);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询秒杀活动
|
||||
*/
|
||||
@Override
|
||||
public MallSeckillVo queryBySkuId(Long skuId) {
|
||||
LambdaQueryWrapper<MallSeckill> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(MallSeckill::getSkuId, skuId);
|
||||
lqw.eq(MallSeckill::getStatus, 0); // 启用状态
|
||||
Date now = new Date();
|
||||
lqw.le(MallSeckill::getStartTime, now); // 已开始
|
||||
lqw.ge(MallSeckill::getEndTime, now); // 未结束
|
||||
lqw.gt(MallSeckill::getSeckillStock, 0); // 有库存
|
||||
lqw.orderByDesc(MallSeckill::getCreateTime);
|
||||
lqw.last("LIMIT 1");
|
||||
return baseMapper.selectVoOne(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增秒杀活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean insertByBo(MallSeckillBo bo) {
|
||||
MallSeckill add = MapstructUtils.convert(bo, MallSeckill.class);
|
||||
validEntityBeforeSave(add);
|
||||
|
||||
// 设置默认状态
|
||||
if (add.getStatus() == null) {
|
||||
add.setStatus(0); // 默认启用
|
||||
}
|
||||
|
||||
// 校验时间
|
||||
validateTimeRange(add.getStartTime(), add.getEndTime());
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改秒杀活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateByBo(MallSeckillBo bo) {
|
||||
MallSeckill update = MapstructUtils.convert(bo, MallSeckill.class);
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
// 校验时间
|
||||
if (update.getStartTime() != null && update.getEndTime() != null) {
|
||||
validateTimeRange(update.getStartTime(), update.getEndTime());
|
||||
}
|
||||
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(MallSeckill entity) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查活动是否存在、SKU是否存在等
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验时间范围
|
||||
*/
|
||||
private void validateTimeRange(Date startTime, Date endTime) {
|
||||
if (startTime != null && endTime != null) {
|
||||
if (startTime.after(endTime)) {
|
||||
throw new ServiceException("开始时间不能晚于结束时间");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除秒杀活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
// TODO: 可以添加业务校验逻辑,如检查是否有进行中的秒杀活动等
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用/禁用秒杀活动
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
MallSeckill seckill = baseMapper.selectById(id);
|
||||
if (seckill == null) {
|
||||
throw new ServiceException("秒杀活动不存在");
|
||||
}
|
||||
|
||||
MallSeckill update = new MallSeckill();
|
||||
update.setId(id);
|
||||
update.setStatus(status);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扣减秒杀库存
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean reduceStock(Long id, Integer quantity) {
|
||||
if (quantity == null || quantity <= 0) {
|
||||
throw new ServiceException("扣减数量必须大于0");
|
||||
}
|
||||
|
||||
MallSeckill seckill = baseMapper.selectById(id);
|
||||
if (seckill == null) {
|
||||
throw new ServiceException("秒杀活动不存在");
|
||||
}
|
||||
|
||||
if (seckill.getSeckillStock() < quantity) {
|
||||
throw new ServiceException("秒杀库存不足");
|
||||
}
|
||||
|
||||
int rows = baseMapper.reduceStock(id, quantity);
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复秒杀库存
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean restoreStock(Long id, Integer quantity) {
|
||||
if (quantity == null || quantity <= 0) {
|
||||
throw new ServiceException("恢复数量必须大于0");
|
||||
}
|
||||
|
||||
MallSeckill seckill = baseMapper.selectById(id);
|
||||
if (seckill == null) {
|
||||
throw new ServiceException("秒杀活动不存在");
|
||||
}
|
||||
|
||||
int rows = baseMapper.restoreStock(id, quantity);
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查秒杀活动是否可用
|
||||
*/
|
||||
@Override
|
||||
public Boolean checkAvailable(Long id) {
|
||||
MallSeckill seckill = baseMapper.selectById(id);
|
||||
if (seckill == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查状态
|
||||
if (seckill.getStatus() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查时间
|
||||
Date now = new Date();
|
||||
if (seckill.getStartTime().after(now) || seckill.getEndTime().before(now)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查库存
|
||||
if (seckill.getSeckillStock() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.dromara.mall.promotion.config.MallPromotionAutoConfiguration
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.mall.promotion.mapper.MallSeckillMapper">
|
||||
|
||||
<resultMap type="org.dromara.mall.promotion.domain.MallSeckill" id="MallSeckillResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="promotionId" column="promotion_id"/>
|
||||
<result property="skuId" column="sku_id"/>
|
||||
<result property="seckillPrice" column="seckill_price"/>
|
||||
<result property="seckillStock" column="seckill_stock"/>
|
||||
<result property="startTime" column="start_time"/>
|
||||
<result property="endTime" column="end_time"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap type="org.dromara.mall.promotion.domain.vo.MallSeckillVo" id="MallSeckillVoResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="promotionId" column="promotion_id"/>
|
||||
<result property="skuId" column="sku_id"/>
|
||||
<result property="seckillPrice" column="seckill_price"/>
|
||||
<result property="seckillStock" column="seckill_stock"/>
|
||||
<result property="startTime" column="start_time"/>
|
||||
<result property="endTime" column="end_time"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 扣减秒杀库存 -->
|
||||
<update id="reduceStock">
|
||||
UPDATE mall_seckill
|
||||
SET seckill_stock = seckill_stock - #{quantity}
|
||||
WHERE id = #{id}
|
||||
AND seckill_stock >= #{quantity}
|
||||
</update>
|
||||
|
||||
<!-- 恢复秒杀库存 -->
|
||||
<update id="restoreStock">
|
||||
UPDATE mall_seckill
|
||||
SET seckill_stock = seckill_stock + #{quantity}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user