[Lilishop Mall] No3-11. Detailed design of modules, detailed design of promotional modules (coupons, discounts, spikes, points)

Only the backend is involved, see the top column for all directories, codes, documents, and interface paths are: 

[Lilishop Mall] Record the study notes of the B2B2C mall system~


The whole article will combine the business introduction to focus on the design logic, including the interface class and business class. The specific combination of source code analysis is not complicated to read~

Caution: Some comments in the source code are wrong, some comments have completely opposite meanings, and some comments are not correct. I updated them during the reading process and added new comments where I did not know. So be careful when reading the source code! 

Table of contents

A1. Coupons

B1.M terminal (belongs to explicit operation)

B2.S terminal (belongs to explicit operation)

B3.B side (belongs to explicit operation)

B4.consumer side (belonging to business operations)

A2. Coupon Activities

B1.M terminal (belongs to explicit operation)

A3. Full discount

B1.S terminal (belongs to explicit operation)

B2.M terminal (belongs to explicit operation)

 A4. Spike

B1.M terminal (belongs to explicit operation)

B2.S terminal (belongs to explicit operation)

B3.B side (belongs to explicit operation)

B4.consumer side (belonging to business operations)

A5.A6. Group buying and bargaining (to be recorded)

A7. Points products

B1. Points classification

C1.M terminal (belongs to explicit operation)

 C2.B side (belongs to explicit operation)

B2. Points products

C1.M terminal (belongs to explicit operation)

C1.B side (belongs to explicit operation)


Before we start, let me tell you that the management of various promotions is not particularly difficult to understand, as long as you understand the interfaces required by each table structure and page, the key point is that the bottom layer of the business service class of promotional activities is implemented from an interface, because all promotions Both have similar general logic (eg, add promotion, modify promotion, initialization, etc.).

A1. Coupons

B1.M terminal (belongs to explicit operation)

There's nothing to say about the interface here

  • Get the coupon list, get coupon details by id, add coupons, modify coupons, modify coupon status, delete in batches
  • Query all classification lists (see product classification, M terminal)
  • Get the product sku list by page (see product, M terminal)

    ​   

B2.S terminal (belongs to explicit operation)

The logic here is similar to that on the M side, except that some attributes need to be modified

  • Get the coupon list, get coupon details by id, add coupons, modify coupons, modify coupon status, delete in batches
  • Obtain the classification of store operations (see product classification, S terminal)
  • Get the product Sku list by page (see product, S side)

   

    

B3.B side (belongs to explicit operation)

Here is what is displayed on the front desk of the B-end, and what the user has received;

However, it is a bit inconvenient to obtain the interface of the coupon list that can be claimed. It only returns all the coupons on the platform, and does not indicate whether the current login account has the coupon~

  • Obtain a list of coupons that can be claimed, obtain a list of coupons for current members, and receive coupons for members

       

B4.consumer side (belonging to business operations)

The coupon received by the user has an expiration date, so it is necessary to add a scheduled task to operate the status of the member coupon to expire.

详见:cn.lili.timetask.handler.impl.coupon.CouponExecute

But I don't understand why EveryDayExecute is used here. It stands to reason that it should be detected every second. It is also measured in seconds online. Maybe it is wrong~

/**
 * 优惠券状态监测
 *
 * @author Bulbasaur
 * @since 2021/5/24 10:08 上午
 */
@Component
public class CouponExecute implements EveryDayExecute {

    /**
     * 过期常量,过期后或者使用后一定时间内,删除无效的优惠券,物理删除
     */
    static final int EXPIRATION_DAY = 3;

    @Autowired
    private MemberCouponService memberCouponService;

