前端:优惠劵领取界面(完成)
parent
6cee744ec1
commit
315dec741f
|
@ -20,4 +20,24 @@ export function getProductRecommendList() {
|
|||
|
||||
// Coupon Template
|
||||
|
||||
export function getCouponTemplate(id) {
|
||||
return request({
|
||||
url: '/promotion-api/users/coupon/template/get',
|
||||
method: 'get',
|
||||
params: {
|
||||
id,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function doAddCouponCard(templateId) {
|
||||
return request({
|
||||
url: '/promotion-api/users/coupon/card/add',
|
||||
method: 'post',
|
||||
params: {
|
||||
templateId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Coupon Card
|
||||
|
|
|
@ -81,7 +81,7 @@ export function getUserInfo() {
|
|||
|
||||
export function doUserUpdateNickname(nickname) {
|
||||
return request({
|
||||
url: 'user-api/users/user/update_nickname',
|
||||
url: '/user-api/users/user/update_nickname',
|
||||
method: 'post',
|
||||
params: {
|
||||
nickname,
|
||||
|
@ -91,7 +91,7 @@ export function doUserUpdateNickname(nickname) {
|
|||
|
||||
export function doPassportMobileRegister(mobile, code) {
|
||||
return request({
|
||||
url: 'user-api/users/passport/mobile/register',
|
||||
url: '/user-api/users/passport/mobile/register',
|
||||
method: 'post',
|
||||
params: {
|
||||
mobile,
|
||||
|
@ -102,7 +102,7 @@ export function doPassportMobileRegister(mobile, code) {
|
|||
|
||||
export function doPassportMobileSendRegisterCode(mobile) {
|
||||
return request({
|
||||
url: 'user-api/users/passport/mobile/send_register_code',
|
||||
url: '/user-api/users/passport/mobile/send_register_code',
|
||||
method: 'post',
|
||||
params: {
|
||||
mobile,
|
||||
|
|
|
@ -1,9 +1,54 @@
|
|||
<template>
|
||||
<div>
|
||||
<van-cell-group>
|
||||
<van-cell title="单元格" value="内容" />
|
||||
<van-cell title="单元格" value="内容" label="描述信息" />
|
||||
<van-cell title="优惠劵编号" :value="couponTemplate.id" />
|
||||
<van-cell title="优惠劵名" :value="couponTemplate.title"/>
|
||||
</van-cell-group>
|
||||
<van-button slot="button" size="small" type="primary" @click="onFetchClick">领取优惠劵</van-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCouponTemplate, doAddCouponCard } from '../../api/promotion';
|
||||
import { Dialog } from 'vant';
|
||||
import { setLoginToken } from '../../utils/cache';
|
||||
|
||||
export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
couponTemplate: {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
let id = this.$route.query.id;
|
||||
let response = getCouponTemplate(id);
|
||||
response.then(data => {
|
||||
this.couponTemplate = data;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
onFetchClick: function () {
|
||||
let that = this;
|
||||
let id = this.$route.query.id;
|
||||
let response = doAddCouponCard(id);
|
||||
response.then(data => {
|
||||
Dialog.alert({
|
||||
title: '系统提示',
|
||||
message: '领取成功',
|
||||
beforeClose: function (action, done) {
|
||||
// 关闭弹窗
|
||||
done();
|
||||
// 跳转到我的优惠劵
|
||||
that.$router.push('/user/coupon');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -2,6 +2,11 @@ package cn.iocoder.mall.promotion.application.config;
|
|||
|
||||
import cn.iocoder.common.framework.config.GlobalExceptionHandler;
|
||||
import cn.iocoder.common.framework.servlet.CorsFilter;
|
||||
import cn.iocoder.mall.admin.sdk.interceptor.AdminAccessLogInterceptor;
|
||||
import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
|
||||
import cn.iocoder.mall.user.sdk.interceptor.UserAccessLogInterceptor;
|
||||
import cn.iocoder.mall.user.sdk.interceptor.UserSecurityInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -14,23 +19,31 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||
@EnableWebMvc
|
||||
@Configuration
|
||||
@Import(value = {GlobalExceptionHandler.class, // 统一全局返回
|
||||
// AdminSecurityInterceptor.class
|
||||
AdminSecurityInterceptor.class, UserAccessLogInterceptor.class,
|
||||
UserSecurityInterceptor.class, AdminAccessLogInterceptor.class,
|
||||
})
|
||||
public class MVCConfiguration implements WebMvcConfigurer {
|
||||
|
||||
// @Autowired
|
||||
// private UserSecurityInterceptor securityInterceptor;
|
||||
|
||||
// @Autowired
|
||||
// private AdminSecurityInterceptor adminSecurityInterceptor;
|
||||
// @Autowired
|
||||
// private AdminAccessLogInterceptor adminAccessLogInterceptor;
|
||||
@Autowired
|
||||
private UserSecurityInterceptor userSecurityInterceptor;
|
||||
@Autowired
|
||||
private UserAccessLogInterceptor userAccessLogInterceptor;
|
||||
@Autowired
|
||||
private AdminSecurityInterceptor adminSecurityInterceptor;
|
||||
@Autowired
|
||||
private AdminAccessLogInterceptor adminAccessLogInterceptor;
|
||||
//
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// registry.addInterceptor(securityInterceptor).addPathPatterns("/user/**", "/admin/**"); // 只拦截我们定义的接口
|
||||
// registry.addInterceptor(adminAccessLogInterceptor).addPathPatterns("/admins/**");
|
||||
// registry.addInterceptor(adminSecurityInterceptor).addPathPatterns("/admins/**");
|
||||
// 用户
|
||||
registry.addInterceptor(userAccessLogInterceptor).addPathPatterns("/users/**");
|
||||
registry.addInterceptor(userSecurityInterceptor).addPathPatterns("/users/**"); // 只拦截我们定义的接口
|
||||
// 管理员
|
||||
registry.addInterceptor(adminAccessLogInterceptor).addPathPatterns("/admins/**");
|
||||
registry.addInterceptor(adminSecurityInterceptor).addPathPatterns("/admins/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,18 +8,16 @@ import cn.iocoder.mall.promotion.application.convert.CouponCardConvert;
|
|||
import cn.iocoder.mall.promotion.application.convert.CouponTemplateConvert;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersCouponCardVO;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersCouponTemplateVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import com.alibaba.dubbo.config.annotation.Reference;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins/coupon")
|
||||
@RequestMapping("users/coupon")
|
||||
@Api("优惠劵(码)模块")
|
||||
public class UsersCouponController {
|
||||
|
||||
|
@ -31,6 +29,7 @@ public class UsersCouponController {
|
|||
@GetMapping("/template/get")
|
||||
@ApiOperation(value = "优惠劵(码)模板信息")
|
||||
@ApiImplicitParam(name = "id", value = "优惠劵(码)模板编号", required = true, example = "10")
|
||||
@PermitAll
|
||||
public CommonResult<UsersCouponTemplateVO> templateGet(@RequestParam("id") Integer id) {
|
||||
CouponTemplateBO template = couponService.getCouponTemplate(id).getData();
|
||||
return CommonResult.success(CouponTemplateConvert.INSTANCE.convert2(template));
|
||||
|
@ -38,7 +37,7 @@ public class UsersCouponController {
|
|||
|
||||
// ========== 优惠劵 ==========
|
||||
|
||||
@GetMapping("/card/add")
|
||||
@PostMapping("/card/add")
|
||||
@ApiOperation(value = "领取优惠劵")
|
||||
@ApiImplicitParam(name = "templateId", value = "优惠劵(码)模板编号", required = true, example = "10")
|
||||
public CommonResult<UsersCouponCardVO> cardAdd(@RequestParam("templateId") Integer templateId) {
|
||||
|
|
|
@ -22,7 +22,8 @@ public enum PromotionErrorCodeEnum {
|
|||
PRODUCT_TEMPLATE_NOT_CODE(1006002002, "不是优惠码模板"),
|
||||
PRODUCT_TEMPLATE_TOTAL_CAN_NOT_REDUCE(1006002003, "优惠劵(码)模板的发放数量不能减小"),
|
||||
PRODUCT_TEMPLATE_STATUS_NOT_ENABLE(1006002004, "优惠劵模板(码)未开启"),
|
||||
|
||||
PRODUCT_TEMPLATE_TOTAL_NOT_ENOUGH(1006002005, "优惠劵(码)模板的发放量不足"),
|
||||
PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA(1006002006, "优惠劵领取到达上限"),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
|
|
@ -15,6 +15,9 @@ public interface CouponCardMapper {
|
|||
|
||||
Integer selectCountByPage(@Param("status") Integer status);
|
||||
|
||||
int selectCountByUserIdAndTemplateId(@Param("userId") Integer userId,
|
||||
@Param("templateId") Integer templateId);
|
||||
|
||||
void insert(CouponCardDO couponCardDO);
|
||||
|
||||
int update(CouponCardDO couponCardDO);
|
||||
|
|
|
@ -27,4 +27,6 @@ public interface CouponTemplateMapper {
|
|||
|
||||
int update(CouponTemplateDO couponTemplate);
|
||||
|
||||
int updateStatFetchNumIncr(@Param("id") Integer id);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO;
|
|||
import cn.iocoder.mall.promotion.biz.dataobject.CouponTemplateDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -176,6 +177,7 @@ public class CouponServiceImpl implements CouponService {
|
|||
// ========== 优惠劵 ==========
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<CouponCardBO> addCouponCard(Integer userId, Integer couponTemplateId) {
|
||||
// 校验 CouponCardTemplate 存在
|
||||
CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId);
|
||||
|
@ -190,6 +192,19 @@ public class CouponServiceImpl implements CouponService {
|
|||
if (!CouponTemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())) {
|
||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_STATUS_NOT_ENABLE.getCode());
|
||||
}
|
||||
// 校验 CouponCardTemplate 是否到达可领取的上限
|
||||
if (template.getStatFetchNum() > template.getTotal()) {
|
||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_TOTAL_NOT_ENOUGH.getCode());
|
||||
}
|
||||
// 校验单人可领取优惠劵是否到达上限
|
||||
if (couponCardMapper.selectCountByUserIdAndTemplateId(userId, couponTemplateId) > template.getQuota()) {
|
||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode());
|
||||
}
|
||||
// 增加优惠劵已领取量
|
||||
int updateTemplateCount = couponTemplateMapper.updateStatFetchNumIncr(couponTemplateId);
|
||||
if (updateTemplateCount == 0) { // 超过 CouponCardTemplate 发放量
|
||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode());
|
||||
}
|
||||
// 创建优惠劵
|
||||
// 1. 基本信息 + 领取情况
|
||||
CouponCardDO card = new CouponCardDO()
|
||||
|
|
|
@ -56,6 +56,20 @@
|
|||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectCountByUserIdAndTemplateId" resultType="Integer">
|
||||
SELECT
|
||||
COUNT(1)
|
||||
FROM coupon_card
|
||||
<where>
|
||||
<if test="userId != null">
|
||||
AND user_id = #{userId}
|
||||
</if>
|
||||
<if test="templateId != null">
|
||||
AND template_id = #{templateId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="CouponCardDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO coupon_card (
|
||||
template_id, status, user_id, take_type,
|
||||
|
|
|
@ -149,4 +149,11 @@
|
|||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateStatFetchNumIncr" parameterType="Integer">
|
||||
UPDATE coupon_template
|
||||
SET stat_fetch_Num = stat_fetch_Num + 1
|
||||
WHERE id = #{id}
|
||||
AND total > stat_fetch_Num
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
|
|
@ -4,6 +4,7 @@ import lombok.Data;
|
|||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
@ -11,7 +12,7 @@ import java.util.Date;
|
|||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserAccessLogAddDTO {
|
||||
public class UserAccessLogAddDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户编号 - 空
|
||||
|
|
Loading…
Reference in New Issue