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