    /**
     * 检测优惠券的使用时间,超期未使用则失效
     * 此方法用于领取*天后失效优惠券使用
     */
    @Override
    public void execute() {
        //业务 1
        //将过期优惠券从领取状态变更为过期状态
        LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
                .eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
                .le(MemberCoupon::getEndTime, new Date())
                .set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
        this.memberCouponService.update(updateWrapper);

        //业务 2
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - EXPIRATION_DAY);
        Date removeTime = calendar.getTime();
        //删除过期/已使用的优惠券(过期一定时间后物理删除)
        LambdaUpdateWrapper<MemberCoupon> deleteWrapper = new LambdaUpdateWrapper<MemberCoupon>()
                //如果结束时间小于 当前时间增加指定删除日期,则删除
                .le(MemberCoupon::getEndTime, removeTime);
        this.memberCouponService.remove(deleteWrapper);


    }

}

A2. Coupon Activities

According to the activity of adding coupons to coupons, the associated members are directly stored in the scope in the main table, and the associated coupons are stored in the sub-table li_coupon_activity_item.

This business is to issue coupons to designated users. The start time and end time of his activity are actually useless. When the activity is created, it is directly issued to the designated user, and it can be used even if the activity has not started or the activity has ended, so What is the real business effect? TvT

B1.M terminal (belongs to explicit operation)

  • Get coupon activity page, get coupon activity by id, add coupon activity, close coupon activity
  • Get a list of coupons (see Coupons, M side)
  • Member page list (see Members, S side)

 

A3. Full discount

The full discount is initiated by the store, and the operation M terminal can be closed, and the full discount includes free shipping, coupons, and gifts~

Free shipping will remove the postage when the conditions are met when the order is placed, and the gift coupon will give a member-designated coupon (this coupon is an activity coupon created by the store) after the order is placed and paid. The gift will generate a sub-order of the gift type after the order is placed. The price is zero.

There can only be one full discount event for the same commodity sku, so there cannot be multiple full-category full discount events~

There is no scheduled task for the failure of the full reduction activity. For the S terminal and the M terminal, it is only judged every time it is acquired, and then the status is recorded. The status field does not exist in the table. If you want to close the full reduction activity, you will directly start - If the deadline is cleared, it will be judged as closed according to the time. On the B side, only when the details of the sku are obtained, the valid promotional full discount activities bound to the sku will be obtained.

(I personally think that such a design is unreasonable, so that the closing will not record the start date of the closed full discount activity. Therefore, it is convenient to add a status field to record.)

The following promotional activities: seckill, also follow this logic!

B1.S terminal (belongs to explicit operation)

  • According to the conditions, query full discount activities, obtain by id, add full discount activities, modify full discount activities, delete full discount activities, and modify full activity status
  • Obtain the classification of store operations (see product classification, S terminal)
  • Get the product Sku list by page (see product, S side)

 

  

B2.M terminal (belongs to explicit operation)

  • Get full discount list, get full discount details, modify full activity status

  

 A4. Spike

Each day’s flash sale is automatically added by the system, and then the store that wants to participate can add a product sku to a certain time of a flash sale, and the operator can delete the product sku or close the flash sale.

From the beginning of the system, you need to add the seckill in the system for the next few days, and then add the seckill every day thereafter. For example: on 12-01, the system initially added a seven-day spike to 12-08, and the scheduled task will be executed on 12-02 the next day, and continue to add spikes until 12-09, because the scheduled task has been added from 12-03 to 12-08 , it will be skipped, and only the spike of 12-09 will be added. (This is just a simple logic. In fact, it is judged that the seckill that has not been opened in the next 7 days will be added, because the generated seckill can be closed~)

Buyer B can view the seckill list and purchase seckill products. Even if the seckill products are no longer in the seckill list, the seckill information will be displayed within a limited time. The seckill list is just a quick entry. 

B1.M terminal (belongs to explicit operation)

  • Initialize the seckill activity, query the seckill activity list by page, obtain by id, modify the seckill activity, delete a seckill activity, and operate the seckill activity status
  • Obtain the application list of seckill activities, delete the application of seckill activities
  • Obtain the classification of store operations (see product classification, S terminal)
  • Get the product Sku list by page (see product, S side)

 

 

