用户-积分-套餐 类开发业务笔记

流程核心

1.根据业务设计表结构
2.然后看原型,写出复制SQL的查询结构
3.最后在开始填满业务JAVA代码

业务表分析

积分价格表

表示积分的单价

create sequence SEQ_TEST_JF_ID start with 1 increment by 1;

create table TEST_JF_PRICE
(
    ID       NUMBER,
    JF_TYPE  VARCHAR2(1),
    JF_PRICE NUMBER(9, 2)
)
/

comment on table TEST_JF_PRICE is '积分价格'
/

comment on column TEST_JF_PRICE.ID is '主键'
/

comment on column TEST_JF_PRICE.JF_TYPE is '积分类型'
/

comment on column TEST_JF_PRICE.JF_PRICE is '价格'
/

数据样例

用户-积分-套餐 类开发业务笔记_第1张图片

积分套餐

create table TEST_JF_PACKAGE
(
    ID         NUMBER not null
        constraint TEST_JS_PACKAGE_PK
            primary key,
    PACKAGE_ID VARCHAR2(32),
    JF_TYPE    VARCHAR2(1),
    COST_NUM   NUMBER
)
/

comment on table TEST_JF_PACKAGE is '积分套餐'
/

comment on column TEST_JF_PACKAGE.ID is '主键'
/

comment on column TEST_JF_PACKAGE.PACKAGE_ID is '包id'
/

comment on column TEST_JF_PACKAGE.JF_TYPE is '积分类型'
/

comment on column TEST_JF_PACKAGE.COST_NUM is '消耗数量'
/

数据样例

用户-积分-套餐 类开发业务笔记_第2张图片

用户积分流水表

记录用户积分的变动情况

create table TEST_JF
(
    ID              NUMBER not null
        constraint TEST_JF_PK
            primary key,
    USER_ID         VARCHAR2(32),
    DATA_TYPE       NUMBER,
    OPERATION_NUM   NUMBER,
    EXPIRED_DATE    TIMESTAMP(0),
    TYPE0_ID        NUMBER,
    JF_TYPE         VARCHAR2(1),
    OPERATION_ORDER VARCHAR2(32)
)
/

comment on table TEST_JF is '积分流水表'
/

comment on column TEST_JF.ID is '主键'
/

comment on column TEST_JF.USER_ID is '用户id'
/

comment on column TEST_JF.DATA_TYPE is '流水类型(1:积分购买,2:积分使用,3:积分退还,4:积分过期)'
/

comment on column TEST_JF.OPERATION_NUM is '操作数量'
/

comment on column TEST_JF.EXPIRED_DATE is '过期日期'
/

comment on column TEST_JF.TYPE0_ID is '类型为0的总量id'
/

comment on column TEST_JF.JF_TYPE is ' 积分类型'
/

comment on column TEST_JF.OPERATION_ORDER is '操作单号'
/

数据样例

用户-积分-套餐 类开发业务笔记_第3张图片

创建用户积分视图

CREATE OR REPLACE VIEW VIEW_TEST_JF_USER AS
select t1.*, nvl(t2.use_num,0) as use_num ,
       nvl(t3.return_num,0) as return_num,
       nvl(t4.expired_num,0) as expired_num,
       t1.buy_num-nvl(t2.use_num,0)+nvl(t3.return_num,0)-nvl(t4.expired_num,0) as own_num,
       P.JF_PRICE
from (
select JF_TYPE,USER_ID,sum(OPERATION_NUM) as buy_num from TEST_JF jf where jf.DATA_TYPE=1 group by JF_TYPE,USER_ID
) t1
left join (
select JF_TYPE,USER_ID,sum(OPERATION_NUM) as use_num from TEST_JF jf where jf.DATA_TYPE=2 group by JF_TYPE,USER_ID
    ) t2 on t1.USER_ID=t2.USER_ID and t1.JF_TYPE=t2.JF_TYPE
left join (
    select JF_TYPE,USER_ID,sum(OPERATION_NUM) as return_num from TEST_JF jf where jf.DATA_TYPE=3 group by JF_TYPE,USER_ID
    ) t3 on t1.USER_ID=t3.USER_ID and t1.JF_TYPE=t3.JF_TYPE
left join (
    select JF_TYPE,USER_ID,sum(OPERATION_NUM) as expired_num from TEST_JF jf where jf.DATA_TYPE=4 group by JF_TYPE,USER_ID
    ) t4 on t1.USER_ID=t4.USER_ID  and t1.JF_TYPE=t3.JF_TYPE
LEFT JOIN TEST_JF_PRICE P on P.JF_TYPE= t1.JF_TYPE
ORDER BY T1.USER_ID,T1.JF_TYPE
;

样例数据

用户-积分-套餐 类开发业务笔记_第4张图片

业务描述

用户按照价格购买积分。
用户按照类型用积分兑换套餐。
对应类型积分不够用时候,高价的积分可以抵扣低价的积分。

代码业务

找到单个套餐消耗的积分, 乘以数量算出总量

SELECT  PACKAGE_ID,P.JF_TYPE,COST_NUM,JF_PRICE FROM TEST_JF_PACKAGE P
LEFT JOIN TEST_JF_PRICE R ON P.JF_TYPE=R.JF_TYPE
WHERE P.PACKAGE_ID='P1';

找到这个用户能消耗的积分

SELECT vu.* FROM VIEW_TEST_JF_USER vu
WHERE vu.USER_ID='U1' and JF_PRICE >= 200.22 ORDER BY JF_PRICE;

遍历循环相减,根据高价抵扣低价的规则,算出每个类型积分扣除数量

找到最快过期的,计算消耗数量然后插入 类型为2的数据

SELECT * FROM TEST_JF where USER_ID='U1' and JF_TYPE='C' order by EXPIRED_DATE ;

JAVA代码样例

使用和过期

        String jfType="C";
        String userId="U1";
        int costNum=3;
        LambdaQueryWrapper<TestJf> queryWrapper = new LambdaQueryWrapper<TestJf>();
        queryWrapper.eq(TestJf::getJfType,jfType);
        queryWrapper.eq(TestJf::getUserId,userId);
        queryWrapper.eq(TestJf::getDataType,DataType.BUY_1);
//        过期加上时间判断就行
        queryWrapper.orderByAsc(TestJf::getExpiredDate);
        List<TestJf> list = testJfService.list(queryWrapper);
        String operationId=IdUtil.fastSimpleUUID();
        for (TestJf testJf : list) {
            Integer operationNum = testJf.getOperationNum();
            int use2Num=operationNum;
            if(costNum>=operationNum){
                costNum=costNum-operationNum;
            }else {
                use2Num=costNum;
            }
            TestJf use2 = new TestJf();
            use2.setUserId(userId);
            use2.setJfType(jfType);
            use2.setDataType(DataType.USE_2);
            use2.setOperationNum(use2Num);
            use2.setType0Id(testJf.getId());
            use2.setOperationOrder(operationId);
            testJfService.save(use2);
        }

退还

 String operationId="7543e6eb514948f5b6bfdcf56e10e204";
        int returnNum=2;
        String jfType="C";
        String userId="U1";
        TestJf use2 = new TestJf();
        use2.setUserId(userId);
        use2.setJfType(jfType);
        use2.setDataType(DataType.RETURN_3);
        use2.setOperationNum(returnNum);
        use2.setOperationOrder(operationId);
        testJfService.save(use2);

你可能感兴趣的:(笔记)