KKSU
2025-01-07 7dce9828e84642d5f37429fff2448dd9c11f71aa
feat(mall): 添加折扣活动功能

- 新增折扣活动相关的 VO 类和 API 接口
- 实现折扣活动的添加和更新功能
- 添加折扣活动的前端页面和交互逻辑
- 更新数据库表结构,增加折扣力度和关联商品等字段
1 files added
9 files modified
206 ■■■■ changed files
src/main/java/cc/mrbird/febs/mall/controller/AdminActivityController.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/ViewActivityController.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/entity/MallActivity.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/IActivityService.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/service/impl/ActivityServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/vo/AdminDiscountVO.java 17 ●●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 6 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 2 ●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/activity/add.html 106 ●●●●● patch | view | raw | blame | history
src/main/resources/templates/febs/views/modules/activity/discountUpdate.html 45 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/mall/controller/AdminActivityController.java
@@ -6,6 +6,7 @@
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.mall.entity.MallActivity;
import cc.mrbird.febs.mall.service.IActivityService;
import cc.mrbird.febs.mall.vo.AdminDiscountVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
@@ -38,4 +39,13 @@
    public FebsResponse addActivity(@RequestBody @Valid MallActivity mallActivity) {
        return iActivityService.addActivity(mallActivity);
    }
    /**
     * 修改折扣活动
     */
    @PostMapping("discountUpdate")
    @ControllerEndpoint(operation = "修改折扣活动", exceptionMessage = "操作失败")
    public FebsResponse discountUpdate(@RequestBody @Valid AdminDiscountVO adminDiscountVO) {
        return iActivityService.discountUpdate(adminDiscountVO);
    }
}
src/main/java/cc/mrbird/febs/mall/controller/ViewActivityController.java
@@ -33,8 +33,8 @@
    /**
     * 新增
     */
    @GetMapping("activityAdd")
    @RequiresPermissions("activityAdd:add")
    @GetMapping("add")
    @RequiresPermissions("add:add")
    public String activityAdd() {
        return FebsUtil.view("modules/activity/add");
    }
src/main/java/cc/mrbird/febs/mall/entity/MallActivity.java
@@ -5,6 +5,7 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@@ -32,4 +33,10 @@
     * 活动类型 1、折扣 2、优惠券
     */
    private Integer type;
    private Long couponId;//优惠券id
    private BigDecimal discountSize;//折扣粒度
    private String activityGoodsIds;//关联的商品ids
}
src/main/java/cc/mrbird/febs/mall/service/IActivityService.java
@@ -3,6 +3,7 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.entity.QueryRequest;
import cc.mrbird.febs.mall.entity.MallActivity;
import cc.mrbird.febs.mall.vo.AdminDiscountVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -11,4 +12,6 @@
    IPage<MallActivity> getAdminListInPage(MallActivity mallActivity, QueryRequest request);
    FebsResponse addActivity(MallActivity mallActivity);
    FebsResponse discountUpdate(AdminDiscountVO adminDiscountVO);
}
src/main/java/cc/mrbird/febs/mall/service/impl/ActivityServiceImpl.java
@@ -6,6 +6,7 @@
import cc.mrbird.febs.mall.entity.MallActivity;
import cc.mrbird.febs.mall.mapper.MallActivityMapper;
import cc.mrbird.febs.mall.service.IActivityService;
import cc.mrbird.febs.mall.vo.AdminDiscountVO;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -45,4 +46,9 @@
        this.baseMapper.insert(mallActivity);
        return null;
    }
    @Override
    public FebsResponse discountUpdate(AdminDiscountVO adminDiscountVO) {
        return null;
    }
}
src/main/java/cc/mrbird/febs/mall/vo/AdminDiscountVO.java
New file
@@ -0,0 +1,17 @@
package cc.mrbird.febs.mall.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "AdminDiscountVO", description = "信息返回类")
public class AdminDiscountVO {
    private Long activityId;//活动ID
    private BigDecimal discountSize;//折扣力度
    private String goodsIds;//折扣商品列表
}
src/main/resources/application-test.yml
@@ -15,10 +15,10 @@
      datasource:
        # 数据源-1,名称为 base
        base:
          username: db_blnka
          password: blnka!@#123
          username: db_e2
          password: db_e20806123!@#
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://121.37.162.173:3306/db_blnka?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
          url: jdbc:mysql://120.27.238.55:3406/db_e2?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
  redis:
    # Redis数据库索引(默认为 0)
src/main/resources/application.yml
@@ -5,7 +5,7 @@
spring:
  profiles:
    active: dev
    active: test
  servlet:
    multipart:
src/main/resources/templates/febs/views/modules/activity/add.html
@@ -10,25 +10,43 @@
                        <div class="layui-tab-content">
                            <div class="layui-tab-item layui-show">
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                <div class="layui-row layui-col-lg6 layui-form-item">
                                        <label class="layui-form-label febs-form-item-require">名称:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="actName" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                <div class="layui-row layui-col-lg6 layui-form-item discount-rule">
                                        <label class="layui-form-label febs-form-item-require">关联商品</label>
                                        <div class="layui-input-block">
                                            <div id="discount-rule"></div>
                                        </div>
                                </div>
                                <div class="layui-row layui-col-lg6 layui-form-item">
                                        <label class="layui-form-label febs-form-item-require">类型</label>
                                        <div class="layui-input-block">
                                            <select name="type" class="award-type" lay-filter="award-type-select">
                                            <select name="type" class="activity-type" lay-filter="activity-type-select">
                                                <option value="1">折扣</option>
                                                <option value="2">优惠卷</option>
                                            </select>
                                        </div>
                                </div>
                                <div class="layui-row layui-col-lg6 discount-size layui-form-item">
                                    <label class="layui-form-label">折扣力度</label>
                                    <div class="layui-input-block">
                                        <input type="text" name="discountSize" placeholder="折扣力度" autocomplete="off" class="layui-input">
                                        <div class="layui-form-mid layui-word-aux">0.98:就是98折</div>
                                    </div>
                                </div>
                                <div class="layui-row layui-col-lg6 febs-hide layui-form-item coupon-size">
                                    <label class="layui-form-label">优惠卷:</label>
                                    <div class="layui-input-block">
                                        <div id="coupon-rule"></div>
                                    </div>
                                </div>
