12 changed files with 556 additions and 0 deletions
@ -0,0 +1,44 @@ |
|||||
|
package cn.nla.coupon.controller; |
||||
|
|
||||
|
import cn.nla.common.enums.CouponCategoryEnum; |
||||
|
import cn.nla.common.util.JsonData; |
||||
|
import cn.nla.coupon.service.CouponService; |
||||
|
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import io.swagger.annotations.ApiParam; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import javax.annotation.Resource; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券表 前端控制器 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@Api(tags = "优惠券控制器") |
||||
|
@RestController |
||||
|
@RequestMapping("/cop/coupon/v1") |
||||
|
public class CouponController { |
||||
|
@Resource |
||||
|
private CouponService couponService; |
||||
|
|
||||
|
@ApiOperation("分页查询优惠券") |
||||
|
@GetMapping("page_coupon") |
||||
|
public JsonData pageCouponList( |
||||
|
@ApiParam(value = "当前页") @RequestParam(value = "page", defaultValue = "1") int page, |
||||
|
@ApiParam(value = "每页显示多少条") @RequestParam(value = "size", defaultValue = "10") int size) { |
||||
|
return JsonData.buildSuccess(couponService.pageCouponActivity(page, size)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 领取优惠券 |
||||
|
*/ |
||||
|
@ApiOperation("领取优惠券") |
||||
|
@GetMapping("/add/promotion/{coupon_id}") |
||||
|
public JsonData addPromotionCoupon(@ApiParam(value = "优惠券id", required = true) @PathVariable("coupon_id") long couponId) { |
||||
|
return couponService.addCoupon(couponId, CouponCategoryEnum.PROMOTION); |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
package cn.nla.coupon.controller; |
||||
|
|
||||
|
|
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
|
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券领劵记录 前端控制器 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@RestController |
||||
|
@RequestMapping("/couponRecordEntity") |
||||
|
public class CouponRecordController { |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
package cn.nla.coupon.mapper; |
||||
|
|
||||
|
import cn.nla.coupon.model.entity.CouponEntity; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券表 Mapper 接口 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
public interface CouponMapper extends BaseMapper<CouponEntity> { |
||||
|
|
||||
|
/** |
||||
|
* 扣减存储 |
||||
|
*/ |
||||
|
int reduceStock(@Param("couponId") long couponId); |
||||
|
|
||||
|
/** |
||||
|
* 扣减存储 |
||||
|
* |
||||
|
* @param couponId 优惠卷id |
||||
|
* @param oldVersion 版本号 |
||||
|
*/ |
||||
|
int reduceStockOpt(@Param("couponId") long couponId, @Param("oldVersion") long oldVersion); |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package cn.nla.coupon.mapper; |
||||
|
|
||||
|
import cn.nla.coupon.model.entity.CouponRecordEntity; |
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券领劵记录 Mapper 接口 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
public interface CouponRecordMapper extends BaseMapper<CouponRecordEntity> { |
||||
|
|
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
package cn.nla.coupon.model.entity; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券表 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = false) |
||||
|
@TableName("coupon") |
||||
|
public class CouponEntity implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* id |
||||
|
*/ |
||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 优惠卷类型[NEW_USER注册赠券,TASK任务卷,PROMOTION促销劵] |
||||
|
*/ |
||||
|
private String category; |
||||
|
|
||||
|
/** |
||||
|
* 发布状态, PUBLISH发布,DRAFT草稿,OFFLINE下线 |
||||
|
*/ |
||||
|
private String publish; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券图片 |
||||
|
*/ |
||||
|
private String couponImg; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券标题 |
||||
|
*/ |
||||
|
private String couponTitle; |
||||
|
|
||||
|
/** |
||||
|
* 抵扣价格 |
||||
|
*/ |
||||
|
private BigDecimal price; |
||||
|
|
||||
|
/** |
||||
|
* 每人限制张数 |
||||
|
*/ |
||||
|
private Integer userLimit; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券开始有效时间 |
||||
|
*/ |
||||
|
private Date startTime; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券失效时间 |
||||
|
*/ |
||||
|
private Date endTime; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券总量 |
||||
|
*/ |
||||
|
private Integer publishCount; |
||||
|
|
||||
|
/** |
||||
|
* 库存 |
||||
|
*/ |
||||
|
private Integer stock; |
||||
|
|
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 满多少才可以使用 |
||||
|
*/ |
||||
|
private BigDecimal conditionPrice; |
||||
|
|
||||
|
/** |
||||
|
* 版本 |
||||
|
*/ |
||||
|
private Long version; |
||||
|
|
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
package cn.nla.coupon.model.entity; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||
|
import java.util.Date; |
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
import java.io.Serializable; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券领劵记录 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = false) |
||||
|
@TableName("coupon_record") |
||||
|
public class CouponRecordEntity implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
@TableId(value = "id", type = IdType.AUTO) |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券id |
||||
|
*/ |
||||
|
private Long couponId; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间获得时间 |
||||
|
*/ |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 使用状态: 可用NEW,已使用USED,过期EXPIRED; |
||||
|
*/ |
||||
|
private String useState; |
||||
|
|
||||
|
/** |
||||
|
* 用户id |
||||
|
*/ |
||||
|
private Long userId; |
||||
|
|
||||
|
/** |
||||
|
* 用户昵称 |
||||
|
*/ |
||||
|
private String userName; |
||||
|
|
||||
|
/** |
||||
|
* 优惠券标题 |
||||
|
*/ |
||||
|
private String couponTitle; |
||||
|
|
||||
|
/** |
||||
|
* 开始时间 |
||||
|
*/ |
||||
|
private Date startTime; |
||||
|
|
||||
|
/** |
||||
|
* 结束时间 |
||||
|
*/ |
||||
|
private Date endTime; |
||||
|
|
||||
|
/** |
||||
|
* 订单id |
||||
|
*/ |
||||
|
private Long orderId; |
||||
|
|
||||
|
/** |
||||
|
* 抵扣价格 |
||||
|
*/ |
||||
|
private BigDecimal price; |
||||
|
|
||||
|
/** |
||||
|
* 满多少才可以使用 |
||||
|
*/ |
||||
|
private BigDecimal conditionPrice; |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package cn.nla.coupon.service; |
||||
|
|
||||
|
import cn.nla.coupon.model.entity.CouponRecordEntity; |
||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券领劵记录 服务类 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
public interface CouponRecordService extends IService<CouponRecordEntity> { |
||||
|
|
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
package cn.nla.coupon.service; |
||||
|
|
||||
|
import cn.nla.common.enums.CouponCategoryEnum; |
||||
|
import cn.nla.common.util.JsonData; |
||||
|
import cn.nla.coupon.model.entity.CouponEntity; |
||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券表 服务类 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
public interface CouponService extends IService<CouponEntity> { |
||||
|
|
||||
|
Map<String, Object> pageCouponActivity(int page, int size); |
||||
|
|
||||
|
/** |
||||
|
* 领劵接口 |
||||
|
* 1、获取优惠券是否存在 |
||||
|
* 2、校验优惠券是否可以领取:时间、库存、超过限制 |
||||
|
* 3、扣减库存 |
||||
|
* 4、保存领劵记录 |
||||
|
*/ |
||||
|
JsonData addCoupon(Long couponId, CouponCategoryEnum category); |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package cn.nla.coupon.service.impl; |
||||
|
|
||||
|
import cn.nla.coupon.model.entity.CouponRecordEntity; |
||||
|
import cn.nla.coupon.mapper.CouponRecordMapper; |
||||
|
import cn.nla.coupon.service.CouponRecordService; |
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券领劵记录 服务实现类 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@Service |
||||
|
public class CouponRecordServiceImpl extends ServiceImpl<CouponRecordMapper, CouponRecordEntity> implements CouponRecordService { |
||||
|
|
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
package cn.nla.coupon.service.impl; |
||||
|
|
||||
|
import cn.nla.common.enums.BizCodeEnum; |
||||
|
import cn.nla.common.enums.CouponCategoryEnum; |
||||
|
import cn.nla.common.enums.CouponPublishEnum; |
||||
|
import cn.nla.common.enums.CouponStateEnum; |
||||
|
import cn.nla.common.exception.BizException; |
||||
|
import cn.nla.common.interceptor.LoginInterceptor; |
||||
|
import cn.nla.common.model.LoginUser; |
||||
|
import cn.nla.common.util.CommonUtil; |
||||
|
import cn.nla.common.util.JsonData; |
||||
|
import cn.nla.coupon.mapper.CouponRecordMapper; |
||||
|
import cn.nla.coupon.model.VO.CouponVO; |
||||
|
import cn.nla.coupon.model.entity.CouponEntity; |
||||
|
import cn.nla.coupon.mapper.CouponMapper; |
||||
|
import cn.nla.coupon.model.entity.CouponRecordEntity; |
||||
|
import cn.nla.coupon.service.CouponService; |
||||
|
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
|
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.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.BeanUtils; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import javax.annotation.Resource; |
||||
|
import java.util.Date; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* <p> |
||||
|
* 优惠券表 服务实现类 |
||||
|
* </p> |
||||
|
* |
||||
|
* @author YJs |
||||
|
* @since 2024-08-08 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> implements CouponService { |
||||
|
|
||||
|
@Resource |
||||
|
private CouponRecordMapper couponRecordMapper; |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, Object> pageCouponActivity(int page, int size) { |
||||
|
Page<CouponEntity> pageInfo = new Page<>(page, size); |
||||
|
IPage<CouponEntity> couponDOIPage = baseMapper.selectPage(pageInfo, |
||||
|
Wrappers.<CouponEntity>lambdaQuery().eq(CouponEntity::getPublish, CouponPublishEnum.PUBLISH) |
||||
|
.eq(CouponEntity::getCategory, CouponCategoryEnum.PROMOTION) |
||||
|
.orderByDesc(CouponEntity::getCreateTime)); |
||||
|
Map<String, Object> pageMap = new HashMap<>(3); |
||||
|
//总条数
|
||||
|
pageMap.put("total_record", couponDOIPage.getTotal()); |
||||
|
//总页数
|
||||
|
pageMap.put("total_page", couponDOIPage.getPages()); |
||||
|
pageMap.put("current_data", couponDOIPage.getRecords().stream().map(this::beanProcess).collect(Collectors.toList())); |
||||
|
return pageMap; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public JsonData addCoupon(Long couponId, CouponCategoryEnum category) { |
||||
|
LoginUser loginUser = LoginInterceptor.threadLocal.get(); |
||||
|
CouponEntity coupon = baseMapper.selectOne( |
||||
|
Wrappers.<CouponEntity>lambdaQuery().eq(CouponEntity::getId, couponId) |
||||
|
.eq(CouponEntity::getCategory, category.name())); |
||||
|
//优惠券是否可以领取
|
||||
|
this.checkCoupon(coupon, loginUser.getId()); |
||||
|
//构建领劵记录
|
||||
|
CouponRecordEntity couponRecord = new CouponRecordEntity(); |
||||
|
BeanUtils.copyProperties(coupon, couponRecord); |
||||
|
couponRecord.setCreateTime(new Date()); |
||||
|
couponRecord.setUseState(CouponStateEnum.NEW.name()); |
||||
|
couponRecord.setUserId(loginUser.getId()); |
||||
|
couponRecord.setUserName(loginUser.getName()); |
||||
|
couponRecord.setCouponId(couponId); |
||||
|
couponRecord.setId(null); |
||||
|
//扣减库存
|
||||
|
// int rows = baseMapper.reduceStock(couponId);
|
||||
|
//⾼并发下扣减劵库存,采⽤乐观锁,当前stock做版本号,延伸多种防⽌超卖的问题,⼀次只能领取1张
|
||||
|
// 数据库添加字段: version INT DEFAULT 1, 根据当前的版本号更新
|
||||
|
int rows = baseMapper.reduceStockOpt(couponId, coupon.getVersion()); |
||||
|
if (rows == 1) { |
||||
|
//库存扣减成功才保存
|
||||
|
couponRecordMapper.insert(couponRecord); |
||||
|
} else { |
||||
|
log.warn("发放优惠券失败:{},⽤ 户:{}", coupon, loginUser); |
||||
|
throw new BizException(BizCodeEnum.COUPON_NO_STOCK); |
||||
|
} |
||||
|
return JsonData.buildSuccess(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private CouponVO beanProcess(CouponEntity entity) { |
||||
|
CouponVO couponVO = new CouponVO(); |
||||
|
BeanUtils.copyProperties(entity, couponVO); |
||||
|
return couponVO; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 校验是否可以领取 |
||||
|
*/ |
||||
|
private void checkCoupon(CouponEntity coupon, Long userId) { |
||||
|
if (coupon == null) { |
||||
|
throw new BizException(BizCodeEnum.COUPON_NO_EXITS); |
||||
|
} |
||||
|
//库存是否足够
|
||||
|
if (coupon.getStock() <= 0) { |
||||
|
throw new BizException(BizCodeEnum.COUPON_NO_STOCK); |
||||
|
} |
||||
|
//判断是否是否发布状态
|
||||
|
if (!coupon.getPublish().equals(CouponPublishEnum.PUBLISH.name())) { |
||||
|
throw new BizException(BizCodeEnum.COUPON_GET_FAIL); |
||||
|
} |
||||
|
//是否在领取时间范围
|
||||
|
long time = CommonUtil.getCurrentTimestamp(); |
||||
|
long start = coupon.getStartTime().getTime(); |
||||
|
long end = coupon.getEndTime().getTime(); |
||||
|
if (time < start || time > end) { |
||||
|
throw new BizException(BizCodeEnum.COUPON_OUT_OF_TIME); |
||||
|
} |
||||
|
//用户是否超过限制
|
||||
|
int recordNum = couponRecordMapper.selectCount( |
||||
|
Wrappers.<CouponRecordEntity>lambdaQuery().eq(CouponRecordEntity::getCouponId, coupon.getId()) |
||||
|
.eq(CouponRecordEntity::getUserId, userId)); |
||||
|
if (recordNum >= coupon.getUserLimit()) { |
||||
|
throw new BizException(BizCodeEnum.COUPON_OUT_OF_LIMIT); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
<?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="cn.nla.coupon.mapper.CouponMapper"> |
||||
|
|
||||
|
<!-- 通用查询映射结果 --> |
||||
|
<resultMap id="BaseResultMap" type="cn.nla.coupon.model.entity.CouponEntity"> |
||||
|
<id column="id" property="id" /> |
||||
|
<result column="category" property="category" /> |
||||
|
<result column="publish" property="publish" /> |
||||
|
<result column="coupon_img" property="couponImg" /> |
||||
|
<result column="coupon_title" property="couponTitle" /> |
||||
|
<result column="price" property="price" /> |
||||
|
<result column="user_limit" property="userLimit" /> |
||||
|
<result column="start_time" property="startTime" /> |
||||
|
<result column="end_time" property="endTime" /> |
||||
|
<result column="publish_count" property="publishCount" /> |
||||
|
<result column="stock" property="stock" /> |
||||
|
<result column="create_time" property="createTime" /> |
||||
|
<result column="condition_price" property="conditionPrice" /> |
||||
|
</resultMap> |
||||
|
|
||||
|
<!-- 通用查询结果列 --> |
||||
|
<sql id="Base_Column_List"> |
||||
|
id, category, publish, coupon_img, coupon_title, price, user_limit, start_time, end_time, publish_count, stock, create_time, condition_price |
||||
|
</sql> |
||||
|
|
||||
|
<!--扣减库存--> |
||||
|
<update id="reduceStock"> |
||||
|
update coupon set stock=stock-1 where id = #{couponId} |
||||
|
</update> |
||||
|
|
||||
|
<!--扣减库存(加版本号,支持高并发下不超发问题)--> |
||||
|
<update id="reduceStockOpt"> |
||||
|
update coupon set stock=stock-1,version=version+1 where id = #{couponId} and stock>0 and version=#{oldVersion} |
||||
|
</update> |
||||
|
</mapper> |
@ -0,0 +1,26 @@ |
|||||
|
<?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="cn.nla.coupon.mapper.CouponRecordMapper"> |
||||
|
|
||||
|
<!-- 通用查询映射结果 --> |
||||
|
<resultMap id="BaseResultMap" type="cn.nla.coupon.model.entity.CouponRecordEntity"> |
||||
|
<id column="id" property="id" /> |
||||
|
<result column="coupon_id" property="couponId" /> |
||||
|
<result column="create_time" property="createTime" /> |
||||
|
<result column="use_state" property="useState" /> |
||||
|
<result column="user_id" property="userId" /> |
||||
|
<result column="user_name" property="userName" /> |
||||
|
<result column="coupon_title" property="couponTitle" /> |
||||
|
<result column="start_time" property="startTime" /> |
||||
|
<result column="end_time" property="endTime" /> |
||||
|
<result column="order_id" property="orderId" /> |
||||
|
<result column="price" property="price" /> |
||||
|
<result column="condition_price" property="conditionPrice" /> |
||||
|
</resultMap> |
||||
|
|
||||
|
<!-- 通用查询结果列 --> |
||||
|
<sql id="Base_Column_List"> |
||||
|
id, coupon_id, create_time, use_state, user_id, user_name, coupon_title, start_time, end_time, order_id, price, condition_price |
||||
|
</sql> |
||||
|
|
||||
|
</mapper> |
Loading…
Reference in new issue