优惠券相关+后台

This commit is contained in:
2025-07-25 11:17:43 +08:00
parent 587c9de5b2
commit 1a1eb79914
12 changed files with 167 additions and 35 deletions

View File

@@ -1,42 +1,45 @@
package com.ycwl.basic.controller.mobile;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.model.mobile.coupon.req.ClaimCouponReq;
import com.ycwl.basic.model.pc.coupon.entity.CouponEntity;
import com.ycwl.basic.model.pc.couponRecord.entity.CouponRecordEntity;
import com.ycwl.basic.service.mobile.CouponRecordService;
import com.ycwl.basic.service.mobile.AppCouponRecordService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/mobile/coupon/v1")
public class AppCouponController {
@Autowired
private CouponRecordService couponRecordService;
private AppCouponRecordService appCouponRecordService;
/**
* 根据memberIdfaceId查找优惠券记录
* 根据memberIdfaceId和type查找优惠券记录
*/
@GetMapping("/records")
public ApiResponse<List<CouponRecordEntity>> getCouponRecords(
@RequestParam Long memberId,
@RequestParam Long faceId) {
List<CouponRecordEntity> records = couponRecordService.queryByMemberIdAndFaceId(memberId, faceId);
return ApiResponse.success(records);
@GetMapping("/record")
public ApiResponse<CouponRecordEntity> getCouponRecords(
@RequestParam Long faceId,
@RequestParam Integer type) {
CouponRecordEntity record = appCouponRecordService.queryByMemberIdAndFaceIdAndType(Long.valueOf(BaseContextHandler.getUserId()), faceId, type);
return ApiResponse.success(record);
}
/**
* 领取优惠券
*/
@PostMapping("/claim")
public ApiResponse<CouponRecordEntity> claimCoupon(
@RequestParam Long memberId,
@RequestParam Long faceId,
@RequestParam Integer type) {
public ApiResponse<CouponEntity> claimCoupon(@RequestBody ClaimCouponReq request) {
request.setMemberId(Long.valueOf(BaseContextHandler.getUserId()));
try {
CouponRecordEntity record = couponRecordService.claimCoupon(memberId, faceId, type);
return ApiResponse.success(record);
CouponEntity coupon = appCouponRecordService.claimCoupon(
request.getMemberId(),
request.getFaceId(),
request.getType()
);
return ApiResponse.success(coupon);
} catch (RuntimeException e) {
return ApiResponse.fail(e.getMessage());
}

View File

@@ -0,0 +1,22 @@
package com.ycwl.basic.controller.pc;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.couponRecord.req.CouponRecordPageQueryReq;
import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordPageResp;
import com.ycwl.basic.service.pc.CouponRecordService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/coupon/record/v1")
public class CouponRecordController {
@Autowired
private CouponRecordService couponRecordService;
@PostMapping("/page")
public ApiResponse<PageInfo<CouponRecordPageResp>> pageQuery(@RequestBody CouponRecordPageQueryReq query) {
return couponRecordService.pageQuery(query);
}
}

View File

@@ -2,6 +2,8 @@ package com.ycwl.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ycwl.basic.model.pc.couponRecord.entity.CouponRecordEntity;
import com.ycwl.basic.model.pc.couponRecord.req.CouponRecordPageQueryReq;
import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordPageResp;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@@ -13,4 +15,6 @@ public interface CouponRecordMapper extends BaseMapper<CouponRecordEntity> {
List<CouponRecordEntity> queryByMemberIdAndFaceId(Long memberId, Long faceId);
CouponRecordEntity queryByMemberIdAndFaceIdAndType(Long memberId, Long faceId, Integer type);
List<CouponRecordPageResp> selectByPageQuery(CouponRecordPageQueryReq query);
}

View File

@@ -40,8 +40,12 @@ public class VideoGoodsDetailVO {
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date shotTime;
// 价格
private Integer couponId;
private Integer couponRecordId;
private BigDecimal couponPrice;
private BigDecimal origPrice;
private String price;
private String slashPrice;
private BigDecimal slashPrice;
// 是否已购买 0否 1是
private Integer isBuy;
// 镜头数
@@ -51,4 +55,14 @@ public class VideoGoodsDetailVO {
private Integer height;
private Integer width;
private BigDecimal duration;
public BigDecimal getDiscountPrice() {
if (slashPrice == null) {
return BigDecimal.ZERO;
}
if (slashPrice.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
return slashPrice.subtract(origPrice);
}
}

View File

@@ -45,4 +45,20 @@ public class CouponEntity {
return originalPrice.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN).multiply(discountPrice);
}
}
public BigDecimal calculateDiscountPrice(String originalPrice) {
BigDecimal priceObj = new BigDecimal(originalPrice);
if (discountType == 0) {
return discountPrice;
} else {
return priceObj.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN).multiply(discountPrice);
}
}
public String calculateDiscountedPrice(String originalPrice) {
BigDecimal priceObj = new BigDecimal(originalPrice);
if (discountType == 0) {
return priceObj.subtract(discountPrice).setScale(2, RoundingMode.HALF_DOWN).toString();
} else {
return priceObj.subtract(priceObj.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_DOWN).multiply(discountPrice)).setScale(2, RoundingMode.HALF_DOWN).toString();
}
}
}

View File

@@ -2,11 +2,13 @@ package com.ycwl.basic.model.pc.couponRecord.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("coupon_record")
public class CouponRecordEntity {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

View File

@@ -9,4 +9,5 @@ public class CouponRecordPageQueryReq {
private Long scenicId;
private String couponName;
private Integer couponType;
private Integer status;
}

View File

@@ -0,0 +1,15 @@
package com.ycwl.basic.service.mobile;
import com.ycwl.basic.model.pc.coupon.entity.CouponEntity;
import com.ycwl.basic.model.pc.couponRecord.entity.CouponRecordEntity;
import java.util.List;
public interface AppCouponRecordService {
List<CouponRecordEntity> queryByMemberIdAndFaceId(Long memberId, Long faceId);
CouponRecordEntity queryByMemberIdAndFaceIdAndType(Long memberId, Long faceId, Integer type);
CouponEntity claimCoupon(Long memberId, Long faceId, Integer type);
}

View File

@@ -1,12 +0,0 @@
package com.ycwl.basic.service.mobile;
import com.ycwl.basic.model.pc.couponRecord.entity.CouponRecordEntity;
import java.util.List;
public interface CouponRecordService {
List<CouponRecordEntity> queryByMemberIdAndFaceId(Long memberId, Long faceId);
CouponRecordEntity claimCoupon(Long memberId, Long faceId, Integer type);
}

View File

@@ -7,7 +7,7 @@ import com.ycwl.basic.model.pc.coupon.entity.CouponEntity;
import com.ycwl.basic.model.pc.couponRecord.entity.CouponRecordEntity;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.service.mobile.CouponRecordService;
import com.ycwl.basic.service.mobile.AppCouponRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -16,7 +16,7 @@ import java.util.Date;
import java.util.List;
@Service
public class CouponRecordServiceImpl implements CouponRecordService {
public class AppCouponRecordServiceImpl implements AppCouponRecordService {
@Autowired
private CouponRecordMapper couponRecordMapper;
@@ -31,9 +31,14 @@ public class CouponRecordServiceImpl implements CouponRecordService {
return couponRecordMapper.queryByMemberIdAndFaceId(memberId, faceId);
}
@Override
public CouponRecordEntity queryByMemberIdAndFaceIdAndType(Long memberId, Long faceId, Integer type) {
return couponRecordMapper.queryByMemberIdAndFaceIdAndType(memberId, faceId, type);
}
@Override
@Transactional(rollbackFor = Exception.class)
public CouponRecordEntity claimCoupon(Long memberId, Long faceId, Integer type) {
public CouponEntity claimCoupon(Long memberId, Long faceId, Integer type) {
// 检查是否已经领取过该类型的优惠券
CouponRecordEntity existingRecord = couponRecordMapper.queryByMemberIdAndFaceIdAndType(memberId, faceId, type);
if (existingRecord != null) {
@@ -64,6 +69,6 @@ public class CouponRecordServiceImpl implements CouponRecordService {
record.setCreateTime(new Date());
couponRecordMapper.insert(record);
return record;
return coupon;
}
}

View File

@@ -6,6 +6,7 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.biz.CouponBiz;
import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.biz.TaskStatusBiz;
import com.ycwl.basic.constant.BaseContextHandler;
@@ -19,6 +20,7 @@ import com.ycwl.basic.mapper.*;
import com.ycwl.basic.model.mobile.goods.*;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.mobile.order.PriceObj;
import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordQueryResp;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
@@ -92,6 +94,8 @@ public class GoodsServiceImpl implements GoodsService {
private TaskStatusBiz taskStatusBiz;
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private CouponBiz couponBiz;
public ApiResponse<List<GoodsPageVO>> goodsList(GoodsReqQuery query) {
Long scenicId = query.getScenicId();
@@ -273,7 +277,8 @@ public class GoodsServiceImpl implements GoodsService {
} else {
goodsDetailVO.setIsBuy(0);
goodsDetailVO.setPrice(priceObj.getPrice().toString());
goodsDetailVO.setSlashPrice(priceObj.getSlashPrice().toString());
goodsDetailVO.setOrigPrice(priceObj.getPrice());
goodsDetailVO.setSlashPrice(priceObj.getSlashPrice());
}
}
}
@@ -304,6 +309,16 @@ public class GoodsServiceImpl implements GoodsService {
});
}
goodsDetailVO.setLensNum(deviceCount.get());
CouponRecordQueryResp couponRecord = couponBiz.queryUserCouponRecord(task.getScenicId(), userId, task.getFaceId(), task.getTemplateId().toString());
if (couponRecord != null) {
if (couponRecord.isUsable()) {
goodsDetailVO.setCouponId(couponRecord.getCouponId());
goodsDetailVO.setCouponRecordId(couponRecord.getId());
goodsDetailVO.setCouponPrice(couponRecord.getCoupon().calculateDiscountPrice(goodsDetailVO.getOrigPrice()));
goodsDetailVO.setPrice(couponRecord.getCoupon().calculateDiscountedPrice(goodsDetailVO.getPrice()));
}
}
return ApiResponse.success(goodsDetailVO);
}

View File

@@ -19,4 +19,51 @@
where cr.member_id = #{memberId} and cr.face_id = #{faceId} and c.type = #{type}
limit 1
</select>
<select id="selectByPageQuery"
resultType="com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordPageResp">
select
cr.id,
cr.coupon_id as couponId,
c.name as couponName,
c.type as couponType,
CASE c.type
WHEN 0 THEN '普通优惠券'
WHEN 1 THEN '第一次推送'
WHEN 2 THEN '第二次推送'
WHEN 3 THEN '第三次推送'
ELSE '未知类型'
END as couponTypeName,
cr.member_id as memberId,
cr.face_id as faceId,
c.scenic_id as scenicId,
s.name as scenicName,
cr.status,
CASE cr.status
WHEN 0 THEN '未使用'
WHEN 1 THEN '已使用'
ELSE '未知状态'
END as statusName,
cr.create_time as createTime,
cr.used_time as usedTime,
cr.used_order_id as usedOrderId
from coupon_record cr
inner join coupon c on cr.coupon_id = c.id
inner join scenic s on c.scenic_id = s.id
<where>
<if test="scenicId != null">
and c.scenic_id = #{scenicId}
</if>
<if test="couponName != null and couponName != ''">
and c.name like concat('%', #{couponName}, '%')
</if>
<if test="couponType != null">
and c.type = #{couponType}
</if>
<if test="status != null">
and cr.status = #{status}
</if>
</where>
order by cr.create_time desc
</select>
</mapper>