B2.S terminal (belongs to explicit operation)

  • Obtain the seckill event list, obtain seckill event information by id, obtain seckill event application list, obtain seckill event application by id, add seckill event application, delete seckill event product
  • Obtain the classification of store operations (see product classification, S terminal)
  • Get the product Sku list by page (see product, S side)

 

 

B3.B side (belongs to explicit operation)

  • Obtain the information of the flash sale event on the day, and obtain the product information of the flash sale event at a certain time

 

B4.consumer side (belonging to business operations)

Daily timed tasks, create spike activities

详见:cn.lili.timetask.handler.impl.promotion.PromotionEverydayExecute

/**
 * 促销活动每日定时器
 *
 * @author Chopper
 * @since 2021/3/18 3:23 下午
 */
@Slf4j
@Component
public class PromotionEverydayExecute implements EveryDayExecute {

    /**
     * ES商品索引
     */
    @Autowired
    private EsGoodsIndexService esGoodsIndexService;
    /**
     * 系统设置
     */
    @Autowired
    private SettingService settingService;
    /**
     * 秒杀活动
     */
    @Autowired
    private SeckillService seckillService;

    /**
     * 将已过期的促销活动置为结束,添加秒杀活动
     */
    @Override
    public void execute() {
        try {
            //清除所有商品索引的无效促销活动
            this.esGoodsIndexService.cleanInvalidPromotion();
        } catch (Exception e) {
            log.error("清楚商品索引中无效促销异常", e);
        }
        try {
            //定时创建活动
            addSeckill();
        } catch (Exception e) {
            log.error("秒杀活动添加异常", e);
        }

    }

    /**
     * 添加秒杀活动
     * 从系统设置中获取秒杀活动的配置
     * 添加明天后的秒杀活动
     */
    private void addSeckill() {
        Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
        SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
        log.info("生成秒杀活动设置:{}", seckillSetting);
        for (int i = 1; i <= SeckillService.PRE_CREATION; i++) {
            Seckill seckill = new Seckill(i, seckillSetting.getHours(), seckillSetting.getSeckillRule());

            //如果已经存在促销,则不再次保存
            if (seckillService.list(PromotionTools.checkActiveTime(seckill.getStartTime(), seckill.getEndTime(), PromotionTypeEnum.SECKILL, null, seckill.getId())).isEmpty()) {
                boolean result = seckillService.savePromotions(seckill);
                log.info("生成秒杀活动参数:{},结果:{}", seckill, result);
            }
        }
    }
}

A5.A6. Group buying and bargaining (to be recorded)

Group buying and bargaining are also businesses only available on the buyer’s mini-program/APP side, not on the buyer’s PC side.

It is too late to understand the detailed business of group buying and bargaining, and it will be recorded later.

A7. Points products

Points products are also a business only available on the buyer’s mini-program/APP side, not on the buyer’s PC side.

Each activity of points-based products includes a product sku, and only the operation M side can manage the points, and the store S side will not manage it. The amount of the product sku added as a point product is 0 after the order is placed, that is, the profit of this order is 0, but in the store reconciliation, the set point settlement amount will be used to replenish the store, so it can be said that it is finally paid by the operation side ~~~ (To add, the platform coupons will also be replenished to the store at the time of settlement. The specific replenishment depends on the proportion of the store in the coupon~)

Points classification is for the classification of the buyer's B side, and has nothing to do with the product.

B1. Points classification

C1.M terminal (belongs to explicit operation)

  • Get point product classification page, get point product classification by id, add point product classification, modify point product classification, delete point product classification

 

 C2.B side (belongs to explicit operation)

This interface is directly placed in the points product on the buyer's end, see point products, buyer B end.

B2. Points products

C1.M terminal (belongs to explicit operation)

  • Obtain point products by page, obtain point product details by id, add point products, modify point products, delete point products, modify point product status

 

  

C1.B side (belongs to explicit operation)

  • Get Points Products by Page, Get Points Event Products

  • Get Points Product Category Pagination

 

Guess you like

Origin blog.csdn.net/vaevaevae233/article/details/128373032