@@ -40,6 +58,9 @@
                                                   placeholder="yyyy-MM-dd" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <div class="layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">结束时间:</label>
                                        <div class="layui-input-block">
@@ -152,6 +173,62 @@
            element = layui.element;
        form.render();
        var activityGoodsIds = xmSelect.render({
            el: '#discount-rule',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            toolbar: {
                show: true,
            },
            // radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/goods/goodsTreeSet', null, function(res) {
            activityGoodsIds.update({
                data : res.data,
                autoRow: true,
            });
        })
        var couponRule = xmSelect.render({
            el: '#coupon-rule',
            language: 'zn',
            prop : {
                value : 'id',
                children : 'child'
            },
            iconfont: {
                parent: 'hidden',
            },
            // radio: true,
            clickClose: true,
            tree: {
                show: true,
                //非严格模式
                strict: false,
            },
            data: []
        })
        febs.get(ctx + 'admin/goods/couponTreeSet', null, function(res) {
            couponRule.update({
                data : res.data,
                autoRow: true,
            });
        })
        laydate.render({
            elem: '#febs-form-group-date-start'
@@ -206,5 +283,22 @@
            })
            return false;
        });
        form.on('select(activity-type-select)', function(data){
            $('.discount-size').each(function() {
                if (data.value == 1) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            })
            $('.coupon-size').each(function() {
                if (data.value == 2) {
                    $(this).show();
                } else {
                    $(this).hide();
                }
            })
        });
    });
</script>
src/main/resources/templates/febs/views/modules/activity/discountUpdate.html
@@ -13,13 +13,22 @@
                                <input type="text" name="id" placeholder="" autoComplete="off" class="layui-input febs-hide">
                                <blockquote class="layui-elem-quote blue-border">折扣</blockquote>
                                <div class="layui-row layui-col-space10 layui-form-item">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">折扣力度:</label>
                                        <div class="layui-input-block">
                                            <input type="text" name="discountSize" lay-verify="required"
                                                   placeholder="" autocomplete="off" class="layui-input">
                                        </div>
                                    </div>
                                </div>
                                <blockquote class="layui-elem-quote blue-border">参与商品</blockquote>
                                <div class="layui-form-item coupon-rule">
                                <div class="layui-form-item discount-rule">
                                    <div class="layui-col-lg6">
                                        <label class="layui-form-label febs-form-item-require">商品:</label>
                                        <div class="layui-input-block">
                                            <div id="coupon-rule"></div>
                                            <div id="discount-rule"></div>
                                        </div>
                                    </div>
                                </div>
@@ -60,15 +69,15 @@
            eleTree = layui.eleTree,
            $view = $('#activity-discount-update'),
            layedit = layui.layedit,
            couponRule = [[${couponRule}]],
            activity = [[${activity}]],
            upload = layui.upload,
            validate = layui.validate,
            element = layui.element;
        form.render();
        var couponRuleGoodsIds = xmSelect.render({
            el: '#coupon-rule',
        var activityGoodsIds = xmSelect.render({
            el: '#discount-rule',
            language: 'zn',
            prop : {
                value : 'id',
@@ -91,7 +100,7 @@
        })
        febs.get(ctx + 'admin/goods/goodsTreeSet', null, function(res) {
            couponRuleGoodsIds.update({
            activityGoodsIds.update({
                data : res.data,
                autoRow: true,
            });
@@ -101,27 +110,17 @@
        function initValue() {
            form.val("activity-discount-update-form", {
                "id": couponRule.id,
                "name": couponRule.name,
                "type": couponRule.type,
                "expireDay": couponRule.expireDay,
                "costAmount": couponRule.costAmount,
                "realAmount": couponRule.realAmount
                "id": activity.id,
                "realAmount": activity.realAmount
            });
            couponRuleGoodsIds.setValue(couponRule.goodsIds);
            activityGoodsIds.setValue(activity.goodsIds);
        }
        form.on('submit(activity-discount-update-form-submit)', function (data) {
            let type = data.field.type;
            let costAmount = data.field.costAmount;
            if(type == 2 && costAmount <= 0){
                febs.alert.warn("累计满减卷,满足金额不能为0");
                return false;
            }
            let couponRuleList = couponRuleGoodsIds.getValue();
            if (couponRuleList.length > 0) {
            let activityList = activityGoodsIds.getValue();
            if (activityList.length > 0) {
                var couponIds = [];
                layui.each(couponRuleList, function (key, item) {
                layui.each(activityList, function (key, item) {
                    couponIds.push(item.id)
                });
                data.field.goodsIds=couponIds;
@@ -137,7 +136,7 @@
                    if(data.code==200){
                        layer.closeAll();
                        febs.alert.success(data.message);
                        $('#febs-coupon-rule').find('#reset').click();
                        $('#febs-activity').find('#reset').click();
                    }else{
                        febs.alert.warn(data.message);
                    }