Commit 3d32c2d8 3d32c2d8dddeb912dd910d902865b3631d1ef50d by xianghan@topdraw.cn

初始化项目

;
1 parent 35b568f7
Showing 268 changed files with 16023 additions and 0 deletions
# 积分台账表
CREATE TABLE `uc_points_standing_book` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`points_produce` bigint(20) NOT NULL COMMENT '积分生产',
`points_consume` bigint(20) NOT NULL COMMENT '积分消耗',
`points_available` bigint(20) NOT NULL COMMENT '可用总积分',
`points_expire` bigint(20) NOT NULL COMMENT '积分过期',
`day` varchar(16) DEFAULT NULL COMMENT '日期',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分台账表';
# 永久权益表
CREATE TABLE `uc_permanent_rights` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(64) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`type` tinyint(4) DEFAULT NULL COMMENT '永久权益类型 0:vip;1:会员等级',
`level` tinyint(4) DEFAULT NULL COMMENT '等级(当权益类型为vip时,对应vip值,当权益类型为会员等级时,对应等级index)',
`item_discount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品折扣,10代表10% off,范围为0-100',
`extra_points` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '额外积分比率,范围为0-1000',
`ad_disabled` tinyint(4) NOT NULL DEFAULT '0' COMMENT '免广告',
`extra_activity_ticket` tinyint(4) NOT NULL DEFAULT '0' COMMENT '额外活动参与机会',
`free_trial` tinyint(4) NOT NULL DEFAULT '0' COMMENT '免费试看',
`zone_sds` tinyint(4) NOT NULL DEFAULT '0' COMMENT '上电视专区权益',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='永久权益表';
CREATE TABLE `uc_points_standing_book` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`points_produce` bigint NOT NULL COMMENT '积分生产',
`points_consume` bigint NOT NULL COMMENT '积分消耗',
`points_available` bigint NOT NULL COMMENT '可用总积分',
`points_expire` bigint NOT NULL COMMENT '积分过期',
`day` varchar(16) DEFAULT NULL COMMENT '日期',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='积分台账表'
#优惠券表
CREATE TABLE `m_coupon` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`code` varchar(64) NOT NULL COMMENT '标识',
`title` varchar(255) NOT NULL COMMENT '名称',
`images` varchar(1024) DEFAULT NULL COMMENT '图片',
`stock` int(11) DEFAULT '-1' COMMENT '发行量,-1代表不限量',
`remain_stock` int(11) '-1' NULL COMMENT '剩余量,-1代表不限量',
`use_type` tinyint(4) DEFAULT '1' COMMENT '优惠形式:1:金额;2:折扣',
`denomination` decimal(10,2) DEFAULT NULL COMMENT '面额',
`discount` decimal(10,2) DEFAULT NULL COMMENT '折扣',
`user_range` tinyint(4) DEFAULT '2' COMMENT '适用用户范围:1:新用户;2:全体用户;3:指定用户分组',
`groups` varchar(1024) DEFAULT NULL COMMENT '用户分组,逗号分隔',
`collect_limit` tinyint(4) DEFAULT '1' COMMENT '限领次数 -1:无限次; >0:具体次数',
`threshold_type` tinyint(4) DEFAULT '1' COMMENT '适用门槛:1:无门槛;2:满减形式',
`amount_threshold` decimal(10,2) DEFAULT null COMMENT '满减门槛',
`item_range` tinyint(4) DEFAULT '1' COMMENT '产品范围:1:全部商品;2:指定商品',
`effect_type` tinyint(4) DEFAULT null COMMENT '生效形式:1:固定日期;2:相对日期',
`start_time` datetime DEFAULT NULL COMMENT '生效时间',
`expire_time` datetime DEFAULT NULL COMMENT '过期时间',
`valid_days` int(11) DEFAULT NULL COMMENT '自领取当日,几天内有效',
`description` varchar(255) DEFAULT NULL COMMENT '使用说明',
`status` tinyint(4) DEFAULT null COMMENT '状态 0:未开始,1:启用;2:停用',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=' 优惠券表';
#优惠券
CREATE TABLE `m_coupon_history` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`coupon_id` bigint DEFAULT NULL COMMENT '优惠券id',
`user_id` bigint DEFAULT NULL COMMENT '领券用户id',
`coupon_code` varchar(64) DEFAULT NULL COMMENT '优惠券code',
`user_nickname` varchar(255) DEFAULT NULL COMMENT '领取人昵称',
`receive_time` datetime DEFAULT NULL COMMENT '领取时间',
`expire_time` datetime DEFAULT NULL COMMENT '失效时间',
`use_status` int DEFAULT NULL COMMENT '使用状态 0:未使用;1:已使用;-1:已过期',
`use_time` datetime DEFAULT NULL COMMENT '使用时间',
`order_detail_id` bigint DEFAULT NULL COMMENT '订单详情id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_member_id` (`user_id`) USING BTREE,
KEY `idx_coupon_id` (`coupon_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=134 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='优惠券领取、使用历史记录表'
\ No newline at end of file
m_coupon
m_coupon_history
tr_rights
tr_rights_histroy
tr_task
tr_task_template
uc_exp_history
uc_exp_detail
uc_permanent_rights
uc_member_related_info
uc_member_address
uc_member_profile
uc_member_level
uc_member
uc_points_standing_book
uc_points_available
uc_points_detail_history
uc_points_detail
uc_user_weixin
uc_user_tv
\ No newline at end of file
## 会员系统概要设计和细化分解
### <font color='darkblue'>建设目的与背景</font>
建立<font color='red'>融合、跨平台</font>的会员体系,对IPTV、互联网App、移动终端平台进行统一会员管理。对用户体系实现<font color='red'>统一的会员认证</font>,有效管理全平台会员数据。融合<font color='red'>用户中心、Boss系统、商城服务体系、活动系统、任务权益体系、积分/成长体系、会员画像系统</font>,提供多元化的产品形态,打造会员体系与运营模式的智能化平台,通过智能化的分析,把会员与平台的影片、产品、活动、增值业务等建立深度的联系,提高平台的服务能力,推动用户业务的使用,并为产品运营提供强有力的支撑。
### <font color='darkblue'>近期目标交付</font>
#### 四川金熊猫OMO
##### <font color='forestgreen'>核心需求</font>
- 核心是小屏
- 会员权益体系,不同vip会员,权益不同,向下覆盖(核心是不同vip标识,弱化会员等级)
- 主推主题活动
- 报名环节(报名费,会员差异,商品关联)
- 参与环节(ugc上载,审核,证书)
- 数据环节(数据统计)
- 积分体系,暂时只对应商城
#### 重数会员系统
##### <font color='forestgreen'>核心需求</font>
- 核心是大屏(至少短时间是大屏)
- 重点关注会员成长体系、会员积分体系,注重会员等级,vip标识可能唯一
- 任务权益体系
- 积分商城
### <font color='darkblue'>整体架构</font>
>整个会员系统由用户中心、Boss系统、商城系统、活动系统、用户画像系统组成,他们的整体架构如下:
### <font color='darkblue'>User Center</font>
> 用户中心,是整个会员系统的核心,负责用户的统一登录、鉴权、积分及权益
#### 用户/账号体系(多屏账号)
> 账号:各业务系统拥有的<font color='red'>独立的账号体系</font>,如大屏的iptv账号,微信的openid或unionid,移动端app的账号
> 用户:对应“自然人”的概念,<font color='red'>为了实现跨屏账号体系而抽象的用户概念</font>,是会员体系的依附(会员是特殊身份的用户)
##### <font color='forestgreen'>会员概要(等级/vip)</font>
- 会员是特殊的一类用户,本质上也是用户
- 成为会员的方式
- 购买会员
- 订阅、关注
- 。。。
- 会员vip标识
- 支持不同层级vip的界定,差异化服务
- vip专享权益
- 与会员等级独立,两个维度
- 会员等级
- 通过会员成长值驱动,不依赖于会员购买
- 基于等级的权益体系
- 会员的生效状态
- 满足条件成为会员
- 不满足条件会员失效
- 使用vip标识来实现
- 会员和成长值的关系
- 无直接联系
- 会员的成长值加速
- 会员等级和成长值加速的关系
##### <font color='forestgreen'>会员信息</font>
- 基本信息
- 注册时间、注册手机号、性别、会员等级、会员积分、会员余额等
- 地址信息
- 收货地址
- 积分信息
- 变动明细
- 优惠券信息
- 优惠券明细及状态,优惠券金额、使用条件、领取时间、使用时间、有效期及使用状态等
- 优惠券的信息一般和账户挂钩,此处需要关联查询
- 订单信息
- 用户对应账号的订单列表
- 子女信息
- 子女姓名,身份证,年龄
#### (会员)成长体系
> <font color='red'>成长值</font>:作为会员成长体系中的核心数据,是贯穿整个会员体系重要依据之一。它直接或间接和会员等级、会员权益相关。
![image-20210927114350241](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927114350.png)
##### <font color='forestgreen'>成长值的来源</font>
- 日常登录
- 观影
- 参与活动
- 订购
- 后台赠送
- ...
##### <font color='forestgreen'>成长值的消耗</font>
- 单向模式:只增加不减少,初期就采用这种简单的模式
- 一些产品中成长值一直累积,伴随的会员等级一直成长,例如:QQ等级随着在线时间的增加而成长,从星星到月亮到太阳最后到皇冠,这种会员等级是单向的,永远朝着更高级别成长。这种规则下,成长值是无消耗的
- 双向模式:会根据规则增加和减少,也会影响对应的会员等级变化,一般适用于粘性较高,有一定用户基础的产品
- 一些产品充成长值是双向的,根据规则可增加可减少,对应的会员等级也会动态的变化
- 典型的例如王者荣耀的段位排名机制
- 还有在电商体系中
- 用户获得成长值的行为失效需要扣减对应成长值,例如:退货、删除评价等行为
- 后台人工干预扣除成长值等
- 一些平台也会在一个特定的时间周期评估用户的各种数据,根据规则重新计算出成长值,然后得出会员等级
##### <font color='forestgreen'>成长值与会员等级</font>
成长值与会员等级有确定的对应关系,当成长值累计到一定数值时,会员等级会随之提升
##### <font color='forestgreen'>会员等级</font>
尊享会员、钻石会员...(产品侧定义)
##### <font color='forestgreen'>会员vip标识</font>
- 不同付费档次(OMO)
- 非会员
- 团粉(关注)
- 上电视会员(99元购买)
- 小演员普通版(999元购买)
- 小演员黄金版(5999元购买)
##### <font color='forestgreen'>会员等级/vip权益</font>
- <font color='red'>一次性奖励权益</font>
- 达到对应等级所能获得的奖励,可以是积分、优惠券、其他实体
- 采用任务-权益体系实现
- <font color='red'>解锁特权</font>
- 下单折扣
- 包邮
- 免费观影
- 积分加成
- 。。。
##### <font color='forestgreen'>成长值风控(第一阶段不做)</font>
- 成长值上限
- 在设置成长值来源时可针对每个来源设置每日获取上限值,同样也可针对每个账号设置每日获取上限值,超过上限时完成任务不再增加成长值
- 异常数据报警
- 通过系统监控所有会员的成长值增加&消耗情况,例如某个会员的成长值突然在短时间内剧增,增幅已经达到系统预警,则需要对该会员的具体数据&行为进行分析
- 黑白名单
- 黑名单无法获得成长值
- 白名单特殊待遇
- 人工干预
- 针对部分系统无法自动处理的场景,可在开发时预留成长值更改接口,运营人员可在后台手动扣减/奖励用户的成长值
##### <font color='forestgreen'>成长值明细/历史</font>
详见成长值/积分计算引擎章节
#### 积分体系
> 积分体系和会员成长体系最基本的模型是一样的,只不过从简单到复杂的演变的过程中表现出了不同的特点。积分可以抽象地理解为现实生活中的货币,货币有发行和回收机制,积分同样也有<font color='red'>发行和回收机制</font>,不然都会导致通货膨胀
![image-20210927141420693](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927141420.png)
##### <font color='forestgreen'>积分价值</font>
- 虚拟货币,需要预先调研定义其货币价值
- 通过成本管控,防止通货膨胀和营销亏损
##### <font color='forestgreen'>积分获取/风控</font>
- 同成长值获取,不在赘述
##### <font color='forestgreen'>积分消耗</font>
- 积分商城
- 使用商城服务,消耗积分获得商品
- 抵扣购物
- 属于积分商场的一种特殊情况,允许用户在购买某一件商品时,使用积分+货币的方式进行组合支付
- 兑换活动机会
- 虚拟物品的一种,也可以是某一张观影券,用户通过这些虚拟物品,可以得到享受到相关的服务
##### <font color='forestgreen'>跨屏积分(一般指大小屏)</font>
- 积分合并
- 策略A:小屏为主体,合并操作后大屏积分划为小屏积分(第一阶段以此策略为主)
- 策略B:所有绑定大屏的小屏,共享使用小屏积分
- 多屏积分的价值比例
##### <font color='forestgreen'>积分到期</font>
- 积分有效期,定期清理,清理时机为查询积分或使用积分时
- 即将到期积分,为用户每次登陆时计算一次
##### <font color='forestgreen'>积分使用优先级</font>
- 优先使用即将到期积分
##### <font color='forestgreen'>积分历史</font>
- 积分获取
- 途径
- 时间
- 业务线
- 积分消耗
- 途径
- 时间
- 业务线
##### <font color='forestgreen'>系统台账</font>
- 系统级别的整体积分清单
#### 权益体系
> 权益体系定义了用户在整个会员系统中能获得的权益集合,包含多种不同的权益类型,用户通过完成任务获得对应的权益
##### <font color='forestgreen'>权益种类</font>
###### <font color='dodgerblue'>核心类</font>
- 成长值
- 积分
###### <font color='dodgerblue'>其他类</font>
- 优惠券
- 观影券
- 活动参与机会
- 。。。
##### <font color='forestgreen'>权益的失效类型</font>
- 指定时间范围(每日清空也算是一种特殊的指定时间范围)
- 获取权益后若干时间后
##### <font color='forestgreen'>权益实体</font>
之前在活动模块设计方案中,权益相关模型没有建立,只是使用权益类型和权益数量来描述权益的获得信息。<font color='red'>针对会员系统的营销多元化手段,将成长值、积分两大常规权益单独独立出来,其余类型权益统一建立权益实体来维护</font>
权益实体可对应优惠券、观影券、奖品、活动参与机会(对应活动),采用entity_type和entity_id的常规模式来描述
##### <font color='forestgreen'>权益的发放</font>
###### <font color='dodgerblue'>即时发放</font>
- 积分、成长值等通过会员引擎计算,即时发放
- 会员等级一次性权益发放
- 大多任务的权益为此类型
###### <font color='dodgerblue'>定期发放</font>
- 会员vip/会员等级的月度权益,以月为时间单位发放
###### <font color='dodgerblue'>即时获取</font>
- 会员权带来的活动次数增加
- 在参与活动时额外地为他增加一次活动机会
#### 任务体系
> 所有的权益获得都通过完成任务这一统一概念获得,任务体系作为一个基础能力贯穿会员系统的始终。<font color='red'>任务定义了不同种类、不同数量、不同组合的用户操作所能获得权益的规则</font>
##### <font color='forestgreen'>关注事件</font>
- 任务的关注事件和消息生产者的topic相关
- 登录任务关注登录事件
- 观影类任务关注用户播放事件
##### <font color='forestgreen'>对应权益</font>
- 完成任务可以获得对应的权益
- 成长值、积分属于特殊权益,有别于其他类型权益单独配置
- 一个任务的完成,可配置可获得成长值、可获得积分、可获得其他类型权益(唯一)
- 权益需要配置,指定一个确定的权益,如果只有积分或成长值的权益奖励,那无需配置具体其他类型权益
##### <font color='forestgreen'>任务类型</font>
- 单次
- 每日
- 非每日
- 多次(有上线)
- 每日
- 非每日
- 无限次
##### <font color='forestgreen'>任务进度</font>
- 对于需要重复完成的操作才能满足条件的任务,进度表可做相关记录
- <font color='red'>已完成的行为量/目标行为量=任务完成进度</font>
- 可支持累计观看、累计登录送XXX等业务
- 随着更多业务场景的引入和复杂度的提升,后续可能需要task detail表支持,验证任务进度的变化
### <font color='darkblue'>User Center管理侧功能</font>
#### 会员管理
##### <font color='forestgreen'>会员查询</font>
- 基本属性
- 地址属性(不同选项卡)
- 标签(来自于用户画像系统)
- 积分信息
- 当前积分,近期过期的积分
- 历史明细
- 黑名单管理
##### <font color='forestgreen'>分群管理</font>
- 引用用户画像相关功能
##### <font color='forestgreen'>会员等级管理</font>
- 名称、标识、状态、对应成长值、<font color='red'>对应权益</font>
- 权益会走任务条线
- 数据以顺序排列
##### <font color='forestgreen'>成长任务管理</font>
- 任务的定义
- 关注事件
- 成长值的获得
#### 积分管理
##### <font color='forestgreen'>积分查询</font>
- 按会员等级、地区、用户(可选)查询积分
- 查看指定用户积分详细
- 手工积分发放
- 也需要写明细
- 导出
##### <font color='forestgreen'>积分任务管理</font>
- 任务的定义
- 关注事件
- 积分的获得
##### <font color='forestgreen'>积分台账</font>
- 以日周月的维度展示系统整体积分变化
- 可查询特定时间整体积分的变化
#### 权益管理
##### <font color='forestgreen'>权益定义</font>
- 名称、种类、失效类型。。。
- 对应实体类型
##### <font color='forestgreen'>权益发放</font>
> 不通任务驱动,直接手工发放
- 对应权益,指定用户,进行发放,权益发放记录(表)
##### <font color='forestgreen'>权益获取记录</font>
- 查询,见模型
### <font color='darkblue'>User Center相关模型定义</font>
![image-20210927191840834](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927191840.png)
#### 账号
- uc_user_tv为大屏表
- 在服务系统中,该表只会有一个渠道的记录
- 在管理系统中,该表会汇聚所有会员系统对接的渠道对应的大屏账号数据
- 小屏侧由于业务的差异性,根据具体客户端进行模型的分离
##### <font color='forestgreen'>uc_user_tv 大屏账号</font>
```sql
# 大屏账号表
CREATE TABLE `uc_user_tv` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员ID',
`platform` varchar(32) DEFAULT NULL COMMENT '运营商平台',
`platform_account` varchar(32) DEFAULT NULL COMMENT '运营商平台账号',
`cellphone` varchar(32) DEFAULT NULL COMMENT '手机号',
`username` varchar(32) DEFAULT NULL COMMENT '用户名',
`password` varchar(32) DEFAULT NULL COMMENT '密码 MD5',
`nickname` varchar(32) DEFAULT NULL COMMENT '昵称 Base64',
`image` varchar(1024) DEFAULT NULL COMMENT '头像',
`login_days` int(11) DEFAULT '0' COMMENT '登录天数(总天数)',
`continue_days` int(11) DEFAULT '0' COMMENT '连续登录天数',
`active_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '活跃时间',
`groups` varchar(32) DEFAULT NULL COMMENT '分组 分组ID用逗号分隔',
`tags` varchar(512) DEFAULT NULL COMMENT '标签 标签用逗号分隔',
`login_type` int(11) DEFAULT NULL COMMENT '登录类型 1-运营商隐式登录 2-手机验证登录 3-微信登录 4-QQ登录 5-微博登录 6-苹果登录',
`status` int(11) DEFAULT NULL COMMENT '状态 0-下线 1-上线',
`description` varchar(512) DEFAULT NULL COMMENT '描述',
`create_by` varchar(32) DEFAULT 'system' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(32) DEFAULT 'system' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `platform` (`platform`),
KEY `platform_account` (`platform_account`),
KEY `username` (`username`),
KEY `status` (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='大屏账号表';
```
##### <font color='forestgreen'>uc_user_weixin微信账号</font>
```sql
# 微信账号表
CREATE TABLE `uc_user_weixin` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`member_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
`unionid` varchar(32) DEFAULT NULL COMMENT '微信unionid,针对开发者',
`appid` varchar(32) DEFAULT NULL COMMENT '微信appid',
`openid` varchar(32) DEFAULT NULL COMMENT '微信openid,针对微信app',
`status` tinyint(4) DEFAULT '0' COMMENT '关注状态 0 -未关注 1 - 已关注',
`sync_status` tinyint(4) DEFAULT '0' COMMENT '关注同步状态 0-未同步,1-已同步',
`nickname` varchar(32) DEFAULT NULL COMMENT '昵称 base64',
`headimg_url` varchar(1024) DEFAULT NULL COMMENT '头像地址',
`privilege` varchar(32) DEFAULT NULL COMMENT '特权信息',
`refresh_token` varchar(128) DEFAULT NULL COMMENT '刷新凭据',
`access_token` varchar(128) DEFAULT NULL COMMENT '凭据',
`expires_in` int(11) DEFAULT NULL COMMENT '超时(秒)',
`expires_time` datetime DEFAULT NULL COMMENT '超时时间',
`description` varchar(512) DEFAULT NULL COMMENT '描述',
`create_by` varchar(32) DEFAULT 'system' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(32) DEFAULT 'system' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `unionid` (`unionid`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8 COMMENT='微信账号表';
```
#### 用户/会员
##### <font color='forestgreen'>uc_member_level 会员等级</font>
```sql
# 会员等级表
CREATE TABLE `uc_member_level` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(32) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0:未启用;1:启用',
`exp_value` bigint(255) NOT NULL COMMENT '对应成长值',
`level` tinyint(4) NOT NULL DEFAULT '1' COMMENT '等级(不可重复,数字越大等级越高)',
`icon_url` varchar(255) DEFAULT NULL COMMENT '会员徽标',
`description` varchar(1024) DEFAULT NULL COMMENT '描述',
`task_id` bigint(20) DEFAULT NULL COMMENT '对应任务id,通过此字段可获得该等级所对应的权益',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员等级表';
```
##### <font color='forestgreen'>uc_member</font>
```sql
# 会员表
CREATE TABLE `uc_member` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(255) NOT NULL COMMENT '标识',
`type` tinyint(4) NOT NULL COMMENT '类型 1:大屏;2:小屏',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态 0:不可用;(禁用权益)1:可用',
`nickname` varchar(64) DEFAULT NULL COMMENT '昵称 base64',
`description` varchar(1024) DEFAULT NULL COMMENT '描述',
`gender` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '性别 0:女;1:男;-1:未知',
`birthday` varchar(32) DEFAULT NULL COMMENT '生日',
`avatar_url` varchar(1024) DEFAULT NULL COMMENT '头像',
`groups` varchar(255) DEFAULT NULL COMMENT '分组信息',
`tags` varchar(1024) DEFAULT NULL COMMENT '标签',
`vip` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0:非会员;1:xx会员; 2:xx会员;(数据字典配置)',
`level` tinyint(4) NOT NULL DEFAULT '1' COMMENT '会员等级(对应level表的level字段,非id)',
`exp` bigint(20) DEFAULT NULL COMMENT '成长值',
`points` bigint(20) DEFAULT NULL COMMENT '当前积分',
`due_points` bigint(20) DEFAULT NULL COMMENT '即将到期积分(一个月内)',
`coupon_amount` int(11) DEFAULT NULL COMMENT '优惠券数量',
`due_coupon_amount` int(11) DEFAULT NULL COMMENT '即将过期优惠券数量',
`user_iptv_id` bigint(20) DEFAULT NULL COMMENT 'iptv账号id',
`bind_iptv_platform_type` tinyint(4) DEFAULT NULL COMMENT '绑定IPTV平台 0:未知;1:电信;2:移动;3:联通',
`bind_iptv_time` datetime DEFAULT NULL COMMENT 'iptv账号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `code` (`code`),
KEY `nickname` (`nickname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员表';
```
##### <font color='forestgreen'>uc_member_profile 会员基础信息</font>
```sql
# 会员基础信息表
CREATE TABLE `uc_member_profile` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`realname` varchar(32) DEFAULT NULL COMMENT '姓名',
`gender` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '性别 0:女; 1:男 -1:未知',
`birthday` date NOT NULL DEFAULT '1900-01-01' COMMENT '生日',
`constellation` varchar(32) DEFAULT NULL COMMENT '星座',
`id_card` varchar(32) NOT NULL DEFAULT '000000000000000000' COMMENT '身份证',
`email` varchar(64) DEFAULT NULL COMMENT '电子邮件',
`country` varchar(32) DEFAULT NULL COMMENT '国家',
`province` varchar(32) DEFAULT NULL COMMENT '省份',
`city` varchar(32) DEFAULT NULL COMMENT '城市',
`district` varchar(32) DEFAULT NULL COMMENT '区县',
`description` varchar(1024) DEFAULT NULL COMMENT '描述',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='会员基础信息表';
```
##### <font color='forestgreen'>uc_member_address 会员地址信息</font>
```sql
# 会员地址信息表
CREATE TABLE `uc_member_address` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '类型 1:家;2:公司;3:学校',
`is_default` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否默认地址',
`sequence` int(11) DEFAULT NULL COMMENT '显示顺序',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态 0:不可用;1-可用',
`contactor` varchar(64) NOT NULL COMMENT '联系人姓名',
`cellphone` varchar(32) NOT NULL COMMENT '联系人电话',
`country` varchar(64) NOT NULL COMMENT '国家',
`province` varchar(64) NOT NULL COMMENT '省份',
`city` varchar(64) NOT NULL COMMENT '城市',
`district` varchar(64) NOT NULL COMMENT '区县',
`address` varchar(255) NOT NULL COMMENT '地址',
`zip_code` varchar(16) DEFAULT NULL COMMENT '邮编',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `contactor` (`contactor`),
KEY `cellphone` (`cellphone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员地址信息表';
```
##### <font color='forestgreen'>uc_member_related_info 会员相关人信息</font>
```sql
# 会员相关人信息表
CREATE TABLE `uc_member_related_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`type` tinyint(4) DEFAULT NULL COMMENT '人物关系 0:子女;1:父母',
`cellphone` varchar(32) DEFAULT NULL COMMENT '手机号',
`id_card` varchar(32) DEFAULT NULL COMMENT '身份证号',
`name` varchar(32) DEFAULT NULL COMMENT '姓名',
`sex` tinyint(4) DEFAULT NULL COMMENT '性别 0:女;1:男;-1:未知',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员相关人信息表';
```
##### <font color='forestgreen'>uc_permanent_rights 永久权益</font>
```sql
# 永久权益表
CREATE TABLE `uc_permanent_rights` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(64) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`type` tinyint(4) DEFAULT NULL COMMENT '永久权益类型 0:vip;1:会员等级',
`level` tinyint(4) DEFAULT NULL COMMENT '等级(当权益类型为vip时,对应vip值,当权益类型为会员等级时,对应等级index)',
`item_discount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品折扣,10代表10% off,范围为0-100',
`extra_points` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '额外积分比率,范围为0-1000',
`ad_disabled` tinyint(4) NOT NULL DEFAULT '0' COMMENT '免广告',
`extra_activity_ticket` tinyint(4) NOT NULL DEFAULT '0' COMMENT '额外活动参与机会',
`free_trial` tinyint(4) NOT NULL DEFAULT '0' COMMENT '免费试看',
`zone_sds` tinyint(4) NOT NULL DEFAULT '0' COMMENT '上电视专区权益',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='永久权益表';
```
#### 任务/权益
> 抽象统一的任务/权益模型,覆盖成长值任务、积分任务及其他任务
##### <font color='forestgreen'>tr_rights 权益</font>
```sql
# 权益表
CREATE TABLE `tr_rights` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) NOT NULL COMMENT '标识',
`type` tinyint(4) NOT NULL COMMENT '类型 1:实体类 (预留字段)',
`device_type` tinyint(4) DEFAULT NULL COMMENT '终端类型 0:大屏;1:微信小程序/公众号;2:App',
`entity_type` varchar(64) NOT NULL COMMENT '权益的实体类型',
`entity_id` bigint(20) NOT NULL COMMENT '实体id',
`image` varchar(1024) DEFAULT NULL COMMENT '图片',
`images` varchar(1024) DEFAULT NULL COMMENT '图片',
`description` varchar(1024) DEFAULT NULL COMMENT '描述',
`valid_time` datetime DEFAULT NULL COMMENT '生效时间,为null表示获取后立即生效,不为空时,表示特定的生效时间',
`expire_time` bigint(20) DEFAULT NULL COMMENT '失效时间,空为不失效,否则为获得权益后直到失效的毫秒数',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `entity_type` (`entity_type`),
KEY `entity_id` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权益表';
```
##### <font color='forestgreen'>tr_task_template 任务模板</font>
```sql
# 任务模板表
CREATE TABLE `tr_task_template` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`code` varchar(64) DEFAULT NULL COMMENT '标识',
`name` varchar(255) DEFAULT NULL COMMENT '名称',
`event` varchar(255) DEFAULT NULL COMMENT '关注事件(和MQ topic相关)',
`description` varchar(1020) COMMENT '描述',
`status` tinyint(4) DEFAULT 1 COMMENT '状态 0:失效;1:生效',
`type` tinyint(4) DEFAULT 0 COMMENT '类型 0:活动任务模板',
`params` text DEFAULT NULL COMMENT '模板参数,json',
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='任务模板表';
```
##### <font color='forestgreen'>tr_task 任务</font>
```sql
CREATE TABLE `tr_task` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(255) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`task_template_id` bigint(20) NOT NULL COMMENT '任务模板id',
`task_repeat_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '任务重复类型,-1:不限次;1:单次;>1:多次',
`task_daily_reset` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务每日重置 0:不重置;1:重置',
`action_amount` int(11) NOT NULL DEFAULT '1' COMMENT '行为量(完成此任务需要多少次相同行为的触发)',
`valid_time` datetime DEFAULT NULL COMMENT '任务生效时间',
`expire_time` datetime DEFAULT NULL COMMENT '任务失效时间',
`sequence` int(11) DEFAULT NULL COMMENT '显示顺序',
`reward_exp` bigint(20) NOT NULL DEFAULT '0' COMMENT '获得成长值',
`reward_points` bigint(20) NOT NULL DEFAULT '0' COMMENT '获得积分(当积分获得类型为随机时,代表最小获得积分数)',
`reward_points_expire_time` bigint(20) DEFAULT NULL COMMENT '积分过期时间(空为不过期)',
`points_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '积分获取类型 0:定值;1:随机',
`reward_max_points` bigint(4) DEFAULT NULL COMMENT '随机积分最大值',
`groups` varchar(255) DEFAULT NULL COMMENT '能够获取该任务的用户分组,为空则都能获取',
`rights_send_strategy` tinyint(4) NOT NULL DEFAULT '0' COMMENT '权益发放策略 0:立即发放;1:次日发放;2:次月发放',
`member_exclusive` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员专享 0:非会员专享 1:会员专享',
`member_level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员等级门槛(0表示无门槛)',
`member_vip` tinyint(4) DEFAULT NULL COMMENT '会员vip门槛(0表示没有门槛)',
`rights_id` bigint(20) DEFAULT NULL COMMENT '权益id',
`rights_amount` int(11) DEFAULT NULL COMMENT '权益数量(活动机会次数、优惠券数量、奖品数量)',
`rights2_id` bigint(20) DEFAULT NULL COMMENT '权益2id',
`rights2_amount` int(11) DEFAULT NULL COMMENT '权益2数量',
`rights3_id` bigint(20) DEFAULT NULL COMMENT '权益3id',
`rights3_amount` int(255) DEFAULT NULL COMMENT '权益3数量',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态 0:失效;1:生效',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `rights_id` (`rights_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='任务表';
```
##### <font color='forestgreen'>tr_rights_history 权益发放记录</font>
```sql
# 权益发放记录表
CREATE TABLE `tr_rights_histroy` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`rights_id` bigint(20) DEFAULT NULL COMMENT '权益id',
`member_id` bigint(20) DEFAULT NULL COMMENT '会员id',
`operator_id` bigint(20) DEFAULT NULL COMMENT '操作者id(手动发放时保存)',
`operator_name` varchar(255) DEFAULT NULL COMMENT '操作者名称(手动发放时保存)',
`send_time` datetime DEFAULT NULL COMMENT '发放时间',
`expire_time` datetime DEFAULT NULL COMMENT '失效时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权益发放记录';
```
#### 成长值
##### <font color='forestgreen'>uc_exp_detail 成长值历史</font>
```sql
# 成长值明细表
CREATE TABLE `uc_exp_detail` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(255) NOT NULL COMMENT '标识',
`app_code` varchar(64) DEFAULT NULL COMMENT '应用code',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`account_id` bigint(20) DEFAULT NULL COMMENT '账号id',
`original_exp` bigint(20) NOT NULL COMMENT '原始成长值',
`result_exp` bigint(20) NOT NULL COMMENT '结果成长值',
`exp` bigint(20) NOT NULL COMMENT '成长值变化,一般为正数',
`device_type` tinyint(4) NOT NULL COMMENT '设备类型 1:大屏;2:小屏(微信)3.小屏(xx)',
`evt_type` tinyint(4) NOT NULL DEFAULT '99' COMMENT '行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他',
`order_id` bigint(20) DEFAULT '0' COMMENT '订单id(针对订购操作)',
`media_id` bigint(20) DEFAULT '0' COMMENT '节目id(针对观影操作)',
`activity_id` bigint(20) DEFAULT NULL COMMENT '活动id(针对参与活动)',
`description` varchar(255) NOT NULL COMMENT '成长值变化描述,用于管理侧显示',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `evt_type` (`evt_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='成长值明细表';
```
##### <font color='forestgreen'>uc_exp_detail_history 成长值明细历史</font>
```sql
# 成长值明细历史表
CREATE TABLE `uc_exp_history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(255) NOT NULL COMMENT '标识',
`app_code` varchar(64) DEFAULT NULL COMMENT '应用code',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`account_id` bigint(20) DEFAULT NULL COMMENT '账号id',
`original_exp` bigint(20) NOT NULL COMMENT '原始成长值',
`result_exp` bigint(20) NOT NULL COMMENT '结果成长值',
`exp` bigint(20) NOT NULL COMMENT '成长值变化,一般为正数',
`device_type` tinyint(4) NOT NULL COMMENT '设备类型 1:大屏;2:小屏(微信)3.小屏(xx)',
`evt_type` tinyint(4) NOT NULL DEFAULT '99' COMMENT '行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他',
`order_id` bigint(20) DEFAULT '0' COMMENT '订单id(针对订购操作)',
`media_id` bigint(20) DEFAULT '0' COMMENT '节目id(针对观影操作)',
`activity_id` bigint(20) DEFAULT NULL COMMENT '活动id(针对参与活动)',
`description` varchar(255) NOT NULL COMMENT '成长值变化描述,用于管理侧显示',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `evt_type` (`evt_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='成长值明细历史表';
```
#### 积分
##### <font color='forestgreen'>uc_points_detail 积分明细</font>
```sql
# 积分历史表
CREATE TABLE `uc_points_detail` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) NOT NULL COMMENT '标识',
`app_code` varchar(64) DEFAULT NULL COMMENT '应用code',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`account_id` bigint(20) DEFAULT NULL COMMENT '账号id',
`original_points` bigint(20) NOT NULL COMMENT '原始积分',
`result_points` bigint(20) NOT NULL COMMENT '结果积分',
`points` bigint(20) NOT NULL COMMENT '积分变化,积分获得为正,积分消耗为负',
`device_type` tinyint(4) NOT NULL COMMENT '设备类型 1:大屏;2:小屏(微信)3.小屏(xx)',
`evt_type` tinyint(4) NOT NULL DEFAULT '99' COMMENT '行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;30:积分兑换商品;98:系统操作;99:其他',
`order_id` bigint(20) DEFAULT '0' COMMENT '订单id(针对订购操作)',
`media_id` bigint(20) DEFAULT '0' COMMENT '节目id(针对观影操作)',
`activity_id` bigint(20) DEFAULT NULL COMMENT '活动id(针对参与活动)',
`item_id` bigint(20) DEFAULT NULL COMMENT '商品id(积分兑换,同时写入订单id)',
`description` varchar(255) NOT NULL COMMENT '积分变化描述,用于管理侧显示',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `evt_type` (`evt_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='积分明细表';
```
##### <font color='forestgreen'>uc_points_detail_history 积分明细历史</font>
```sql
# 积分历史表
CREATE TABLE `uc_points_detail_history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) NOT NULL COMMENT '标识',
`app_code` varchar(64) DEFAULT NULL COMMENT '应用code',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`account_id` bigint(20) DEFAULT NULL COMMENT '账号id',
`original_points` bigint(20) NOT NULL COMMENT '原始积分',
`result_points` bigint(20) NOT NULL COMMENT '结果积分',
`points` bigint(20) NOT NULL COMMENT '积分变化,积分获得为正,积分消耗为负',
`device_type` tinyint(4) NOT NULL COMMENT '设备类型 1:大屏;2:小屏(微信)3.小屏(xx)',
`evt_type` tinyint(4) NOT NULL DEFAULT '99' COMMENT '行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他',
`order_id` bigint(20) DEFAULT '0' COMMENT '订单id(针对订购操作)',
`media_id` bigint(20) DEFAULT '0' COMMENT '节目id(针对观影操作)',
`activity_id` bigint(20) DEFAULT NULL COMMENT '活动id(针对参与活动)',
`description` varchar(255) NOT NULL COMMENT '积分变化描述,用于管理侧显示',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `evt_type` (`evt_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='积分明细历史表';
```
##### <font color='forestgreen'>uc_points_available 可用积分表</font>
```sql
# 可用积分表
CREATE TABLE `uc_points_available` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` varchar(64) NOT NULL COMMENT '标识',
`points_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '积分类型 0:通用型',
`device_type` tinyint(4) DEFAULT NULL COMMENT '设备类型 1:大屏;2:小屏(微信)3.小屏(xx)',
`member_id` bigint(20) NOT NULL COMMENT '会员id',
`points` bigint(20) NOT NULL COMMENT '积分值',
`expire_time` datetime DEFAULT NULL COMMENT '过期时间',
`description` varchar(255) NOT NULL COMMENT '描述',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='可用积分表';
```
##### <font color='forestgreen'>uc_points_standing_book 积分台账</font>
```sql
# 积分台账表
CREATE TABLE `uc_points_standing_book` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`points_produce` bigint(20) NOT NULL COMMENT '积分生产',
`points_consume` bigint(20) NOT NULL COMMENT '积分消耗',
`points_available` bigint(20) NOT NULL COMMENT '可用总积分',
`points_expire` bigint(20) NOT NULL COMMENT '积分过期',
`day` varchar(16) DEFAULT NULL COMMENT '日期',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分台账表';
```
#### 优惠券
> 使用商城系统中的营销模块,基本没有改变
##### <font color='forestgreen'>m_coupon 优惠券</font>
```sql
#优惠券表
CREATE TABLE `m_coupon` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`code` varchar(64) NOT NULL COMMENT '标识',
`title` varchar(255) NOT NULL COMMENT '名称',
`images` varchar(1024) DEFAULT NULL COMMENT '图片',
`stock` int(11) DEFAULT '-1' COMMENT '发行量,-1代表不限量',
`remain_stock` int(11) DEFAULT '-1' NULL COMMENT '剩余量,-1代表不限量',
`use_type` tinyint(4) DEFAULT '1' COMMENT '优惠形式:1:金额;2:折扣',
`denomination` decimal(10,2) DEFAULT NULL COMMENT '面额',
`discount` decimal(10,2) DEFAULT NULL COMMENT '折扣',
`user_range` tinyint(4) DEFAULT '2' COMMENT '适用用户范围:1:新用户;2:全体用户;3:指定用户分组',
`groups` varchar(1024) DEFAULT NULL COMMENT '用户分组,逗号分隔',
`collect_limit` tinyint(4) DEFAULT '1' COMMENT '限领次数 -1:无限次; >0:具体次数',
`threshold_type` tinyint(4) DEFAULT '1' COMMENT '适用门槛:1:无门槛;2:满减形式',
`amount_threshold` decimal(10,2) DEFAULT null COMMENT '满减门槛',
`item_range` tinyint(4) DEFAULT '1' COMMENT '产品范围:1:全部商品;2:指定商品',
`effect_type` tinyint(4) DEFAULT null COMMENT '生效形式:1:固定日期;2:相对日期',
`start_time` datetime DEFAULT NULL COMMENT '生效时间',
`expire_time` datetime DEFAULT NULL COMMENT '过期时间',
`valid_days` int(11) DEFAULT NULL COMMENT '自领取当日,几天内有效',
`description` varchar(255) DEFAULT NULL COMMENT '使用说明',
`status` tinyint(4) DEFAULT null COMMENT '状态 0:未开始,1:启用;2:停用',
`member_exclusive` tinyint(4) DEFAULT null COMMENT '会员专享 0:非会员专享 1:会员专享',
`member_level` tinyint(4) DEFAULT null COMMENT '会员等级门槛(0:表示无门槛)',
`member_vip` tinyint(4) DEFAULT null COMMENT '会员vi门槛(0:表示无门槛)',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=' 优惠券表';
```
##### <font color='forestgreen'>m_coupon_history</font>
```sql
#优惠券领取、使用历史记录表
CREATE TABLE `m_coupon_history` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`coupon_id` bigint DEFAULT NULL COMMENT '优惠券id',
`user_id` bigint DEFAULT NULL COMMENT '领券用户id(对应账号)',
`coupon_code` varchar(64) DEFAULT NULL COMMENT '优惠券code',
`user_nickname` varchar(255) DEFAULT NULL COMMENT '领取人昵称',
`receive_time` datetime DEFAULT NULL COMMENT '领取时间',
`expire_time` datetime DEFAULT NULL COMMENT '失效时间',
`use_status` int DEFAULT NULL COMMENT '使用状态 0:未使用;1:已使用;-1:已过期',
`use_time` datetime DEFAULT NULL COMMENT '使用时间',
`order_detail_id` bigint DEFAULT NULL COMMENT '订单详情id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_member_id` (`user_id`) USING BTREE,
KEY `idx_coupon_id` (`coupon_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='优惠券领取、使用历史记录表';
```
### <font color='darkblue'>User Center 成长值/积分计算引擎,API</font>
> 会员成长/积分计算引擎内置于User Center中,<font color='red'>负责异步处理成长值、积分的获得,一般为消息队列的消费者</font>,通过不同的事件进行驱动,数据库指向服务侧
> 会员引擎统一API数据库指向管理侧,<font color='red'>在中央统一处理积分的消耗,避免多端的数据一致性问题</font>,具体部署时应考虑系统压力
简单来说,积分的获得实时性要求不高,由服务侧通过消息队列,异步更新到中央数据库中,积分的消耗由于牵涉到并发,数据一致性问题,直接请求api,中央统一处理保证数据的一致性
#### 引擎功能
![image-20210927153528449](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927153528.png)
#### 会员引擎架构
![image-20210927181349132](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927181349.png)
#### 积分过期、积分消耗、积分明细查询的技术实现
积分明细表记录了用户积分的增减情况,需要展现给用户,所以无法在这上面下手,为此新添加了一张表来记录当前<font color='red'>可用积分明细</font>。该表的关键字段如下:
| 字段 | 含义 |
| -------- | ---------------- |
| 积分值 | 该记录的积分值 |
| 创建时间 | 该积分的生效时间 |
| 过期时间 | 该积分的过期时间 |
##### <font color='forestgreen'>积分过期</font>
- <font color='red'>可用积分表</font>(uc_points_available)删除过期记录
- <font color='red'>积分明细表</font>(uc_points_detail)添加一条过期明细,即负的积分
- <font color='red'>积分总额表</font>(uc_points)更新为当前积分总额
> 每天定时扫描<font color='red'>可用积分表</font>,将过期积分删除,并及时更新积分明细表和积分总额表
##### <font color='forestgreen'>积分使用</font>
![image-20210927155637989](https://cy-topdraw.oss-cn-shanghai.aliyuncs.com/typora/20210927155638.png)
### <font color='darkblue'>商城服务体系</font>
#### 商品体系
> 商品整个设计见mall-service相关文档
- 支持商品会员价
- vip/会员等级权益(折扣)
- 会员专属价格(不建议等级差异化,过于复杂)
- 上述两者最好二选一,或者有会员专属价格的优先计算,不再使用vip/会员等级权益折扣
- 支持会员专享商品
- 角标
- <font color='red'>下单接口一定要区分领券购买和普通购买</font>
#### 营销体系
#### 模型变更
##### <font color='forestgreen'>i_item 商品</font>
```sql
# 会员专享
ALTER TABLE i_item ADD COLUMN member_exclusive tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员专享 0:非会员专享 1:会员专享' AFTER is_unite_tail;
ALTER TABLE i_item ADD COLUMN member_price decimal(10,2) NOT NULL COMMENT '会员价格' AFTER price;
```
##### <font color='forestgreen'>i_sku 商品规格</font>
```sql
# 会员价
ALTER TABLE i_sku ADD COLUMN member_price decimal(10,2) DEFAULT NULL COMMENT '会员价格' AFTER promotion_price;
```
##### <font color='forestgreen'>m_coupon</font>
```sql
# 会员专享
ALTER TABLE `m_coupon` ADD COLUMN `member_exclusive` tinyint(4) NULL DEFAULT 0 COMMENT '会员专享 0:非会员专享 1:会员专享' AFTER `effect_type`;
# 会员等级门槛
ALTER TABLE `m_coupon` ADD COLUMN `member_level` tinyint(4) NULL DEFAULT 0 COMMENT '会员等级门槛(0表示无门槛)' AFTER `member_exclusive`;
# 会员vip门槛
ALTER TABLE `m_coupon` ADD COLUMN `member_vip` tinyint(4) NULL DEFAULT 0 COMMENT '会员vip门槛(0表示没有门槛)' AFTER `member_level`;
```
### <font color='darkblue'>活动服务体系</font>
>为了区分IPTV常规营销活动和小屏侧主题活动(暂定名)或赛事,<font color='red'>将原有的活动模型拆分为两个独立的模型,明晰模型定位</font>
#### 营销活动
常规的IPTV影响活动,现在主要分为三大类,投票、抽奖、闯关。后续可根据实际情况扩展。
此部分有单独文档定义,这里不再赘述。
#### 主题活动
- OMO新版本的核心
- 支持报名相关配置
- 活动的参与条件
- 流程的完整定义(报名、参与、审核、支付、证书)
##### <font color='forestgreen'>ugc</font>
- ugc是主题活动关联的主体,不再关联原先的营销活动
- ugc支持作品、花絮不同种类的支持
- ugc的投票已支持
- ugc的点赞
- ugc的评论(短期不做)
- 动态???
##### <font color='forestgreen'>报名</font>
- 报名费统一采用商品支持,即主题活动可关联商品(开启报名为前提)
- 活动邀请券使用商品优惠券的方式实现
- 全额抵扣
- 部分抵扣
- 优惠券受会员等级约束
##### <font color='forestgreen'>商品包装</font>
> 主题活动可作为商品的一种包装形式,<font color='red'>可支持特殊商品的定制化呈现</font>
- 普通商品的包装
- 报名费的包装
#### 主题活动专区
- OMO新版本需求核心“小演员”,“上电视”其实就是专区的概念
- 专区类似栏目,支持对主题活动的编排
#### 模型定义
##### <font color='forestgreen'>act_theme_activity_section 主题活动专区</font>
```sql
# 主题活动专区表
CREATE TABLE `act_theme_activity_section` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(32) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`description` varchar(1000) DEFAULT NULL COMMENT '描述',
`sequence` int(11) NOT NULL DEFAULT '0' COMMENT '显示顺序',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态 0:下线;1:上线',
`member_exclusive` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员专享 0:非会员专享 1:会员专享',
`member_level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员等级门槛(0表示没有门槛)',
`member_vip` tinyint(4) DEFAULT NULL COMMENT '会员vip门槛(0表示没有门槛)',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='主题活动专区表';
```
##### <font color='forestgreen'>act_theme_activity 主题活动</font>
```sql
# 主题活动表
CREATE TABLE `act_theme_activity` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(32) NOT NULL COMMENT '标识',
`name` varchar(255) NOT NULL COMMENT '名称',
`description` varchar(1000) DEFAULT NULL COMMENT '描述',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态 0:下线;1:上线',
`sequence` int(11) NOT NULL DEFAULT '0' COMMENT '显示顺序',
`section_id` bigint(20) NOT NULL COMMENT '专区id',
`member_exclusive` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员专享 0:非会员专享 1:会员专享',
`member_level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员等级门槛(0表示无门槛)',
`member_vip` tinyint(4) NOT NULL DEFAULT '0' COMMENT '会员vip门槛(0表示没有门槛)',
`app_id` bigint(20) NOT NULL COMMENT '所属应用',
`start_time` datetime NOT NULL COMMENT '活动开始时间',
`end_time` datetime NOT NULL COMMENT '活动结束时间',
`register_switch` tinyint(4) NOT NULL DEFAULT '1' COMMENT '报名开关 0:关闭报名环节;1:开启报名环节',
`register_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '报名类型 0:资质类;1:直通类',
`register_info` varchar(1000) DEFAULT NULL COMMENT '报名信息(json格式)',
`register_ugc_type` tinyint(4) DEFAULT NULL COMMENT '报名作品类型 0:图片;1:视频;10:图片或视频',
`register_start_time` datetime DEFAULT NULL COMMENT '报名开始时间',
`register_end_time` datetime DEFAULT NULL COMMENT '报名截止时间',
`item_id` bigint(20) DEFAULT NULL COMMENT '商品id(主题活动/报名费可视作一个商品,只有在开启报名时有效)',
`vote_activity_id` bigint(20) DEFAULT NULL COMMENT '投票活动id(当主题活动有投票环节时启用)',
`group_range` varchar(500) DEFAULT NULL COMMENT '活动分组列表,多个使用逗号分隔',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='主题活动表';
```
#### 模型变更
##### <font color='forestgreen'>x_ugc</font>
```sql
# 会员id
ALTER TABLE x_ugc ADD COLUMN member_id bigint(20) COMMENT '会员id' AFTER user_id;
# ugc
ALTER TABLE x_ugc ADD COLUMN category tinyint(4) COMMENT '类别 0:作品;1:花絮' AFTER type;
# 审核原因
ALTER TABLE `x_ugc` ADD COLUMN `audit_remark` varchar(2048) NULL COMMENT '审核原因' AFTER `comment_number`;
```
##### <font color='forestgreen'>act_user_sign_up</font>
```sql
# 审核原因
ALTER TABLE `act_user_sign_up` ADD COLUMN `audit_remark` varchar(2048) NULL COMMENT '审核原因' AFTER `qualification_image`;
```
### <font color='darkblue'>CMS系统</font>
#### 推荐位编排
> 支持上电视专区的瀑布流配置
>
- 支持主题活动跳转
- 支持主题活动专区跳转
### <font color='darkblue'>boss系统</font>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>member-service</artifactId>
<groupId>com.topdraw</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>member-service-api</artifactId>
<properties>
</properties>
<dependencies>
<!--代码生成器-->
<dependency>
<groupId>com.topdraw</groupId>
<artifactId>code-generator</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.topdraw.module.mq;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataSyncMsg implements Serializable {
// 事件类型(用户的实际操作)
@NotNull
private String eventType;
// 消息体
private MsgData msg;
// 其他属性
private String extraData;
/**
* 消息体
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class MsgData {
private String remarks; //备注
@NotNull
private Integer event; // 具体事件 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;30:积分兑换商品;98:系统操作;99:其他
@NotNull
private Long memberId; // 会员id
@NotNull
private Integer deviceType; //设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
@NotNull
private String appCode; //用户对应的应用code
private Long accountId; // 账号id
private Long orderId;
private Long activityId;
private Long mediaId;
private Long itemId;
}
}
package com.topdraw.module.mq;
import lombok.Getter;
// 实体类型
@Getter
public enum EntityType {
// 用户
PERSON,
// 会员
MEMBER,
// 小屏-微信
WEIXIN_USER,
// 大屏
VIS_USER,
// 地址
PERSON_ADDRESS
}
package com.topdraw.module.mq;
// 关注的事件
public enum EventType {
// 关注
SUBSCRIBE,
// 取消关注
UN_SUBSCRIBE,
// 绑定
BIND,
// 取消绑定
UN_BIND,
// 变更主账号
C_M_ACCOUNT,
// 获取积分
GAIN_POINT,
// 消耗积分
CONSUME_POINT,
// 观影
VIEWING,
// 登录
LOGIN,
// 订购产品包
SUBSCRIBE_PRODUCT_PACKAGE
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>member-service</artifactId>
<groupId>com.topdraw</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>member-service-impl</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<jjwt.version>0.9.1</jjwt.version>
</properties>
<dependencies>
<!--redisson-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.3</version>
</dependency>
<!--api-->
<dependency>
<groupId>com.topdraw</groupId>
<artifactId>member-service-api</artifactId>
<version>${parent.version}</version>
</dependency>
<!--代码生成器-->
<dependency>
<groupId>com.topdraw</groupId>
<artifactId>code-generator</artifactId>
<version>3.1.0</version>
</dependency>
<!-- Spring boot 热部署 : 此热部署会遇到 java.lang.ClassCastException 异常 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--Mysql依赖包,版本差异,需单独引入-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 支持AES/CBC/PKCS7Padding,用于微信小程序登录数据解密 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<!--消息队列相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--重试-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
<profiles>
<profile>
<!-- 本地开发环境 -->
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<!-- 默认的,不加参数时执行这个profile -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 生产环境 -->
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
<modifier>-prod</modifier>
</properties>
</profile>
</profiles>
<build>
<finalName>member-service</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<!-- 复制指定配置文件到指定目录 -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources/config</directory>
<includes>
<include>application.yml</include>
<include>application-${profiles.active}.yml</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}/config</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- jar包内剔除所有配置文件 -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!--不打入jar包的文件类型或者路径-->
<excludes>
<exclude>config/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.topdraw;
import com.topdraw.utils.SpringContextHolder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author XiangHan
* @version 0.0.1
*/
@EnableJpaAuditing
@EnableAsync
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
@EnableTransactionManagement
@EnableRetry
public class MemberServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MemberServiceApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MemberServiceApplication.class);
}
@Bean
public SpringContextHolder springContextHolder() {
return new SpringContextHolder();
}
}
package com.topdraw.aspect;
import com.alibaba.fastjson.JSON;
import com.topdraw.mq.domain.TableOperationMsg;
import com.topdraw.mq.producer.MessageProducer;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.lang.reflect.Method;
@Component
@Slf4j
@Aspect
public class AsyncMqProducer {
private static final Logger LOG = LoggerFactory.getLogger(AsyncMqProducer.class);
@Autowired
MessageProducer messageProducer;
@Resource(name = "executorTask")
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Pointcut(value = "@annotation(asyncMqSend)")
public void sendMqMsg(AsyncMqSend asyncMqSend){
LOG.info("AsyncMqProducer ===>>> sendMqMsg ====>> start");
}
@After("sendMqMsg(asyncMqSend)")
public void doAfter(JoinPoint joinPoint, AsyncMqSend asyncMqSend){
LOG.info("AsyncMqProducer ===>>> doAfter ====>> start");
boolean open = asyncMqSend.open();
if (open) {
try {
this.doTask(joinPoint,asyncMqSend);
} catch (Throwable e) {
e.printStackTrace();
}
}
LOG.info("AsyncMqProducer ===>>> doAfter ====>> end ===>> " );
}
private void doTask(JoinPoint joinPoint, AsyncMqSend asyncMqSend) {
LOG.info("AsyncMqProducer ===>>> doTask ====>> start ===>> " );
String entityName = asyncMqSend.entityName();
String methodName = asyncMqSend.method();
Object defaultServiceImpl = joinPoint.getTarget();
String defaultServiceImplName = defaultServiceImpl.getClass().getName();
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
String defaultMethodName = method.getName();
Object[] args = joinPoint.getArgs();
Object arg = args[0];
String defaultEntityName = arg.getClass().getName();
TableOperationMsg tableOperationMsg = new TableOperationMsg();
tableOperationMsg.setMethodName(StringUtils.isEmpty(methodName)?defaultMethodName:methodName);
tableOperationMsg.setEntityBody(JSON.toJSONString(arg));
tableOperationMsg.setInterfaceName(defaultServiceImplName);
tableOperationMsg.setEntityName(StringUtils.isEmpty(entityName)?defaultEntityName:entityName);
boolean async = asyncMqSend.async();
if (async) {
// 异步
this.sendMqMessage(tableOperationMsg);
} else {
// 同步
this.sendMqMessage(tableOperationMsg);
}
LOG.info("AsyncMqProducer ===>>> doTask ====>> end ===>> " );
}
private void sendMqMessage(TableOperationMsg tableOperationMsg){
this.messageProducer.sendFanoutMessage(JSON.toJSONString(tableOperationMsg));
}
}
package com.topdraw.aspect;
import org.springframework.amqp.core.ExchangeTypes;
import java.lang.annotation.*;
/**
* 在对应的方法上添加此注解,表示对应方法结束后
* 进行异步发送消息到mq中
*
* @author XiangHan
* @date 2021-10-30
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AsyncMqSend {
/** true:开启 false:关闭 */
boolean open() default true;
/** true:异步 false:同步 */
boolean async() default true;
/** 接口实现 */
String serviceImpl() default "";
/** 对应的方法 */
String method() default "";
/** 实体名 */
String entityName() default "";
/** 交换机 */
String exchangeName() default "";
/** 队列名 */
String routeKeyName() default "";
/**交换机类型 */
String exchangeType() default ExchangeTypes.DIRECT;
}
package com.topdraw.business.basicdata.coupon.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="m_coupon")
public class Coupon implements Serializable {
// id
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 名称
@Column(name = "title", nullable = false)
private String title;
// 图片
@Column(name = "images")
private String images;
// 发行量,-1代表不限量
@Column(name = "stock")
private Integer stock;
// 剩余量,-1代表不限量
@Column(name = "remain_stock")
private Integer remainStock;
// 优惠形式:1:现金;2:折扣
@Column(name = "use_type")
private Integer useType;
// 面额
@Column(name = "denomination")
private BigDecimal denomination;
// 折扣
@Column(name = "discount")
private BigDecimal discount;
// 适用用户范围:1:新用户;2:全体用户
@Column(name = "user_range")
private Integer userRange;
// 限领次数 -1:无限次; >0:具体次数
@Column(name = "collect_limit")
private Integer collectLimit;
// 适用门槛:1:无门槛;2:满减形式
@Column(name = "threshold_type")
private Integer thresholdType;
// 满减门槛
@Column(name = "amount_threshold")
private BigDecimal amountThreshold;
// 产品范围:1:全部商品;2:指定商品
@Column(name = "item_range")
private Integer itemRange;
// 生效形式:1:固定日期;2:相对日期
@Column(name = "effect_type")
private Integer effectType;
// 生效时间
@Column(name = "start_time")
private Timestamp startTime;
// 过期时间
@Column(name = "expire_time")
private Timestamp expireTime;
// 自领取当日,几天内有效
@Column(name = "valid_days")
private Integer validDays;
// 使用说明
@Column(name = "description")
private String description;
// 状态0:未开始,1:启用;2:停用
@Column(name = "status")
private Integer status;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(Coupon source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.coupon.history.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="m_coupon_history")
public class CouponHistory implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 优惠券id
@Column(name = "coupon_id")
private Long couponId;
// 领券用户id(对应账号)
@Column(name = "user_id")
private Long userId;
// 优惠券code
@Column(name = "coupon_code")
private String couponCode;
// 领取人昵称
@Column(name = "user_nickname")
private String userNickname;
// 领取时间
@Column(name = "receive_time")
private Timestamp receiveTime;
// 失效时间
@Column(name = "expire_time")
private Timestamp expireTime;
// 使用状态 0:未使用;1:已使用;-1:已过期
@Column(name = "use_status")
private Integer useStatus;
// 使用时间
@Column(name = "use_time")
private Timestamp useTime;
// 订单详情id
@Column(name = "order_detail_id")
private Long orderDetailId;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(CouponHistory source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.coupon.history.repository;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.sql.Timestamp;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-23
*/
public interface CouponHistoryRepository extends JpaRepository<CouponHistory, Long>, JpaSpecificationExecutor<CouponHistory> {
Long countByUserId(Long userId);
Long countByUserIdAndExpireTimeBefore(Long userId, Timestamp now);
Long countByUserIdAndExpireTimeBetween(Long userId, Timestamp now, Timestamp expireTime);
}
package com.topdraw.business.basicdata.coupon.history.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import com.topdraw.business.basicdata.coupon.history.service.CouponHistoryService;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Api(tags = "CouponHistory管理")
@RestController
@RequestMapping("/api/CouponHistory")
public class CouponHistoryController {
@Autowired
private CouponHistoryService CouponHistoryService;
@GetMapping
@ApiOperation("查询CouponHistory")
public ResultInfo getCouponHistorys(CouponHistoryQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(CouponHistoryService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有CouponHistory")
public ResultInfo getCouponHistorys(CouponHistoryQueryCriteria criteria) {
return ResultInfo.success(CouponHistoryService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增CouponHistory")
public ResultInfo create(@Validated @RequestBody CouponHistory resources) {
CouponHistoryService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改CouponHistory")
public ResultInfo update(@Validated @RequestBody CouponHistory resources) {
CouponHistoryService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除CouponHistory")
public ResultInfo delete(@PathVariable Long id) {
CouponHistoryService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.coupon.history.service;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryDTO;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.sql.Timestamp;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-23
*/
public interface CouponHistoryService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(CouponHistoryQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<CouponHistoryDTO>
*/
List<CouponHistoryDTO> queryAll(CouponHistoryQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return CouponHistoryDTO
*/
CouponHistoryDTO findById(Long id);
void create(CouponHistory resources);
void update(CouponHistory resources);
void delete(Long id);
Long countByUserId(Long userId);
Long countByUserIdAndExpireTimeBefore(Long userId, Timestamp now);
Long countByUserIdAndExpireTimeBetween(Long userId, Timestamp now, Timestamp expireTime);
}
package com.topdraw.business.basicdata.coupon.history.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Data
public class CouponHistoryDTO implements Serializable {
// 主键
private Long id;
// 优惠券id
private Long couponId;
// 领券用户id(对应账号)
private Long userId;
// 优惠券code
private String couponCode;
// 领取人昵称
private String userNickname;
// 领取时间
private Timestamp receiveTime;
// 失效时间
private Timestamp expireTime;
// 使用状态 0:未使用;1:已使用;-1:已过期
private Integer useStatus;
// 使用时间
private Timestamp useTime;
// 订单详情id
private Long orderDetailId;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.coupon.history.service.dto;
import lombok.Data;
import com.topdraw.annotation.Query;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Data
public class CouponHistoryQueryCriteria{
}
package com.topdraw.business.basicdata.coupon.history.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.coupon.history.repository.CouponHistoryRepository;
import com.topdraw.business.basicdata.coupon.history.service.CouponHistoryService;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryDTO;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryQueryCriteria;
import com.topdraw.business.basicdata.coupon.history.service.mapper.CouponHistoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class CouponHistoryServiceImpl implements CouponHistoryService {
@Autowired
private CouponHistoryRepository CouponHistoryRepository;
@Autowired
private CouponHistoryMapper CouponHistoryMapper;
@Override
public Map<String, Object> queryAll(CouponHistoryQueryCriteria criteria, Pageable pageable) {
Page<CouponHistory> page = CouponHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(CouponHistoryMapper::toDto));
}
@Override
public List<CouponHistoryDTO> queryAll(CouponHistoryQueryCriteria criteria) {
return CouponHistoryMapper.toDto(CouponHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public CouponHistoryDTO findById(Long id) {
CouponHistory CouponHistory = CouponHistoryRepository.findById(id).orElseGet(CouponHistory::new);
ValidationUtil.isNull(CouponHistory.getId(),"CouponHistory","id",id);
return CouponHistoryMapper.toDto(CouponHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(CouponHistory resources) {
CouponHistoryRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(CouponHistory resources) {
CouponHistory CouponHistory = CouponHistoryRepository.findById(resources.getId()).orElseGet(CouponHistory::new);
ValidationUtil.isNull( CouponHistory.getId(),"CouponHistory","id",resources.getId());
CouponHistory.copy(resources);
CouponHistoryRepository.save(CouponHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
CouponHistory CouponHistory = CouponHistoryRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", CouponHistory.class, id), 1));
CouponHistoryRepository.delete(CouponHistory);
}
@Override
public Long countByUserId(Long userId) {
return this.CouponHistoryRepository.countByUserId(userId);
}
@Override
public Long countByUserIdAndExpireTimeBefore(Long userId, Timestamp now) {
return this.CouponHistoryRepository.countByUserIdAndExpireTimeBefore(userId,now);
}
@Override
public Long countByUserIdAndExpireTimeBetween(Long userId, Timestamp now, Timestamp expireTime) {
return this.CouponHistoryRepository.countByUserIdAndExpireTimeBetween(userId,now,expireTime);
}
}
package com.topdraw.business.basicdata.coupon.history.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import com.topdraw.business.basicdata.coupon.history.service.dto.CouponHistoryDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CouponHistoryMapper extends BaseMapper<CouponHistoryDTO, CouponHistory> {
}
package com.topdraw.business.basicdata.coupon.repository;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface CouponRepository extends JpaRepository<Coupon, Long>, JpaSpecificationExecutor<Coupon> {
Optional<Coupon> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.coupon.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import com.topdraw.business.basicdata.coupon.service.CouponService;
import com.topdraw.business.basicdata.coupon.service.dto.CouponQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Coupon管理")
@RestController
@RequestMapping("/api/Coupon")
public class CouponController {
@Autowired
private CouponService CouponService;
@GetMapping
@ApiOperation("查询Coupon")
public ResultInfo getCoupons(CouponQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(CouponService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有Coupon")
public ResultInfo getCoupons(CouponQueryCriteria criteria) {
return ResultInfo.success(CouponService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增Coupon")
public ResultInfo create(@Validated @RequestBody Coupon resources) {
CouponService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改Coupon")
public ResultInfo update(@Validated @RequestBody Coupon resources) {
CouponService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除Coupon")
public ResultInfo delete(@PathVariable Long id) {
CouponService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(CouponService.getByCode(code));
}
}
package com.topdraw.business.basicdata.coupon.service;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import com.topdraw.business.basicdata.coupon.service.dto.CouponDTO;
import com.topdraw.business.basicdata.coupon.service.dto.CouponQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface CouponService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(CouponQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<CouponDTO>
*/
List<CouponDTO> queryAll(CouponQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return CouponDTO
*/
CouponDTO findById(Long id);
void create(Coupon resources);
void update(Coupon resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return CouponDTO
*/
CouponDTO getByCode(String code);
}
package com.topdraw.business.basicdata.coupon.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class CouponDTO implements Serializable {
// id
private Long id;
// 标识
private String code;
// 名称
private String title;
// 图片
private String images;
// 发行量,-1代表不限量
private Integer stock;
// 剩余量,-1代表不限量
private Integer remainStock;
// 优惠形式:1:现金;2:折扣
private Integer useType;
// 面额
private BigDecimal denomination;
// 折扣
private BigDecimal discount;
// 适用用户范围:1:新用户;2:全体用户
private Integer userRange;
// 限领次数 -1:无限次; >0:具体次数
private Integer collectLimit;
// 适用门槛:1:无门槛;2:满减形式
private Integer thresholdType;
// 满减门槛
private BigDecimal amountThreshold;
// 产品范围:1:全部商品;2:指定商品
private Integer itemRange;
// 生效形式:1:固定日期;2:相对日期
private Integer effectType;
// 生效时间
private Timestamp startTime;
// 过期时间
private Timestamp expireTime;
// 自领取当日,几天内有效
private Integer validDays;
// 使用说明
private String description;
// 状态0:未开始,1:启用;2:停用
private Integer status;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.coupon.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class CouponQueryCriteria{
}
package com.topdraw.business.basicdata.coupon.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import com.topdraw.util.RedissonUtil;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.coupon.repository.CouponRepository;
import com.topdraw.business.basicdata.coupon.service.CouponService;
import com.topdraw.business.basicdata.coupon.service.dto.CouponDTO;
import com.topdraw.business.basicdata.coupon.service.dto.CouponQueryCriteria;
import com.topdraw.business.basicdata.coupon.service.mapper.CouponMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class CouponServiceImpl implements CouponService {
@Autowired
private CouponRepository CouponRepository;
@Autowired
private CouponMapper CouponMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(CouponQueryCriteria criteria, Pageable pageable) {
Page<Coupon> page = CouponRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(CouponMapper::toDto));
}
@Override
public List<CouponDTO> queryAll(CouponQueryCriteria criteria) {
return CouponMapper.toDto(CouponRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public CouponDTO findById(Long id) {
Coupon Coupon = CouponRepository.findById(id).orElseGet(Coupon::new);
ValidationUtil.isNull(Coupon.getId(),"Coupon","id",id);
return CouponMapper.toDto(Coupon);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(Coupon resources) {
CouponRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(Coupon resources) {
RLock rLock = this.redissonClient.getLock(resources.getId().toString());
try {
RedissonUtil.lock(rLock);
Coupon Coupon = CouponRepository.findById(resources.getId()).orElseGet(Coupon::new);
ValidationUtil.isNull( Coupon.getId(),"Coupon","id",resources.getId());
Coupon.copy(resources);
CouponRepository.save(Coupon);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
RedissonUtil.unlock(rLock);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
Coupon Coupon = CouponRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", Coupon.class, id), 1));
CouponRepository.delete(Coupon);
}
@Override
public CouponDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? CouponMapper.toDto(CouponRepository.findFirstByCode(code).orElseGet(Coupon::new))
: new CouponDTO();
}
}
package com.topdraw.business.basicdata.coupon.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import com.topdraw.business.basicdata.coupon.service.dto.CouponDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CouponMapper extends BaseMapper<CouponDTO, Coupon> {
}
package com.topdraw.business.basicdata.exp.detail.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_exp_detail")
public class ExpDetail implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 应用code
@Column(name = "app_code")
private String appCode;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 账号id
@Column(name = "account_id")
private Long accountId;
// 原始成长值
@Column(name = "original_exp", nullable = false)
private Long originalExp;
// 结果成长值
@Column(name = "result_exp", nullable = false)
private Long resultExp;
// 成长值变化,一般为正数
@Column(name = "exp", nullable = false)
private Long exp;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
@Column(name = "device_type", nullable = false)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他
@Column(name = "evt_type", nullable = false)
private Integer evtType;
// 订单id(针对订购操作)
@Column(name = "order_id")
private Long orderId;
// 节目id(针对观影操作)
@Column(name = "media_id")
private Long mediaId;
// 活动id(针对参与活动)
@Column(name = "activity_id")
private Long activityId;
// 成长值变化描述,用于管理侧显示
@Column(name = "description", nullable = false)
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(ExpDetail source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.exp.detail.repository;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface ExpDetailRepository extends JpaRepository<ExpDetail, Long>, JpaSpecificationExecutor<ExpDetail> {
Optional<ExpDetail> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.exp.detail.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import com.topdraw.business.basicdata.exp.detail.service.ExpDetailService;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "ExpDetail管理")
@RestController
@RequestMapping("/api/ExpDetail")
public class ExpDetailController {
@Autowired
private ExpDetailService ExpDetailService;
@GetMapping
@ApiOperation("查询ExpDetail")
public ResultInfo getExpDetails(ExpDetailQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(ExpDetailService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有ExpDetail")
public ResultInfo getExpDetails(ExpDetailQueryCriteria criteria) {
return ResultInfo.success(ExpDetailService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增ExpDetail")
public ResultInfo create(@Validated @RequestBody ExpDetail resources) {
ExpDetailService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改ExpDetail")
public ResultInfo update(@Validated @RequestBody ExpDetail resources) {
ExpDetailService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除ExpDetail")
public ResultInfo delete(@PathVariable Long id) {
ExpDetailService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(ExpDetailService.getByCode(code));
}
}
package com.topdraw.business.basicdata.exp.detail.service;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailDTO;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface ExpDetailService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(ExpDetailQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<ExpDetailDTO>
*/
List<ExpDetailDTO> queryAll(ExpDetailQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return ExpDetailDTO
*/
ExpDetailDTO findById(Long id);
void create(ExpDetail resources);
void update(ExpDetail resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return ExpDetailDTO
*/
ExpDetailDTO getByCode(String code);
}
package com.topdraw.business.basicdata.exp.detail.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class ExpDetailDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 应用code
private String appCode;
// 会员id
private Long memberId;
// 账号id
private Long accountId;
// 原始成长值
private Long originalExp;
// 结果成长值
private Long resultExp;
// 成长值变化,一般为正数
private Long exp;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他
private Integer evtType;
// 订单id(针对订购操作)
private Long orderId;
// 节目id(针对观影操作)
private Long mediaId;
// 活动id(针对参与活动)
private Long activityId;
// 成长值变化描述,用于管理侧显示
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.exp.detail.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class ExpDetailQueryCriteria{
}
package com.topdraw.business.basicdata.exp.detail.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.exp.detail.repository.ExpDetailRepository;
import com.topdraw.business.basicdata.exp.detail.service.ExpDetailService;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailDTO;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailQueryCriteria;
import com.topdraw.business.basicdata.exp.detail.service.mapper.ExpDetailMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ExpDetailServiceImpl implements ExpDetailService {
@Autowired
private ExpDetailRepository ExpDetailRepository;
@Autowired
private ExpDetailMapper ExpDetailMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(ExpDetailQueryCriteria criteria, Pageable pageable) {
Page<ExpDetail> page = ExpDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(ExpDetailMapper::toDto));
}
@Override
public List<ExpDetailDTO> queryAll(ExpDetailQueryCriteria criteria) {
return ExpDetailMapper.toDto(ExpDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public ExpDetailDTO findById(Long id) {
ExpDetail ExpDetail = ExpDetailRepository.findById(id).orElseGet(ExpDetail::new);
ValidationUtil.isNull(ExpDetail.getId(),"ExpDetail","id",id);
return ExpDetailMapper.toDto(ExpDetail);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(ExpDetail resources) {
ExpDetailRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(ExpDetail resources) {
RLock rLock = this.redissonClient.getLock(resources.getId().toString());
try {
ExpDetail ExpDetail = ExpDetailRepository.findById(resources.getId()).orElseGet(ExpDetail::new);
ValidationUtil.isNull( ExpDetail.getId(),"ExpDetail","id",resources.getId());
ExpDetail.copy(resources);
ExpDetailRepository.save(ExpDetail);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
rLock.unlock();
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
ExpDetail ExpDetail = ExpDetailRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", ExpDetail.class, id), 1));
ExpDetailRepository.delete(ExpDetail);
}
@Override
public ExpDetailDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? ExpDetailMapper.toDto(ExpDetailRepository.findFirstByCode(code).orElseGet(ExpDetail::new))
: new ExpDetailDTO();
}
}
package com.topdraw.business.basicdata.exp.detail.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import com.topdraw.business.basicdata.exp.detail.service.dto.ExpDetailDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ExpDetailMapper extends BaseMapper<ExpDetailDTO, ExpDetail> {
}
package com.topdraw.business.basicdata.exp.history.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_exp_history")
public class ExpHistory implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 账号id
@Column(name = "account_id")
private Long accountId;
// 原始成长值
@Column(name = "original_exp", nullable = false)
private Long originalExp;
// 结果成长值
@Column(name = "result_exp", nullable = false)
private Long resultExp;
// 成长值变化,一般为正数
@Column(name = "exp", nullable = false)
private Long exp;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)4.系统赠送
@Column(name = "device_type", nullable = false)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他
@Column(name = "evt_type", nullable = false)
private Integer evtType;
// 订单id(针对订购操作)
@Column(name = "order_id")
private Long orderId;
// 节目id(针对观影操作)
@Column(name = "media_id")
private Long mediaId;
// 活动id(针对参与活动)
@Column(name = "activity_id")
private Long activityId;
// 成长值变化描述,用于管理侧显示
@Column(name = "description", nullable = false)
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(ExpHistory source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.exp.history.repository;
import com.topdraw.business.basicdata.exp.history.domain.ExpHistory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface ExpHistoryRepository extends JpaRepository<ExpHistory, Long>, JpaSpecificationExecutor<ExpHistory> {
Optional<ExpHistory> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.exp.history.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.exp.history.domain.ExpHistory;
import com.topdraw.business.basicdata.exp.history.service.ExpHistoryService;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "ExpHistory管理")
@RestController
@RequestMapping("/api/ExpHistory")
public class ExpHistoryController {
@Autowired
private ExpHistoryService ExpHistoryService;
@GetMapping
@ApiOperation("查询ExpHistory")
public ResultInfo getExpHistorys(ExpHistoryQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(ExpHistoryService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有ExpHistory")
public ResultInfo getExpHistorys(ExpHistoryQueryCriteria criteria) {
return ResultInfo.success(ExpHistoryService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增ExpHistory")
public ResultInfo create(@Validated @RequestBody ExpHistory resources) {
ExpHistoryService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改ExpHistory")
public ResultInfo update(@Validated @RequestBody ExpHistory resources) {
ExpHistoryService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除ExpHistory")
public ResultInfo delete(@PathVariable Long id) {
ExpHistoryService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(ExpHistoryService.getByCode(code));
}
}
package com.topdraw.business.basicdata.exp.history.service;
import com.topdraw.business.basicdata.exp.history.domain.ExpHistory;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryDTO;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface ExpHistoryService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(ExpHistoryQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<ExpHistoryDTO>
*/
List<ExpHistoryDTO> queryAll(ExpHistoryQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return ExpHistoryDTO
*/
ExpHistoryDTO findById(Long id);
void create(ExpHistory resources);
void update(ExpHistory resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return ExpHistoryDTO
*/
ExpHistoryDTO getByCode(String code);
}
package com.topdraw.business.basicdata.exp.history.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class ExpHistoryDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 会员id
private Long memberId;
// 账号id
private Long accountId;
// 原始成长值
private Long originalExp;
// 结果成长值
private Long resultExp;
// 成长值变化,一般为正数
private Long exp;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)4.系统赠送
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;98:系统操作;99:其他
private Integer evtType;
// 订单id(针对订购操作)
private Long orderId;
// 节目id(针对观影操作)
private Long mediaId;
// 活动id(针对参与活动)
private Long activityId;
// 成长值变化描述,用于管理侧显示
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.exp.history.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class ExpHistoryQueryCriteria{
}
package com.topdraw.business.basicdata.exp.history.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.exp.history.domain.ExpHistory;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.exp.history.repository.ExpHistoryRepository;
import com.topdraw.business.basicdata.exp.history.service.ExpHistoryService;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryDTO;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryQueryCriteria;
import com.topdraw.business.basicdata.exp.history.service.mapper.ExpHistoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ExpHistoryServiceImpl implements ExpHistoryService {
@Autowired
private ExpHistoryRepository ExpHistoryRepository;
@Autowired
private ExpHistoryMapper ExpHistoryMapper;
@Override
public Map<String, Object> queryAll(ExpHistoryQueryCriteria criteria, Pageable pageable) {
Page<ExpHistory> page = ExpHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(ExpHistoryMapper::toDto));
}
@Override
public List<ExpHistoryDTO> queryAll(ExpHistoryQueryCriteria criteria) {
return ExpHistoryMapper.toDto(ExpHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public ExpHistoryDTO findById(Long id) {
ExpHistory ExpHistory = ExpHistoryRepository.findById(id).orElseGet(ExpHistory::new);
ValidationUtil.isNull(ExpHistory.getId(),"ExpHistory","id",id);
return ExpHistoryMapper.toDto(ExpHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
// @AsyncMqSend()
public void create(ExpHistory resources) {
ExpHistoryRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(ExpHistory resources) {
ExpHistory ExpHistory = ExpHistoryRepository.findById(resources.getId()).orElseGet(ExpHistory::new);
ValidationUtil.isNull( ExpHistory.getId(),"ExpHistory","id",resources.getId());
ExpHistory.copy(resources);
ExpHistoryRepository.save(ExpHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
ExpHistory ExpHistory = ExpHistoryRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", ExpHistory.class, id), 1));
ExpHistoryRepository.delete(ExpHistory);
}
@Override
public ExpHistoryDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? ExpHistoryMapper.toDto(ExpHistoryRepository.findFirstByCode(code).orElseGet(ExpHistory::new))
: new ExpHistoryDTO();
}
}
package com.topdraw.business.basicdata.exp.history.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.exp.history.domain.ExpHistory;
import com.topdraw.business.basicdata.exp.history.service.dto.ExpHistoryDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ExpHistoryMapper extends BaseMapper<ExpHistoryDTO, ExpHistory> {
}
package com.topdraw.business.basicdata.member.address.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member_address")
public class MemberAddress implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 类型 1:家;2:公司;3:学校
@Column(name = "type", nullable = false)
private Integer type;
// 是否默认地址
@Column(name = "is_default", nullable = false)
private Integer isDefault;
// 显示顺序
@Column(name = "sequence")
private Integer sequence;
// 状态 0:不可用;1-可用
@Column(name = "status", nullable = false)
private Integer status;
// 联系人姓名
@Column(name = "contactor", nullable = false)
private String contactor;
// 联系人电话
@Column(name = "cellphone", nullable = false)
private String cellphone;
// 国家
@Column(name = "country", nullable = false)
private String country;
// 省份
@Column(name = "province", nullable = false)
private String province;
// 城市
@Column(name = "city", nullable = false)
private String city;
// 区县
@Column(name = "district", nullable = false)
private String district;
// 地址
@Column(name = "address", nullable = false)
private String address;
// 邮编
@Column(name = "zip_code")
private String zipCode;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(MemberAddress source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.address.repository;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberAddressRepository extends JpaRepository<MemberAddress, Long>, JpaSpecificationExecutor<MemberAddress> {
}
package com.topdraw.business.basicdata.member.address.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.business.basicdata.member.address.service.MemberAddressService;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "MemberAddress管理")
@RestController
@RequestMapping("/api/MemberAddress")
public class MemberAddressController {
@Autowired
private MemberAddressService MemberAddressService;
@GetMapping(value = "/pageMemberAddress")
@ApiOperation("查询MemberAddress")
public ResultInfo pageMemberAddress(MemberAddressQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(MemberAddressService.queryAll(criteria,pageable));
}
@GetMapping(value = "/findById/{id}")
@ApiOperation("查询指定MemberAddress")
public ResultInfo findById(@PathVariable(value = "id") Long id) {
return ResultInfo.success(MemberAddressService.findById(id));
}
@Log
@PostMapping(value = "/create")
@ApiOperation("新增MemberAddress")
public ResultInfo create(@Validated @RequestBody MemberAddress resources) {
MemberAddressService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping(value = "/update")
@ApiOperation("修改MemberAddress")
public ResultInfo update(@Validated @RequestBody MemberAddress resources) {
MemberAddressService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/delete/{id}")
@ApiOperation("删除MemberAddress")
public ResultInfo delete(@PathVariable Long id) {
MemberAddressService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.member.address.service;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressDTO;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberAddressService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberAddressQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberAddressDTO>
*/
List<MemberAddressDTO> queryAll(MemberAddressQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberAddressDTO
*/
MemberAddressDTO findById(Long id);
void create(MemberAddress resources);
void update(MemberAddress resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.member.address.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberAddressDTO implements Serializable {
// 主键
private Long id;
// 会员id
private Long memberId;
// 类型 1:家;2:公司;3:学校
private Integer type;
// 是否默认地址
private Integer isDefault;
// 显示顺序
private Integer sequence;
// 状态 0:不可用;1-可用
private Integer status;
// 联系人姓名
private String contactor;
// 联系人电话
private String cellphone;
// 国家
private String country;
// 省份
private String province;
// 城市
private String city;
// 区县
private String district;
// 地址
private String address;
// 邮编
private String zipCode;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.member.address.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberAddressQueryCriteria{
@Query
private Long memberId;
}
package com.topdraw.business.basicdata.member.address.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.member.address.repository.MemberAddressRepository;
import com.topdraw.business.basicdata.member.address.service.MemberAddressService;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressDTO;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressQueryCriteria;
import com.topdraw.business.basicdata.member.address.service.mapper.MemberAddressMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberAddressServiceImpl implements MemberAddressService {
@Autowired
private MemberAddressRepository MemberAddressRepository;
@Autowired
private MemberAddressMapper MemberAddressMapper;
@Override
public Map<String, Object> queryAll(MemberAddressQueryCriteria criteria, Pageable pageable) {
Page<MemberAddress> page = MemberAddressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(MemberAddressMapper::toDto));
}
@Override
public List<MemberAddressDTO> queryAll(MemberAddressQueryCriteria criteria) {
return MemberAddressMapper.toDto(MemberAddressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberAddressDTO findById(Long id) {
MemberAddress MemberAddress = MemberAddressRepository.findById(id).orElseGet(MemberAddress::new);
ValidationUtil.isNull(MemberAddress.getId(),"MemberAddress","id",id);
return MemberAddressMapper.toDto(MemberAddress);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(MemberAddress resources) {
MemberAddressRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(MemberAddress resources) {
MemberAddress MemberAddress = MemberAddressRepository.findById(resources.getId()).orElseGet(MemberAddress::new);
ValidationUtil.isNull( MemberAddress.getId(),"MemberAddress","id",resources.getId());
MemberAddress.copy(resources);
MemberAddressRepository.save(MemberAddress);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
MemberAddress MemberAddress = MemberAddressRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", MemberAddress.class, id), 1));
MemberAddressRepository.delete(MemberAddress);
}
}
package com.topdraw.business.basicdata.member.address.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberAddressMapper extends BaseMapper<MemberAddressDTO, MemberAddress> {
}
package com.topdraw.business.basicdata.member.domain;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member")
public class Member implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 类型 1:大屏;2:小屏
@Column(name = "`type`", nullable = false)
private Integer type;
// 状态 0:不可用;1:可用
@Column(name = "`status`", nullable = false)
private Integer status;
// 昵称 base64
@Column(name = "nickname")
private String nickname;
// 描述
@Column(name = "description")
private String description;
// 性别 0:女;1:男;-1:未知
@Column(name = "gender", nullable = false)
private Integer gender;
// 生日
@Column(name = "birthday")
private String birthday;
// 头像
@Column(name = "avatar_url")
private String avatarUrl;
// 分组信息
@Column(name = "`groups`")
private String groups;
// 标签
@Column(name = "tags")
private String tags;
// 是否会员 0:非会员;1:会员
@Column(name = "vip", nullable = false)
private Integer vip;
// 会员等级(对应level表的level字段,非id)
@Column(name = "`level`", nullable = false)
private Integer level;
// 成长值
@Column(name = "`exp`")
private Long exp;
// 当前积分
@Column(name = "`points`")
private Long points;
// 即将到期积分(一个月内)
@Column(name = "due_points")
private Long duePoints;
// 优惠券数量
@Column(name = "coupon_amount")
private Long couponAmount;
// 即将过期优惠券数量
@Column(name = "due_coupon_amount")
private Long dueCouponAmount;
// iptv账号id
@Column(name = "user_iptv_id")
private Long userIptvId;
// 绑定IPTV平台 0:未知;1:电信;2:移动;3:联通
@Column(name = "bind_iptv_platform_type")
private Integer bindIptvPlatformType;
// iptv账号绑定时间
@Column(name = "bind_iptv_time")
private Timestamp bindIptvTime;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
// 是否在黑名单 1:是;0否
// @Column(name = "black_status")
// private Integer blackStatus;
public void copy(Member source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.level.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member_level")
public class MemberLevel implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 名称
@Column(name = "name", nullable = false)
private String name;
// 状态 0:未启用;1:启用
@Column(name = "status", nullable = false)
private Integer status;
// 对应成长值
@Column(name = "exp_value", nullable = false)
private Long expValue;
// 等级(不可重复,数字越大等级越高)
@Column(name = "level", nullable = false)
private Integer level;
// 会员徽标
@Column(name = "icon_url")
private String iconUrl;
// 描述
@Column(name = "description")
private String description;
// 对应任务id,通过此字段可获得该等级所对应的权益
@Column(name = "task_id")
private Long taskId;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(MemberLevel source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.level.repository;
import com.topdraw.business.basicdata.member.level.domain.MemberLevel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberLevelRepository extends JpaRepository<MemberLevel, Long>, JpaSpecificationExecutor<MemberLevel> {
Optional<MemberLevel> findFirstByCode(String code);
List<MemberLevel> findByLevelAndStatus(Integer level, Integer status);
}
package com.topdraw.business.basicdata.member.level.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.level.domain.MemberLevel;
import com.topdraw.business.basicdata.member.level.service.MemberLevelService;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "MemberLevel管理")
@RestController
@RequestMapping("/api/MemberLevel")
public class MemberLevelController {
@Autowired
private MemberLevelService MemberLevelService;
@GetMapping
@ApiOperation("查询MemberLevel")
public ResultInfo getMemberLevels(MemberLevelQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(MemberLevelService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有MemberLevel")
public ResultInfo getMemberLevels(MemberLevelQueryCriteria criteria) {
return ResultInfo.success(MemberLevelService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增MemberLevel")
public ResultInfo create(@Validated @RequestBody MemberLevel resources) {
MemberLevelService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改MemberLevel")
public ResultInfo update(@Validated @RequestBody MemberLevel resources) {
MemberLevelService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除MemberLevel")
public ResultInfo delete(@PathVariable Long id) {
MemberLevelService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(MemberLevelService.getByCode(code));
}
}
package com.topdraw.business.basicdata.member.level.service;
import com.topdraw.business.basicdata.member.level.domain.MemberLevel;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberLevelService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberLevelQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberLevelDTO>
*/
List<MemberLevelDTO> queryAll(MemberLevelQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberLevelDTO
*/
MemberLevelDTO findById(Long id);
void create(MemberLevel resources);
void update(MemberLevel resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return MemberLevelDTO
*/
MemberLevelDTO getByCode(String code);
List<MemberLevelDTO> findLevelAndStatus(Integer i, Integer status);
}
package com.topdraw.business.basicdata.member.level.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberLevelDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 名称
private String name;
// 状态 0:未启用;1:启用
private Integer status;
// 对应成长值
private Long expValue;
// 等级(不可重复,数字越大等级越高)
private Integer level;
// 会员徽标
private String iconUrl;
// 描述
private String description;
// 对应任务id,通过此字段可获得该等级所对应的权益
private Long taskId;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.member.level.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberLevelQueryCriteria{
}
package com.topdraw.business.basicdata.member.level.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.member.level.domain.MemberLevel;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.member.level.repository.MemberLevelRepository;
import com.topdraw.business.basicdata.member.level.service.MemberLevelService;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelQueryCriteria;
import com.topdraw.business.basicdata.member.level.service.mapper.MemberLevelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberLevelServiceImpl implements MemberLevelService {
@Autowired
private MemberLevelRepository MemberLevelRepository;
@Autowired
private MemberLevelMapper MemberLevelMapper;
@Override
public Map<String, Object> queryAll(MemberLevelQueryCriteria criteria, Pageable pageable) {
Page<MemberLevel> page = MemberLevelRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(MemberLevelMapper::toDto));
}
@Override
public List<MemberLevelDTO> queryAll(MemberLevelQueryCriteria criteria) {
return MemberLevelMapper.toDto(MemberLevelRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberLevelDTO findById(Long id) {
MemberLevel MemberLevel = MemberLevelRepository.findById(id).orElseGet(MemberLevel::new);
ValidationUtil.isNull(MemberLevel.getId(),"MemberLevel","id",id);
return MemberLevelMapper.toDto(MemberLevel);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(MemberLevel resources) {
MemberLevelRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(MemberLevel resources) {
MemberLevel MemberLevel = MemberLevelRepository.findById(resources.getId()).orElseGet(MemberLevel::new);
ValidationUtil.isNull( MemberLevel.getId(),"MemberLevel","id",resources.getId());
MemberLevel.copy(resources);
MemberLevelRepository.save(MemberLevel);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
MemberLevel MemberLevel = MemberLevelRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", MemberLevel.class, id), 1));
MemberLevelRepository.delete(MemberLevel);
}
@Override
public MemberLevelDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? MemberLevelMapper.toDto(MemberLevelRepository.findFirstByCode(code).orElseGet(MemberLevel::new))
: new MemberLevelDTO();
}
@Override
public List<MemberLevelDTO> findLevelAndStatus(Integer level, Integer status) {
return MemberLevelMapper.toDto(MemberLevelRepository.findByLevelAndStatus(level,status));
}
}
package com.topdraw.business.basicdata.member.level.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.level.domain.MemberLevel;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberLevelMapper extends BaseMapper<MemberLevelDTO, MemberLevel> {
}
package com.topdraw.business.basicdata.member.profile;
public interface DoSaveMemberProfileGroup {
}
package com.topdraw.business.basicdata.member.profile;
public interface DoUpdateMemberProfileGroup {
}
package com.topdraw.business.basicdata.member.profile.domain;
import com.topdraw.business.basicdata.member.profile.DoSaveMemberProfileGroup;
import com.topdraw.business.basicdata.member.profile.DoUpdateMemberProfileGroup;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member_profile")
public class MemberProfile implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(message = "【id】 not be null!!" , groups = DoUpdateMemberProfileGroup.class)
private Long id;
// 会员id
@NotNull(message = "【memberId】 not be null!!" , groups = DoSaveMemberProfileGroup.class)
@Column(name = "member_id", nullable = false)
private Long memberId;
// 姓名
@Column(name = "realname")
private String realname;
// 性别 0:女; 1:男 -1:未知
@Column(name = "gender", nullable = false)
@NotNull(message = "【gender】 not be null!!" , groups = {DoSaveMemberProfileGroup.class})
private Integer gender;
// 生日
@NotNull(message = "【memberId】 not be null!!" , groups = DoSaveMemberProfileGroup.class)
@Column(name = "birthday", nullable = false)
private Timestamp birthday;
// 星座
@Column(name = "constellation")
private String constellation;
// 身份证
@NotNull(message = "【idCard】 not be null!!" , groups = DoSaveMemberProfileGroup.class)
@Column(name = "id_card", nullable = false)
private String idCard;
// 电子邮件
@Column(name = "email")
private String email;
// 国家
@Column(name = "country")
private String country;
// 省份
@Column(name = "province")
private String province;
// 城市
@Column(name = "city")
private String city;
// 区县
@Column(name = "district")
private String district;
// 描述
@Column(name = "description")
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(MemberProfile source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.profile.repository;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberProfileRepository extends JpaRepository<MemberProfile, Long>, JpaSpecificationExecutor<MemberProfile> {
}
package com.topdraw.business.basicdata.member.profile.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import com.topdraw.business.basicdata.member.profile.service.MemberProfileService;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "MemberProfile管理")
@RestController
@RequestMapping("/api/MemberProfile")
public class MemberProfileController {
@Autowired
private MemberProfileService MemberProfileService;
/*@GetMapping
@ApiOperation("查询MemberProfile")
public ResultInfo getMemberProfiles(MemberProfileQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(MemberProfileService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有MemberProfile")
public ResultInfo getMemberProfiles(MemberProfileQueryCriteria criteria) {
return ResultInfo.success(MemberProfileService.queryAll(criteria));
}*/
@Log
@PostMapping
@ApiOperation("新增MemberProfile")
public ResultInfo create(@Validated @RequestBody MemberProfile resources) {
MemberProfileService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改MemberProfile")
public ResultInfo update(@Validated @RequestBody MemberProfile resources) {
MemberProfileService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除MemberProfile")
public ResultInfo delete(@PathVariable Long id) {
MemberProfileService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.member.profile.service;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileDTO;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberProfileService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberProfileQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberProfileDTO>
*/
List<MemberProfileDTO> queryAll(MemberProfileQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberProfileDTO
*/
MemberProfileDTO findById(Long id);
void create(MemberProfile resources);
void update(MemberProfile resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.member.profile.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberProfileDTO implements Serializable {
// 主键
private Long id;
// 会员id
private Long memberId;
// 姓名
private String realname;
// 性别 0:女; 1:男 -1:未知
private Integer gender;
// 生日
private Timestamp birthday;
// 星座
private String constellation;
// 身份证
private String idCard;
// 电子邮件
private String email;
// 国家
private String country;
// 省份
private String province;
// 城市
private String city;
// 区县
private String district;
// 描述
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.member.profile.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberProfileQueryCriteria{
}
package com.topdraw.business.basicdata.member.profile.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.member.profile.repository.MemberProfileRepository;
import com.topdraw.business.basicdata.member.profile.service.MemberProfileService;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileDTO;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileQueryCriteria;
import com.topdraw.business.basicdata.member.profile.service.mapper.MemberProfileMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberProfileServiceImpl implements MemberProfileService {
@Autowired
private MemberProfileRepository MemberProfileRepository;
@Autowired
private MemberProfileMapper MemberProfileMapper;
@Override
public Map<String, Object> queryAll(MemberProfileQueryCriteria criteria, Pageable pageable) {
Page<MemberProfile> page = MemberProfileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(MemberProfileMapper::toDto));
}
@Override
public List<MemberProfileDTO> queryAll(MemberProfileQueryCriteria criteria) {
return MemberProfileMapper.toDto(MemberProfileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberProfileDTO findById(Long id) {
MemberProfile MemberProfile = MemberProfileRepository.findById(id).orElseGet(MemberProfile::new);
ValidationUtil.isNull(MemberProfile.getId(),"MemberProfile","id",id);
return MemberProfileMapper.toDto(MemberProfile);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(MemberProfile resources) {
MemberProfileRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(MemberProfile resources) {
MemberProfile MemberProfile = MemberProfileRepository.findById(resources.getId()).orElseGet(MemberProfile::new);
ValidationUtil.isNull( MemberProfile.getId(),"MemberProfile","id",resources.getId());
MemberProfile.copy(resources);
MemberProfileRepository.save(MemberProfile);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
MemberProfile MemberProfile = MemberProfileRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", MemberProfile.class, id), 1));
MemberProfileRepository.delete(MemberProfile);
}
}
package com.topdraw.business.basicdata.member.profile.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import com.topdraw.business.basicdata.member.profile.service.dto.MemberProfileDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberProfileMapper extends BaseMapper<MemberProfileDTO, MemberProfile> {
}
package com.topdraw.business.basicdata.member.relatedinfo.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_member_related_info")
public class MemberRelatedInfo implements Serializable {
// ID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 人物关系 0:子女;1:父母
@Column(name = "type")
private Integer type;
// 手机号
@Column(name = "cellphone")
private String cellphone;
// 身份证号
@Column(name = "id_card")
private String idCard;
// 姓名
@Column(name = "name")
private String name;
// 性别 0:女;1:男;-1:未知
@Column(name = "sex")
private Integer sex;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(MemberRelatedInfo source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.member.relatedinfo.repository;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberRelatedInfoRepository extends JpaRepository<MemberRelatedInfo, Long>, JpaSpecificationExecutor<MemberRelatedInfo> {
}
package com.topdraw.business.basicdata.member.relatedinfo.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import com.topdraw.business.basicdata.member.relatedinfo.service.MemberRelatedInfoService;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan /api/MemberRelatedInfo
* @date 2021-10-22
*/
@Api(tags = "MemberRelatedInfo管理")
@RestController
@RequestMapping("/api/MemberRelatedInfo")
public class MemberRelatedInfoController {
@Autowired
private MemberRelatedInfoService MemberRelatedInfoService;
@GetMapping(value = "/pageMemberRelatedInfos")
@ApiOperation("查询MemberRelatedInfo")
public ResultInfo pageMemberRelatedInfos(@Validated MemberRelatedInfoQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(MemberRelatedInfoService.queryAll(criteria,pageable));
}
@Log
@PostMapping(value = "/create")
@ApiOperation("新增MemberRelatedInfo")
public ResultInfo create(@Validated @RequestBody MemberRelatedInfo resources) {
MemberRelatedInfoService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping(value = "/update")
@ApiOperation("修改MemberRelatedInfo")
public ResultInfo update(@Validated @RequestBody MemberRelatedInfo resources) {
MemberRelatedInfoService.update(resources);
return ResultInfo.success();
}
@GetMapping(value = "/findById/{id}")
@ApiOperation("查询指定MemberRelatedInfo")
public ResultInfo findById(@PathVariable("id") Long id) {
return ResultInfo.success(MemberRelatedInfoService.findById(id));
}
@Log
@DeleteMapping(value = "/delete//{id}")
@ApiOperation("删除MemberRelatedInfo")
public ResultInfo delete(@PathVariable Long id) {
MemberRelatedInfoService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.member.relatedinfo.service;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoDTO;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberRelatedInfoService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberRelatedInfoQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberRelatedInfoDTO>
*/
List<MemberRelatedInfoDTO> queryAll(MemberRelatedInfoQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberRelatedInfoDTO
*/
MemberRelatedInfoDTO findById(Long id);
void create(MemberRelatedInfo resources);
void update(MemberRelatedInfo resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.member.relatedinfo.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberRelatedInfoDTO implements Serializable {
// ID
private Long id;
// 会员id
private Long memberId;
// 人物关系 0:子女;1:父母
private Integer type;
// 手机号
private String cellphone;
// 身份证号
private String idCard;
// 姓名
private String name;
// 性别 0:女;1:男;-1:未知
private Integer sex;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.member.relatedinfo.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberRelatedInfoQueryCriteria{
@Query
private Long memberId;
}
package com.topdraw.business.basicdata.member.relatedinfo.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.member.relatedinfo.repository.MemberRelatedInfoRepository;
import com.topdraw.business.basicdata.member.relatedinfo.service.MemberRelatedInfoService;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoDTO;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoQueryCriteria;
import com.topdraw.business.basicdata.member.relatedinfo.service.mapper.MemberRelatedInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberRelatedInfoServiceImpl implements MemberRelatedInfoService {
@Autowired
private MemberRelatedInfoRepository MemberRelatedInfoRepository;
@Autowired
private MemberRelatedInfoMapper MemberRelatedInfoMapper;
@Override
public Map<String, Object> queryAll(MemberRelatedInfoQueryCriteria criteria, Pageable pageable) {
Page<MemberRelatedInfo> page = MemberRelatedInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(MemberRelatedInfoMapper::toDto));
}
@Override
public List<MemberRelatedInfoDTO> queryAll(MemberRelatedInfoQueryCriteria criteria) {
return MemberRelatedInfoMapper.toDto(MemberRelatedInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberRelatedInfoDTO findById(Long id) {
MemberRelatedInfo MemberRelatedInfo = MemberRelatedInfoRepository.findById(id).orElseGet(MemberRelatedInfo::new);
ValidationUtil.isNull(MemberRelatedInfo.getId(),"MemberRelatedInfo","id",id);
return MemberRelatedInfoMapper.toDto(MemberRelatedInfo);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(MemberRelatedInfo resources) {
MemberRelatedInfoRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(MemberRelatedInfo resources) {
MemberRelatedInfo MemberRelatedInfo = MemberRelatedInfoRepository.findById(resources.getId()).orElseGet(MemberRelatedInfo::new);
ValidationUtil.isNull( MemberRelatedInfo.getId(),"MemberRelatedInfo","id",resources.getId());
MemberRelatedInfo.copy(resources);
MemberRelatedInfoRepository.save(MemberRelatedInfo);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
MemberRelatedInfo MemberRelatedInfo = MemberRelatedInfoRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", MemberRelatedInfo.class, id), 1));
MemberRelatedInfoRepository.delete(MemberRelatedInfo);
}
}
package com.topdraw.business.basicdata.member.relatedinfo.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberRelatedInfoMapper extends BaseMapper<MemberRelatedInfoDTO, MemberRelatedInfo> {
}
package com.topdraw.business.basicdata.member.repository;
import com.topdraw.business.basicdata.member.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberRepository extends JpaRepository<Member, Long>, JpaSpecificationExecutor<Member> {
Optional<Member> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.member.rest;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberQueryCriteria;
import com.topdraw.common.ResultInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Member管理")
@RestController
@RequestMapping("/api/member")
public class MemberController {
@Autowired
private MemberService memberService;
/* @GetMapping(value = "/pageMembers")
@ApiOperation("查询Member")
public ResultInfo pageMembers(MemberQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(memberService.queryAll(criteria,pageable));
}
@GetMapping(value = "/findById/{id}")
@ApiOperation("查询指定Member")
public ResultInfo findById(@PathVariable("id") Long id) {
return ResultInfo.success(memberService.findById(id));
}
*/
@Log
@PostMapping(value = "/create")
@ApiOperation("新增Member")
public ResultInfo create(@Validated @RequestBody Member resources) {
Long id = memberService.create(resources);
return ResultInfo.success(id);
}
@Log
@PutMapping(value = "/doUpdateVip")
@ApiOperation("修改Member等级")
public ResultInfo doUpdateVip(Long memberId , Integer vip) {
Assert.isNull(memberId,"MemberController -->> doUpdateVip -->>【memberId】 not be null!!");
Assert.isNull(vip,"MemberController -->> doUpdateVip -->>【memberId】 not be null!!");
Member member = new Member();
member.setId(memberId);
member.setVip(vip);
memberService.update(member);
return ResultInfo.success();
}
@Log
@PutMapping(value = "/update")
@ApiOperation("修改Member")
public ResultInfo update(@Validated @RequestBody Member resources) {
memberService.update(resources);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(memberService.getByCode(code));
}
}
package com.topdraw.business.basicdata.member.service;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.member.service.dto.MemberQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface MemberService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(MemberQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<MemberDTO>
*/
List<MemberDTO> queryAll(MemberQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return MemberDTO
*/
MemberDTO findById(Long id);
Long create(Member resources);
void update(Member resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return MemberDTO
*/
MemberDTO getByCode(String code);
}
package com.topdraw.business.basicdata.member.service.dto;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 类型 1:大屏;2:小屏
private Integer type;
// 状态 0:不可用;1:可用
private Integer status;
// 昵称 base64
private String nickname;
// 描述
private String description;
// 性别 0:女;1:男;-1:未知
private Integer gender;
// 生日
private String birthday;
// 头像
private String avatarUrl;
// 分组信息
private String groups;
// 标签
private String tags;
// 是否会员 0:非会员;1:会员
private Integer vip;
// 会员等级(对应level表的level字段,非id)
private Integer level;
// 成长值
private Long exp;
// 当前积分
private Long points;
// 即将到期积分(一个月内)
private Long duePoints;
// 优惠券数量
private Long couponAmount;
// 即将过期优惠券数量
private Long dueCouponAmount;
// iptv账号id
private Long userIptvId;
// 绑定IPTV平台 0:未知;1:电信;2:移动;3:联通
private Integer bindIptvPlatformType;
// iptv账号绑定时间
private Timestamp bindIptvTime;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
// 是否在黑名单 1:是;0否
// private Integer blackStatus;
}
package com.topdraw.business.basicdata.member.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class MemberQueryCriteria{
@Query(type = Query.Type.LEFT_LIKE)
private String code;
// 类型 1:大屏;2:小屏
@Query(type = Query.Type.EQUAL)
private Integer type;
// 状态 0:不可用;1:可用
@Query(type = Query.Type.EQUAL)
private Integer status;
// 昵称 base64
@Query(type = Query.Type.LEFT_LIKE)
private String nickname;
// 性别 0:女;1:男;-1:未知
@Query(type = Query.Type.EQUAL)
private Integer gender;
// 分组信息
@Query(type = Query.Type.EQUAL)
private String groups;
// 标签
@Query(type = Query.Type.IN)
private String tags;
// 是否会员 0:非会员;1:会员
@Query(type = Query.Type.EQUAL)
private Integer vip;
// 会员等级(对应level表的level字段,非id)
@Query(type = Query.Type.EQUAL)
private Integer level;
// iptv账号id
@Query(type = Query.Type.EQUAL)
private Long userIptvId;
// 绑定IPTV平台 0:未知;1:电信;2:移动;3:联通
@Query(type = Query.Type.IN)
private Integer bindIptvPlatformType;
}
package com.topdraw.business.basicdata.member.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.repository.MemberRepository;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.member.service.dto.MemberQueryCriteria;
import com.topdraw.business.basicdata.member.service.mapper.MemberMapper;
import com.topdraw.mq.config.RabbitMqConfig;
import com.topdraw.util.IdWorker;
import com.topdraw.util.RedissonUtil;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import com.topdraw.utils.ValidationUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MemberServiceImpl implements MemberService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private MemberMapper memberMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(MemberQueryCriteria criteria, Pageable pageable) {
Page<Member> page = memberRepository.findAll((root, criteriaQuery, criteriaBuilder)
-> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(memberMapper::toDto));
}
@Override
public List<MemberDTO> queryAll(MemberQueryCriteria criteria) {
return memberMapper.toDto(memberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public MemberDTO findById(Long id) {
Member member = memberRepository.findById(id).orElseGet(Member::new);
ValidationUtil.isNull(member.getId(),"Member","id",id);
return memberMapper.toDto(member);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public Long create(Member resources) {
Member member = this.checkMemberData(resources);
memberRepository.save(member);
return member.getId();
}
private Member checkMemberData(Member member) {
Long defaultValue = 0L;
member.setCode(String.valueOf(IdWorker.generator()));
Integer gender = member.getGender();
member.setGender(Objects.nonNull(gender) ? gender : 0);
Integer type = member.getType();
member.setType(Objects.nonNull(type) ? type:-1);
Integer status = member.getStatus();
member.setStatus(Objects.nonNull(status) ? status:1);
Integer vip = member.getVip();
member.setVip(Objects.nonNull(vip) ? status:0);
Integer level = member.getLevel();
member.setLevel(Objects.nonNull(level) ? level:0);
member.setExp(defaultValue);
member.setPoints(defaultValue);
member.setDuePoints(defaultValue);
member.setCouponAmount(defaultValue);
member.setDueCouponAmount(defaultValue);
return member;
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(Member resources) {
RLock rLock = this.redissonClient.getLock("updateMember" + resources.getId().toString());
try {
RedissonUtil.lock(rLock);
Member member = memberRepository.findById(resources.getId()).orElseGet(Member::new);
ValidationUtil.isNull(member.getId(), "Member", "id", resources.getId());
member.copy(resources);
memberRepository.save(member);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
RedissonUtil.unlock(rLock);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
Member member = memberRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", Member.class, id), 1));
memberRepository.delete(member);
}
@Override
public MemberDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? memberMapper.toDto(memberRepository.findFirstByCode(code).orElseGet(Member::new))
: new MemberDTO();
}
}
package com.topdraw.business.basicdata.member.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MemberMapper extends BaseMapper<MemberDTO, Member> {
}
package com.topdraw.business.basicdata.points.available.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.util.UUID;
import java.io.Serializable;
/**
* 每天定时扫描可用积分表,将过期积分删除,并及时更新积分明细表和积分总额表
*
* @author XiangHan
* @date 2021-10-23
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_points_available")
public class PointsAvailable implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code")
private String code;
// 积分类型 0:通用型
@Column(name = "points_type")
private Integer pointsType;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
@Column(name = "device_type")
private Integer deviceType;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 积分值
@Column(name = "points")
private Long points;
// 过期时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "expire_time")
private Timestamp expireTime;
// 描述
@Column(name = "description")
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(PointsAvailable source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.points.available.repository;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-23
*/
public interface PointsAvailableRepository extends JpaRepository<PointsAvailable, Long>, JpaSpecificationExecutor<PointsAvailable> {
Optional<PointsAvailable> findFirstByCode(String code);
List<PointsAvailableDTO> findByMemberId(Long memberId);
List<PointsAvailable> findByMemberIdAndExpireTimeBefore(Long memberId , Date now);
/**
* 即将过期的积分
* @param memberId
* @param factor
* @return
*/
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where upa.member_id = ?1 " +
" and (TO_DAYS(expire_time) - TO_DAYS(NOW())) <= ?2 "
,nativeQuery = true)
Long findSoonExpireTime(Long memberId, Integer factor);
/**
* 总积分
* @param criteria
* @return
*/
@Deprecated
@Query(value = "SELECT sum(upa.points) AS pointsProduce FROM uc_points_available upa WHERE (TO_DAYS(create_time)+1) = TO_DAYS(NOW())"
,nativeQuery = true)
Long findEveryDayPointsProduce(PointsAvailableQueryCriteria criteria);
/**
* 可用总积分
* @param criteria
* @return
*/
@Deprecated
@Query(value = "SELECT sum(upa.points) AS pointsAvailable FROM uc_points_available upa WHERE (TO_DAYS(create_time)+1) = TO_DAYS(NOW())"
,nativeQuery = true)
Long findEveryDayPointsAvailable(PointsAvailableQueryCriteria criteria);
/**
* 过期总积分
* @param criteria
* @return
*/
@Deprecated
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where (TO_DAYS(create_time)+1) = TO_DAYS(NOW()) " +
" and TO_DAYS(expire_time) < TO_DAYS(NOW())"
,nativeQuery = true)
Long findEveryDayPointsExpire(PointsAvailableQueryCriteria criteria);
/**
* 获取可用积分
* @param memberId
* @return
*/
@Query(value = "SELECT sum(upa.points) AS pointsExpire from uc_points_available upa where upa.member_id = ?1 and upa.expire_time >= now()"
,nativeQuery = true)
long findAvailablePointsByMemberId(long memberId);
List<PointsAvailable> findByMemberIdOrderByExpireTime(Long memberId);
@Transactional
@Modifying
@Query(value = "delete from uc_points_available where id in ?1" ,nativeQuery = true)
void deleteBatchByIds(List<Long> id);
List<PointsAvailable> findByExpireTimeBefore(Timestamp now);
}
package com.topdraw.business.basicdata.points.available.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-23
*/
//@Api(tags = "PointsAvailable管理")
//@RestController
//@RequestMapping("/api/PointsAvailable")
public class PointsAvailableController {
/*@Autowired
private PointsAvailableService PointsAvailableService;
@GetMapping
@ApiOperation("查询PointsAvailable")
public ResultInfo getPointsAvailables(PointsAvailableQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PointsAvailableService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有PointsAvailable")
public ResultInfo getPointsAvailables(PointsAvailableQueryCriteria criteria) {
return ResultInfo.success(PointsAvailableService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增PointsAvailable")
public ResultInfo create(@Validated @RequestBody PointsAvailable resources) {
PointsAvailableService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改PointsAvailable")
public ResultInfo update(@Validated @RequestBody PointsAvailable resources) {
PointsAvailableService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除PointsAvailable")
public ResultInfo delete(@PathVariable Long id) {
PointsAvailableService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(PointsAvailableService.getByCode(code));
}*/
}
package com.topdraw.business.basicdata.points.available.service;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import com.topdraw.business.process.domian.TempPoints;
import org.springframework.data.domain.Pageable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-23
*/
public interface PointsAvailableService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PointsAvailableQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PointsAvailableDTO>
*/
List<PointsAvailableDTO> queryAll(PointsAvailableQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PointsAvailableDTO
*/
PointsAvailableDTO findById(Long id);
/**
*
* @param resources
*/
void create(PointsAvailable resources);
/**
*
* @param resources
*/
void update(PointsAvailable resources);
/**
*
* @param id
*/
void delete(Long id);
/**
*
* @param id
*/
void deleteBatchByIds(List<Long> id);
/**
* Code校验
* @param code
* @return PointsAvailableDTO
*/
PointsAvailableDTO getByCode(String code);
/**
* 已过期的积分
* @param memberId
* @param timestamp
* @return
*/
List<PointsAvailableDTO> findByMemberIdAndExpireTimeBefore(Long memberId, Date timestamp);
/**
* 即将过期的积分
* @param memberId 会员id
* @param factor 阈值
* @return
*/
Long findSoonExpireTime(Long memberId,Integer factor);
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> findByMemberIdAndExpireTimeBefore(PointsAvailableQueryCriteria criteria, Pageable pageable);
/**
*
* @param memberId
* @return
*/
List<PointsAvailableDTO> findByMemberIdOrderByExpireTime(Long memberId);
/**
* 可用总积分
* @param criteria 条件参数
* @return Map<String,Object>
*/
Long findEveryDayPointsAvailable(PointsAvailableQueryCriteria criteria);
/**
* 总积分
* @param criteria
* @return
*/
Long findEveryDayPointsProduce(PointsAvailableQueryCriteria criteria);
/**
* 积分消耗
* @param criteria
* @return
*/
Long findEveryDayPointsConsume(PointsAvailableQueryCriteria criteria);
/**
* 积分过期
* @param criteria
* @return
*/
Long findEveryDayPointsExpire(PointsAvailableQueryCriteria criteria);
long findAvailablePointsByMemberId(long memberId);
List<PointsAvailableDTO> findByExpireTimeBefore(Timestamp now);
}
package com.topdraw.business.basicdata.points.available.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Data
public class PointsAvailableDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 积分类型 0:通用型
private Integer pointsType;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
private Integer deviceType;
// 会员id
private Long memberId;
// 积分值
private Long points;
// 过期时间
private Timestamp expireTime;
// 描述
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.points.available.service.dto;
import lombok.Data;
import com.topdraw.annotation.Query;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Data
public class PointsAvailableQueryCriteria{
@Query
private Long memberId;
@Query
private Long accountId;
@Query(type = Query.Type.GREATER_THAN)
private Timestamp expireTime;
private PointsAvailableQueryType queryType;
}
package com.topdraw.business.basicdata.points.available.service.dto;
public enum PointsAvailableQueryType {
// 全部
ALL,
// 可用
AVAILABLE_ONLY
}
package com.topdraw.business.basicdata.points.available.service.impl;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.util.RedissonUtil;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.points.available.repository.PointsAvailableRepository;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import com.topdraw.business.basicdata.points.available.service.mapper.PointsAvailableMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsAvailableServiceImpl implements PointsAvailableService {
@Autowired
private PointsAvailableRepository PointsAvailableRepository;
@Autowired
private PointsAvailableMapper PointsAvailableMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(PointsAvailableQueryCriteria criteria, Pageable pageable) {
Page<PointsAvailable> page = PointsAvailableRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PointsAvailableMapper::toDto));
}
@Override
public Map<String, Object> findByMemberIdAndExpireTimeBefore(PointsAvailableQueryCriteria criteria, Pageable pageable) {
return this.queryAll(criteria,pageable);
}
@Override
public List<PointsAvailableDTO> findByMemberIdOrderByExpireTime(Long memberId) {
return PointsAvailableMapper.toDto(PointsAvailableRepository.findByMemberIdOrderByExpireTime(memberId));
}
@Override
public List<PointsAvailableDTO> queryAll(PointsAvailableQueryCriteria criteria) {
return PointsAvailableMapper.toDto(PointsAvailableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PointsAvailableDTO findById(Long id) {
PointsAvailable PointsAvailable = PointsAvailableRepository.findById(id).orElseGet(PointsAvailable::new);
ValidationUtil.isNull(PointsAvailable.getId(),"PointsAvailable","id",id);
return PointsAvailableMapper.toDto(PointsAvailable);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(PointsAvailable resources) {
PointsAvailableRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(PointsAvailable resources) {
RLock rLock = this.redissonClient.getLock("updatePointsAvailable"+resources.getId().toString());
try {
RedissonUtil.lock(rLock);
PointsAvailable PointsAvailable = PointsAvailableRepository.findById(resources.getId()).orElseGet(PointsAvailable::new);
ValidationUtil.isNull( PointsAvailable.getId(),"PointsAvailable","id",resources.getId());
PointsAvailable.copy(resources);
PointsAvailableRepository.save(PointsAvailable);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
RedissonUtil.unlock(rLock);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
PointsAvailable PointsAvailable = PointsAvailableRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", PointsAvailable.class, id), 1));
PointsAvailableRepository.delete(PointsAvailable);
}
@Override
public void deleteBatchByIds(List<Long> id) {
PointsAvailableRepository.deleteBatchByIds(id);
}
@Override
public PointsAvailableDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? PointsAvailableMapper.toDto(PointsAvailableRepository.findFirstByCode(code).orElseGet(PointsAvailable::new))
: new PointsAvailableDTO();
}
@Override
public List<PointsAvailableDTO> findByMemberIdAndExpireTimeBefore(Long memberId, Date timestamp) {
return Objects.nonNull(memberId)?
PointsAvailableMapper.toDto(PointsAvailableRepository.findByMemberIdAndExpireTimeBefore(memberId, timestamp))
:null;
}
@Override
public Long findSoonExpireTime(Long memberId, Integer factor) {
return PointsAvailableRepository.findSoonExpireTime(memberId, factor);
}
@Override
public Long findEveryDayPointsAvailable(PointsAvailableQueryCriteria criteria) {
return PointsAvailableRepository.findEveryDayPointsAvailable(criteria);
}
@Override
public Long findEveryDayPointsProduce(PointsAvailableQueryCriteria criteria) {
return this.PointsAvailableRepository.findEveryDayPointsProduce(criteria);
}
@Override
public Long findEveryDayPointsConsume(PointsAvailableQueryCriteria criteria) {
return 0L;
}
@Override
public Long findEveryDayPointsExpire(PointsAvailableQueryCriteria criteria) {
return this.PointsAvailableRepository.findEveryDayPointsExpire(criteria);
}
@Override
public long findAvailablePointsByMemberId(long memberId) {
return this.PointsAvailableRepository.findAvailablePointsByMemberId(memberId);
}
@Override
public List<PointsAvailableDTO> findByExpireTimeBefore(Timestamp now) {
return PointsAvailableMapper.toDto(this.PointsAvailableRepository.findByExpireTimeBefore(now));
}
}
package com.topdraw.business.basicdata.points.available.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-23
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PointsAvailableMapper extends BaseMapper<PointsAvailableDTO, PointsAvailable> {
}
package com.topdraw.business.basicdata.points.detail.detailhistory.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_points_detail_history")
public class PointsDetailHistory implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 应用code
@Column(name = "app_code")
private String appCode;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 账号id
@Column(name = "account_id")
private Long accountId;
// 原始积分
@Column(name = "original_points", nullable = false)
private Long originalPoints;
// 结果积分
@Column(name = "result_points", nullable = false)
private Long resultPoints;
// 积分变化,积分获得为正,积分消耗为负
@Column(name = "points", nullable = false)
private Long points;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
@Column(name = "device_type", nullable = false)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他
@Column(name = "evt_type", nullable = false)
private Integer evtType;
// 订单id(针对订购操作)
@Column(name = "order_id")
private Long orderId;
// 节目id(针对观影操作)
@Column(name = "media_id")
private Long mediaId;
// 活动id(针对参与活动)
@Column(name = "activity_id")
private Long activityId;
// 积分变化描述,用于管理侧显示
@Column(name = "description", nullable = false)
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(PointsDetailHistory source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.points.detail.detailhistory.repository;
import com.topdraw.business.basicdata.points.detail.detailhistory.domain.PointsDetailHistory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsDetailHistoryRepository extends JpaRepository<PointsDetailHistory, Long>, JpaSpecificationExecutor<PointsDetailHistory> {
Optional<PointsDetailHistory> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.points.detail.detailhistory.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.detail.detailhistory.domain.PointsDetailHistory;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.PointsDetailHistoryService;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "PointsDetailHistory管理")
//@RestController
//@RequestMapping("/api/PointsDetailHistory")
public class PointsDetailHistoryController {
/*@Autowired
private PointsDetailHistoryService PointsDetailHistoryService;
@GetMapping
@ApiOperation("查询PointsDetailHistory")
public ResultInfo getPointsDetailHistorys(PointsDetailHistoryQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PointsDetailHistoryService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有PointsDetailHistory")
public ResultInfo getPointsDetailHistorys(PointsDetailHistoryQueryCriteria criteria) {
return ResultInfo.success(PointsDetailHistoryService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增PointsDetailHistory")
public ResultInfo create(@Validated @RequestBody PointsDetailHistory resources) {
PointsDetailHistoryService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改PointsDetailHistory")
public ResultInfo update(@Validated @RequestBody PointsDetailHistory resources) {
PointsDetailHistoryService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除PointsDetailHistory")
public ResultInfo delete(@PathVariable Long id) {
PointsDetailHistoryService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(PointsDetailHistoryService.getByCode(code));
}*/
}
package com.topdraw.business.basicdata.points.detail.detailhistory.service;
import com.topdraw.business.basicdata.points.detail.detailhistory.domain.PointsDetailHistory;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryDTO;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsDetailHistoryService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PointsDetailHistoryQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PointsDetailHistoryDTO>
*/
List<PointsDetailHistoryDTO> queryAll(PointsDetailHistoryQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PointsDetailHistoryDTO
*/
PointsDetailHistoryDTO findById(Long id);
void create(PointsDetailHistory resources);
void update(PointsDetailHistory resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return PointsDetailHistoryDTO
*/
PointsDetailHistoryDTO getByCode(String code);
}
package com.topdraw.business.basicdata.points.detail.detailhistory.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsDetailHistoryDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 应用code
private String appCode;
// 会员id
private Long memberId;
// 账号id
private Long accountId;
// 原始积分
private Long originalPoints;
// 结果积分
private Long resultPoints;
// 积分变化,积分获得为正,积分消耗为负
private Long points;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他
private Integer evtType;
// 订单id(针对订购操作)
private Long orderId;
// 节目id(针对观影操作)
private Long mediaId;
// 活动id(针对参与活动)
private Long activityId;
// 积分变化描述,用于管理侧显示
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.points.detail.detailhistory.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsDetailHistoryQueryCriteria{
}
package com.topdraw.business.basicdata.points.detail.detailhistory.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.points.detail.detailhistory.domain.PointsDetailHistory;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.points.detail.detailhistory.repository.PointsDetailHistoryRepository;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.PointsDetailHistoryService;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryDTO;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryQueryCriteria;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.mapper.PointsDetailHistoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsDetailHistoryServiceImpl implements PointsDetailHistoryService {
@Autowired
private PointsDetailHistoryRepository PointsDetailHistoryRepository;
@Autowired
private PointsDetailHistoryMapper PointsDetailHistoryMapper;
@Override
public Map<String, Object> queryAll(PointsDetailHistoryQueryCriteria criteria, Pageable pageable) {
Page<PointsDetailHistory> page = PointsDetailHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PointsDetailHistoryMapper::toDto));
}
@Override
public List<PointsDetailHistoryDTO> queryAll(PointsDetailHistoryQueryCriteria criteria) {
return PointsDetailHistoryMapper.toDto(PointsDetailHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PointsDetailHistoryDTO findById(Long id) {
PointsDetailHistory PointsDetailHistory = PointsDetailHistoryRepository.findById(id).orElseGet(PointsDetailHistory::new);
ValidationUtil.isNull(PointsDetailHistory.getId(),"PointsDetailHistory","id",id);
return PointsDetailHistoryMapper.toDto(PointsDetailHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(PointsDetailHistory resources) {
PointsDetailHistoryRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(PointsDetailHistory resources) {
PointsDetailHistory PointsDetailHistory = PointsDetailHistoryRepository.findById(resources.getId()).orElseGet(PointsDetailHistory::new);
ValidationUtil.isNull( PointsDetailHistory.getId(),"PointsDetailHistory","id",resources.getId());
PointsDetailHistory.copy(resources);
PointsDetailHistoryRepository.save(PointsDetailHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
PointsDetailHistory PointsDetailHistory = PointsDetailHistoryRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", PointsDetailHistory.class, id), 1));
PointsDetailHistoryRepository.delete(PointsDetailHistory);
}
@Override
public PointsDetailHistoryDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? PointsDetailHistoryMapper.toDto(PointsDetailHistoryRepository.findFirstByCode(code).orElseGet(PointsDetailHistory::new))
: new PointsDetailHistoryDTO();
}
}
package com.topdraw.business.basicdata.points.detail.detailhistory.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.points.detail.detailhistory.domain.PointsDetailHistory;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.dto.PointsDetailHistoryDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PointsDetailHistoryMapper extends BaseMapper<PointsDetailHistoryDTO, PointsDetailHistory> {
}
package com.topdraw.business.basicdata.points.detail.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_points_detail")
public class PointsDetail implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 应用code
@Column(name = "app_code")
private String appCode;
// 会员id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 账号id
@Column(name = "account_id")
private Long accountId;
// 原始积分
@Column(name = "original_points", nullable = false)
private Long originalPoints;
// 结果积分
@Column(name = "result_points", nullable = false)
private Long resultPoints;
// 积分变化,积分获得为正,积分消耗为负
@Column(name = "points", nullable = false)
private Long points;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
@Column(name = "device_type", nullable = false)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他
@Column(name = "evt_type", nullable = false)
private Integer evtType;
// 订单id(针对订购操作)
@Column(name = "order_id")
private Long orderId;
// 节目id(针对观影操作)
@Column(name = "media_id")
private Long mediaId;
// 活动id(针对参与活动)
@Column(name = "activity_id")
private Long activityId;
// 积分变化描述,用于管理侧显示
@Column(name = "description", nullable = false)
private String description;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(PointsDetail source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.points.detail.repository;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsDetailRepository extends JpaRepository<PointsDetail, Long>, JpaSpecificationExecutor<PointsDetail> {
Optional<PointsDetail> findFirstByCode(String code);
List<PointsDetail> findByMemberId(Long memberId);
}
package com.topdraw.business.basicdata.points.detail.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "PointsDetail管理")
//@RestController
//@RequestMapping("/api/PointsDetail")
public class PointsDetailController {
/*@Autowired
private PointsDetailService PointsDetailService;
@GetMapping
@ApiOperation("查询PointsDetail")
public ResultInfo getPointsDetails(PointsDetailQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PointsDetailService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有PointsDetail")
public ResultInfo getPointsDetails(PointsDetailQueryCriteria criteria) {
return ResultInfo.success(PointsDetailService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增PointsDetail")
public ResultInfo create(@Validated @RequestBody PointsDetail resources) {
PointsDetailService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改PointsDetail")
public ResultInfo update(@Validated @RequestBody PointsDetail resources) {
PointsDetailService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除PointsDetail")
public ResultInfo delete(@PathVariable Long id) {
PointsDetailService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(PointsDetailService.getByCode(code));
}*/
}
package com.topdraw.business.basicdata.points.detail.service;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailDTO;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Date;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsDetailService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PointsDetailQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PointsDetailDTO>
*/
List<PointsDetailDTO> queryAll(PointsDetailQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PointsDetailDTO
*/
PointsDetailDTO findById(Long id);
void create(PointsDetail resources);
void update(PointsDetail resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return PointsDetailDTO
*/
PointsDetailDTO getByCode(String code);
List<PointsDetailDTO> loadListExpirePointsByMemberId(Long memberId);
/**
* 已过期的积分
* @param memberId
* @return
*/
List<PointsDetailDTO> findByMemberId(Long memberId);
}
package com.topdraw.business.basicdata.points.detail.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsDetailDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 应用code
private String appCode;
// 会员id
private Long memberId;
// 账号id
private Long accountId;
// 原始积分
private Long originalPoints;
// 结果积分
private Long resultPoints;
// 积分变化,积分获得为正,积分消耗为负
private Long points;
// 设备类型 1:大屏;2:小屏(微信)3.小屏(xx)
private Integer deviceType;
// 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他
private Integer evtType;
// 订单id(针对订购操作)
private Long orderId;
// 节目id(针对观影操作)
private Long mediaId;
// 活动id(针对参与活动)
private Long activityId;
// 积分变化描述,用于管理侧显示
private String description;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.points.detail.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsDetailQueryCriteria{
@Query(type = Query.Type.EQUAL)
private Long memberId;
@Query(type = Query.Type.EQUAL)
private Long accountId;
}
package com.topdraw.business.basicdata.points.detail.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.points.detail.repository.PointsDetailRepository;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailDTO;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailQueryCriteria;
import com.topdraw.business.basicdata.points.detail.service.mapper.PointsDetailMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsDetailServiceImpl implements PointsDetailService {
@Autowired
private PointsDetailRepository PointsDetailRepository;
@Autowired
private PointsDetailMapper PointsDetailMapper;
@Override
public Map<String, Object> queryAll(PointsDetailQueryCriteria criteria, Pageable pageable) {
Page<PointsDetail> page = PointsDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PointsDetailMapper::toDto));
}
@Override
public List<PointsDetailDTO> queryAll(PointsDetailQueryCriteria criteria) {
return PointsDetailMapper.toDto(PointsDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PointsDetailDTO findById(Long id) {
PointsDetail PointsDetail = PointsDetailRepository.findById(id).orElseGet(PointsDetail::new);
ValidationUtil.isNull(PointsDetail.getId(),"PointsDetail","id",id);
return PointsDetailMapper.toDto(PointsDetail);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(PointsDetail resources) {
PointsDetailRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(PointsDetail resources) {
PointsDetail PointsDetail = PointsDetailRepository.findById(resources.getId()).orElseGet(PointsDetail::new);
ValidationUtil.isNull( PointsDetail.getId(),"PointsDetail","id",resources.getId());
PointsDetail.copy(resources);
PointsDetailRepository.save(PointsDetail);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
PointsDetail PointsDetail = PointsDetailRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", PointsDetail.class, id), 1));
PointsDetailRepository.delete(PointsDetail);
}
@Override
public PointsDetailDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? PointsDetailMapper.toDto(PointsDetailRepository.findFirstByCode(code).orElseGet(PointsDetail::new))
: new PointsDetailDTO();
}
@Override
public List<PointsDetailDTO> loadListExpirePointsByMemberId(Long memberId) {
return null;
}
@Override
public List<PointsDetailDTO> findByMemberId(Long memberId) {
return Objects.nonNull(memberId)?
PointsDetailMapper.toDto(PointsDetailRepository.findByMemberId(memberId))
:null;
}
}
package com.topdraw.business.basicdata.points.detail.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PointsDetailMapper extends BaseMapper<PointsDetailDTO, PointsDetail> {
}
package com.topdraw.business.basicdata.points.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_points")
public class Points implements Serializable {
@Id
@Column(name = "id")
private Long id;
@Column(name = "user_id")
private Long userId;
// 积分类型,通用,绑定, 区分大小屏 todo
@Column(name = "point_type")
private Integer pointType;
// 绑定对应的实体, 如何描述?
@Column(name = "target_no")
private String targetNo;
// 本月期初积分值
@Column(name = "begin_points")
private Integer beginPoints;
// 当前积分余额
@Column(name = "current_points")
private Integer currentPoints;
// 本月到期积分
@Column(name = "expire_points")
private Integer expirePoints;
// 积分类型:10:通用积分(跨屏) 11:定向积分(跨屏,绑定用途)20:通用积分(大屏) 21:定向积分(大屏,绑定用途)30:通用积分(小屏) 31:定向积分(小屏,绑定用途)
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 最后修改时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(Points source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.points.repository;
import com.topdraw.business.basicdata.points.domain.Points;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsRepository extends JpaRepository<Points, Long>, JpaSpecificationExecutor<Points> {
}
package com.topdraw.business.basicdata.points.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.domain.Points;
import com.topdraw.business.basicdata.points.service.PointsService;
import com.topdraw.business.basicdata.points.service.dto.PointsQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Points管理")
//@RestController
//@RequestMapping("/api/Points")
public class PointsController {
/* @Autowired
private PointsService PointsService;
@GetMapping
@ApiOperation("查询Points")
public ResultInfo getPointss(PointsQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PointsService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有Points")
public ResultInfo getPointss(PointsQueryCriteria criteria) {
return ResultInfo.success(PointsService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增Points")
public ResultInfo create(@Validated @RequestBody Points resources) {
PointsService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改Points")
public ResultInfo update(@Validated @RequestBody Points resources) {
PointsService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除Points")
public ResultInfo delete(@PathVariable Long id) {
PointsService.delete(id);
return ResultInfo.success();
}*/
}
package com.topdraw.business.basicdata.points.service;
import com.topdraw.business.basicdata.points.domain.Points;
import com.topdraw.business.basicdata.points.service.dto.PointsDTO;
import com.topdraw.business.basicdata.points.service.dto.PointsQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PointsService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PointsQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PointsDTO>
*/
List<PointsDTO> queryAll(PointsQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PointsDTO
*/
PointsDTO findById(Long id);
void create(Points resources);
void update(Points resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.points.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsDTO implements Serializable {
// 处理精度丢失问题
@JsonSerialize(using= ToStringSerializer.class)
private Long id;
private Long userId;
// 积分类型,通用,绑定, 区分大小屏 todo
private Integer pointType;
// 绑定对应的实体, 如何描述?
private String targetNo;
// 本月期初积分值
private Integer beginPoints;
// 当前积分余额
private Integer currentPoints;
// 本月到期积分
private Integer expirePoints;
// 积分类型:10:通用积分(跨屏) 11:定向积分(跨屏,绑定用途)20:通用积分(大屏) 21:定向积分(大屏,绑定用途)30:通用积分(小屏) 31:定向积分(小屏,绑定用途)
private Timestamp createTime;
// 最后修改时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.points.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PointsQueryCriteria{
}
package com.topdraw.business.basicdata.points.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.points.domain.Points;
import com.topdraw.util.RedissonUtil;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.points.repository.PointsRepository;
import com.topdraw.business.basicdata.points.service.PointsService;
import com.topdraw.business.basicdata.points.service.dto.PointsDTO;
import com.topdraw.business.basicdata.points.service.dto.PointsQueryCriteria;
import com.topdraw.business.basicdata.points.service.mapper.PointsMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsServiceImpl implements PointsService {
@Autowired
private PointsRepository PointsRepository;
@Autowired
private PointsMapper PointsMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(PointsQueryCriteria criteria, Pageable pageable) {
Page<Points> page = PointsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PointsMapper::toDto));
}
@Override
public List<PointsDTO> queryAll(PointsQueryCriteria criteria) {
return PointsMapper.toDto(PointsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PointsDTO findById(Long id) {
Points Points = PointsRepository.findById(id).orElseGet(Points::new);
ValidationUtil.isNull(Points.getId(),"Points","id",id);
return PointsMapper.toDto(Points);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(Points resources) {
Snowflake snowflake = IdUtil.createSnowflake(1, 1);
resources.setId(snowflake.nextId());
PointsRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(Points resources) {
RLock rLock = this.redissonClient.getLock(resources.getId().toString());
try {
RedissonUtil.lock(rLock);
Points Points = PointsRepository.findById(resources.getId()).orElseGet(Points::new);
ValidationUtil.isNull(Points.getId(), "Points", "id", resources.getId());
Points.copy(resources);
PointsRepository.save(Points);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
RedissonUtil.unlock(rLock);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
Points Points = PointsRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", Points.class, id), 1));
PointsRepository.delete(Points);
}
}
package com.topdraw.business.basicdata.points.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.points.domain.Points;
import com.topdraw.business.basicdata.points.service.dto.PointsDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PointsMapper extends BaseMapper<PointsDTO, Points> {
}
package com.topdraw.business.basicdata.points.standingbook.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_points_standing_book")
public class PointsStandingBook implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 积分生产
@Column(name = "points_produce", nullable = false)
private Long pointsProduce;
// 积分消耗
@Column(name = "points_consume", nullable = false)
private Long pointsConsume;
// 可用总积分
@Column(name = "points_available", nullable = false)
private Long pointsAvailable;
// 积分过期
@Column(name = "points_expire", nullable = false)
private Long pointsExpire;
// 日期
@Column(name = "day")
private String day;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 创建时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(PointsStandingBook source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.points.standingbook.repository;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-29
*/
public interface PointsStandingBookRepository extends JpaRepository<PointsStandingBook, Long>, JpaSpecificationExecutor<PointsStandingBook> {
}
package com.topdraw.business.basicdata.points.standingbook.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import com.topdraw.business.basicdata.points.standingbook.service.PointsStandingBookService;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Api(tags = "PointsStandingBook管理")
@RestController
@RequestMapping("/api/PointsStandingBook")
public class PointsStandingBookController {
@Autowired
private PointsStandingBookService PointsStandingBookService;
@GetMapping
@ApiOperation("查询PointsStandingBook")
public ResultInfo getPointsStandingBooks(PointsStandingBookQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PointsStandingBookService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有PointsStandingBook")
public ResultInfo getPointsStandingBooks(PointsStandingBookQueryCriteria criteria) {
return ResultInfo.success(PointsStandingBookService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增PointsStandingBook")
public ResultInfo create(@Validated @RequestBody PointsStandingBook resources) {
PointsStandingBookService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改PointsStandingBook")
public ResultInfo update(@Validated @RequestBody PointsStandingBook resources) {
PointsStandingBookService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除PointsStandingBook")
public ResultInfo delete(@PathVariable Long id) {
PointsStandingBookService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.points.standingbook.service;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookDTO;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-10-29
*/
public interface PointsStandingBookService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PointsStandingBookQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PointsStandingBookDTO>
*/
List<PointsStandingBookDTO> queryAll(PointsStandingBookQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PointsStandingBookDTO
*/
PointsStandingBookDTO findById(Long id);
void create(PointsStandingBook resources);
void update(PointsStandingBook resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.points.standingbook.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Data
public class PointsStandingBookDTO implements Serializable {
// 主键
private Long id;
// 积分生产
private Long pointsProduce;
// 积分消耗
private Long pointsConsume;
// 可用总积分
private Long pointsAvailable;
// 积分过期
private Long pointsExpire;
// 日期
private String day;
// 创建时间
private Timestamp createTime;
// 创建时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.points.standingbook.service.dto;
import lombok.Data;
import com.topdraw.annotation.Query;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Data
public class PointsStandingBookQueryCriteria{
}
package com.topdraw.business.basicdata.points.standingbook.service.impl;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.utils.FileUtil;
import com.topdraw.business.basicdata.points.standingbook.repository.PointsStandingBookRepository;
import com.topdraw.business.basicdata.points.standingbook.service.PointsStandingBookService;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookDTO;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookQueryCriteria;
import com.topdraw.business.basicdata.points.standingbook.service.mapper.PointsStandingBookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsStandingBookServiceImpl implements PointsStandingBookService {
@Autowired
private PointsStandingBookRepository PointsStandingBookRepository;
@Autowired
private PointsStandingBookMapper PointsStandingBookMapper;
@Override
public Map<String, Object> queryAll(PointsStandingBookQueryCriteria criteria, Pageable pageable) {
Page<PointsStandingBook> page = PointsStandingBookRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PointsStandingBookMapper::toDto));
}
@Override
public List<PointsStandingBookDTO> queryAll(PointsStandingBookQueryCriteria criteria) {
return PointsStandingBookMapper.toDto(PointsStandingBookRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PointsStandingBookDTO findById(Long id) {
PointsStandingBook PointsStandingBook = PointsStandingBookRepository.findById(id).orElseGet(PointsStandingBook::new);
ValidationUtil.isNull(PointsStandingBook.getId(),"PointsStandingBook","id",id);
return PointsStandingBookMapper.toDto(PointsStandingBook);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(PointsStandingBook resources) {
PointsStandingBookRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(PointsStandingBook resources) {
PointsStandingBook PointsStandingBook = PointsStandingBookRepository.findById(resources.getId()).orElseGet(PointsStandingBook::new);
ValidationUtil.isNull( PointsStandingBook.getId(),"PointsStandingBook","id",resources.getId());
PointsStandingBook.copy(resources);
PointsStandingBookRepository.save(PointsStandingBook);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
PointsStandingBook PointsStandingBook = PointsStandingBookRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", PointsStandingBook.class, id), 1));
PointsStandingBookRepository.delete(PointsStandingBook);
}
}
package com.topdraw.business.basicdata.points.standingbook.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import com.topdraw.business.basicdata.points.standingbook.service.dto.PointsStandingBookDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-29
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PointsStandingBookMapper extends BaseMapper<PointsStandingBookDTO, PointsStandingBook> {
}
package com.topdraw.business.basicdata.rights.constant;
public class RightsType {
public static String TYPE_1 = "1";
Integer TYPE_2 = 2;
Integer TYPE_3 = 3;
}
package com.topdraw.business.basicdata.rights.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="tr_rights")
public class Rights implements Serializable {
// 主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 权益名称
// @Column(name = "name")
// private String name;
// 类型 1:实体类 (预留字段)
@Column(name = "type", nullable = false)
private Integer type;
// 终端类型 0:大屏;1:微信小程序/公众号;2:App
@Column(name = "device_type", nullable = false)
private Integer deviceType;
// 权益的实体类型 1:积分;2成长值;3优惠券
@Column(name = "entity_type", nullable = false)
private String entityType;
// 实体id
@Column(name = "entity_id", nullable = false)
private Long entityId;
// 生效时间,为null表示获取后立即生效,不为空时,表示特定的生效时间
@Column(name = "valid_time")
private Timestamp validTime;
// 失效时间,空为不失效,否则为获得权益后直到失效的毫秒数
@Column(name = "expire_time")
private Long expireTime;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
// 图片
@Column(name = "image")
private String image;
// 图片
@Column(name = "images")
private String images;
// 描述
@Column(name = "description")
private String description;
public void copy(Rights source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.rights.history.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="tr_rights_histroy")
public class RightsHistory implements Serializable {
// 主键id
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 权益id
@Column(name = "rights_id",nullable = false)
private Long rightsId;
// 会员id
@Column(name = "member_id",nullable = false)
private Long memberId;
@Transient
private Long userId;
// 操作者id(手动发放时保存)
@Column(name = "operator_id",nullable = false)
private Long operatorId;
// 操作者名称(手动发放时保存)
@Column(name = "operator_name",nullable = false)
private String operatorName;
// 发放时间
@Column(name = "send_time")
private Timestamp sendTime;
// 失效时间
@Column(name = "expire_time")
private Timestamp expireTime;
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(RightsHistory source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.rights.history.repository;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface RightsHistoryRepository extends JpaRepository<RightsHistory, Long>, JpaSpecificationExecutor<RightsHistory> {
}
package com.topdraw.business.basicdata.rights.history.rest;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryType;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.RightsHistoryService;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryCriteria;
import com.topdraw.util.TimestampUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "RightsHistory管理")
@RestController
@RequestMapping("/api/RightsHistory")
public class RightsHistoryController {
@Autowired
private RightsHistoryService RightsHistoryService;
@GetMapping(value = "/pageRightsHistory")
@ApiOperation("查询RightsHistory")
public ResultInfo pageRightsHistory(RightsHistoryQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(RightsHistoryService.queryAll(criteria,pageable));
}
@GetMapping(value = "/pageAvailableRights")
@ApiOperation("查询用户可用权益列表")
public ResultInfo pageAvailableRights(RightsHistoryQueryCriteria criteria, Pageable pageable) {
criteria.setExpireTime(TimestampUtil.now());
return ResultInfo.successPage(RightsHistoryService.queryAll(criteria,pageable));
}
}
package com.topdraw.business.basicdata.rights.history.service;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryDTO;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface RightsHistoryService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(RightsHistoryQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<RightsHistoryDTO>
*/
List<RightsHistoryDTO> queryAll(RightsHistoryQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return RightsHistoryDTO
*/
RightsHistoryDTO findById(Long id);
/**
*
* @param resources
*/
void create(RightsHistory resources);
/**
*
* @param resources
*/
void update(RightsHistory resources);
/**
*
* @param id
*/
void delete(Long id);
}
package com.topdraw.business.basicdata.rights.history.service.dto;
import lombok.Data;
import javax.persistence.Column;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class RightsHistoryDTO implements Serializable {
// 主键id
private Long id;
// 权益id
private Long rightsId;
// 会员id
private Long memberId;
// 操作者id(手动发放时保存)
private Long operatorId;
// 操作者名称(手动发放时保存)
private String operatorName;
// 发放时间
private Timestamp sendTime;
// 失效时间
private Timestamp expireTime;
private Timestamp createTime;
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.rights.history.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class RightsHistoryQueryCriteria{
@Query
private Long memberId;
@Query(type = Query.Type.GREATER_THAN)
private Timestamp expireTime;
private RightsHistoryQueryType queryType;
}
package com.topdraw.business.basicdata.rights.history.service.dto;
public enum RightsHistoryQueryType {
// 全部
ALL,
// 可用
AVAILABLE_ONLY
}
package com.topdraw.business.basicdata.rights.history.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.rights.history.repository.RightsHistoryRepository;
import com.topdraw.business.basicdata.rights.history.service.RightsHistoryService;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryDTO;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryCriteria;
import com.topdraw.business.basicdata.rights.history.service.mapper.RightsHistoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RightsHistoryServiceImpl implements RightsHistoryService {
@Autowired
private RightsHistoryRepository RightsHistoryRepository;
@Autowired
private RightsHistoryMapper RightsHistoryMapper;
@Override
public Map<String, Object> queryAll(RightsHistoryQueryCriteria criteria, Pageable pageable) {
Page<RightsHistory> page = RightsHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(RightsHistoryMapper::toDto));
}
@Override
public List<RightsHistoryDTO> queryAll(RightsHistoryQueryCriteria criteria) {
return RightsHistoryMapper.toDto(RightsHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public RightsHistoryDTO findById(Long id) {
RightsHistory RightsHistory = RightsHistoryRepository.findById(id).orElseGet(RightsHistory::new);
ValidationUtil.isNull(RightsHistory.getId(),"RightsHistory","id",id);
return RightsHistoryMapper.toDto(RightsHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(RightsHistory resources) {
RightsHistoryRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(RightsHistory resources) {
RightsHistory RightsHistory = RightsHistoryRepository.findById(resources.getId()).orElseGet(RightsHistory::new);
ValidationUtil.isNull( RightsHistory.getId(),"RightsHistory","id",resources.getId());
RightsHistory.copy(resources);
RightsHistoryRepository.save(RightsHistory);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
RightsHistory RightsHistory = RightsHistoryRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", RightsHistory.class, id), 1));
RightsHistoryRepository.delete(RightsHistory);
}
}
package com.topdraw.business.basicdata.rights.history.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RightsHistoryMapper extends BaseMapper<RightsHistoryDTO, RightsHistory> {
}
package com.topdraw.business.basicdata.rights.permanentrights.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_permanent_rights")
public class PermanentRights implements Serializable {
// ID
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code", nullable = false)
private String code;
// 名称
@Column(name = "name", nullable = false)
private String name;
// 永久权益类型 0:vip;1:会员等级
@Column(name = "type")
private Integer type;
// 等级(当权益类型为vip时,对应vip值,当权益类型为会员等级时,对应等级index)
@Column(name = "level")
private Integer level;
// 商品折扣,10代表10% off,范围为0-100
@Column(name = "item_discount", nullable = false)
private BigDecimal itemDiscount;
// 额外积分比率,范围为0-1000
@Column(name = "extra_points", nullable = false)
private BigDecimal extraPoints;
// 免广告
@Column(name = "ad_disabled", nullable = false)
private Integer adDisabled;
// 额外活动参与机会
@Column(name = "extra_activity_ticket", nullable = false)
private Integer extraActivityTicket;
// 免费试看
@Column(name = "free_trial", nullable = false)
private Integer freeTrial;
// 上电视专区权益
@Column(name = "zone_sds", nullable = false)
private Integer zoneSds;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(PermanentRights source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.rights.permanentrights.repository;
import com.topdraw.business.basicdata.rights.permanentrights.domain.PermanentRights;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PermanentRightsRepository extends JpaRepository<PermanentRights, Long>, JpaSpecificationExecutor<PermanentRights> {
Optional<PermanentRights> findFirstByCode(String code);
}
package com.topdraw.business.basicdata.rights.permanentrights.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.rights.permanentrights.domain.PermanentRights;
import com.topdraw.business.basicdata.rights.permanentrights.service.PermanentRightsService;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "PermanentRights管理")
@RestController
@RequestMapping("/api/PermanentRights")
public class PermanentRightsController {
@Autowired
private PermanentRightsService PermanentRightsService;
@GetMapping
@ApiOperation("查询PermanentRights")
public ResultInfo pagePermanentRights(PermanentRightsQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(PermanentRightsService.queryAll(criteria,pageable));
}
@GetMapping(value = "/findById/{id}")
@ApiOperation("查询PermanentRights")
public ResultInfo findById(@PathVariable("id") Long id) {
return ResultInfo.success(PermanentRightsService.findById(id));
}
@Log
@PostMapping(value = "/create")
@ApiOperation("新增PermanentRights")
public ResultInfo create(@Validated @RequestBody PermanentRights resources) {
PermanentRightsService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping(value = "/update")
@ApiOperation("修改PermanentRights")
public ResultInfo update(@Validated @RequestBody PermanentRights resources) {
PermanentRightsService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/delete/{id}")
@ApiOperation("删除PermanentRights")
public ResultInfo delete(@PathVariable Long id) {
PermanentRightsService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(PermanentRightsService.getByCode(code));
}
}
package com.topdraw.business.basicdata.rights.permanentrights.service;
import com.topdraw.business.basicdata.rights.permanentrights.domain.PermanentRights;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsDTO;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface PermanentRightsService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(PermanentRightsQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<PermanentRightsDTO>
*/
List<PermanentRightsDTO> queryAll(PermanentRightsQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return PermanentRightsDTO
*/
PermanentRightsDTO findById(Long id);
void create(PermanentRights resources);
void update(PermanentRights resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return PermanentRightsDTO
*/
PermanentRightsDTO getByCode(String code);
}
package com.topdraw.business.basicdata.rights.permanentrights.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PermanentRightsDTO implements Serializable {
// ID
private Long id;
// 标识
private String code;
// 名称
private String name;
// 永久权益类型 0:vip;1:会员等级
private Integer type;
// 等级(当权益类型为vip时,对应vip值,当权益类型为会员等级时,对应等级index)
private Integer level;
// 商品折扣,10代表10% off,范围为0-100
private BigDecimal itemDiscount;
// 额外积分比率,范围为0-1000
private BigDecimal extraPoints;
// 免广告
private Integer adDisabled;
// 额外活动参与机会
private Integer extraActivityTicket;
// 免费试看
private Integer freeTrial;
// 上电视专区权益
private Integer zoneSds;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.rights.permanentrights.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class PermanentRightsQueryCriteria{
@Query(type = Query.Type.EQUAL)
private Integer level;
}
package com.topdraw.business.basicdata.rights.permanentrights.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.rights.permanentrights.domain.PermanentRights;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.rights.permanentrights.repository.PermanentRightsRepository;
import com.topdraw.business.basicdata.rights.permanentrights.service.PermanentRightsService;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsDTO;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsQueryCriteria;
import com.topdraw.business.basicdata.rights.permanentrights.service.mapper.PermanentRightsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PermanentRightsServiceImpl implements PermanentRightsService {
@Autowired
private PermanentRightsRepository PermanentRightsRepository;
@Autowired
private PermanentRightsMapper PermanentRightsMapper;
@Override
public Map<String, Object> queryAll(PermanentRightsQueryCriteria criteria, Pageable pageable) {
Page<PermanentRights> page = PermanentRightsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(PermanentRightsMapper::toDto));
}
@Override
public List<PermanentRightsDTO> queryAll(PermanentRightsQueryCriteria criteria) {
return PermanentRightsMapper.toDto(PermanentRightsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public PermanentRightsDTO findById(Long id) {
PermanentRights PermanentRights = PermanentRightsRepository.findById(id).orElseGet(PermanentRights::new);
ValidationUtil.isNull(PermanentRights.getId(),"PermanentRights","id",id);
return PermanentRightsMapper.toDto(PermanentRights);
}
@Override
@Transactional(rollbackFor = Exception.class)
// @AsyncMqSend()
public void create(PermanentRights resources) {
PermanentRightsRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
// @AsyncMqSend()
public void update(PermanentRights resources) {
PermanentRights PermanentRights = PermanentRightsRepository.findById(resources.getId()).orElseGet(PermanentRights::new);
ValidationUtil.isNull( PermanentRights.getId(),"PermanentRights","id",resources.getId());
PermanentRights.copy(resources);
PermanentRightsRepository.save(PermanentRights);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
PermanentRights PermanentRights = PermanentRightsRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", PermanentRights.class, id), 1));
PermanentRightsRepository.delete(PermanentRights);
}
@Override
public PermanentRightsDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? PermanentRightsMapper.toDto(PermanentRightsRepository.findFirstByCode(code).orElseGet(PermanentRights::new))
: new PermanentRightsDTO();
}
}
package com.topdraw.business.basicdata.rights.permanentrights.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.rights.permanentrights.domain.PermanentRights;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface PermanentRightsMapper extends BaseMapper<PermanentRightsDTO, PermanentRights> {
}
package com.topdraw.business.basicdata.rights.repository;
import com.topdraw.business.basicdata.rights.domain.Rights;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface RightsRepository extends JpaRepository<Rights, Long>, JpaSpecificationExecutor<Rights> {
Optional<Rights> findFirstByCode(String code);
@Query(value = "FROM Rights r WHERE r.id IN (?2)",nativeQuery = false)
List<Rights> findBatchByIds(Long[] ids);
}
package com.topdraw.business.basicdata.rights.rest;
import com.topdraw.business.basicdata.rights.service.RightsService;
import com.topdraw.business.basicdata.rights.service.dto.RightsQueryCriteria;
import com.topdraw.common.ResultInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Rights管理")
@RestController
@RequestMapping("/api/Rights")
public class RightsController {
@Autowired
private RightsService rightsService;
@GetMapping(value = "/findById/{id}")
@ApiOperation("查询Rights")
public ResultInfo findById(@PathVariable("id") Long id) {
return ResultInfo.success(rightsService.findById(id));
}
}
package com.topdraw.business.basicdata.rights.service;
import com.topdraw.business.basicdata.rights.domain.Rights;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import com.topdraw.business.basicdata.rights.service.dto.RightsQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface RightsService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(RightsQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<RightsDTO>
*/
List<RightsDTO> queryAll(RightsQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return RightsDTO
*/
RightsDTO findById(Long id);
/**
* 批量查询
* @param ids
* @return
*/
List<RightsDTO> findBatchByIds(Long... ids);
void create(Rights resources);
void update(Rights resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return RightsDTO
*/
RightsDTO getByCode(String code);
}
package com.topdraw.business.basicdata.rights.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class RightsDTO implements Serializable {
// 主键
private Long id;
// 标识
private String code;
// 权益名称
// private String name;
// 终端类型 0:大屏;1:微信小程序/公众号;2:App
private Integer deviceType;
// 类型 1:实体类 (预留字段)
private Integer type;
// 权益的实体类型 1:积分;2成长值;3优惠券
private String entityType;
// 实体id
private Long entityId;
// 生效时间,为null表示获取后立即生效,不为空时,表示特定的生效时间
private Timestamp validTime;
// 失效时间,空为不失效,否则为获得权益后直到失效的毫秒数
private Long expireTime;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
// 图片
private String image;
// 图片
private String images;
// 描述
private String description;
}
package com.topdraw.business.basicdata.rights.service.dto;
import com.topdraw.annotation.Query;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class RightsQueryCriteria{
@Query
private Long memberId;
private RightsQueryType queryType;
}
package com.topdraw.business.basicdata.rights.service.dto;
public enum RightsQueryType {
// 全部
ALL,
// 可用
AVAILABLE_ONLY
}
package com.topdraw.business.basicdata.rights.service.impl;
import com.topdraw.aspect.AsyncMqSend;
import com.topdraw.business.basicdata.rights.domain.Rights;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.rights.repository.RightsRepository;
import com.topdraw.business.basicdata.rights.service.RightsService;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import com.topdraw.business.basicdata.rights.service.dto.RightsQueryCriteria;
import com.topdraw.business.basicdata.rights.service.mapper.RightsMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RightsServiceImpl implements RightsService {
@Autowired
private RightsRepository RightsRepository;
@Autowired
private RightsMapper RightsMapper;
@Autowired
private RedissonClient redissonClient;
@Override
public Map<String, Object> queryAll(RightsQueryCriteria criteria, Pageable pageable) {
Page<Rights> page = RightsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(RightsMapper::toDto));
}
@Override
public List<RightsDTO> queryAll(RightsQueryCriteria criteria) {
return RightsMapper.toDto(RightsRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public RightsDTO findById(Long id) {
Rights Rights = RightsRepository.findById(id).orElseGet(Rights::new);
ValidationUtil.isNull(Rights.getId(),"Rights","id",id);
return RightsMapper.toDto(Rights);
}
@Override
public List<RightsDTO> findBatchByIds(Long... ids) {
List<Rights> rightsList = this.RightsRepository.findBatchByIds(ids);
return !CollectionUtils.isEmpty(rightsList) ? RightsMapper.toDto(rightsList) : null;
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void create(Rights resources) {
RightsRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void update(Rights resources) {
RLock rLock = this.redissonClient.getLock(resources.getId().toString());
try {
Rights Rights = RightsRepository.findById(resources.getId()).orElseGet(Rights::new);
ValidationUtil.isNull( Rights.getId(),"Rights","id",resources.getId());
Rights.copy(resources);
RightsRepository.save(Rights);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
rLock.unlock();
}
}
@Override
@Transactional(rollbackFor = Exception.class)
@AsyncMqSend()
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
Rights Rights = RightsRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", Rights.class, id), 1));
RightsRepository.delete(Rights);
}
@Override
public RightsDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? RightsMapper.toDto(RightsRepository.findFirstByCode(code).orElseGet(Rights::new))
: new RightsDTO();
}
}
package com.topdraw.business.basicdata.rights.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.rights.domain.Rights;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RightsMapper extends BaseMapper<RightsDTO, Rights> {
}
package com.topdraw.business.basicdata.task.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="tr_task")
public class Task implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 任务模板id
@Column(name = "task_template_id", nullable = false)
private Long taskTemplateId;
// 任务重复类型,-1:不限次;1:单次;>1:多次
@Column(name = "task_repeat_type", nullable = false)
private Integer taskRepeatType;
// 任务每日重置 0:不重置;1:重置
@Column(name = "task_daily_reset", nullable = false)
private Integer taskDailyReset;
// 行为量(完成此任务需要多少次相同行为的触发)
@Column(name = "action_amount", nullable = false)
private Integer actionAmount;
// 任务生效时间
@Column(name = "valid_time")
private Timestamp validTime;
// 任务失效时间
@Column(name = "expire_time")
private Timestamp expireTime;
// 显示顺序
@Column(name = "sequence")
private Integer sequence;
// 获得成长值
@Column(name = "reward_exp", nullable = false)
private Long rewardExp;
// 获得积分
@Column(name = "reward_points", nullable = false)
private Long rewardPoints;
// 积分过期时间(空为不过期)
@Column(name = "reward_points_expire_time")
private Long rewardPointsExpireTime;
// 积分获取类型 0:定值;1:随机
@Column(name = "points_type")
private Integer pointsType;
// 随机积分最大值
@Column(name = "reward_max_points")
private Integer rewardMaxPoints;
// 能够获取该任务的用户分组,为空则都能获取
@Column(name = "groups")
private String groups;
// 权益发放策略 0:立即发放;1:次日发放;2:次月发放
@Column(name = "rights_send_strategy", nullable = false)
private Integer rightsSendStrategy;
// 会员等级门槛(0表示无门槛)
@Column(name = "member_level", nullable = false)
private Integer memberLevel;
// 会员vip门槛(0表示没有门槛)
@Column(name = "member_vip")
private Integer memberVip;
// 权益id
@Column(name = "rights_id")
private Long rightsId;
// 权益数量(活动机会次数、优惠券数量、奖品数量)
@Column(name = "rights_amount")
private Integer rightsAmount;
// 权益2id
@Column(name = "rights2_id")
private Long rights2Id;
// 权益2数量
@Column(name = "rights2_amount")
private Integer rights2Amount;
// 权益3id
@Column(name = "rights3_id")
private Long rights3Id;
// 权益3数量
@Column(name = "rights3_amount")
private Integer rights3Amount;
// 状态 0:失效;1:生效
@Column(name = "status", nullable = false)
private Integer status;
// 创建时间
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
// 更新时间
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(Task source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.task.progress.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="uc_tr_task_progress")
@AllArgsConstructor
@NoArgsConstructor
public class TrTaskProgress implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 用户id
@Column(name = "member_id", nullable = false)
private Long memberId;
// 任务id
@Column(name = "task_id")
private Long taskId;
// 已完成的行为量
@Column(name = "current_action_amount")
private Integer currentActionAmount;
// 目标行为量
@Column(name = "target_action_amount")
private Integer targetActionAmount;
// 状态 0:未完成;1:已完成
@Column(name = "status")
private Integer status;
// 完成时间
@Column(name = "completion_time")
private Timestamp completionTime;
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(TrTaskProgress source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.task.progress.repository;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-11-02
*/
public interface TrTaskProgressRepository extends JpaRepository<TrTaskProgress, Long>, JpaSpecificationExecutor<TrTaskProgress> {
}
package com.topdraw.business.basicdata.task.progress.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import com.topdraw.business.basicdata.task.progress.service.TrTaskProgressService;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Api(tags = "TrTaskProgress管理")
@RestController
@RequestMapping("/api/TrTaskProgress")
public class TrTaskProgressController {
@Autowired
private TrTaskProgressService TrTaskProgressService;
@GetMapping
@ApiOperation("查询TrTaskProgress")
public ResultInfo getTrTaskProgresss(TrTaskProgressQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(TrTaskProgressService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有TrTaskProgress")
public ResultInfo getTrTaskProgresss(TrTaskProgressQueryCriteria criteria) {
return ResultInfo.success(TrTaskProgressService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增TrTaskProgress")
public ResultInfo create(@Validated @RequestBody TrTaskProgress resources) {
TrTaskProgressService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改TrTaskProgress")
public ResultInfo update(@Validated @RequestBody TrTaskProgress resources) {
TrTaskProgressService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除TrTaskProgress")
public ResultInfo delete(@PathVariable Long id) {
TrTaskProgressService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.task.progress.service;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressDTO;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author XiangHan
* @date 2021-11-02
*/
public interface TrTaskProgressService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(TrTaskProgressQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<TrTaskProgressDTO>
*/
List<TrTaskProgressDTO> queryAll(TrTaskProgressQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return TrTaskProgressDTO
*/
TrTaskProgressDTO findById(Long id);
void create(TrTaskProgress resources);
void update(TrTaskProgress resources);
void delete(Long id);
}
package com.topdraw.business.basicdata.task.progress.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Data
public class TrTaskProgressDTO implements Serializable {
private Long id;
// 用户id
private Long memberId;
// 任务id
private Long taskId;
// 已完成的行为量
private Integer currentActionAmount;
// 目标行为量
private Integer targetActionAmount;
// 状态 0:未完成;1:已完成
private Integer status;
// 完成时间
private Timestamp completionTime;
private Timestamp createTime;
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.task.progress.service.dto;
import lombok.Data;
import com.topdraw.annotation.Query;
import java.sql.Timestamp;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Data
public class TrTaskProgressQueryCriteria{
@Query(type = Query.Type.EQUAL)
private Long taskId;
@Query(type = Query.Type.EQUAL)
private Long memberId;
@Query(type = Query.Type.BETWEEN)
private String completionTime;
}
package com.topdraw.business.basicdata.task.progress.service.impl;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.utils.FileUtil;
import com.topdraw.business.basicdata.task.progress.repository.TrTaskProgressRepository;
import com.topdraw.business.basicdata.task.progress.service.TrTaskProgressService;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressDTO;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressQueryCriteria;
import com.topdraw.business.basicdata.task.progress.service.mapper.TrTaskProgressMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TrTaskProgressServiceImpl implements TrTaskProgressService {
@Autowired
private TrTaskProgressRepository TrTaskProgressRepository;
@Autowired
private TrTaskProgressMapper TrTaskProgressMapper;
@Override
public Map<String, Object> queryAll(TrTaskProgressQueryCriteria criteria, Pageable pageable) {
Page<TrTaskProgress> page = TrTaskProgressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(TrTaskProgressMapper::toDto));
}
@Override
public List<TrTaskProgressDTO> queryAll(TrTaskProgressQueryCriteria criteria) {
return TrTaskProgressMapper.toDto(TrTaskProgressRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public TrTaskProgressDTO findById(Long id) {
TrTaskProgress TrTaskProgress = TrTaskProgressRepository.findById(id).orElseGet(TrTaskProgress::new);
ValidationUtil.isNull(TrTaskProgress.getId(),"TrTaskProgress","id",id);
return TrTaskProgressMapper.toDto(TrTaskProgress);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(TrTaskProgress resources) {
TrTaskProgressRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(TrTaskProgress resources) {
TrTaskProgress TrTaskProgress = TrTaskProgressRepository.findById(resources.getId()).orElseGet(TrTaskProgress::new);
ValidationUtil.isNull( TrTaskProgress.getId(),"TrTaskProgress","id",resources.getId());
TrTaskProgress.copy(resources);
TrTaskProgressRepository.save(TrTaskProgress);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
TrTaskProgress TrTaskProgress = TrTaskProgressRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", TrTaskProgress.class, id), 1));
TrTaskProgressRepository.delete(TrTaskProgress);
}
}
package com.topdraw.business.basicdata.task.progress.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-11-02
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TrTaskProgressMapper extends BaseMapper<TrTaskProgressDTO, TrTaskProgress> {
}
package com.topdraw.business.basicdata.task.repository;
import com.topdraw.business.basicdata.task.domain.Task;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface TaskRepository extends JpaRepository<Task, Long>, JpaSpecificationExecutor<Task> {
List<Task> findByTaskTemplateId(Long taskTemplateId);
// List<Task> findByTemplateId(Long taskTemplateId);
}
package com.topdraw.business.basicdata.task.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.business.basicdata.task.service.dto.TaskQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Task管理")
@RestController
@RequestMapping("/api/Task")
public class TaskController {
@Autowired
private TaskService TaskService;
@GetMapping
@ApiOperation("查询Task")
public ResultInfo getTasks(TaskQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(TaskService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有Task")
public ResultInfo getTasks(TaskQueryCriteria criteria) {
return ResultInfo.success(TaskService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增Task")
public ResultInfo create(@Validated @RequestBody Task resources) {
TaskService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改Task")
public ResultInfo update(@Validated @RequestBody Task resources) {
TaskService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除Task")
public ResultInfo delete(@PathVariable Long id) {
TaskService.delete(id);
return ResultInfo.success();
}
}
package com.topdraw.business.basicdata.task.service;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.dto.TaskDTO;
import com.topdraw.business.basicdata.task.service.dto.TaskQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface TaskService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(TaskQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<TaskDTO>
*/
List<TaskDTO> queryAll(TaskQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return TaskDTO
*/
TaskDTO findById(Long id);
void create(Task resources);
void update(Task resources);
void delete(Long id);
List<Task> findByTemplateId(Long taskTemplateId);
}
package com.topdraw.business.basicdata.task.service.dto;
import lombok.Data;
import javax.persistence.Column;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class TaskDTO implements Serializable {
private Long id;
// 任务模板id
private Long taskTemplateId;
// 任务重复类型,-1:不限次;1:单次;>1:多次
private Integer taskRepeatType;
// 任务每日重置 0:不重置;1:重置
private Integer taskDailyReset;
// 行为量(完成此任务需要多少次相同行为的触发)
private Integer actionAmount;
// 任务生效时间
private Timestamp validTime;
// 任务失效时间
private Timestamp expireTime;
// 显示顺序
private Integer sequence;
// 获得成长值
private Long rewardExp;
// 获得积分
private Long rewardPoints;
// 积分过期时间(空为不过期)
private Long rewardPointsExpireTime;
// 能够获取该任务的用户分组,为空则都能获取
private String groups;
// 会员等级门槛(0表示无门槛)
private Integer memberLevel;
// 会员vip门槛(0表示没有门槛)
private Integer memberVip;
// 权益id
private Long rightsId;
// 权益数量(活动机会次数、优惠券数量、奖品数量)
private Integer rightsAmount;
// 权益2id
private Long rights2Id;
// 权益2数量
private Integer rights2Amount;
// 权益3id
private Long rights3Id;
// 权益3数量
private Integer rights3Amount;
// 状态 0:失效;1:生效
private Integer status;
// 创建时间
private Timestamp createTime;
// 更新时间
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.task.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class TaskQueryCriteria{
}
package com.topdraw.business.basicdata.task.service.impl;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.utils.StringUtils;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.task.repository.TaskRepository;
import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.business.basicdata.task.service.dto.TaskDTO;
import com.topdraw.business.basicdata.task.service.dto.TaskQueryCriteria;
import com.topdraw.business.basicdata.task.service.mapper.TaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TaskServiceImpl implements TaskService {
@Autowired
private TaskRepository TaskRepository;
@Autowired
private TaskMapper TaskMapper;
@Override
public Map<String, Object> queryAll(TaskQueryCriteria criteria, Pageable pageable) {
Page<Task> page = TaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(TaskMapper::toDto));
}
@Override
public List<TaskDTO> queryAll(TaskQueryCriteria criteria) {
return TaskMapper.toDto(TaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public TaskDTO findById(Long id) {
Task Task = TaskRepository.findById(id).orElseGet(Task::new);
ValidationUtil.isNull(Task.getId(),"Task","id",id);
return TaskMapper.toDto(Task);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Task resources) {
TaskRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Task resources) {
Task Task = TaskRepository.findById(resources.getId()).orElseGet(Task::new);
ValidationUtil.isNull( Task.getId(),"Task","id",resources.getId());
Task.copy(resources);
TaskRepository.save(Task);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
Task Task = TaskRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", Task.class, id), 1));
TaskRepository.delete(Task);
}
@Override
public List<Task> findByTemplateId(Long taskTemplateId) {
return Objects.nonNull(taskTemplateId) ? this.TaskRepository.findByTaskTemplateId(taskTemplateId) : null;
}
}
package com.topdraw.business.basicdata.task.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.dto.TaskDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TaskMapper extends BaseMapper<TaskDTO, Task> {
}
package com.topdraw.business.basicdata.task.template.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="tr_task_template")
public class TaskTemplate implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// 标识
@Column(name = "code")
private String code;
// 名称
@Column(name = "name")
private String name;
// 关注事件(和MQ topic相关)
@Column(name = "event")
private String event;
// 描述
@Column(name = "description")
private String description;
// 状态 0:失效;1:生效
@Column(name = "status")
private Integer status;
// 类型 0:活动任务模板
@Column(name = "type")
private Integer type;
// 模板参数,json
@Column(name = "params")
private String params;
@CreatedDate
@Column(name = "create_time")
private Timestamp createTime;
@LastModifiedDate
@Column(name = "update_time")
private Timestamp updateTime;
public void copy(TaskTemplate source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package com.topdraw.business.basicdata.task.template.repository;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface TaskTemplateRepository extends JpaRepository<TaskTemplate, Long>, JpaSpecificationExecutor<TaskTemplate> {
Optional<TaskTemplate> findFirstByCode(String code);
TaskTemplate findByEvent(String event);
}
package com.topdraw.business.basicdata.task.template.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.TaskTemplateService;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateQueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "TaskTemplate管理")
@RestController
@RequestMapping("/api/TaskTemplate")
public class TaskTemplateController {
@Autowired
private TaskTemplateService TaskTemplateService;
@GetMapping
@ApiOperation("查询TaskTemplate")
public ResultInfo getTaskTemplates(TaskTemplateQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(TaskTemplateService.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有TaskTemplate")
public ResultInfo getTaskTemplates(TaskTemplateQueryCriteria criteria) {
return ResultInfo.success(TaskTemplateService.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增TaskTemplate")
public ResultInfo create(@Validated @RequestBody TaskTemplate resources) {
TaskTemplateService.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改TaskTemplate")
public ResultInfo update(@Validated @RequestBody TaskTemplate resources) {
TaskTemplateService.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{id}")
@ApiOperation("删除TaskTemplate")
public ResultInfo delete(@PathVariable Long id) {
TaskTemplateService.delete(id);
return ResultInfo.success();
}
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(TaskTemplateService.getByCode(code));
}
}
package com.topdraw.business.basicdata.task.template.service;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateDTO;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
public interface TaskTemplateService {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(TaskTemplateQueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<TaskTemplateDTO>
*/
List<TaskTemplateDTO> queryAll(TaskTemplateQueryCriteria criteria);
/**
* 根据ID查询
* @param id ID
* @return TaskTemplateDTO
*/
TaskTemplateDTO findById(Long id);
void create(TaskTemplate resources);
void update(TaskTemplate resources);
void delete(Long id);
/**
* Code校验
* @param code
* @return TaskTemplateDTO
*/
TaskTemplateDTO getByCode(String code);
TaskTemplate findByEvent(String event);
}
package com.topdraw.business.basicdata.task.template.service.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class TaskTemplateDTO implements Serializable {
private Long id;
// 标识
private String code;
// 名称
private String name;
// 关注事件(和MQ topic相关)
private String event;
// 描述
private String description;
// 状态 0:失效;1:生效
private Integer status;
// 类型 0:活动任务模板
private Integer type;
// 模板参数,json
private String params;
private Timestamp createTime;
private Timestamp updateTime;
}
package com.topdraw.business.basicdata.task.template.service.dto;
import lombok.Data;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class TaskTemplateQueryCriteria{
}
package com.topdraw.business.basicdata.task.template.service.impl;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.utils.ValidationUtil;
import com.topdraw.business.basicdata.task.template.repository.TaskTemplateRepository;
import com.topdraw.business.basicdata.task.template.service.TaskTemplateService;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateDTO;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateQueryCriteria;
import com.topdraw.business.basicdata.task.template.service.mapper.TaskTemplateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TaskTemplateServiceImpl implements TaskTemplateService {
@Autowired
private TaskTemplateRepository TaskTemplateRepository;
@Autowired
private TaskTemplateMapper TaskTemplateMapper;
@Override
public Map<String, Object> queryAll(TaskTemplateQueryCriteria criteria, Pageable pageable) {
Page<TaskTemplate> page = TaskTemplateRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(TaskTemplateMapper::toDto));
}
@Override
public List<TaskTemplateDTO> queryAll(TaskTemplateQueryCriteria criteria) {
return TaskTemplateMapper.toDto(TaskTemplateRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public TaskTemplateDTO findById(Long id) {
TaskTemplate TaskTemplate = TaskTemplateRepository.findById(id).orElseGet(TaskTemplate::new);
ValidationUtil.isNull(TaskTemplate.getId(),"TaskTemplate","id",id);
return TaskTemplateMapper.toDto(TaskTemplate);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(TaskTemplate resources) {
TaskTemplateRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(TaskTemplate resources) {
TaskTemplate TaskTemplate = TaskTemplateRepository.findById(resources.getId()).orElseGet(TaskTemplate::new);
ValidationUtil.isNull( TaskTemplate.getId(),"TaskTemplate","id",resources.getId());
TaskTemplate.copy(resources);
TaskTemplateRepository.save(TaskTemplate);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Assert.notNull(id, "The given id must not be null!");
TaskTemplate TaskTemplate = TaskTemplateRepository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", TaskTemplate.class, id), 1));
TaskTemplateRepository.delete(TaskTemplate);
}
@Override
public TaskTemplateDTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? TaskTemplateMapper.toDto(TaskTemplateRepository.findFirstByCode(code).orElseGet(TaskTemplate::new))
: new TaskTemplateDTO();
}
@Override
public TaskTemplate findByEvent(String event) {
return StringUtils.isNotEmpty(event) ? this.TaskTemplateRepository.findByEvent(event) : null;
}
}
package com.topdraw.business.basicdata.task.template.service.mapper;
import com.topdraw.base.BaseMapper;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.dto.TaskTemplateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface TaskTemplateMapper extends BaseMapper<TaskTemplateDTO, TaskTemplate> {
}
package com.topdraw.business.process.domian;
public enum RightType {
/**积分*/
POINTS,
/**成长值*/
EXP,
/**优惠券券*/
COUPON,
/**权益统称*/
RIGHTS
}
package com.topdraw.business.process.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Transient;
import java.sql.Timestamp;
/**
* 权益-非持久化数据
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TempCoupon extends TempRights {
@Transient
protected String code;
@Transient
protected Integer useStatus;
@Transient
protected Timestamp useTime;
/**领取时间*/
@Transient
protected Timestamp receiveTime;
@Transient
protected String userNickname;
}
package com.topdraw.business.process.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Transient;
/**
* 权益-非持久化数据
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TempExp extends TempRights {
// 获得成长值
@Transient
protected Long rewardExp;
}
package com.topdraw.business.process.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
/**
* 权益-非持久化数据
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class TempPoints extends TempRights {
// 获得积分
@Transient
@NotNull(message = "【points】积分数值不得为空!!")
protected Long points;
// 积分类型 0:通用
@Transient
@NotNull(message = "【pointsType】积分类型不得为空!!")
protected Integer pointsType;
@Transient
protected Long rewardPointsExpireTime;
}
package com.topdraw.business.process.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
/**
* 权益-非持久化数据
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TempRights {
/** 主键 */
@Transient
protected Long id;
/** 会员ID */
@Transient
@NotNull(message = "")
protected Long memberId;
/** 账号id */
@Transient
protected Long userId;
/** 发放策略 */
@Transient
protected Integer rightsSendStrategy;
/** 账号id */
@Transient
private Long accountId;
/** 过期时间 */
@Transient
protected Timestamp expireTime;
/** 设备类型 1:大屏;2:小屏(微信)3.小屏(xx) */
@Transient
@NotNull(message = "")
protected Integer deviceType;
/** 应用code(表示当前用户对应应用的标识) */
@Transient
// @NotNull
protected String appCode;
/** 订单id */
@Transient
protected Long orderId;
/** 节目id(针对观影操作) */
@Transient
protected Long mediaId;
/** 活动id(针对参与活动) */
@Transient
protected Long activityId;
/** 商品id */
@Transient
protected Long itemId;
/** 积分变化描述,用于管理侧显示 */
@Transient
protected String description;
/** 行为事件类型 1:登录;2:观影;3:参与活动;4:订购;10:跨屏绑定;11:积分转移;98:系统操作;99:其他 */
@Transient
protected Integer evtType;
/** 数量 */
@Transient
protected Integer rightsAmount;
}
package com.topdraw.business.process.rest;
import com.topdraw.annotation.Log;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.service.CouponOperationService;
import com.topdraw.common.ResultInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "CouponOperation管理")
@RestController
@RequestMapping("/api/CouponOperation")
public class CouponOperationController {
@Autowired
private CouponOperationService couponOperationService;
@Log
@PostMapping(value = "/grantCouponByManual")
@ApiOperation("手动发放优惠券")
public ResultInfo grantCouponByManual(Long memberId , Long userId , List<TempCoupon> tempCouponList) {
this.couponOperationService.grantCouponByManual(memberId,userId,tempCouponList);
return ResultInfo.success();
}
}
package com.topdraw.business.process.rest;
import com.topdraw.annotation.Log;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.domian.TempExp;
import com.topdraw.business.process.service.CouponOperationService;
import com.topdraw.business.process.service.ExpOperationService;
import com.topdraw.common.ResultInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "ExpOperation管理")
@RestController
@RequestMapping("/api/ExpOperation")
public class ExpOperationController {
@Autowired
private ExpOperationService expOperationService;
@Log
@PostMapping(value = "/grantExpByManual")
@ApiOperation("手动发放成长值")
public ResultInfo grantExpByManual(@Validated @RequestBody TempExp tempExp) {
List<TempExp> tempExpList = Arrays.asList(tempExp);
this.expOperationService.grantExpByManual(tempExpList);
return ResultInfo.success();
}
}
package com.topdraw.business.process.rest;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryType;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailQueryCriteria;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.common.ResultInfo;
import com.topdraw.util.TimestampUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "PointsOperation管理")
@RestController
@RequestMapping("/api/PointsOperation")
public class PointsOperationController {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationController.class);
@Autowired
private PointsOperationService pointsOperationService;
@Autowired
private PointsDetailService pointsDetailService;
@Autowired
private PointsAvailableService pointsAvailableService;
@GetMapping(value = "/pagePointsDetails")
@ApiOperation("查询PointsDetail")
public ResultInfo pagePointsDetails(PointsDetailQueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(pointsDetailService.queryAll(criteria,pageable));
}
@GetMapping(value = "/pageAvailablePoints")
@ApiOperation("查询PointsAvailable")
public ResultInfo pageAvailablePoints(PointsAvailableQueryCriteria criteria, Pageable pageable) {
PointsAvailableQueryType queryType = criteria.getQueryType();
// 可用
if (queryType == PointsAvailableQueryType.AVAILABLE_ONLY) {
criteria.setExpireTime(TimestampUtil.now());
}
return ResultInfo.successPage(pointsAvailableService.queryAll(criteria,pageable));
}
@Log
@PostMapping(value = "/grantPointsByManual")
@ApiOperation("新增PointsDetail")
public ResultInfo grantPointsByManual(@Validated @RequestBody TempPoints tempPoints) {
Long memberId = tempPoints.getMemberId();
LOG.info("PointsOperationController -->> grantPointsByManual -->> " + tempPoints);
this.pointsOperationService.grantPointsByManual(memberId,tempPoints);
return ResultInfo.success();
}
@Log
@PostMapping(value = "/customPoints")
@ApiOperation("积分消耗")
public ResultInfo customPoints(@Validated @RequestBody TempPoints tempPoints) {
this.pointsOperationService.customPoints(tempPoints);
return ResultInfo.success();
}
}
package com.topdraw.business.process.rest;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.RightsHistoryService;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryCriteria;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryType;
import com.topdraw.business.process.service.RightsOperationService;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import com.topdraw.business.basicdata.rights.domain.Rights;
import com.topdraw.business.basicdata.rights.service.RightsService;
import com.topdraw.util.TimestampUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.util.Arrays;
import java.util.List;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Api(tags = "Rights管理")
@RestController
@RequestMapping("/api/RightsOperation")
public class RightsOperationController {
@Autowired
private RightsOperationService rightsOperationService;
@Autowired
private RightsHistoryService rightsHistoryService;
@Autowired
private RightsService rightsService;
@GetMapping
@ApiOperation("查询RightsHistory")
public ResultInfo queryRightsHistory(RightsHistoryQueryCriteria criteria, Pageable pageable) {
RightsHistoryQueryType queryType = criteria.getQueryType();
if (queryType == RightsHistoryQueryType.AVAILABLE_ONLY) {
criteria.setExpireTime(TimestampUtil.now());
}
return ResultInfo.successPage(rightsHistoryService.queryAll(criteria,pageable));
}
@GetMapping(value = "/findRightsHistoryById/{id}")
@ApiOperation("查询RightsHistory")
public ResultInfo findRightsHistoryById(@PathVariable Long id) {
return ResultInfo.success(rightsHistoryService.findById(id));
}
@PostMapping(value = "/grantRightsByManual")
@ApiOperation("查询RightsHistory")
public ResultInfo grantRightsByManual(@Validated @RequestBody RightsHistory rightsHistory) {
List<RightsHistory> rightsHistories = Arrays.asList(rightsHistory);
this.rightsOperationService.grantRightsByManual(rightsHistories);
return ResultInfo.success();
}
}
package com.topdraw.business.process.rest;
import com.topdraw.annotation.Log;
import com.topdraw.business.process.service.TaskOperationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api("任务处理")
@RestController
@RequestMapping(value = "/api/TaskOperation")
public class TaskOperationController {
@Autowired
TaskOperationService taskOperationService;
/**
* 处理事件
*
* @param criteria 消息
*/
@Log
@PostMapping(value = "/dealTask")
@ApiOperation("事件处理")
public void dealTask(@RequestBody @Validated TaskOperationQueryCriteria criteria) {
// 任务处理
this.taskOperationService.dealTask(criteria.getContent());
}
}
package com.topdraw.business.process.rest;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author XiangHan
* @date 2021-10-22
*/
@Data
public class TaskOperationQueryCriteria {
@NotNull(message = "【content】 not be null !!!")
private String content;
}
package com.topdraw.business.process.service;
import com.topdraw.business.basicdata.coupon.domain.Coupon;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.domian.TempRights;
import java.util.List;
/**
* @description 权益操作接口
* @author XiangHan
* @date 2021.10.22
*/
public interface CouponOperationService {
/**
* 基于已完成的任务发放优惠券
* @param tempCouponList
*/
void grantCouponThroughTempCoupon(List<TempCoupon> tempCouponList);
/**
* 系统手动发放优惠券
* @param memberId
* @param userId
* @param tempCouponList
*/
void grantCouponByManual(Long memberId,Long userId ,List<TempCoupon> tempCouponList);
}
package com.topdraw.business.process.service;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.domian.TempExp;
import com.topdraw.business.process.domian.TempRights;
import java.util.List;
/**
* @description 权益操作接口
* @author XiangHan
* @date 2021.10.22
*/
public interface ExpOperationService {
/**
* 任务完成后自动发放成长值
* @param tempExpList
*/
void grantPointsThroughTempExp( List<TempExp> tempExpList);
/**
* 系统手动发放优惠券
* @param memberId
* @param userId
* @param tempExpList
*/
void grantExpByManual(Long memberId,Long userId ,List<TempExp> tempExpList);
void grantExpByManual(List<TempExp> tempExpList);
}
package com.topdraw.business.process.service;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
public interface MemberOperationService {
void doUpdateMemberInfo(Member member);
void doInsertMember(Member member);
MemberDTO findById(Long memberId);
void doUpdateMemberExp(Member member);
void doUpdateMemberPoints(Member member);
void doUpdateMemberCoupon(Member member);
}
package com.topdraw.business.process.service;
import com.topdraw.business.basicdata.points.domain.Points;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.process.domian.TempPoints;
import java.util.List;
/**
* @description 积分操作接口
* @author XiangHan
* @date 2021.10.22
*/
public interface PointsOperationService {
/**
* 手动发放积分
* @param memberId 会员id
* @param tempPoints 积分详情
*/
void grantPointsByManual(Long memberId , TempPoints tempPoints);
/**
* 积分扣减
* @param tempPoints 积分对象
*/
boolean customPoints(TempPoints tempPoints);
/**
* 积分发放,基于已获得的权益
* @param tempPointsList 已获得的权益
*/
void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList);
/**
* 清理过期的积分
*/
void cleanInvalidAvailablePoints();
}
package com.topdraw.business.process.service;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.process.domian.RightType;
import java.util.List;
import java.util.Map;
/**
* @description 权益操作接口
* @author XiangHan
* @date 2021.10.22
*/
public interface RightsOperationService {
/**
* 系统手动发放权益
* @param rightsHistories
*/
void grantRightsByManual(List<RightsHistory> rightsHistories);
/**
* 任务完成自动发放权益
* @param tempRightsMap
*/
void grantRights(Map<RightType, Object> tempRightsMap);
}
package com.topdraw.business.process.service;
public interface TaskDealService {
}
package com.topdraw.business.process.service;
import com.topdraw.module.mq.DataSyncMsg;
/**
* @description 权益操作接口
* @author XiangHan
* @date 2021.10.22
*/
public interface TaskOperationService {
/**
* 处理任务
*
* @param content 任务对象
*/
void dealTask(String content);
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.util.TimestampUtil;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
@FunctionalInterface
public interface CompareTaskCondition {
boolean compareCondition(MemberDTO memberDTO, List<Task> taskList);
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.coupon.history.domain.CouponHistory;
import com.topdraw.business.basicdata.coupon.history.service.CouponHistoryService;
import com.topdraw.business.basicdata.coupon.service.CouponService;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.process.service.CouponOperationService;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.service.RightsOperationService;
import com.topdraw.util.TimestampUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
@Service
public class CouponOperationServiceImpl implements CouponOperationService {
private static final Logger LOG = LoggerFactory.getLogger(CouponOperationServiceImpl.class);
@Autowired
CouponService couponService;
@Autowired
CouponHistoryService couponHistoryService;
@Autowired
MemberOperationService memberOperationService;
@Autowired
RightsOperationService rightsOperationService;
// 过期阀值(默认一个月)
private static final Integer EXPIRE_FACTOR_MONTH = 1;
private ReentrantLock reentrantLock = new ReentrantLock(true);
@Override
public void grantCouponThroughTempCoupon(List<TempCoupon> tempCouponList) {
// 优惠券领取、使用历史记录表
for (TempCoupon tempCoupon : tempCouponList) {
this.refresh(tempCoupon);
}
}
/**
* 手动发放优惠券
* @param memberId 会员id
* @param tempCouponList
*/
@Override
public void grantCouponByManual(Long memberId,Long userId ,List<TempCoupon> tempCouponList) {
// 优惠券领取、使用历史记录表
for (TempCoupon tempCoupon : tempCouponList) {
this.refresh(tempCoupon);
}
}
/**
* 优惠券领取历史记录表
*
* @param tempCoupon 领取的优惠券
*/
private void refresh(TempCoupon tempCoupon) {
// 1.保存优惠券领取、使用历史记录表
this.doInsertCouponHistory(tempCoupon);
// 2.更新会员优惠券数量
this.refreshMemberCoupon(tempCoupon);
}
/**
* 更新会员优惠券信息
* @param tempCoupon 账号id
*/
private void refreshMemberCoupon(TempCoupon tempCoupon) {
Long userId = tempCoupon.getUserId();
Long memberId = tempCoupon.getMemberId();
try{
// reentrantLock.lock();
// 1.获取用户领取的总优惠券
Long totalCouponCount = this.getTotalCoupon(userId);
// 2.获取已过期的优惠券数量
Long expireCouponCount = this.getTotalExpireCoupon(userId);
// 3.即将过期的优惠券数量
Long expireSoonCouponCount = this.getTotalExpireSoonCoupon(userId,EXPIRE_FACTOR_MONTH);
// 4.当前优惠券数量 = 总优惠券-已过期的优惠券
Long currentCoupon = this.getCurrentCoupon(totalCouponCount,expireCouponCount);
// 5.更新用户信息(优惠券数量、即将过期的优惠券数量)
this.doUpdateMemberInfo(memberId,currentCoupon,expireSoonCouponCount);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
// reentrantLock.unlock();
}
}
/**
* 更新当前用户优惠券信息
* @param memberId
* @param currentCoupon
* @param expireSoonCouponCount
*/
private void doUpdateMemberInfo(Long memberId, Long currentCoupon, Long expireSoonCouponCount) {
Member member = new Member();
member.setId(memberId);
member.setCouponAmount(currentCoupon);
member.setDueCouponAmount(expireSoonCouponCount);
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberInfo(member);
}
/**
* 当前优惠券数量 = 总优惠券-已过期的优惠券
* @param totalCouponCount 总数
* @param expireCouponCount 已过期总数
* @return
*/
private Long getCurrentCoupon(Long totalCouponCount, Long expireCouponCount) {
return (Objects.nonNull(totalCouponCount)?totalCouponCount:0L)-(Objects.nonNull(expireCouponCount)?expireCouponCount:0L);
}
/**
* 即将过期的优惠券数量
* @param expireFactor
* @return
*/
private Long getTotalExpireSoonCoupon(Long userId, Integer expireFactor) {
LocalDateTime localDateTime = LocalDateTime.now();
String s = EXPIRE_FACTOR_MONTH.toString();
String[] s1 = s.split("_");
String s2 = s1[s1.length-1];
switch (s2) {
case "YEAR":
localDateTime.plusYears(expireFactor);
break;
case "MONTH":
localDateTime.plusMonths(expireFactor);
break;
case "DAY":
localDateTime.plusDays(expireFactor);
break;
case "HOUR":
localDateTime.plusHours(expireFactor);
break;
default:
break;
}
Timestamp expireTime = TimestampUtil.now(localDateTime);
return this.couponHistoryService.countByUserIdAndExpireTimeBetween(userId,TimestampUtil.now(),expireTime);
}
/**
* 获取已过期的优惠券数量
* @param userId
* @return
*/
private Long getTotalExpireCoupon(Long userId) {
return this.couponHistoryService.countByUserIdAndExpireTimeBefore(userId,TimestampUtil.now());
}
/**
* 获取用户领取的总优惠券
* @param userId
* @return
*/
private Long getTotalCoupon(Long userId) {
return this.couponHistoryService.countByUserId(userId);
}
/**
* 优惠券领取、使用历史记录表
* @param tempCoupon 优惠券
*/
private void doInsertCouponHistory(TempCoupon tempCoupon) {
CouponHistory couponHistory = new CouponHistory();
BeanUtils.copyProperties(tempCoupon,couponHistory);
couponHistory.setId(null);
couponHistory.setCouponId(tempCoupon.getId());
couponHistory.setUserId(tempCoupon.getUserId());
couponHistory.setCouponCode(tempCoupon.getCode());
couponHistory.setUserNickname(tempCoupon.getUserNickname());
couponHistory.setOrderDetailId(tempCoupon.getOrderId());
this.couponHistoryService.create(couponHistory);
}
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.exp.detail.domain.ExpDetail;
import com.topdraw.business.basicdata.exp.detail.service.ExpDetailService;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.level.service.MemberLevelService;
import com.topdraw.business.basicdata.member.level.service.dto.MemberLevelDTO;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.process.service.ExpOperationService;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.business.process.domian.TempExp;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
*
*/
@Service
public class ExpOperationServiceImpl implements ExpOperationService {
private static final Logger LOG = LoggerFactory.getLogger(ExpOperationServiceImpl.class);
@Autowired
ExpDetailService expDetailService;
@Autowired
MemberOperationService memberOperationService;
@Autowired
MemberLevelService memberLevelService;
@Override
public void grantPointsThroughTempExp(List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
}
@Override
public void grantExpByManual(Long memberId, Long userId, List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
}
@Override
public void grantExpByManual(List<TempExp> tempExpList) {
for (TempExp tempExp : tempExpList) {
this.refresh(tempExp);
}
}
/**
*
* @param tempExp
*/
private void refresh(TempExp tempExp) {
// 1.添加成长值记录
this.doInsertExpDetail(tempExp);
// 2.更新成长值与等级
this.refreshMemberExpAndLevel(tempExp);
}
/**
* 更新成长值与等级
*
* @param tempExp 成长值列表
*/
private void refreshMemberExpAndLevel(TempExp tempExp) {
Long memberId = tempExp.getMemberId();
// 1.获取当前成长值
MemberDTO memberDTO = this.getMemberInfoByMemberId(memberId);
// 2.获取下一级需要的成长值
MemberLevelDTO memberLevelDTO = this.getNextLevelExp(memberDTO.getLevel()+1,1);
// 3.成长值累加
Long newExp = memberDTO.getExp() + tempExp.getRewardExp();
// 4.成长值比较,判断是否升级
long i = this.compareExp(newExp,memberLevelDTO);
// 5.更新用户信息
this.updateMemberInfo(i,newExp,memberLevelDTO,memberId);
}
/**
*
* @param i
* @param newExp 总积分
* @param memberLevelDTO 下一级
* @param memberId 会员id
*/
private void updateMemberInfo(long i,Long newExp,MemberLevelDTO memberLevelDTO,Long memberId) {
Member member = new Member();
member.setId(memberId);
member.setExp(newExp);
if (i > 0) {
Integer level = memberLevelDTO.getLevel();
member.setLevel(level);
}
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberInfo(member);
}
private long compareExp(long newExp, MemberLevelDTO memberLevelDTO) {
if (Objects.nonNull(memberLevelDTO)) {
Long nextLevelExp = memberLevelDTO.getExpValue();
if (Objects.nonNull(nextLevelExp) && nextLevelExp > 0)
return newExp - nextLevelExp;
}
return -1;
}
private MemberLevelDTO getNextLevelExp(Integer i,Integer status) {
List<MemberLevelDTO> memberLevelDTOList = this.memberLevelService.findLevelAndStatus(i,status);
if (!CollectionUtils.isEmpty(memberLevelDTOList)) {
return memberLevelDTOList.get(0);
}
return null;
}
/**
* 获取当前会员的成长值
* @param memberId 会员id
* @return Long 当前会员成长值
*/
private MemberDTO getMemberInfoByMemberId(Long memberId) {
MemberDTO memberDTO = this.memberOperationService.findById(memberId);
return memberDTO;
}
/**
* 添加成长值记录
*
* @param tempExp 成长值列表
*/
private void doInsertExpDetail(TempExp tempExp) {
ExpDetail expDetail = new ExpDetail();
BeanUtils.copyProperties(tempExp,expDetail);
MemberDTO memberDTO = this.memberOperationService.findById(expDetail.getMemberId());
Long exp = memberDTO.getExp();
Long rewardExp = tempExp.getRewardExp();
Long originalExp = exp;
expDetail.setCode(String.valueOf(IdWorker.generator()));
expDetail.setOriginalExp(Objects.nonNull(originalExp) ? originalExp : 0L);
expDetail.setResultExp((Objects.nonNull(rewardExp) ? rewardExp : 0L) + (Objects.nonNull(originalExp) ? originalExp : 0L));
expDetail.setExp(rewardExp);
if (StringUtils.isEmpty(expDetail.getDescription())) {
expDetail.setDescription("#");
}
this.expDetailService.create(expDetail);
}
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.process.service.MemberOperationService;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.Objects;
@Service
public class MemberOperationServiceImpl implements MemberOperationService {
@Autowired
MemberService memberService;
@Override
public void doUpdateMemberInfo(Member member) {
Long id = member.getId();
Assert.notNull(id,"ERROR MSG: MemberOperationServiceImpl -> doUpdateMemberInfo -> id not be null!!");
this.memberService.update(member);
}
@Override
public void doInsertMember(Member member) {
this.memberService.create(member);
}
@Override
public MemberDTO findById(Long memberId) {
return Objects.nonNull(memberId) ? this.memberService.findById(memberId) : null;
}
@Override
public void doUpdateMemberExp(Member member) {
this.doUpdateMemberInfo(member);
}
@Override
public void doUpdateMemberPoints(Member member) {
this.doUpdateMemberInfo(member);
}
@Override
public void doUpdateMemberCoupon(Member member) {
this.doUpdateMemberInfo(member);
}
}
package com.topdraw.business.process.service.impl;
import cn.hutool.core.map.MapUtil;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.detail.detailhistory.service.PointsDetailHistoryService;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.basicdata.points.service.PointsService;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import com.topdraw.utils.StringUtils;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PointsOperationServiceImpl implements PointsOperationService {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationServiceImpl.class);
@Autowired
PointsService pointsService;
@Autowired
PointsDetailService pointsDetailService;
@Autowired
PointsAvailableService pointsAvailableService;
@Autowired
PointsDetailHistoryService pointsDetailHistoryService;
@Autowired
MemberOperationService memberOperationService;
// 过期阈值 30天
private static final Integer EXPIRE_FACTOR = 30;
private static final String DELETE_AVAILABLE_POINTS = "delete";
private static final String INSERT_AVAILABLE_POINTS = "insert";
@Autowired
private RedissonClient redissonClient;
@Override
@Transactional(rollbackFor = Exception.class)
public void grantPointsByManual(Long memberId,TempPoints tempPoints){
this.refresh(tempPoints);
}
/**
* 积分消耗
* @param tempPoints 任务对象
* @return true: 满足 false:不满足
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean customPoints(TempPoints tempPoints) {
Long memberId = tempPoints.getMemberId();
// 1.判断可用积分是否够用
boolean b = this.checkAvailablePoints(tempPoints);
if (b) {
// 当前可用总积分
long currentPoints = this.findAvailablePointsByMemberId(memberId);
// 1.可用积分表,按照过期时间进行升序排列
List<PointsAvailableDTO> pointsAvailableDTOS = this.findByMemberIdOrderByExpireTime(tempPoints);
// 2.优先使用即将过期的积分,累加到超过需兑换积分时,需要进行拆分
Map<String, List<PointsAvailableDTO>> customAvailablePointsMap = this.customAvailablePoints(tempPoints, pointsAvailableDTOS);
// 3.添加积分明细
this.doInsertTrPointsDetailByAvailablePointsMap(tempPoints,customAvailablePointsMap,currentPoints);
// 4.更新可用积分表,超过的删除,剩余的新增
long totalPoints = this.doFreshTrPointsAvailableByAvailablePointsMap(customAvailablePointsMap,currentPoints);
// 4.获取即将过期的积分
long soonExpireTime = this.getSoonExpirePoints(memberId,tempPoints);
// 6.更新会员积分信息
this.freshMemberCurrentPoints(memberId,totalPoints,soonExpireTime);
return true;
}
return false;
}
/**
* 更新可用积分表
* @param customAvailablePointsMap
*/
private long doFreshTrPointsAvailableByAvailablePointsMap(
Map<String, List<PointsAvailableDTO>> customAvailablePointsMap,long currentPoints) {
long totalCustomAvailablePoints = 0L;
if (customAvailablePointsMap != null) {
// 需要删除的
List<PointsAvailableDTO> pointsAvailableDTOS1 = customAvailablePointsMap.get(DELETE_AVAILABLE_POINTS);
if (!CollectionUtils.isEmpty(pointsAvailableDTOS1)) {
for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS1) {
totalCustomAvailablePoints = (totalCustomAvailablePoints+pointsAvailableDTO.getPoints());
this.pointsAvailableService.delete(pointsAvailableDTO.getId());
}
}
// 需要添加的
List<PointsAvailableDTO> pointsAvailableDTOS2 = customAvailablePointsMap.get(INSERT_AVAILABLE_POINTS);
if (!CollectionUtils.isEmpty(pointsAvailableDTOS2)) {
PointsAvailableDTO pointsAvailableDTO = pointsAvailableDTOS2.get(0);
PointsAvailable pointsAvailable = new PointsAvailable();
BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailable);
pointsAvailable.setId(null);
pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
this.pointsAvailableService.create(pointsAvailable);
}
}
return currentPoints - totalCustomAvailablePoints;
}
/**
* 优先使用即将过期的积分,累加到超过需兑换积分时,需要进行拆分
* @param customAvailablePointsMap
*/
private void doInsertTrPointsDetailByAvailablePointsMap(TempPoints tempPoints,
Map<String, List<PointsAvailableDTO>> customAvailablePointsMap,
long currentPoints) {
// 兑换的积分
Long points = tempPoints.getPoints();
List<PointsAvailableDTO> pointsAvailableDTOS = customAvailablePointsMap.get(DELETE_AVAILABLE_POINTS);
if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
PointsAvailableDTO pointsAvailableDTO = pointsAvailableDTOS.get(0);
Long memberId = pointsAvailableDTO.getMemberId();
TempPoints tempPoints1 = new TempPoints();
BeanUtils.copyProperties(pointsAvailableDTO,tempPoints1);
BeanUtils.copyProperties(tempPoints,tempPoints1);
tempPoints1.setPoints(-(Math.abs(points)));
this.doInsertTrPointsDetail(memberId,tempPoints1,currentPoints);
}
}
/**
* 消耗过期的积分
* @param tempPoints 需要消耗的积分
* @param pointsAvailableDTOS 可用积分列表
* @return List<PointsAvailableDTO> 已消耗的可用积分列表
*/
private Map<String,List<PointsAvailableDTO>> customAvailablePoints(TempPoints tempPoints, List<PointsAvailableDTO> pointsAvailableDTOS) {
// 兑换的积分
Long points = tempPoints.getPoints();
Long points1_ = 0L;
List<PointsAvailableDTO> pointsAvailableDTOS1 = new ArrayList<>();
List<PointsAvailableDTO> pointsAvailableDTOS2 = new ArrayList<>();
Map<String,List<PointsAvailableDTO>> map = new HashMap<>();
for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
Long points1 = pointsAvailableDTO.getPoints();
points1_ = (points1_ + points1);
// 不够
if (points1_ < points) {
pointsAvailableDTOS1.add(pointsAvailableDTO);
continue;
}
// 刚好
if (points1_ == points) {
pointsAvailableDTOS1.add(pointsAvailableDTO);
break;
}
// 超了,拆分
if (points1_ > points) {
// 超过的
long beyond = points1_ - points;
// 新增
PointsAvailableDTO pointsAvailableDTO2 = new PointsAvailableDTO();
BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailableDTO2);
pointsAvailableDTO2.setPoints(beyond);
pointsAvailableDTOS2.add(pointsAvailableDTO2);
// 剩余的
long suit = points1 - beyond;
// 扣除
PointsAvailableDTO pointsAvailableDTO1 = new PointsAvailableDTO();
BeanUtils.copyProperties(pointsAvailableDTO,pointsAvailableDTO1);
pointsAvailableDTO1.setPoints(suit);
pointsAvailableDTOS1.add(pointsAvailableDTO1);
break;
}
}
map.put(DELETE_AVAILABLE_POINTS,pointsAvailableDTOS1);
map.put(INSERT_AVAILABLE_POINTS,pointsAvailableDTOS2);
return map;
}
/**
* 可用积分表,按照过期时间进行升序排列
* @param tempPoints
* @return
*/
private List<PointsAvailableDTO> findByMemberIdOrderByExpireTime(TempPoints tempPoints) {
return this.pointsAvailableService.findByMemberIdOrderByExpireTime(tempPoints.getMemberId());
}
/**
* 检查当前用户可用积分是否足够
* @param tempPoints
* @return true : 满足 false: 不满足
*/
private boolean checkAvailablePoints(TempPoints tempPoints) {
Long memberId = tempPoints.getMemberId();
// 可用积分
long currentPoints = this.findAvailablePointsByMemberId(memberId);
long points1 = tempPoints.getPoints();
if (currentPoints > 0 && points1 > 0 && (currentPoints - Math.abs(points1) >= 0)) {
return true;
}
return false;
}
/**
* 积分发放,基于已获得的权益
*
* @param tempPointsList 已获得的权益
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void grantPointsThroughTempRightsList(List<TempPoints> tempPointsList){
for (TempPoints tempPoints : tempPointsList){
this.refresh(tempPoints);
}
}
/**
* 定时清理过期的可用积分
*/
@Override
public void cleanInvalidAvailablePoints() {
// 获取已过期的积分
List<PointsAvailableDTO> pointsAvailableDTOS = pointsAvailableService.findByExpireTimeBefore(TimestampUtil.now());
if (!CollectionUtils.isEmpty(pointsAvailableDTOS)) {
// 添加积分明细 uc_points_detail
this.doCreatePointsDetail(pointsAvailableDTOS);
// 删除已过期的积分
this.doDeleteInvalidAvailablePoints(pointsAvailableDTOS);
}
}
/**
*
* @param pointsAvailableDTOS
*/
private void doDeleteInvalidAvailablePoints(List<PointsAvailableDTO> pointsAvailableDTOS) {
List<Long> collect = pointsAvailableDTOS.stream().map(pointsAvailableDTO -> pointsAvailableDTO.getId()).collect(Collectors.toList());
this.pointsAvailableService.deleteBatchByIds(collect);
}
/**
*
* @param pointsAvailableDTOS
*/
private void doCreatePointsDetail(List<PointsAvailableDTO> pointsAvailableDTOS) {
//1.获取原始积分
for (PointsAvailableDTO pointsAvailableDTO : pointsAvailableDTOS) {
Long memberId = pointsAvailableDTO.getMemberId();
// 原始积分
long availablePoints = this.findAvailablePointsByMemberId(memberId);
// 过期积分
long l = pointsAvailableDTO.getPoints();
// 结果积分
long resultPoints = availablePoints - l;
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(pointsAvailableDTO,pointsDetail);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setOriginalPoints(availablePoints);
pointsDetail.setResultPoints(resultPoints);
pointsDetail.setDescription("过期积分");
pointsDetail.setEvtType(99);
this.doInsertPointsDetail(pointsDetail);
long soonExpireTime = this.getSoonExpirePoints(memberId,null);
// 更新会员积分
this.freshMemberCurrentPoints(memberId,resultPoints,soonExpireTime);
}
}
/**
* 模板方法,提供更新积分的总体流程
*
* @param tempPoints 积分
*/
private void refresh(TempPoints tempPoints) {
Long memberId = tempPoints.getMemberId();
// 1.可用总积分
long currentPoints = this.findAvailablePointsByMemberId(memberId);
// 2.添加积分明细,并计算总积分
long totalPoints = this.doInsertTrPointsDetail(memberId, tempPoints,currentPoints);
// 3.获取即将过期的积分
long soonExpireTime = this.getSoonExpirePoints(memberId,tempPoints);
// 4.更新会员的总积分
this.freshMemberCurrentPoints(memberId,totalPoints,soonExpireTime);
// 5.添加可用积分
this.doInsertTrPointsAvailable(tempPoints);
}
/**
* 获取即将过期的积分
* @param memberId
* @return
*/
private long getSoonExpirePoints(Long memberId,TempPoints tempPoints) {
// 计算即将过期的天数
Integer factor = this.calculateExpireFactor(tempPoints);
if (Objects.isNull(factor)) {
factor = EXPIRE_FACTOR;
}
Long soonExpireTime = this.pointsAvailableService.findSoonExpireTime(memberId, factor);
return Objects.nonNull(soonExpireTime) ? soonExpireTime : 0L;
}
/**
* 如果过期时间和过期天数同时存在,则以过期时间为准
* @param tempPoints
* @return
*/
private Integer calculateExpireFactor(TempPoints tempPoints) {
// TODO 计算过期的相对时间
return null;
}
/**
* 更新会员总积分
* @param memberId 会员Id
* @param currentPoints 当前总积分
* @param duePoints 即将过期的积分
*/
private void freshMemberCurrentPoints(Long memberId, Long currentPoints,long duePoints){
Member member = new Member();
member.setId(memberId);
member.setPoints(Objects.nonNull(currentPoints)?currentPoints:0);
member.setDuePoints(duePoints);
member.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
try {
this.memberOperationService.doUpdateMemberPoints(member);
} catch (Exception e){
throw e;
}
}
/**
* 计算当前总积分
* @param memberId 会员id
* @return
*/
private long findAvailablePointsByMemberId(long memberId){
return this.pointsAvailableService.findAvailablePointsByMemberId(memberId);
}
/**
* 更新可用积分表
* @param tempPoints
*/
private void doInsertTrPointsAvailable(TempPoints tempPoints){
PointsAvailable pointsAvailable = new PointsAvailable();
BeanUtils.copyProperties(tempPoints,pointsAvailable);
String description = pointsAvailable.getDescription();
pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
pointsAvailable.setDescription(StringUtils.isEmpty(description)?"#":description);
Timestamp timestamp = tempPoints.getExpireTime();
if (Objects.nonNull(timestamp)) {
pointsAvailable.setExpireTime(timestamp);
}
// 添加可用积分记录
this.doInsertTrPointsAvailable(pointsAvailable);
}
/**
* 添加可用积分记录
* @param pointsAvailable 可用积分
*/
private void doInsertTrPointsAvailable(PointsAvailable pointsAvailable) {
this.pointsAvailableService.create(pointsAvailable);
}
/**
* 添加积分明细
* @param memberId 会员Id
* @param tempPoints 积分
* @return Integer 总积分
*/
private long doInsertTrPointsDetail(Long memberId, TempPoints tempPoints,long currentPoints){
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(tempPoints,pointsDetail);
// 获取的积分
long rewardPoints = tempPoints.getPoints();
// 原始积分
long originalPoints = currentPoints;
// 总积分
long totalPoints = originalPoints + rewardPoints;
pointsDetail.setMemberId(memberId);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setOriginalPoints(originalPoints);
pointsDetail.setResultPoints(totalPoints);
String description = pointsDetail.getDescription();
if (StringUtils.isEmpty(description)) {
pointsDetail.setDescription("#");
}
// 保存积分流水
this.doInsertPointsDetail(pointsDetail);
return totalPoints;
}
/**
*
* @param pointsDetail
*/
private void doInsertPointsDetail(PointsDetail pointsDetail){
this.pointsDetailService.create(pointsDetail);
}
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.basicdata.rights.history.service.RightsHistoryService;
import com.topdraw.business.basicdata.rights.service.RightsService;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import com.topdraw.business.process.service.CouponOperationService;
import com.topdraw.business.process.service.ExpOperationService;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.business.process.service.RightsOperationService;
import com.topdraw.business.process.domian.*;
import com.topdraw.util.TimestampUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
/**
* 权益处理
*
* @author XiangHan
* @date 2021.10.23
*/
@Service
public class RightsOperationServiceImpl implements RightsOperationService {
private static final Logger LOG = LoggerFactory.getLogger(RightsOperationServiceImpl.class);
@Autowired
RightsHistoryService rightsHistoryService;
@Autowired
CouponOperationService couponOperationService;
@Autowired
RightsService rightsService;
@Autowired
ExpOperationService expOperationService;
@Autowired
PointsOperationService pointsOperationService;
@Resource(name = "executorTask")
ThreadPoolTaskExecutor threadPoolTaskExecutor;
/**
* 系统手动发放
* 实现步骤:
* 1.当前权益只有实体券
* @param rightsList
*/
@Override
public void grantRightsByManual(List<RightsHistory> rightsList) {
// 1.权益区分
Map<RightType,Object> tempRightsMap = this.distinguishRight(rightsList);
// 2.权益下发
this.refresh(tempRightsMap);
// 3.保存权益历史
this.doInsertTrRightHistory(rightsList);
}
/**
* 权益发放
* @param tempRightsMap 权益类型
*/
@Override
public void grantRights(Map<RightType, Object> tempRightsMap) {
// 1.权益下发
this.refresh(tempRightsMap);
// 2.创建权益历史对象
List<RightsHistory> rightsList = this.getRightHistory(tempRightsMap);
// 3.保存权益历史
this.doInsertTrRightHistory(rightsList);
}
/**
*
* @param tempRightsMap
* @return
*/
private List<RightsHistory> getRightHistory(Map<RightType, Object> tempRightsMap) {
List<TempRights> values = (List<TempRights>)tempRightsMap.get(RightType.RIGHTS);
List<RightsHistory> rightsHistoryList = new ArrayList<>();
values.forEach(value -> {
RightsHistory rightsHistory = new RightsHistory();
rightsHistory.setSendTime(TimestampUtil.now());
rightsHistory.setRightsId(value.getId());
rightsHistory.setMemberId(value.getMemberId());
rightsHistory.setExpireTime(value.getExpireTime());
rightsHistoryList.add(rightsHistory);
});
return rightsHistoryList;
}
/**
* 成长值发放,基于已获得的权益
* @param tempExpList 权益列表
*/
private void grantExp(List<TempExp> tempExpList) {
if (!CollectionUtils.isEmpty(tempExpList))
this.expOperationService.grantPointsThroughTempExp(tempExpList);
}
/**
* 发放积分,基于已获得的权益
*
* @param tempPointsList 权益列表
*/
private void grantPoint(List<TempPoints> tempPointsList) {
if (!CollectionUtils.isEmpty(tempPointsList))
this.pointsOperationService.grantPointsThroughTempRightsList(tempPointsList);
}
/**
* 发放优惠券,基于已获得的权益
*
* @param tempCouponList 优惠券
*/
private void grantCoupon(List<TempCoupon> tempCouponList) {
// 发放优惠券
if (!CollectionUtils.isEmpty(tempCouponList))
this.couponOperationService.grantCouponThroughTempCoupon(tempCouponList);
}
/**
* 权益发放
* @param tempRightsMap
*/
private void refresh(Map<RightType, Object> tempRightsMap) {
/*threadPoolTaskExecutor.execute(()->{
this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
});
threadPoolTaskExecutor.execute(()->{
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
});
threadPoolTaskExecutor.execute(()->{
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));
});*/
this.grantPoint((List<TempPoints>)tempRightsMap.get(RightType.POINTS));
this.grantExp((List<TempExp>)tempRightsMap.get(RightType.EXP));
this.grantCoupon((List<TempCoupon>)tempRightsMap.get(RightType.COUPON));
}
/**
* 区分权益
* @param rightsList
* @return
*/
private Map<RightType, Object> distinguishRight(List<RightsHistory> rightsList) {
Map<RightType,Object> map = new HashMap<>();
// 优惠券
List<TempCoupon> tempCouponList = new ArrayList<>();
for (RightsHistory right : rightsList) {
Long rightId = right.getRightsId();
Long memberId = right.getMemberId();
Long userId = right.getUserId();
// 权益类型
RightsDTO rightsDTO = this.getRights(rightId);
Integer type = rightsDTO.getType();
// 优惠券
if (type == 1) {
TempCoupon tempCoupon = new TempCoupon();
tempCoupon.setId(rightId);
tempCoupon.setMemberId(memberId);
tempCoupon.setUserId(userId);
tempCoupon.setRightsAmount(1);
tempCoupon.setRightsSendStrategy(0);
tempCouponList.add(tempCoupon);
}
}
// TODO 其他
// 优惠券
map.put(RightType.COUPON,tempCouponList);
return map;
}
/**
* 权益详情
* @param rightsId
* @return
*/
private RightsDTO getRights(Long rightsId) {
RightsDTO rightsDTO = this.rightsService.findById(rightsId);
return rightsDTO;
}
/**
* 添加权益领取记录
* @param rightsHistories
*/
private void doInsertTrRightHistory(List<RightsHistory> rightsHistories) {
if (!CollectionUtils.isEmpty(rightsHistories)) {
for (RightsHistory rightsHistory : rightsHistories) {
rightsHistory.setSendTime(TimestampUtil.now());
this.rightsHistoryService.create(rightsHistory);
}
}
}
}
package com.topdraw.business.process.service.impl;
public class TaskDealHandler {
}
package com.topdraw.business.process.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.business.basicdata.rights.constant.RightsType;
import com.topdraw.business.basicdata.rights.service.RightsService;
import com.topdraw.business.basicdata.rights.service.dto.RightsDTO;
import com.topdraw.business.basicdata.task.progress.domain.TrTaskProgress;
import com.topdraw.business.basicdata.task.progress.service.TrTaskProgressService;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressDTO;
import com.topdraw.business.basicdata.task.progress.service.dto.TrTaskProgressQueryCriteria;
import com.topdraw.business.process.service.RightsOperationService;
import com.topdraw.business.process.service.TaskDealService;
import com.topdraw.business.process.service.TaskOperationService;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.TaskTemplateService;
import com.topdraw.business.process.domian.*;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EventType;
import com.topdraw.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;
/**
* 任务处理
*
* @author XiangHan
* @date 2021.10.23
*/
@Service
public class TaskOperationServiceImpl implements TaskOperationService {
private static final Logger LOG = LoggerFactory.getLogger(PointsOperationServiceImpl.class);
@Autowired
private TaskService taskService;
@Autowired
private MemberService memberService;
@Autowired
private RightsService rightsService;
@Autowired
private TaskTemplateService taskTemplateService;
@Autowired
private RightsOperationService rightsOperationService;
@Autowired
private TrTaskProgressService trTaskProgressService;
private static final Integer POINTS_TYPE_RANDOM = 1;
private static final Integer POINTS_MIN = 1;
private static final Integer TASK_FINISH_STATUS = 1;
@Resource(name = "executorTask")
ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void dealTask(String content) {
long l = System.currentTimeMillis();
DataSyncMsg dataSyncMsg = JSONUtil.parseMsg2Object(content, DataSyncMsg.class);
String eventType = dataSyncMsg.getEventType();
DataSyncMsg.MsgData msgData = dataSyncMsg.getMsg();
Long memberId = msgData.getMemberId();
// 1.通过任务标识获取任务模板
TaskTemplate taskTemplate = this.getTaskTemplate(eventType);
// 2.解析模板参数
Map<String,Object> paramMap = this.parseTaskTemplateParam(taskTemplate);
// 3.通过任务模板获取对应的任务列表
List<Task> taskList = this.loadListTaskByTaskTemplate(taskTemplate,paramMap);
// 4.判断当前用户是否满足任务完成条件
boolean checkResult = this.checkTaskCompletion(memberId,taskList);
if (checkResult) {
// 4.权益区分(积分、权益、成长值)
Map<RightType,Object> tempRightsMap = this.distinguishRight(memberId,taskList,msgData);
// 5.权益发放
this.grantRight(tempRightsMap);
}
long r = System.currentTimeMillis();
LOG.info("总耗时======>>>>>" + (r-l));
}
/**
* 解析模板参数
* @param taskTemplate
* @return
*/
private Map<String, Object> parseTaskTemplateParam(TaskTemplate taskTemplate) {
if (Objects.nonNull(taskTemplate)) {
String params = taskTemplate.getParams();
if (!StringUtils.isEmpty(params)) {
Map paramMap = JSONObject.parseObject(params,Map.class);
return paramMap;
}
}
return null;
}
/**
* 保存任务的完成情况
*/
private void doRefreshTrTaskProcess(TrTaskProgress resources) {
Long id = resources.getId();
if (Objects.nonNull(id)) {
resources.setUpdateTime(TimestampUtil.now());
this.trTaskProgressService.update(resources);
} else {
this.trTaskProgressService.create(resources);
}
}
/**
* 权益发放
* @param tempRightsMap 会员id
*/
private void grantRight(Map<RightType,Object> tempRightsMap) {
this.rightsOperationService.grantRights(tempRightsMap);
}
/**
* 权益区分
*
* @param taskList 任务列表
*/
private Map<RightType,Object> distinguishRight(Long memberId,List<Task> taskList,DataSyncMsg.MsgData msgData) {
Map<RightType,Object> map = new HashMap<>();
// 区分权益类型(成长值(reward_exp)、积分(reward_points)、实体券),并发放权益
for (Task task : taskList) {
// 积分
List<TempPoints> tempPointsList = this.getTempPoints(memberId,msgData,task);
map.put(RightType.POINTS,tempPointsList);
// 成长值
List<TempExp> tempExpList = this.getTempExp(memberId,msgData,task);
map.put(RightType.EXP,tempExpList);
// 权益
map = this.getTempRight(memberId,task,map);
}
return map;
}
/**
* 创建权益
* @param memberId
* @param rightsId
* @param rightsAmount
* @param expireTime
* @return
*/
private TempRights tmpRightsBuild(Long memberId ,Long rightsId, Integer rightsAmount,Long expireTime){
TempRights tempRights = new TempRights();
tempRights.setMemberId(memberId);
tempRights.setRightsAmount(rightsAmount);
tempRights.setId(rightsId);
if (Objects.nonNull(expireTime))
tempRights.setExpireTime(TimestampUtil.long2Timestamp(expireTime));
return tempRights;
}
/**
* 优惠券
* @param memberId
* @param rightsId
* @param rightsAmount
* @param rightsSendStrategy
* @return
*/
private TempCoupon tempCouponBuild(Long memberId ,Long rightsId, Integer rightsAmount,Integer rightsSendStrategy){
TempCoupon tempCoupon = new TempCoupon();
tempCoupon.setMemberId(memberId);
tempCoupon.setId(rightsId);
tempCoupon.setRightsAmount(rightsAmount);
tempCoupon.setRightsSendStrategy(Objects.isNull(rightsSendStrategy) ? 0 : rightsSendStrategy);
return tempCoupon;
}
/**
* 权益1
* @param task
* @return
*/
private Map<RightType,Object> getTempRight(Long memberId , Task task,Map<RightType,Object> map) {
// 优惠券
List<TempCoupon> tempCouponList = new ArrayList<>();
// 权益列表,用以保存权益记录
List<TempRights> rightsList = new ArrayList<>();
// 权益1
Long rights1Id = task.getRightsId();
if (Objects.nonNull(rights1Id)) {
// 权益详情
RightsDTO rightsDTO = this.getRight(rights1Id);
// 领取的权益数量
Integer rights1Amount = task.getRightsAmount();
// TODO 权益1发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
if (Objects.nonNull(rightsDTO)){
// 用以保存权益历史
Long expireTime = rightsDTO.getExpireTime();
TempRights tempRights = this.tmpRightsBuild(memberId,rights1Id,rights1Amount,expireTime);
rightsList.add(tempRights);
// 权益类型
Integer type = rightsDTO.getType();
switch (type) {
case 1:
// 优惠券
TempCoupon tempCoupon = this.tempCouponBuild(memberId,rights1Id,rights1Amount,rightsSendStrategy);
tempCouponList.add(tempCoupon);
break;
default:
break;
}
}
}
// 权益2
Long rights2Id = task.getRights2Id();
if (Objects.nonNull(rights2Id)) {
// 权益详情
RightsDTO rightsDTO = this.getRight(rights2Id);
Integer rights2Amount = task.getRights2Amount();
// TODO 权益2发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
if (Objects.nonNull(rightsDTO)) {
// 用以保存权益历史
Long expireTime = rightsDTO.getExpireTime();
TempRights tempRights = this.tmpRightsBuild(memberId,rights2Id,rights2Amount,expireTime);
rightsList.add(tempRights);
// 权益类型
Integer type = rightsDTO.getType();
switch (type) {
case 1:
// 优惠券
TempCoupon tempCoupon = this.tempCouponBuild(memberId,rights2Id,rights2Amount,rightsSendStrategy);
tempCouponList.add(tempCoupon);
break;
default:
break;
}
}
}
// 权益3
Long rights3Id = task.getRights3Id();
if (Objects.nonNull(rights3Id)) {
// 权益详情
RightsDTO rightsDTO = this.getRight(rights3Id);
Integer rights3Amount = task.getRights3Amount();
// TODO 权益3发放的策略
Integer rightsSendStrategy = task.getRightsSendStrategy();
if (Objects.nonNull(rightsDTO)){
// 用以保存权益历史
Long expireTime = rightsDTO.getExpireTime();
TempRights tempRights = this.tmpRightsBuild(memberId,rights3Id,rights3Amount,expireTime);
rightsList.add(tempRights);
// 权益类型
Integer type = rightsDTO.getType();
switch (type) {
case 1:
// 优惠券
TempCoupon tempCoupon = this.tempCouponBuild(memberId,rights3Id,rights3Amount,rightsSendStrategy);
tempCouponList.add(tempCoupon);
break;
default:
break;
}
}
}
// 优惠券
map.put(RightType.COUPON,tempCouponList);
map.put(RightType.RIGHTS,rightsList);
return map;
}
/**
*
* @param rightsId
* @return
*/
private Integer getRightType(Long rightsId) {
RightsDTO rightsDTO = this.getRight(rightsId);
return Objects.nonNull(rightsDTO) ? rightsDTO.getType() : -999;
}
/**
*
* @param rightsId
* @return
*/
private RightsDTO getRight(Long rightsId) {
RightsDTO rightsDTO = this.rightsService.findById(rightsId);
return rightsDTO;
}
/**
* 成长值
* @param task
* @return
*/
private List<TempExp> getTempExp(Long memberId , DataSyncMsg.MsgData msgData,Task task) {
TempExp tempExp = new TempExp();
tempExp.setMemberId(memberId);
tempExp.setAppCode(msgData.getAppCode());
tempExp.setMemberId(msgData.getMemberId());
tempExp.setItemId(msgData.getItemId());
tempExp.setAccountId(msgData.getAccountId());
tempExp.setRewardExp(task.getRewardExp());
tempExp.setDeviceType(msgData.getDeviceType());
tempExp.setEvtType(msgData.getEvent());
tempExp.setOrderId(msgData.getOrderId());
tempExp.setMediaId(msgData.getMediaId());
tempExp.setActivityId(msgData.getOrderId());
Integer rightsSendStrategy = task.getRightsSendStrategy();
tempExp.setRightsSendStrategy(Objects.isNull(rightsSendStrategy) ? 0 : rightsSendStrategy);
return Arrays.asList(tempExp);
}
/**
* 积分
* @param task
* @return
*/
private List<TempPoints> getTempPoints(Long memberId,DataSyncMsg.MsgData msgData,Task task) {
// 积分: 数值、过期时间、积分类型(定值、随机)、随机积分最大值
Long rewardPoints = task.getRewardPoints();
// 过期时间
Long rewardPointsExpireTime = task.getRewardPointsExpireTime();
Timestamp expireTime = task.getExpireTime();
// 积分类型(0:定值、1:随机)
Integer pointsType = task.getPointsType();
// 随机积分的最大值
Integer rewardMaxPoints = task.getRewardMaxPoints();
if (Objects.nonNull(rewardPoints)) {
TempPoints tempPoints = new TempPoints();
// 如果积分是随机的,则取随机值
if (pointsType == POINTS_TYPE_RANDOM) {
rewardPoints = RandomUtil.getRandomPoints(POINTS_MIN,rewardMaxPoints);
}
tempPoints.setRewardPointsExpireTime(rewardPointsExpireTime);
tempPoints.setMemberId(memberId);
tempPoints.setAppCode(msgData.getAppCode());
tempPoints.setPoints(rewardPoints);
tempPoints.setPointsType(pointsType);
tempPoints.setDeviceType(msgData.getDeviceType());
tempPoints.setExpireTime(expireTime);
tempPoints.setOrderId(msgData.getOrderId());
tempPoints.setActivityId(msgData.getOrderId());
tempPoints.setMediaId(msgData.getMediaId());
tempPoints.setItemId(msgData.getItemId());
tempPoints.setAccountId(msgData.getAccountId());
tempPoints.setEvtType(msgData.getEvent());
Integer rightsSendStrategy = task.getRightsSendStrategy();
tempPoints.setRightsSendStrategy(Objects.isNull(rightsSendStrategy) ? 0 : rightsSendStrategy);
return Arrays.asList(tempPoints);
}
return null;
}
/**
* 判断任务是否完成
* 完成的条件如下:->
* 1. status 当前任务的状态 0:失效;1:生效
* 1. task_repeat_type 任务重复类型,-1:不限次;1:单次;>1:多次
* 2. valid_time 任务生效时间
* 3. expire_time 任务失效时间
* 5. member_level 会员等级门槛(0表示无门槛)
* 6. member_vip 会员vip门槛(0表示没有门槛)
* 7. groups 能够获取该任务的用户分组,为空则都能获取
* 8. action_amount 行为量(完成此任务需要多少次相同行为的触发)
*
* @param taskList 任务列表
* @return boolean true:success false:fail
*/
private boolean checkTaskCompletion(Long memberId , List<Task> taskList) {
if (!CollectionUtils.isEmpty(taskList)) {
// 会员信息
MemberDTO memberDTO = this.memberService.findById(memberId);
// 判断是否完成任务
CompareTaskCondition compareTaskCondition =(MemberDTO memberDTO1,List<Task> taskList1) -> {
List<Task> taskStream = taskList1.stream().filter(task1 ->
task1.getStatus() == 1 &&
(Objects.isNull(task1.getExpireTime()) || task1.getExpireTime().compareTo(TimestampUtil.now()) <= 0) &&
(Objects.isNull(task1.getGroups()) || task1.getGroups().equalsIgnoreCase(memberDTO1.getGroups())) &&
(Objects.isNull(task1.getValidTime()) || task1.getValidTime().compareTo(TimestampUtil.now()) <= 0) &&
(Objects.isNull(task1.getMemberLevel()) || task1.getMemberLevel() == 0 || task1.getMemberLevel() <= memberDTO1.getLevel()) &&
(Objects.isNull(task1.getMemberVip()) || task1.getMemberVip() == 0 || task1.getMemberVip() == memberDTO1.getVip())
).collect(Collectors.toList());
if (CollectionUtils.isEmpty(taskStream)) {
// 获取当前任务的完成情况
boolean result = this.checkAndRefreshTaskCompletion(memberId,taskStream);
return result;
}
return true;
};
return compareTaskCondition.compareCondition(memberDTO,taskList);
}
return false;
}
/**
* 检查并更新当前任务的完成情况
* @param memberId
* @param taskStream
* @return
*/
private boolean checkAndRefreshTaskCompletion(Long memberId , List<Task> taskStream) {
TrTaskProgressQueryCriteria trTaskProgressQueryCriteria = new TrTaskProgressQueryCriteria();
trTaskProgressQueryCriteria.setMemberId(memberId);
String time1 = LocalDateTimeUtil.todayStart();
String time2 = LocalDateTimeUtil.todayEnd();;
trTaskProgressQueryCriteria.setCompletionTime(time1+","+time2);
ArrayList array = new ArrayList<>();
for (Task task : taskStream) {
TrTaskProgress trTaskProgress = new TrTaskProgress();
Long taskId = task.getId();
// 行为量(完成此任务需要多少次相同行为的触发)
Integer actionAmount = task.getActionAmount();
trTaskProgressQueryCriteria.setTaskId(taskId);
List<TrTaskProgressDTO> trTaskProgressDTOS = this.trTaskProgressService.queryAll(trTaskProgressQueryCriteria);
Long id = null;
Integer currentActionAmount = null;
Timestamp completionTime = null;
Integer status = 0;
// 行为量 1
if (actionAmount == 1) {
if (CollectionUtils.isEmpty(trTaskProgressDTOS)) {
currentActionAmount = 1;
completionTime = TimestampUtil.now();
status = TASK_FINISH_STATUS;
}
if (!CollectionUtils.isEmpty(trTaskProgressDTOS)) {
// 此任务做过,但未完成
TrTaskProgressDTO trTaskProgressDTO = trTaskProgressDTOS.get(0);
Long id_ = trTaskProgressDTO.getId();
Integer status_ = trTaskProgressDTO.getStatus();
Integer currentActionAmount_ = trTaskProgressDTO.getCurrentActionAmount();
if (status_ != 1 && Objects.isNull(trTaskProgressDTO.getCompletionTime())) {
id = id_;
currentActionAmount = 1;
completionTime = TimestampUtil.now();
status = TASK_FINISH_STATUS;
} else {
id = id_;
currentActionAmount = currentActionAmount_+1;
}
}
}
// 行为量不是1
if (actionAmount != 1) {
if (!CollectionUtils.isEmpty(trTaskProgressDTOS)) {
// 此任务做过,但未完成
TrTaskProgressDTO trTaskProgressDTO = trTaskProgressDTOS.get(0);
Long id_ = trTaskProgressDTO.getId();
// 状态 0:未完成;1:已完成
Integer status_ = trTaskProgressDTO.getStatus();
Timestamp completionTime_ = trTaskProgressDTO.getCompletionTime();
Integer currentActionAmount_ = trTaskProgressDTO.getCurrentActionAmount();
if (status_ != 1 && Objects.isNull(completionTime_) && actionAmount == currentActionAmount_+1) {
id = id_;
currentActionAmount = actionAmount;
completionTime = TimestampUtil.now();
status = TASK_FINISH_STATUS;
} else {
id = id_;
currentActionAmount = currentActionAmount_+1;
}
} else {
currentActionAmount = 1;
}
}
trTaskProgress.setId(id);
trTaskProgress.setCurrentActionAmount(currentActionAmount);
trTaskProgress.setCompletionTime(completionTime);
trTaskProgress.setStatus(status);
trTaskProgress.setTaskId(taskId);
trTaskProgress.setMemberId(memberId);
trTaskProgress.setTargetActionAmount(actionAmount);
// 更新任务完成情况
this.doRefreshTrTaskProcess(trTaskProgress);
if (status == 1) {
array.add(task);
}
}
if (CollectionUtils.isEmpty(array)) {
return true;
}
return false;
}
/**
* 获取任务模板对应的任务列表
*
* @param taskTemplate 任务模板
* @return List<task> 任务列表
*/
private List<Task> loadListTaskByTaskTemplate(TaskTemplate taskTemplate,Map<String,Object> paramMap) {
if (Objects.nonNull(taskTemplate)) {
Long taskTemplateId = taskTemplate.getId();
return this.taskService.findByTemplateId(taskTemplateId);
}
return null;
}
/**
* 获取任务模板
* @param event 任务
* @return TaskTemplate 任务模板
*/
private TaskTemplate getTaskTemplate(String event) {
return this.taskTemplateService.findByEvent(event);
}
}
package com.topdraw.business.process.service.impl;
import com.topdraw.business.process.service.TaskDealService;
import org.springframework.stereotype.Service;
@Service
public class UnsubscribeProductPackageTaskDealServiceImpl implements TaskDealService {
}
package com.topdraw.config;
public class LocalConstants {
// 小屏侧
public static final String ENV_MOBILE = "mobile";
// 大屏侧
public static final String ENV_VIS = "vis";
// 大屏类型
public static final int DEVICE_VIS = 1;
// 小屏类型
public static final int DEVICE_MOBILE = 2;
}
package com.topdraw.config;
import com.topdraw.utils.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
// @Value("122.112.214.149")
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedissonClient redisson(){
Config config = new Config();
// config.useSingleServer().setAddress("redis://"+redisHost+":"+port).setPassword("redis123");
if (StringUtils.isNotEmpty(password)) {
config.useSingleServer().setAddress("redis://"+redisHost+":"+port).setPassword(password);;
} else {
config.useSingleServer().setAddress("redis://"+redisHost+":"+port);
}
/* config.useClusterServers().addNodeAddress(
"redis://172.29.3.245:6375","redis://172.29.3.245:6376", "redis://172.29.3.245:6377",
"redis://172.29.3.245:6378","redis://172.29.3.245:6i379", "redis://172.29.3.245:6380")
.setPassword("a123456").setScanInterval(5000);*/
return Redisson.create(config);
}
}
package com.topdraw.config;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTaskConfig {
}
package com.topdraw.config;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ServiceEnvConfig {
// uc两侧部署,需配置位于哪一侧 mobile小屏侧 vis大屏侧
public static String UC_SERVICE_TYPE;
@Value("${uc.service.type:mobile}")
public void setUcServiceType(String ucServiceType) {
UC_SERVICE_TYPE = ucServiceType;
}
public static boolean isMobile() {
return ObjectUtil.equals(UC_SERVICE_TYPE, LocalConstants.ENV_MOBILE);
}
public static boolean isVis() {
return ObjectUtil.equals(UC_SERVICE_TYPE, LocalConstants.ENV_VIS);
}
}
package com.topdraw.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@PropertySource(value = {"classpath:executor.properties"}, ignoreResourceNotFound=false, encoding="UTF-8")
@Slf4j
@EnableAsync
public class ThreadPoolTaskExecutorConfig {
@Value("${threadPoolExecutor.core_pool_size}")
private int corePoolSize;
@Value("${threadPoolExecutor.max_pool_size}")
private int maxPoolSize;
@Value("${threadPoolExecutor.queue_capacity}")
private int queueCapacity;
@Value("${threadPoolExecutor.name.prefix}")
private String namePrefix;
@Value("${threadPoolExecutor.keep_alive_seconds}")
private int keepAliveSeconds;
@Bean(value = "executorTask")
public ThreadPoolTaskExecutor executorTask(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(corePoolSize);
// 最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 任务队列大小
executor.setQueueCapacity(queueCapacity);
// 线程前缀名
executor.setThreadNamePrefix(namePrefix);
// 线程的空闲时间
executor.setKeepAliveSeconds(keepAliveSeconds);
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程初始化
executor.initialize();
return executor;
}
}
package com.topdraw.mq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
/** 交换机--广播*/
public static final String UC_EXCHANGE_FANOUT = "uc.fanout";
/** 队列-- */
public static final String UC_QUEUE_FANOUT_IPTV = "uc.fanout.iptv";
public static final String UC_QUEUE_FANOUT_WEIXIN = "uc.fanout.weixin";
@Bean
FanoutExchange ucFanoutExchange(){
return ExchangeBuilder.fanoutExchange(UC_EXCHANGE_FANOUT).build();
}
@Bean
Queue ucFanoutQueueIptv(){
return new Queue(UC_QUEUE_FANOUT_IPTV);
}
@Bean
Queue ucFanoutQueueWeiXin(){
return new Queue(UC_QUEUE_FANOUT_WEIXIN);
}
@Bean
Binding fanoutExchangeBindingIptv(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueIptv){
return BindingBuilder.bind(ucFanoutQueueIptv).to(ucFanoutExchange);
}
@Bean
Binding fanoutExchangeBindingWeiXin(FanoutExchange ucFanoutExchange , Queue ucFanoutQueueWeiXin){
return BindingBuilder.bind(ucFanoutQueueWeiXin).to(ucFanoutExchange);
}
}
package com.topdraw.mq.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TableOperationMsg {
// 数据表操作类型
private TableOperationType tableOperationType;
// 模型名称
private String entityName;
// 消息体
private String entityBody;
private String interfaceName;
private String methodName;
}
package com.topdraw.mq.domain;
// 数据表操作类型
public enum TableOperationType {
// 新增
ADD,INSERT,DOADD,DOINSERT,
// 修改
UPDATE,DOUPDATE,
// 删除
DELETE,DODELETE
}
package com.topdraw.mq.producer;
import com.topdraw.mq.config.RabbitMqConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
@Slf4j
public class MessageProducer {
@Autowired
private AmqpTemplate amqpTemplate;
/**
* 广播
* @param msg
* @param exchangeName
* @author XiangHan
* @date 2021/9/7 11:10 上午
*/
public void sendFanoutMessage(String msg,String exchangeName) {
if (StringUtils.isEmpty(exchangeName)) {
exchangeName = RabbitMqConfig.UC_EXCHANGE_FANOUT;
}
amqpTemplate.convertAndSend(exchangeName, "", msg);
log.info("send sendFanoutMessage msg || entityType: {} || msg:{} ", msg);
}
/**
* 广播
* @param msg
* @author XiangHan
* @date 2021/9/7 11:10 上午
*/
public void sendFanoutMessage(String msg) {
this.sendFanoutMessage(msg,null);
}
}
package com.topdraw.resttemplate;
import com.alibaba.fastjson.JSONObject;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import java.util.Map;
@Slf4j
@Component
public class ApiUtil {
private static RestTemplate restTemplate;
private static String BASE_URL;
@Autowired
private Environment environment;
@PostConstruct
private void init() {
BASE_URL = environment.getProperty("api.baseUrl");
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// 设置连接超时
factory.setConnectTimeout(5000);
// 设置读取超时
factory.setReadTimeout(8000);
restTemplate = new RestTemplate(factory);
}
public static JSONObject getMemberInfo(Long memberId) {
JSONObject resultSet = null;
String url = BASE_URL + "/api/member/findById/" + memberId;
log.info("request uc : url is " + url + ", memberId is " + memberId);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
String entityBody = responseEntity.getBody();
JSONObject jsonObject = JSONObject.parseObject(entityBody);
if (jsonObject.getInteger("businessCode").equals(200)) {
resultSet = jsonObject.getJSONArray("resultSet").getJSONObject(0);
}
}
log.info("uc response: " + resultSet.toJSONString());
return resultSet;
}
public static String createMember(Member member) {
String entityBody = "";
String url = BASE_URL + "/api/member/create";
log.info("request uc : url is " + url + ", memberId is " + com.alibaba.fastjson.JSONObject.toJSONString(member));
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, member, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
entityBody = responseEntity.getBody();
}
return entityBody;
}
public static String updateMember(Member member) {
String entityBody = "";
String url = BASE_URL + "/api/member/update";
log.info("request uc : url is " + url + ", memberId is " + com.alibaba.fastjson.JSONObject.toJSONString(member));
restTemplate.put(url, member);
return entityBody;
}
public static String createMemberAddress(MemberAddress member) {
JSONObject resultSet = null;
String url = BASE_URL + "/api/MemberAddress/create";
log.info("request uc : url is " + url + ", memberId is " + com.alibaba.fastjson.JSONObject.toJSONString(member));
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, member, String.class);
String entityBody = "";
if (responseEntity.getStatusCode().is2xxSuccessful()) {
entityBody = responseEntity.getBody();
}
log.info("uc response: " + entityBody);
return entityBody;
}
public static void updateMemberAddress(MemberAddress member) {
String url = BASE_URL + "/api/MemberAddress/update";
log.info("request uc : url is " + url + ", memberId is " + com.alibaba.fastjson.JSONObject.toJSONString(member));
restTemplate.put(url, member);
}
public static void deleteMemberAddress(Long id) {
String url = BASE_URL + "/api/MemberAddress/delete/" + id;
log.info("request uc : url is " + url + ", memberId is " + id);
restTemplate.delete(url);
}
public static JSONObject getMemberProfile(Long memberId) {
JSONObject resultSet = null;
String url = BASE_URL + "/api/MemberRelatedInfo/getMemberRelatedInfos";
log.info("request uc : url is " + url + ", memberId is " + memberId);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
String entityBody = responseEntity.getBody();
JSONObject jsonObject = JSONObject.parseObject(entityBody);
if (jsonObject.getInteger("businessCode").equals(200)) {
resultSet = jsonObject.getJSONArray("resultSet").getJSONObject(0);
}
}
log.info("uc response: " + resultSet.toJSONString());
return resultSet;
}
public static String getMemberAddress(Map<String, Object> param) {
String entityBody = "";
String url = BASE_URL + "/api/MemberAddress/pageMemberAddress?page=" + param.get("page") + "&size=" + param.get("size") + "&memberId=" + param.get("memberId");
log.info("request uc : url is " + url + ", param is " + param);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
entityBody = responseEntity.getBody();
}
log.info("uc response: " + entityBody);
return entityBody;
}
public static String getMemberRelatedInfo(Map<String, Object> param) {
String entityBody = "";
String url = BASE_URL + "/api/MemberRelatedInfo/pageMemberRelatedInfos?page=" + param.get("page") + "&size=" + param.get("size") + "&memberId=" + param.get("memberId");
log.info("request uc : url is " + url + ", memberId is " + param);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
entityBody = responseEntity.getBody();
}
log.info("uc response: " + entityBody);
return entityBody;
}
public static void deleteMemberRelatedInfo(Long memberRelatedId) {
String url = BASE_URL + "/api/MemberRelatedInfo/delete/" + memberRelatedId;
log.info("request uc : url is " + url + ", memberId is " + memberRelatedId);
restTemplate.delete(url, String.class);
}
public static String addMemberRelatedInfo(MemberRelatedInfo resources) {
String entityBody = null;
String url = BASE_URL + "/api/MemberRelatedInfo/create";
log.info("request uc : url is " + url + ", memberRelatedId is " + com.alibaba.fastjson.JSONObject.toJSONString(resources));
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, resources, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
entityBody = responseEntity.getBody();
// JSONObject jsonObject = JSONObject.parseObject(entityBody);
// if (jsonObject.getInteger("businessCode").equals(200)) {
// resultSet = jsonObject.getJSONArray("resultSet").getJSONObject(0);
// }
}
log.info("uc response: " + entityBody);
return entityBody;
}
public static String updateMemberRelatedInfo(MemberRelatedInfo resources) {
String resultSet = "";
String url = BASE_URL + "/api/MemberRelatedInfo/update";
log.info("request uc : url is " + url + ", memberRelatedId is " + com.alibaba.fastjson.JSONObject.toJSONString(resources));
restTemplate.put(url, resources);
return resultSet;
}
}
package com.topdraw.schedule;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import com.topdraw.business.basicdata.points.standingbook.domain.PointsStandingBook;
import com.topdraw.business.basicdata.points.standingbook.service.PointsStandingBookService;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.List;
/**
* 积分台账
*/
@Component
@Slf4j
@EnableScheduling
public class ScheduledTask {
@Autowired
PointsOperationService pointsOperationService;
// @Scheduled(cron = "0/59 59 23 * * ? ")
/**
* 清理已过期的积分
*/
@Scheduled(cron = "0 0/1 * * * ? ")
public void cleanValidAvailablePoints(){
this.pointsOperationService.cleanInvalidAvailablePoints();
}
}
package com.topdraw.util;
import java.time.LocalDateTime;
import java.util.Date;
public class DateUtil {
public static Date newDate(){
return new Date();
}
public static long currentTimestamp(){
return System.currentTimeMillis();
}
}
package com.topdraw.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
/**
* 生成订单ID, 雪花算法代码实现
*/
public class IdWorker {
private static final Logger LOG = LoggerFactory.getLogger(IdWorker.class.getName());
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
private final static long workerIdBits = 5L;
// 数据中心标识位数
private final static long datacenterIdBits = 5L;
// 机器ID最大值
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 数据中心ID最大值
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 毫秒内自增位
private final static long sequenceBits = 12L;
// 机器ID偏左移12位
private final static long workerIdShift = sequenceBits;
// 数据中心ID左移17位
private final static long datacenterIdShift = sequenceBits + workerIdBits;
// 时间毫秒左移22位
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/* 上次生产id时间戳 */
private static long lastTimestamp = -1L;
// 0,并发控制
private long sequence = 0L;
private final long workerId;
// 数据标识id部分
private final long datacenterId;
public IdWorker(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId 工作机器ID
* @param datacenterId 序列号
*/
public IdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 获取下一个ID
* @return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID,并返回ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
* 获取 maxWorkerId
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
* GET jvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
* MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
* 数据标识id部分
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
if (null == mac) {
return 1L;
}
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
LOG.warn(" getDatacenterId: " + e.getMessage());
}
return id;
}
public static long generator(){
IdWorker idWorker = new IdWorker();
return idWorker.nextId();
}
public static void main(String[] args) {
IdWorker idWorker = new IdWorker();
System.out.println(idWorker.nextId());
}
}
package com.topdraw.util;
import com.alibaba.fastjson.JSON;
public class JSONUtil<T> {
public static <T> T parseMsg2Object(String content , Class<T> clazz) {
T t = JSON.parseObject(content, clazz);
return t;
}
}
package com.topdraw.util;
import java.time.LocalDate;
public class LocalDateTimeUtil {
public static String todayStart() {
LocalDate now = LocalDate.now();
return now+" 00:00:00";
}
public static String todayEnd() {
LocalDate now = LocalDate.now();
return now+" 23:59:59";
}
public static void main(String[] args) {
String end = todayEnd();
System.out.println("end ==>> "+end);
String start = todayStart();
System.out.println("start ==>> "+start);
}
}
package com.topdraw.util;
import java.util.Random;
public class RandomUtil {
/**
* 获取随机积分
* @param max
* @param min
* @return
*/
public static long getRandomPoints(Integer min,Integer max) {
Random random = new Random();
int s = random.nextInt(max)%(max-min+1) + min;
return s;
}
public static void main(String[] args) {
for (int i=0;i<30;i++) {
long randomPoints = getRandomPoints(1, 10);
System.out.println(randomPoints);
}
}
}
package com.topdraw.util;
import org.redisson.api.RLock;
public class RedissonUtil {
public static void lock(RLock rLock){
rLock.lock();
}
public static void unlock(RLock rLock){
if (rLock.isLocked() && rLock.isHeldByCurrentThread())
rLock.unlock();
}
}
package com.topdraw.util;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class TimestampUtil {
public static Timestamp now(){
return new Timestamp(System.currentTimeMillis());
}
public static Timestamp now(LocalDateTime localDateTime) {
long epochSecond = localDateTime.toInstant(ZoneOffset.of("+8")).getEpochSecond();
return new Timestamp(epochSecond);
}
public static long localDateTime2Timestamp(LocalDateTime localDateTime){
long epochSecond = localDateTime.atZone(ZoneOffset.systemDefault()).toEpochSecond();
return epochSecond;
}
public static Timestamp long2Timestamp(long timestamp){
Timestamp timestamp1 = Timestamp.from(Instant.ofEpochSecond(timestamp));
return timestamp1;
}
public static long Timestamp2long(Timestamp timestamp){
return timestamp.toInstant().getEpochSecond();
}
public static void main(String[] args) {
LocalDateTime of = LocalDateTime.of(2021, 10, 28, 11, 00, 00);
long l = localDateTime2Timestamp(of);
// long l = 16342727230L;
Timestamp timestamp = long2Timestamp(l);
System.out.println(timestamp.toString());
}
}
___________ .___
\__ ___/___ ______ __| _/___________ __ _ __
| | / _ \\____ \ / __ |\_ __ \__ \\ \/ \/ /
| |( <_> ) |_> > /_/ | | | \// __ \\ /
|____| \____/| __/\____ | |__| (____ /\/\_/
|__| \/ \/
:: UserCenter :: Spring Boot - ${spring-boot.version}
#配置数据源
spring:
datasource:
# 测试/演示库
url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: Tjlh@2017
# url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: root
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#Druid
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 初始化配置
initial-size: 3
# 最小连接数
min-idle: 3
# 最大连接数
max-active: 15
# 获取连接超时时间
max-wait: 5000
# 连接有效性检测时间
time-between-eviction-runs-millis: 90000
# 最大空闲时间
min-evictable-idle-time-millis: 1800000
test-while-idle: true
test-on-borrow: false
test-on-return: false
validation-query: select 1
# 配置监控统计拦截的filters
filters: stat
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
#配置 Jpa
jpa:
hibernate:
# 生产环境设置成 none,避免程序运行时自动更新数据库结构
ddl-auto: none
servlet:
multipart:
file-size-threshold: 2KB
max-file-size: 100MB
max-request-size: 200MB
redis:
#数据库索引
database: 16
host: 122.112.214.149
# host: 139.196.4.234
port: 6379
password: redis123
# password:
#连接超时时间
timeout: 5000
rabbitmq:
host: 122.112.214.149 # rabbitmq的连接地址
#host: 139.196.192.242 # rabbitmq的连接地址
port: 5672 # rabbitmq的连接端口号
#virtual-host: /member_center # rabbitmq的虚拟host
#username: member_center # rabbitmq的用户名
#password: Tjlh@2021 # rabbitmq的密码
virtual-host: / # rabbitmq的虚拟host
username: guest # rabbitmq的用户名
password: guest # rabbitmq的密码
publisher-confirms: true #如果对异步消息需要回调必须设置为true
#jwt。依赖的common中有需要jwt的部分属性。
jwt:
header: Authorization
secret: mySecret
# token 过期时间/毫秒,6小时 1小时 = 3600000 毫秒
expiration: 7200000
# 在线用户key
online: online-token
# 验证码
codeKey: code-key
# token 续期检查时间范围(60分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
detect: 3600000
# 续期时间,2小时,单位毫秒
renew: 7200000
#是否允许生成代码,生产环境设置为false
generator:
enabled: true
#是否开启 swagger-ui
swagger:
enabled: true
#配置数据源
spring:
datasource:
# 测试/演示库
url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: Tjlh@2017
# url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: root
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#Druid
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 初始化配置
initial-size: 3
# 最小连接数
min-idle: 3
# 最大连接数
max-active: 15
# 获取连接超时时间
max-wait: 5000
# 连接有效性检测时间
time-between-eviction-runs-millis: 90000
# 最大空闲时间
min-evictable-idle-time-millis: 1800000
test-while-idle: true
test-on-borrow: false
test-on-return: false
validation-query: select 1
# 配置监控统计拦截的filters
filters: stat
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
#配置 Jpa
jpa:
hibernate:
# 生产环境设置成 none,避免程序运行时自动更新数据库结构
ddl-auto: none
servlet:
multipart:
file-size-threshold: 2KB
max-file-size: 100MB
max-request-size: 200MB
redis:
#数据库索引
database: 16
host: 122.112.214.149
# host: 139.196.4.234
port: 6379
password: redis123
# password:
#连接超时时间
timeout: 5000
rabbitmq:
host: 122.112.214.149 # rabbitmq的连接地址
#host: 139.196.192.242 # rabbitmq的连接地址
port: 5672 # rabbitmq的连接端口号
#virtual-host: /member_center # rabbitmq的虚拟host
#username: member_center # rabbitmq的用户名
#password: Tjlh@2021 # rabbitmq的密码
virtual-host: / # rabbitmq的虚拟host
username: guest # rabbitmq的用户名
password: guest # rabbitmq的密码
publisher-confirms: true #如果对异步消息需要回调必须设置为true
#jwt。依赖的common中有需要jwt的部分属性。
jwt:
header: Authorization
secret: mySecret
# token 过期时间/毫秒,6小时 1小时 = 3600000 毫秒
expiration: 7200000
# 在线用户key
online: online-token
# 验证码
codeKey: code-key
# token 续期检查时间范围(60分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
detect: 3600000
# 续期时间,2小时,单位毫秒
renew: 7200000
#是否允许生成代码,生产环境设置为false
generator:
enabled: true
#是否开启 swagger-ui
swagger:
enabled: true
#配置数据源
spring:
datasource:
# 测试/演示库
url: jdbc:log4jdbc:mysql://139.196.192.242:3306/tj_user_0819?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
username: root
password: Tjlh@2017
# url: jdbc:log4jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://122.112.214.149:3306/tj_user?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
# username: root
# password: root
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#Druid
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 初始化配置
initial-size: 3
# 最小连接数
min-idle: 3
# 最大连接数
max-active: 15
# 获取连接超时时间
max-wait: 5000
# 连接有效性检测时间
time-between-eviction-runs-millis: 90000
# 最大空闲时间
min-evictable-idle-time-millis: 1800000
test-while-idle: true
test-on-borrow: false
test-on-return: false
validation-query: select 1
# 配置监控统计拦截的filters
filters: stat
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
web-stat-filter:
url-pattern: /*
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
#配置 Jpa
jpa:
hibernate:
# 生产环境设置成 none,避免程序运行时自动更新数据库结构
ddl-auto: none
servlet:
multipart:
file-size-threshold: 2KB
max-file-size: 100MB
max-request-size: 200MB
redis:
#数据库索引
database: 16
host: 122.112.214.149
# host: 139.196.4.234
port: 6379
password: redis123
# password:
#连接超时时间
timeout: 5000
rabbitmq:
host: 122.112.214.149 # rabbitmq的连接地址
#host: 139.196.192.242 # rabbitmq的连接地址
port: 5672 # rabbitmq的连接端口号
#virtual-host: /member_center # rabbitmq的虚拟host
#username: member_center # rabbitmq的用户名
#password: Tjlh@2021 # rabbitmq的密码
virtual-host: / # rabbitmq的虚拟host
username: guest # rabbitmq的用户名
password: guest # rabbitmq的密码
publisher-confirms: true #如果对异步消息需要回调必须设置为true
#jwt。依赖的common中有需要jwt的部分属性。
jwt:
header: Authorization
secret: mySecret
# token 过期时间/毫秒,6小时 1小时 = 3600000 毫秒
expiration: 7200000
# 在线用户key
online: online-token
# 验证码
codeKey: code-key
# token 续期检查时间范围(60分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
detect: 3600000
# 续期时间,2小时,单位毫秒
renew: 7200000
#是否允许生成代码,生产环境设置为false
generator:
enabled: true
#是否开启 swagger-ui
swagger:
enabled: true
server:
port: 8447
spring:
application:
name: member-service
freemarker:
check-template-location: false
profiles:
active: test
jackson:
time-zone: GMT+8
data:
redis:
repositories:
enabled: false
#配置 Jpa
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
open-in-view: true
task:
pool:
# 核心线程池大小
core-pool-size: 10
# 最大线程数
max-pool-size: 30
# 活跃时间
keep-alive-seconds: 60
# 队列容量
queue-capacity: 50
#登录图形验证码有效时间/分钟
loginCode:
expiration: 2
#默认上传图片类型
default-image-type: -1
threadPoolExecutor.core_pool_size=5
threadPoolExecutor.max_pool_size=15
threadPoolExecutor.queue_capacity=10
threadPoolExecutor.name.prefix=asyncExecutor
threadPoolExecutor.keep_alive_seconds=2
\ No newline at end of file
#数据库类型转Java类型
tinyint=Integer
smallint=Integer
mediumint=Integer
int=Integer
integer=Integer
bigint=Long
float=Float
double=Double
decimal=BigDecimal
bit=Boolean
char=String
varchar=String
tinytext=String
text=String
mediumtext=String
longtext=String
date=Timestamp
datetime=Timestamp
timestamp=Timestamp
# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.auto.load.popular.drivers=false
log4jdbc.drivers=com.mysql.cj.jdbc.Driver
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>UserCenter</contextName>
<!--定义参数,后面可以通过${app.name}使用-->
<property name="app.name" value="user-center"/>
<property name="log.path" value="./logs"/>
<property name="log.pattern" value="%d [%thread] %-5level %logger{36} [%file : %line] - %msg%n"/>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默认配置为PatternLayoutEncoder -->
<!--定义控制台输出格式-->
<encoder>
<pattern>%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %msg %n</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!--获取比info级别高(包括info级别)但除error级别的日志-->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<!--滚动策略-->
<file>${log.path}/${app.name}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${log.path}/info/${app.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<!--滚动策略-->
<file>${log.path}/${app.name}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${log.path}/error/${app.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
</appender>
<!--普通日志输出到控制台-->
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="info" />
<appender-ref ref="error" />
</root>
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
<logger name="jdbc.resultset" level="ERROR" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
<!-- 如想看到表格数据,将OFF改为INFO -->
<logger name="jdbc.resultsettable" level="OFF" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="info" />
</logger>
</configuration>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style>
@page {
margin: 0;
}
</style>
</head>
<body style="margin: 0px;
padding: 0px;
font: 100% SimSun, Microsoft YaHei, Times New Roman, Verdana, Arial, Helvetica, sans-serif;
color: #000;">
<div style="height: auto;
width: 820px;
min-width: 820px;
margin: 0 auto;
margin-top: 20px;
border: 1px solid #eee;">
<div style="padding: 10px;padding-bottom: 0px;">
<p style="margin-bottom: 10px;padding-bottom: 0px;">尊敬的用户,您好:</p>
<p style="text-indent: 2em; margin-bottom: 10px;">您正在申请邮箱验证,您的验证码为:</p>
<p style="text-align: center;
font-family: Times New Roman;
font-size: 22px;
color: #C60024;
padding: 20px 0px;
margin-bottom: 10px;
font-weight: bold;
background: #ebebeb;">${code}</p>
<div style="list-style: none;
margin-top: 22px;
maigin-bottom: 10px;
font-size: 14px;
color: #555;">
<p style="line-height: 12px;">Github:<a hover="color: #DA251D;" style="color: #999;" href="https://github.com/elunez/eladmin" target="_blank">https://github.com/elunez/eladmin</a></p>
</div>
<div class="foot-hr hr" style="margin: 0 auto;
z-index: 111;
width: 800px;
margin-top: 30px;
border-top: 1px solid #DA251D;">
</div>
<div style="text-align: center;
font-size: 12px;
padding: 20px 0px;
font-family: Microsoft YaHei;">
Copyright &copy;${.now?string("yyyy")} EL-ADMIN 后台管理系统 All Rights Reserved.
</div>
</div>
</div>
</body>
</html>
package ${package}.rest;
import com.topdraw.common.ResultInfo;
import com.topdraw.annotation.Log;
import ${package}.domain.${className};
import ${package}.service.${className}Service;
import ${package}.service.dto.${className}QueryCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author ${author}
* @date ${date}
*/
@Api(tags = "${className}管理")
@RestController
@RequestMapping("/api/${changeClassName}")
public class ${className}Controller {
@Autowired
private ${className}Service ${changeClassName}Service;
@GetMapping
@ApiOperation("查询${className}")
public ResultInfo get${className}s(${className}QueryCriteria criteria, Pageable pageable) {
return ResultInfo.successPage(${changeClassName}Service.queryAll(criteria,pageable));
}
@GetMapping(value = "/all")
@ApiOperation("查询所有${className}")
public ResultInfo get${className}s(${className}QueryCriteria criteria) {
return ResultInfo.success(${changeClassName}Service.queryAll(criteria));
}
@Log
@PostMapping
@ApiOperation("新增${className}")
public ResultInfo create(@Validated @RequestBody ${className} resources) {
${changeClassName}Service.create(resources);
return ResultInfo.success();
}
@Log
@PutMapping
@ApiOperation("修改${className}")
public ResultInfo update(@Validated @RequestBody ${className} resources) {
${changeClassName}Service.update(resources);
return ResultInfo.success();
}
@Log
@DeleteMapping(value = "/{${pkChangeColName}}")
@ApiOperation("删除${className}")
public ResultInfo delete(@PathVariable ${pkColumnType} ${pkChangeColName}) {
${changeClassName}Service.delete(${pkChangeColName});
return ResultInfo.success();
}
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
@GetMapping(value = "/getByCode/{code}")
@ApiOperation(value = "根据标识查询")
public ResultInfo getByCode(@PathVariable String code) {
return ResultInfo.success(${changeClassName}Service.getByCode(code));
}
</#if>
</#list>
</#if>
}
package ${package}.service.dto;
import lombok.Data;
<#if hasTimestamp>
import java.sql.Timestamp;
</#if>
<#if hasBigDecimal>
import java.math.BigDecimal;
</#if>
import java.io.Serializable;
<#if !auto && pkColumnType = 'Long'>
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
</#if>
/**
* @author ${author}
* @date ${date}
*/
@Data
public class ${className}DTO implements Serializable {
<#if columns??>
<#list columns as column>
<#if column.columnComment != ''>
// ${column.columnComment}
</#if>
<#if column.columnKey = 'PRI'>
<#if !auto && pkColumnType = 'Long'>
// 处理精度丢失问题
@JsonSerialize(using= ToStringSerializer.class)
</#if>
</#if>
private ${column.columnType} ${column.changeColumnName};
</#list>
</#if>
}
package ${package}.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
<#if hasTimestamp>
import java.sql.Timestamp;
</#if>
<#if hasBigDecimal>
import java.math.BigDecimal;
</#if>
<#if hasCode>
import java.util.UUID;
</#if>
import java.io.Serializable;
/**
* @author ${author}
* @date ${date}
*/
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
@Accessors(chain = true)
@Table(name="${tableName}")
public class ${className} implements Serializable {
<#if columns??>
<#list columns as column>
<#if column.columnComment != ''>
// ${column.columnComment}
</#if>
<#if column.columnKey = 'PRI'>
@Id
<#if auto>
@GeneratedValue(strategy = GenerationType.IDENTITY)
</#if>
</#if>
<#if column.columnName == 'create_time'>
@CreatedDate
</#if>
<#if column.columnName == 'update_time'>
@LastModifiedDate
</#if>
@Column(name = "${column.columnName}"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.isNullable = 'NO' && column.columnKey != 'PRI'>, nullable = false</#if>)
private ${column.columnType} ${column.changeColumnName};
</#list>
</#if>
public void copy(${className} source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}
package ${package}.service.mapper;
import com.topdraw.base.BaseMapper;
import ${package}.domain.${className};
import ${package}.service.dto.${className}DTO;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author ${author}
* @date ${date}
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface ${className}Mapper extends BaseMapper<${className}DTO, ${className}> {
}
package ${package}.service.dto;
import lombok.Data;
<#if queryHasTimestamp>
import java.sql.Timestamp;
</#if>
<#if queryHasBigDecimal>
import java.math.BigDecimal;
</#if>
<#if queryColumns??>
import com.topdraw.annotation.Query;
</#if>
/**
* @author ${author}
* @date ${date}
*/
@Data
public class ${className}QueryCriteria{
<#if queryColumns??>
<#list queryColumns as column>
<#if column.columnQuery = '1'>
// 模糊
@Query(type = Query.Type.INNER_LIKE)
</#if>
<#if column.columnQuery = '2'>
// 精确
@Query
</#if>
private ${column.columnType} ${column.changeColumnName};
</#list>
</#if>
}
package ${package}.repository;
import ${package}.domain.${className};
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
/**
* @author ${author}
* @date ${date}
*/
public interface ${className}Repository extends JpaRepository<${className}, ${pkColumnType}>, JpaSpecificationExecutor<${className}> {
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
${className} findBy${column.capitalColumnName}(${column.columnType} ${column.columnName});
</#if>
</#list>
</#if>
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
Optional<${className}> findFirstByCode(String code);
</#if>
</#list>
</#if>
}
package ${package}.service;
import ${package}.domain.${className};
import ${package}.service.dto.${className}DTO;
import ${package}.service.dto.${className}QueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @author ${author}
* @date ${date}
*/
public interface ${className}Service {
/**
* 查询数据分页
* @param criteria 条件参数
* @param pageable 分页参数
* @return Map<String,Object>
*/
Map<String,Object> queryAll(${className}QueryCriteria criteria, Pageable pageable);
/**
* 查询所有数据不分页
* @param criteria 条件参数
* @return List<${className}DTO>
*/
List<${className}DTO> queryAll(${className}QueryCriteria criteria);
/**
* 根据ID查询
* @param ${pkChangeColName} ID
* @return ${className}DTO
*/
${className}DTO findById(${pkColumnType} ${pkChangeColName});
void create(${className} resources);
void update(${className} resources);
void delete(${pkColumnType} ${pkChangeColName});
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
/**
* Code校验
* @param code
* @return ${className}DTO
*/
${className}DTO getByCode(String code);
</#if>
</#list>
</#if>
}
package ${package}.service.impl;
import ${package}.domain.${className};
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
<#if column_index = 1>
import com.topdraw.exception.EntityExistException;
</#if>
</#if>
</#list>
</#if>
import com.topdraw.utils.ValidationUtil;
import com.topdraw.utils.FileUtil;
import ${package}.repository.${className}Repository;
import ${package}.service.${className}Service;
import ${package}.service.dto.${className}DTO;
import ${package}.service.dto.${className}QueryCriteria;
import ${package}.service.mapper.${className}Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.dao.EmptyResultDataAccessException;
<#if !auto && pkColumnType = 'Long'>
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
</#if>
<#if !auto && pkColumnType = 'String'>
import cn.hutool.core.util.IdUtil;
</#if>
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
import com.topdraw.utils.PageUtil;
import com.topdraw.utils.QueryHelp;
import com.topdraw.utils.StringUtils;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
/**
* @author ${author}
* @date ${date}
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ${className}ServiceImpl implements ${className}Service {
@Autowired
private ${className}Repository ${changeClassName}Repository;
@Autowired
private ${className}Mapper ${changeClassName}Mapper;
@Override
public Map<String, Object> queryAll(${className}QueryCriteria criteria, Pageable pageable) {
Page<${className}> page = ${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(${changeClassName}Mapper::toDto));
}
@Override
public List<${className}DTO> queryAll(${className}QueryCriteria criteria) {
return ${changeClassName}Mapper.toDto(${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
}
@Override
public ${className}DTO findById(${pkColumnType} ${pkChangeColName}) {
${className} ${changeClassName} = ${changeClassName}Repository.findById(${pkChangeColName}).orElseGet(${className}::new);
ValidationUtil.isNull(${changeClassName}.get${pkCapitalColName}(),"${className}","${pkChangeColName}",${pkChangeColName});
return ${changeClassName}Mapper.toDto(${changeClassName});
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(${className} resources) {
<#if !auto && pkColumnType = 'Long'>
Snowflake snowflake = IdUtil.createSnowflake(1, 1);
resources.set${pkCapitalColName}(snowflake.nextId());
</#if>
<#if !auto && pkColumnType = 'String'>
resources.set${pkCapitalColName}(IdUtil.simpleUUID());
</#if>
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
if(${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()) != null) {
throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
}
</#if>
</#list>
</#if>
${changeClassName}Repository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(${className} resources) {
${className} ${changeClassName} = ${changeClassName}Repository.findById(resources.get${pkCapitalColName}()).orElseGet(${className}::new);
ValidationUtil.isNull( ${changeClassName}.get${pkCapitalColName}(),"${className}","id",resources.get${pkCapitalColName}());
<#if columns??>
<#list columns as column>
<#if column.columnKey = 'UNI'>
<#if column_index = 1>
${className} ${changeClassName}1 = null;
</#if>
${changeClassName}1 = ${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}());
if(${changeClassName}1 != null && !${changeClassName}1.get${pkCapitalColName}().equals(${changeClassName}.get${pkCapitalColName}())){
throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
}
</#if>
</#list>
</#if>
${changeClassName}.copy(resources);
${changeClassName}Repository.save(${changeClassName});
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(${pkColumnType} ${pkChangeColName}) {
Assert.notNull(id, "The given id must not be null!");
${className} ${changeClassName} = ${changeClassName}Repository.findById(id).orElseThrow(
() -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", ${className}.class, id), 1));
${changeClassName}Repository.delete(${changeClassName});
}
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
@Override
public ${className}DTO getByCode(String code) {
return StringUtils.isNotEmpty(code) ? ${changeClassName}Mapper.toDto(${changeClassName}Repository.findFirstByCode(code).orElseGet(${className}::new))
: new ${className}DTO();
}
</#if>
</#list>
</#if>
}
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/${changeClassName}',
method: 'post',
data
})
}
export function del(${pkChangeColName}) {
return request({
url: 'api/${changeClassName}/' + ${pkChangeColName},
method: 'delete'
})
}
export function edit(data) {
return request({
url: 'api/${changeClassName}',
method: 'put',
data
})
}
export function download${className}(params) {
return request({
url: 'api/${changeClassName}/download',
method: 'get',
params,
responseType: 'blob'
})
}
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
export function getByCode(code) {
return request({
url: 'api/${changeClassName}/getByCode/' + code,
method: 'get'
})
}
</#if>
</#list>
</#if>
<template>
<el-dialog :append-to-body="true" :close-on-click-modal="false" :visible.sync="dialog" :title="isAdd ? '新增' : '编辑'" width="960px" @closed="doClose">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px" style="padding: 30px;margin: -20px 0">
<el-row>
<#if columns??>
<#list columns as column>
<#if column.changeColumnName != '${pkChangeColName}'>
<#if column.columnName != 'images' && column.columnName != 'create_time' && column.columnName != 'update_time'>
<el-col :span="12">
<el-form-item label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>" <#if column.isNullable =
'NO'>prop="${column.changeColumnName}"</#if>>
<#if column.columnName = 'code'>
<el-input v-model="form.${column.changeColumnName}" prop="code"/>
<#elseif column.columnType = 'Timestamp'>
<el-date-picker v-model="form.${column.changeColumnName}" type="datetime"/>
<#elseif column.columnName = 'image'>
<images-upload ref="upload" :limit="5" :image.sync="form.image" :images.sync="form.images" upload-entity="${changeClassName}" />
<#else>
<el-input v-model="form.${column.changeColumnName}"/>
</#if>
</el-form-item>
</el-col>
</#if>
</#if>
</#list>
</#if>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancel">取消</el-button>
<el-button :loading="loading" type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
</template>
<script>
import { add, edit } from '@/api/${changeClassName}'
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
import { getByCode } from '@/api/${changeClassName}'
</#if>
</#list>
</#if>
import ImagesUpload from '@/components/ImagesUpload/index'
export default {
components: { ImagesUpload },
props: {
isAdd: {
type: Boolean,
required: true
},
dictMap: {
type: Object,
required: true
}
},
data() {
return {
loading: false, dialog: false,
form: {
<#if columns??>
<#list columns as column>
${column.changeColumnName}: ''<#if column_has_next>,</#if>
</#list>
</#if>
},
rules: {
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
code: [
{ required: true, message: '请输入标识', trigger: 'blur' }, { validator: this.validateCode, trigger: 'blur' }
],
</#if>
</#list>
</#if>
<#function filter columns>
<#local result = []>
<#list columns as column>
<#if column.columnKey != 'PRI' && column.isNullable = 'NO'>
<#local result = result + [column]>
</#if>
</#list>
<#return result>
</#function>
<#assign filteredData = filter(columns)>
<#list filteredData as column>
${column.changeColumnName}: [
{ required: true, message: '${column.columnComment}不能为空', trigger: 'blur' }
]<#sep>,</#sep>
</#list>
}
}
},
methods: {
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
validateCode(rule, value, callback) {
// 当为编辑状态且code未改变时不进行校验
if (!this.isAdd && this.form.originalCode === value) {
callback()
} else {
getByCode(value)
.then(res => {
typeof (res) === 'undefined' || res.id === null || this.form.id === res.id
? callback()
: callback(new Error('该code已存在!'))
})
.catch((err) => {
console.log(err)
callback()
})
}
},
</#if>
</#list>
</#if>
cancel() {
this.dialog = false
},
doSubmit() {
if (this.isAdd) {
this.doAdd()
} else this.doEdit()
},
doAdd() {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
add(this.form).then(() => {
this.$notify({
title: '添加成功',
type: 'success',
duration: 2500
})
this.dialog = false
this.loading = false
this.$parent.init()
}).catch(err => {
this.loading = false
console.log(err)
})
} else {
this.$notify({
title: '警告',
message: '信息不合法',
type: 'warning',
duration: 2000
})
}
})
},
doEdit() {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
edit(this.form).then(() => {
this.$notify({
title: '修改成功',
type: 'success',
duration: 2500
})
this.loading = false
this.dialog = false
this.$parent.init()
}).catch(err => {
console.log(err)
this.loading = false
})
} else {
this.$notify({
title: '警告',
message: '信息不合法',
type: 'warning',
duration: 2000
})
}
})
},
doClose() {
this.resetForm()
},
resetForm() {
this.$refs['form'].resetFields()
this.form = {
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
originalCode: '',
</#if>
${column.changeColumnName}: ''<#if column_has_next>,</#if>
</#list>
</#if>
}
}
}
}
</script>
<style scoped>
</style>
<#--noinspection ALL-->
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<#if hasQuery>
<!-- 搜索 -->
<el-select v-model="query.type" clearable placeholder="聚合筛选条件" class="filter-item" style="width: 130px">
<el-option v-for="item in queryTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
</el-select>
<el-input v-model="query.value" clearable placeholder="输入搜索内容" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
</#if>
<!-- 新增 -->
<div style="display: inline-block;margin: 0 2px;">
<el-button
v-permission="['admin','${changeClassName}:add']"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-plus"
@click="add">新增</el-button>
</div>
</div>
<!--表单组件-->
<eForm ref="form" :is-add="isAdd" :dict-map="dictMap"/>
<!--表格渲染-->
<el-table v-loading="loading" :data="data" size="small" style="width: 100%;" @row-dblclick="edit">
<#if columns??>
<#list columns as column>
<#if column.columnShow = 'true'>
<#if column.columnType != 'Timestamp'>
<el-table-column prop="${column.changeColumnName}" label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>" <#if column.columnName = 'id' || column.columnName = 'name' || column.columnName = 'code'>sortable </#if>/>
<#else>
<el-table-column prop="${column.changeColumnName}" label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.${column.changeColumnName}) }}</span>
</template>
</el-table-column>
</#if>
</#if>
</#list>
</#if>
<el-table-column label="操作" width="120px" fixed="right" align="center">
<template slot-scope="scope">
<el-button v-permission="['admin','${changeClassName}:edit']" size="mini" type="primary" icon="el-icon-edit" @click="edit(scope.row)"/>
<el-popover
v-permission="['admin','${changeClassName}:del']"
:ref="scope.row.${pkChangeColName}"
placement="top"
width="180">
<p>确定删除本条数据吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="$refs[scope.row.${pkChangeColName}].doClose()">取消</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="subDelete(scope.row.${pkChangeColName})">确定</el-button>
</div>
<el-button slot="reference" type="danger" icon="el-icon-delete" size="mini"/>
</el-popover>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<el-pagination
:total="total"
:current-page="page + 1"
style="margin-top: 8px;"
layout="total, prev, pager, next, sizes"
@size-change="sizeChange"
@current-change="pageChange"/>
</div>
</template>
<script>
import initData from '@/mixins/initData'
import initDict from '@/mixins/initDict'
import { getAttrByValueFromDict } from '@/utils/common-util'
import { del, download${className} } from '@/api/${changeClassName}'
<#if hasTimestamp>
import { parseTime, downloadFile } from '@/utils/index'
</#if>
import eForm from './form'
export default {
components: { eForm },
mixins: [initData, initDict],
data() {
return {
delLoading: false<#if hasQuery>,</#if>
<#if hasQuery>
queryTypeOptions: [
<#if queryColumns??>
<#list queryColumns as column>
{ key: '${column.changeColumnName}', display_name: '<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>' }<#if column_has_next>,</#if>
</#list>
</#if>
]
</#if>
}
},
created() {
this.$nextTick(() => {
this.init()
this.getDictMap('')
})
},
methods: {
<#if hasTimestamp>
parseTime,
</#if>
getAttrByValueFromDict,
beforeInit() {
this.url = 'api/${changeClassName}'
const sort = '${pkChangeColName},desc'
this.params = { page: this.page, size: this.size, sort: sort }
<#if hasQuery>
const query = this.query
const type = query.type
const value = query.value
if (type && value) { this.params[type] = value }
</#if>
return true
},
subDelete(${pkChangeColName}) {
this.delLoading = true
del(${pkChangeColName}).then(res => {
this.delLoading = false
this.$refs[${pkChangeColName}].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
this.$refs[${pkChangeColName}].doClose()
console.log(err.response.data.message)
})
},
add() {
this.isAdd = true
this.$refs.form.dialog = true
},
edit(data) {
this.isAdd = false
const _this = this.$refs.form
_this.form = {
<#if columns??>
<#list columns as column>
<#if column.columnName == 'code'>
originalCode: data.code,
</#if>
${column.changeColumnName}: data.${column.changeColumnName}<#if column_has_next>,</#if>
</#list>
</#if>
}
_this.dialog = true
},
// 导出
download() {
this.beforeInit()
this.downloadLoading = true
download${className}(this.params).then(result => {
downloadFile(result, '${className}列表', 'xlsx')
this.downloadLoading = false
}).catch(() => {
this.downloadLoading = false
})
}
}
}
</script>
<style scoped>
</style>
package com.topdraw;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes= MemberServiceApplication.class)
@RunWith(SpringRunner.class)
public class BaseTest {
public Logger LOG = LoggerFactory.getLogger(BaseTest.class);
}
package com.topdraw.code;
import com.topdraw.BaseTest;
import com.topdraw.domain.GenConfig;
import com.topdraw.domain.vo.ColumnInfo;
import com.topdraw.MemberServiceApplication;
import com.topdraw.service.GeneratorService;
import lombok.var;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author Hongyan Wang
* @packageName PACKAGE_NAME
* @className GeneratorCode
* @description
* @date 2020/12/30 0:11
*/
public class GeneratorCode extends BaseTest {
@Autowired
private GeneratorService generatorService;
// @Autowired
// private WeixinInfoConfig weixinInfoConfig;
@Test
@Rollback(value = false)
@Transactional(rollbackFor = Exception.class)
public void generator() {
var dbName = "uc_tr_task_progress";
// 表名称,支持多表
var tableNames = Arrays.asList(dbName);
String[] s = dbName.split("_");
var pre = s[0];
var target1 = s[s.length-1];
var preRoute = "com.topdraw.business.basicdata.task.";
StringBuilder builder = new StringBuilder(preRoute);
builder.append("progress");
// builder.append(target);
tableNames.forEach(tableName -> {
// 生成的表名称
// var tableName = "x_media";
// 拿参数
var columnsMap = (Map<String, Object>) generatorService.getColumns(tableName);
var columnInfos = (List<ColumnInfo>) columnsMap.get("content");
// 只生成后端的话,只需要配置下包名和是否覆盖,
var genConfig = new GenConfig()
// 未设置id无法生成
.setId(1L)
// 根据需求更改包路径
.setPack(builder.toString())
// 前端路径。不生成前端可置空
.setPath("")
// 作者
.setAuthor("XiangHan")
// 表前缀。生成实体时,会移除该前缀
.setPrefix(pre)
// 若文件存在,是否进行覆盖
.setCover(true);
// 生成代码
generatorService.generator(columnInfos, genConfig, tableName);
});
}
}
package com.topdraw.test.business.basicdata.member;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class MemberServiceTest extends BaseTest {
@Autowired
private MemberService memberService;
@Test
public void findById(){
Long memberId = 1L;
MemberDTO memberDTO = this.memberService.findById(memberId);
LOG.info("=====>>>" + memberDTO);
}
}
package com.topdraw.test.business.basicdata.member.profile;
import com.alibaba.fastjson.JSON;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.member.profile.domain.MemberProfile;
import com.topdraw.business.basicdata.member.profile.service.MemberProfileService;
import com.topdraw.business.basicdata.member.service.MemberService;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class MemberProfileServiceTest extends BaseTest {
@Autowired
private MemberProfileService memberProfileService;
@Test
public void create(){
Long memberId = 1L;
MemberProfile resources = new MemberProfile();
resources.setMemberId(memberId);
resources.setIdCard("422827199208010713");
resources.setBirthday(TimestampUtil.now());
resources.setGender(1);
resources.setDescription("");
resources.setRealname("");
resources.setConstellation("");
resources.setProvince("");
resources.setCity("");
resources.setEmail("");
resources.setDistrict("");
String s = JSON.toJSONString(resources);
this.memberProfileService.create(resources);
LOG.info("=====>>>"+s);
}
@Test
public void update(){
Long memberId = 1L;
MemberProfile resources = new MemberProfile();
resources.setId(1L);
resources.setMemberId(memberId);
resources.setCity("sh");
String s = JSON.toJSONString(resources);
this.memberProfileService.update(resources);
LOG.info("=====>>>s=====>>>" + s);
}
@Test
public void delete(){
Long memberId = 1L;
this.memberProfileService.delete(memberId);
LOG.info("=====>>>s=====>>>");
}
}
package com.topdraw.test.business.basicdata.member.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.basicdata.member.address.domain.MemberAddress;
import com.topdraw.business.basicdata.member.address.rest.MemberAddressController;
import com.topdraw.business.basicdata.member.address.service.dto.MemberAddressQueryCriteria;
import com.topdraw.common.ResultInfo;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public class MemberAddressControllerTest extends BaseTest {
@Autowired
MemberAddressController memberAddressController;
@Test
public void pageMemberAddress(){
MemberAddressQueryCriteria memberQueryCriteria = new MemberAddressQueryCriteria();
memberQueryCriteria.setMemberId(1L);
Pageable pageable = PageRequest.of(0,20);
ResultInfo byId = this.memberAddressController.pageMemberAddress(memberQueryCriteria,pageable);
LOG.info("===>>>"+byId);
}
@Test
public void update(){
MemberAddress memberAddress = new MemberAddress();
memberAddress.setId(1L);
memberAddress.setMemberId(1L);
memberAddress.setType(1);
memberAddress.setIsDefault(1);
memberAddress.setSequence(1);
memberAddress.setStatus(1);
memberAddress.setContactor("");
memberAddress.setCellphone("1");
memberAddress.setCountry("");
memberAddress.setProvince("final String province");
memberAddress.setCity("");
memberAddress.setDistrict("");
memberAddress.setAddress("");
memberAddress.setZipCode("");
String s = JSON.toJSONString(memberAddress);
ResultInfo byId = this.memberAddressController.update(memberAddress);
LOG.info("===>>>"+byId);
}
@Test
public void create(){
MemberAddress memberAddress = new MemberAddress();
// memberAddress.setId(1L);
memberAddress.setMemberId(1L);
memberAddress.setType(1);
memberAddress.setIsDefault(1);
memberAddress.setSequence(1);
memberAddress.setStatus(1);
memberAddress.setContactor("");
memberAddress.setCellphone("1");
memberAddress.setCountry("");
memberAddress.setProvince("final String province");
memberAddress.setCity("");
memberAddress.setDistrict("");
memberAddress.setAddress("");
memberAddress.setZipCode("");
String s = JSON.toJSONString(memberAddress);
ResultInfo byId = this.memberAddressController.create(memberAddress);
LOG.info("===>>>"+byId);
}
@Test
public void findById(){
ResultInfo byId = this.memberAddressController.findById(1L);
LOG.info("===>>>"+byId);
}
@Test
public void delete(){
ResultInfo byId = this.memberAddressController.delete(1L);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.basicdata.member.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.rest.MemberController;
import com.topdraw.business.basicdata.member.service.dto.MemberQueryCriteria;
import com.topdraw.common.ResultInfo;
import com.topdraw.BaseTest;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public class MemberControllerTest extends BaseTest {
@Autowired
MemberController memberController;
@Test
public void update(){
Member member = new Member();
member.setId(5L);
member.setType(1);
member.setStatus(1);
member.setNickname("五号员工");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(10L);
member.setPoints(5L);
member.setDuePoints(0L);
member.setCouponAmount(1L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
String s = JSON.toJSONString(member);
ResultInfo byId = this.memberController.update(member);
LOG.info("===>>>"+byId);
}
@Test
public void create(){
Member member = new Member();
member.setCode(String.valueOf(IdWorker.generator()));
member.setType(1);
member.setStatus(1);
member.setNickname("nickname");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(10L);
member.setPoints(5L);
member.setDuePoints(0L);
member.setCouponAmount(1L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
member.setUpdateTime(TimestampUtil.now());
String s = JSON.toJSONString(member);
ResultInfo byId = this.memberController.create(member);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.basicdata.member.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.basicdata.member.relatedinfo.domain.MemberRelatedInfo;
import com.topdraw.business.basicdata.member.relatedinfo.rest.MemberRelatedInfoController;
import com.topdraw.business.basicdata.member.relatedinfo.service.dto.MemberRelatedInfoQueryCriteria;
import com.topdraw.common.ResultInfo;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
//public class MemberControllerTest {
public class MemberRelatedInfoControllerTest extends BaseTest {
@Autowired
MemberRelatedInfoController memberRelatedInfoController;
@Test
public void getMembers(){
MemberRelatedInfoQueryCriteria memberQueryCriteria = new MemberRelatedInfoQueryCriteria();
Pageable pageable = PageRequest.of(0,20);
ResultInfo byId = this.memberRelatedInfoController.pageMemberRelatedInfos(memberQueryCriteria,pageable);
LOG.info("===>>>"+byId);
}
@Test
public void update(){
MemberRelatedInfo member = new MemberRelatedInfo();
member.setId(1L);
// member.setMemberId(2L);
member.setType(1);
member.setCellphone("18271269120");
member.setIdCard("422827199208010713");
member.setName("fdfd");
member.setSex(1);
// member.setCreateTime();
// member.setUpdateTime();
String s = JSON.toJSONString(member);
ResultInfo byId = this.memberRelatedInfoController.update(member);
LOG.info("===>>>"+byId);
}
@Test
public void create(){
MemberRelatedInfo member = new MemberRelatedInfo();
// member.setId(final Long id);
member.setMemberId(2L);
member.setType(1);
member.setCellphone("18271269120");
member.setIdCard("422827199208010713");
member.setName("fdfd");
member.setSex(1);
// member.setCreateTime();
// member.setUpdateTime();
String s = JSON.toJSONString(member);
ResultInfo byId = this.memberRelatedInfoController.create(member);
LOG.info("===>>>"+byId);
}
@Test
public void findById(){
ResultInfo byId = this.memberRelatedInfoController.findById(1L);
LOG.info("===>>>"+byId);
}
@Test
public void delete(){
ResultInfo byId = this.memberRelatedInfoController.delete(1L);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.basicdata.points;
import com.topdraw.business.basicdata.points.available.domain.PointsAvailable;
import com.topdraw.business.basicdata.points.available.service.PointsAvailableService;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableDTO;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.BaseTest;
import com.topdraw.util.DateUtil;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class PointsAvailableServiceTest extends BaseTest {
@Autowired
private PointsAvailableService pointsAvailableService;
@Test
public void loadListExpirePointsByMemberId() {
Long memberId = 2L;
List<PointsAvailableDTO> pointsAvailableDTOS =
this.pointsAvailableService.findByMemberIdAndExpireTimeBefore(memberId, DateUtil.newDate());
LOG.info("===>>>"+pointsAvailableDTOS);
}
@Test
public void findSoonExpireTime(){
Long memberId = 2L;
Long soonExpireTime = this.pointsAvailableService.findSoonExpireTime(memberId, 30);
LOG.info("=====>>>"+soonExpireTime);
}
@Test
public void create(){
Long memberId = 2L;
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(memberId);
tempPoints.setPointsType(0);
tempPoints.setRightsSendStrategy(1);
tempPoints.setActivityId(0L);
tempPoints.setOrderId(0L);
tempPoints.setDeviceType(2);
tempPoints.setMediaId(0L);
tempPoints.setAccountId(1L);
tempPoints.setAppCode("OMO");
// tempPoints.setDescription("#");
tempPoints.setEvtType(1);
tempPoints.setPoints(10L);
tempPoints.setExpireTime(TimestampUtil.now());
PointsAvailable pointsAvailable = new PointsAvailable();
BeanUtils.copyProperties(tempPoints,pointsAvailable);
pointsAvailable.setMemberId(memberId);
pointsAvailable.setCode(String.valueOf(IdWorker.generator()));
this.pointsAvailableService.create(pointsAvailable);
LOG.info("=====>>>");
}
}
package com.topdraw.test.business.basicdata.points;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.BaseTest;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
public class PointsDetailServiceTest extends BaseTest {
@Autowired
private PointsDetailService pointsDetailService;
@Autowired
MemberOperationService memberOperationService;
@Test
public void create(){
Long memberId = 2L;
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(memberId);
tempPoints.setPointsType(0);
tempPoints.setRightsSendStrategy(1);
tempPoints.setActivityId(0L);
tempPoints.setOrderId(0L);
tempPoints.setDeviceType(2);
tempPoints.setMediaId(0L);
tempPoints.setAccountId(1L);
tempPoints.setAppCode("OMO");
tempPoints.setDescription("");
tempPoints.setEvtType(1);
tempPoints.setPoints(10L);
tempPoints.setExpireTime(TimestampUtil.now());
MemberDTO memberDTO = this.memberOperationService.findById(memberId);
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(tempPoints,pointsDetail);
// 获取的积分
long rewardPoints = tempPoints.getPoints();
// 原始积分
long originalPoints = memberDTO.getPoints();
pointsDetail.setMemberId(memberId);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setOriginalPoints(originalPoints);
pointsDetail.setResultPoints(originalPoints+rewardPoints);
this.pointsDetailService.create(pointsDetail);
LOG.info("=====>>>");
}
}
package com.topdraw.test.business.basicdata.rights;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.points.detail.domain.PointsDetail;
import com.topdraw.business.basicdata.points.detail.service.PointsDetailService;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
public class RightsServiceTest extends BaseTest {
@Autowired
private PointsDetailService pointsDetailService;
@Autowired
MemberOperationService memberOperationService;
@Test
public void create(){
Long memberId = 2L;
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(memberId);
tempPoints.setPointsType(0);
tempPoints.setRightsSendStrategy(1);
tempPoints.setActivityId(0L);
tempPoints.setOrderId(0L);
tempPoints.setDeviceType(2);
tempPoints.setMediaId(0L);
tempPoints.setAccountId(1L);
tempPoints.setAppCode("OMO");
tempPoints.setDescription("");
tempPoints.setEvtType(1);
tempPoints.setPoints(10L);
tempPoints.setExpireTime(TimestampUtil.now());
MemberDTO memberDTO = this.memberOperationService.findById(memberId);
PointsDetail pointsDetail = new PointsDetail();
BeanUtils.copyProperties(tempPoints,pointsDetail);
// 获取的积分
long rewardPoints = tempPoints.getPoints();
// 原始积分
long originalPoints = memberDTO.getPoints();
pointsDetail.setMemberId(memberId);
pointsDetail.setCode(String.valueOf(IdWorker.generator()));
pointsDetail.setOriginalPoints(originalPoints);
pointsDetail.setResultPoints(originalPoints+rewardPoints);
this.pointsDetailService.create(pointsDetail);
LOG.info("=====>>>");
}
}
package com.topdraw.test.business.basicdata.rights.history;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.member.service.dto.MemberQueryCriteria;
import com.topdraw.business.basicdata.rights.history.rest.RightsHistoryController;
import com.topdraw.business.basicdata.rights.history.service.dto.RightsHistoryQueryCriteria;
import com.topdraw.business.basicdata.rights.rest.RightsController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public class RightsHistoryControllerTest extends BaseTest {
@Autowired
RightsHistoryController rightsHistoryController;
@Test
public void pageRightsHistory(){
RightsHistoryQueryCriteria memberQueryCriteria = new RightsHistoryQueryCriteria();
memberQueryCriteria.setMemberId(1L);
Pageable pageable = PageRequest.of(0,20);
ResultInfo byId = this.rightsHistoryController.pageRightsHistory(memberQueryCriteria,pageable);
LOG.info("===>>>"+byId);
}
@Test
public void pageAvailableRights(){
RightsHistoryQueryCriteria memberQueryCriteria = new RightsHistoryQueryCriteria();
memberQueryCriteria.setMemberId(1L);
Pageable pageable = PageRequest.of(0,20);
ResultInfo byId = this.rightsHistoryController.pageAvailableRights(memberQueryCriteria,pageable);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.basicdata.rights.permanentrights;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.rights.permanentrights.rest.PermanentRightsController;
import com.topdraw.business.basicdata.rights.permanentrights.service.dto.PermanentRightsQueryCriteria;
import com.topdraw.business.basicdata.rights.rest.RightsController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public class PermanentRightsControllerTest extends BaseTest {
@Autowired
PermanentRightsController permanentRightsController;
@Test
public void pagePermanentRights(){
PermanentRightsQueryCriteria criteria = new PermanentRightsQueryCriteria();
criteria.setLevel(2);
Pageable pageable = PageRequest.of(0,20);
ResultInfo byId = this.permanentRightsController.pagePermanentRights(criteria,pageable);
LOG.info("===>>>"+byId);
}
@Test
public void findById(){
ResultInfo byId = this.permanentRightsController.findById(1L);
LOG.info("===>>>"+byId);
}
/*@Test
public void create(){
ResultInfo byId = this.permanentRightsController.create(1L);
LOG.info("===>>>"+byId);
}
@Test
public void update(){
ResultInfo byId = this.permanentRightsController.update(1L);
LOG.info("===>>>"+byId);
}
@Test
public void delete(){
ResultInfo byId = this.permanentRightsController.delete(1L);
LOG.info("===>>>"+byId);
}*/
}
package com.topdraw.test.business.basicdata.rights.rest;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.rights.rest.RightsController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class RightsControllerTest extends BaseTest {
@Autowired
RightsController rightsController;
@Test
public void findById(){
ResultInfo byId = this.rightsController.findById(1L);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.basicdata.task;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.basicdata.member.service.dto.MemberDTO;
import com.topdraw.business.basicdata.task.domain.Task;
import com.topdraw.business.basicdata.task.service.TaskService;
import com.topdraw.BaseTest;
import com.topdraw.business.process.service.impl.CompareTaskCondition;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.assertj.core.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
//public class TaskServiceTest extends BaseTest {
public class TaskServiceTest {
@Test
public void dealTaskTest(){
// List<Task> taskList = this.taskService.findByTemplateId(1L);
// LOG.info("=====>>>" + taskList);
Task task = new Task();
task.setTaskTemplateId(1L);
task.setTaskDailyReset(1);
task.setActionAmount(1);
task.setValidTime(TimestampUtil.now());
task.setExpireTime(TimestampUtil.now());
task.setSequence(1);
task.setRewardExp(10L);
task.setRewardPoints(1L);
task.setRewardPointsExpireTime(TimestampUtil.Timestamp2long(TimestampUtil.now()));
task.setPointsType(1);
task.setRewardMaxPoints(1);
task.setGroups("groups");
task.setRightsSendStrategy(1);
task.setMemberLevel(1);
task.setMemberVip(1);
task.setRightsId(1L);
task.setRightsAmount(1);
task.setRights2Id(2L);
task.setRights2Amount(1);
task.setRights3Id(3L);
task.setRights3Amount(1);
task.setStatus(1);
List<Task> taskList = new ArrayList<>();
taskList.add(task);
MemberDTO member = new MemberDTO();
member.setCode(String.valueOf(IdWorker.generator()));
member.setType(1);
member.setStatus(1);
member.setNickname("nickname");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(10L);
member.setPoints(5L);
member.setDuePoints(0L);
member.setCouponAmount(1L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
member.setUpdateTime(TimestampUtil.now());
// 判断是否完成任务
CompareTaskCondition compareTaskCondition =(MemberDTO memberDTO1, List<Task> taskList1) -> {
List<Task> taskStream = taskList1.stream().filter(task1 ->
task1.getStatus() == 1 &&
(Objects.isNull(task1.getExpireTime()) || task1.getExpireTime().compareTo(TimestampUtil.now()) <= 0) &&
(Objects.isNull(task1.getGroups()) || task1.getGroups().equalsIgnoreCase(memberDTO1.getGroups())) &&
(Objects.isNull(task1.getValidTime()) || task1.getValidTime().compareTo(TimestampUtil.now()) <= 0) &&
(task1.getMemberLevel() == 0 || task1.getMemberLevel() <= memberDTO1.getLevel()) &&
(task1.getMemberVip() == 0 || task1.getMemberVip() == memberDTO1.getVip())
).collect(Collectors.toList());
if (CollectionUtils.isEmpty(taskStream)) {
return false;
}
return true;
};
boolean b = compareTaskCondition.compareCondition(member, taskList);
System.out.println(b);
}
}
package com.topdraw.test.business.basicdata.task;
import com.topdraw.business.basicdata.task.template.domain.TaskTemplate;
import com.topdraw.business.basicdata.task.template.service.TaskTemplateService;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class TaskTemplateServiceTest extends BaseTest {
@Autowired
TaskTemplateService taskTemplateService;
@Test
public void dealTaskTest(){
String eventCode = "tv";
TaskTemplate taskTemplate = this.taskTemplateService.findByEvent(eventCode);
LOG.info("=====>>>" + taskTemplate);
}
}
package com.topdraw.test.business.process.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.BaseTest;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.rest.CouponOperationController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
public class CouponOperationControllerTest extends BaseTest {
@Autowired
CouponOperationController couponOperationController;
@Test
public void grantCouponByManual(){
Long memberId = 2L;
Long userId = 2L;
TempCoupon tempCoupon = new TempCoupon();
tempCoupon.setId(1L);
tempCoupon.setRightsAmount(1);
tempCoupon.setCode("233");
tempCoupon.setUseStatus(1);
tempCoupon.setUserNickname("");
tempCoupon.setMemberId(2L);
tempCoupon.setRightsSendStrategy(0);
tempCoupon.setAccountId(2L);
tempCoupon.setExpireTime(Timestamp.valueOf("2021-10-28 09:00:00"));
tempCoupon.setDeviceType(2);
tempCoupon.setAppCode("WEI_XIN_GOLD_PANDA");
tempCoupon.setOrderId(null);
tempCoupon.setMediaId(null);
tempCoupon.setActivityId(null);
tempCoupon.setItemId(null);
tempCoupon.setDescription("#");
tempCoupon.setEvtType(1);
List<TempCoupon> tempCouponList = new ArrayList<>();
tempCouponList.add(tempCoupon);
String s = JSON.toJSONString(tempCouponList);
// tempCouponList.add(tempCoupon1);
ResultInfo byId = this.couponOperationController.grantCouponByManual(memberId,userId,tempCouponList);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.process.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.BaseTest;
import com.topdraw.business.process.domian.TempCoupon;
import com.topdraw.business.process.domian.TempExp;
import com.topdraw.business.process.rest.CouponOperationController;
import com.topdraw.business.process.rest.ExpOperationController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
public class ExpOperationControllerTest extends BaseTest {
@Autowired
ExpOperationController expOperationController;
@Test
public void grantExpByManual(){
Long memberId = 2L;
Long userId = 2L;
TempExp tempExp = new TempExp();
tempExp.setMemberId(memberId);
tempExp.setRewardExp(10L);
tempExp.setMemberId(2L);
tempExp.setRightsSendStrategy(0);
tempExp.setAccountId(userId);
tempExp.setExpireTime(Timestamp.valueOf("2021-10-28 09:00:00"));
tempExp.setDeviceType(2);
tempExp.setAppCode("WEI_XIN_GOLD_PANDA");
tempExp.setOrderId(null);
tempExp.setMediaId(null);
tempExp.setActivityId(null);
tempExp.setItemId(null);
tempExp.setDescription("#");
tempExp.setEvtType(1);
String s = JSON.toJSONString(tempExp);
// tempCouponList.add(tempCoupon1);
ResultInfo byId = this.expOperationController.grantExpByManual(tempExp);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.process.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryCriteria;
import com.topdraw.business.basicdata.points.available.service.dto.PointsAvailableQueryType;
import com.topdraw.business.basicdata.points.detail.rest.PointsDetailController;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.points.detail.service.dto.PointsDetailQueryCriteria;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.business.process.rest.PointsOperationController;
import com.topdraw.common.ResultInfo;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import java.sql.Timestamp;
public class PointsOperationControllerTest extends BaseTest {
@Autowired
PointsOperationController pointsOperationController;
@Test
public void customPoints() {
Long memberId = 2L;
/*DataSyncMsg dataSyncMsg = new DataSyncMsg();
dataSyncMsg.setEntityType(EntityType.MEMBER);
dataSyncMsg.setEventType(EventType.VIEWING);
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setRemarks("remark");
msgData.setMemberId(memberId);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsgData(msgData);*/
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(memberId);
tempPoints.setPoints(1L);
tempPoints.setEvtType(1);
tempPoints.setAppCode("PADON");
tempPoints.setPointsType(0);
tempPoints.setMediaId(1L);
tempPoints.setDeviceType(1);
String s = JSON.toJSONString(tempPoints);
this.pointsOperationController.customPoints(tempPoints);
}
@Test
public void grantPointsByManual(){
TempPoints tempPoints = new TempPoints();
tempPoints.setPoints(10L);
tempPoints.setPointsType(0);
tempPoints.setMemberId(2L);
tempPoints.setRightsSendStrategy(0);
tempPoints.setAccountId(2L);
tempPoints.setExpireTime(Timestamp.valueOf("2021-10-27 09:00:00"));
tempPoints.setDeviceType(2);
tempPoints.setAppCode("WEI_XIN_GOLD_PANDA");
tempPoints.setOrderId(null);
tempPoints.setMediaId(null);
tempPoints.setActivityId(null);
tempPoints.setItemId(null);
tempPoints.setDescription("#");
tempPoints.setEvtType(1);
String s = JSON.toJSONString(tempPoints);
ResultInfo byId = this.pointsOperationController.grantPointsByManual(tempPoints);
LOG.info("===>>>"+byId);
}
/*@Test
public void update(){
MemberAddress memberAddress = new MemberAddress();
memberAddress.setId(1L);
memberAddress.setMemberId(1L);
memberAddress.setType(1);
memberAddress.setIsDefault(1);
memberAddress.setSequence(1);
memberAddress.setStatus(1);
memberAddress.setContactor("");
memberAddress.setCellphone("1");
memberAddress.setCountry("");
memberAddress.setProvince("final String province");
memberAddress.setCity("");
memberAddress.setDistrict("");
memberAddress.setAddress("");
memberAddress.setZipCode("");
String s = JSON.toJSONString(memberAddress);
ResultInfo byId = this.memberAddressController.update(memberAddress);
LOG.info("===>>>"+byId);
}
@Test
public void create(){
PointsDetail memberAddress = new PointsDetail();
String s = JSON.toJSONString(memberAddress);
ResultInfo byId = this.pointsDetailController.create(memberAddress);
LOG.info("===>>>"+byId);
}
@Test
public void findById(){
ResultInfo byId = this.memberAddressController.findById(1L);
LOG.info("===>>>"+byId);
}
@Test
public void delete(){
ResultInfo byId = this.memberAddressController.delete(1L);
LOG.info("===>>>"+byId);
}*/
}
package com.topdraw.test.business.process.rest;
import com.topdraw.BaseTest;
import com.topdraw.business.basicdata.rights.history.domain.RightsHistory;
import com.topdraw.business.process.rest.RightsOperationController;
import com.topdraw.common.ResultInfo;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class RightOperationControllerTest extends BaseTest {
@Autowired
RightsOperationController rightsOperationController;
@Test
public void grantRightsByManual(){
RightsHistory rightsHistory = new RightsHistory();
rightsHistory.setRightsId(1L);
rightsHistory.setMemberId(5L);
rightsHistory.setOperatorId(3L);
rightsHistory.setOperatorName("鲁二龙");
rightsHistory.setExpireTime(TimestampUtil.now());
rightsHistory.setUserId(2L);
ResultInfo byId = this.rightsOperationController.grantRightsByManual(rightsHistory);
LOG.info("===>>>"+byId);
}
}
package com.topdraw.test.business.process.rest;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.basicdata.points.service.dto.PointsQueryCriteria;
import com.topdraw.business.process.rest.TaskOperationController;
import com.topdraw.business.process.rest.TaskOperationQueryCriteria;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EntityType;
import com.topdraw.module.mq.EventType;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class TaskOperationControllerTest extends BaseTest {
@Autowired
TaskOperationController taskOperationController;
@Test
public void dealTask() {
try {
DataSyncMsg dataSyncMsg = new DataSyncMsg();
dataSyncMsg.setEventType(EventType.LOGIN.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setRemarks("remark");
msgData.setMemberId(1L);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsg(msgData);
String s = JSON.toJSONString(dataSyncMsg);
TaskOperationQueryCriteria pointsQueryCriteria = new TaskOperationQueryCriteria();
pointsQueryCriteria.setContent(s);
this.taskOperationController.dealTask(pointsQueryCriteria);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.topdraw.test.business.process.service;
import com.topdraw.business.basicdata.member.domain.Member;
import com.topdraw.business.process.service.MemberOperationService;
import com.topdraw.BaseTest;
import com.topdraw.util.IdWorker;
import com.topdraw.util.TimestampUtil;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class MemberOperationServiceTest extends BaseTest {
@Autowired
MemberOperationService memberOperationService;
@Test
public void findById() {
Long memberId = 2L;
this.memberOperationService.findById(memberId);
}
@Test
public void doUpdateMemberInfo() {
Member member = new Member();
member.setId(2L);
member.setCode(String.valueOf(IdWorker.generator()));
member.setType(1);
member.setStatus(1);
member.setNickname("nickname");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(10L);
member.setPoints(5L);
member.setDuePoints(0L);
member.setCouponAmount(1L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
member.setUpdateTime(TimestampUtil.now());
this.memberOperationService.doUpdateMemberInfo(member);
}
@Test
public void doInsertMember() {
Member member = new Member();
member.setCode(String.valueOf(IdWorker.generator()));
member.setType(1);
member.setStatus(1);
member.setNickname("nickname");
member.setDescription("description");
member.setGender(1);
member.setBirthday("birthday");
member.setAvatarUrl("avatarUrl");
member.setGroups("groups");
member.setTags("tags");
member.setVip(1);
member.setLevel(1);
member.setExp(0L);
member.setPoints(0L);
member.setDuePoints(0L);
member.setCouponAmount(0L);
member.setDueCouponAmount(0L);
member.setUserIptvId(1L);
member.setBindIptvPlatformType(0);
member.setBindIptvTime(TimestampUtil.now());
member.setCreateTime(TimestampUtil.now());
member.setUpdateTime(TimestampUtil.now());
// member.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
this.memberOperationService.doInsertMember(member);
}
}
package com.topdraw.test.business.process.service;
import com.alibaba.fastjson.JSON;
import com.topdraw.BaseTest;
import com.topdraw.business.process.domian.TempPoints;
import com.topdraw.business.process.service.PointsOperationService;
import com.topdraw.business.process.service.TaskOperationService;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EntityType;
import com.topdraw.module.mq.EventType;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class PointsOperationServiceTest extends BaseTest {
@Autowired
PointsOperationService pointsOperationService;
@Test
public void customPoints() {
Long memberId = 2L;
/*DataSyncMsg dataSyncMsg = new DataSyncMsg();
dataSyncMsg.setEntityType(EntityType.MEMBER);
dataSyncMsg.setEventType(EventType.VIEWING);
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setRemarks("remark");
msgData.setMemberId(memberId);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsgData(msgData);*/
TempPoints tempPoints = new TempPoints();
tempPoints.setMemberId(memberId);
tempPoints.setPoints(1L);
tempPoints.setEvtType(1);
tempPoints.setAppCode("PADON");
tempPoints.setPointsType(0);
tempPoints.setMediaId(1L);
tempPoints.setDeviceType(1);
String s = JSON.toJSONString(tempPoints);
this.pointsOperationService.customPoints(tempPoints);
}
@Test
public void cleanInvalidAvailablePoints() {
this.pointsOperationService.cleanInvalidAvailablePoints();
}
}
package com.topdraw.test.business.process.service;
import com.alibaba.fastjson.JSON;
import com.topdraw.business.process.service.TaskOperationService;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EntityType;
import com.topdraw.module.mq.EventType;
import com.topdraw.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class TaskOperationServiceTest extends BaseTest {
@Autowired
TaskOperationService taskOperationService;
@Test
public void dealTaskTest() {
Long memberId = 2L;
DataSyncMsg dataSyncMsg = new DataSyncMsg();
// dataSyncMsg.setEntityType(EntityType.MEMBER);
dataSyncMsg.setEventType(EventType.LOGIN.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setRemarks("remark");
msgData.setMemberId(memberId);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsg(msgData);
String s = JSON.toJSONString(dataSyncMsg);
this.taskOperationService.dealTask(s);
}
}
package com.topdraw.test.mq;
import com.alibaba.fastjson.JSON;
import com.topdraw.BaseTest;
import com.topdraw.module.mq.DataSyncMsg;
import com.topdraw.module.mq.EventType;
import com.topdraw.mq.config.RabbitMqConfig;
import com.topdraw.mq.producer.MessageProducer;
import org.junit.Test;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
public class MqTest extends BaseTest {
@Autowired
MessageProducer messageProducer;
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void test(){
DataSyncMsg dataSyncMsg = new DataSyncMsg();
dataSyncMsg.setEventType(EventType.LOGIN.name());
DataSyncMsg.MsgData msgData = new DataSyncMsg.MsgData();
msgData.setEvent(1);
msgData.setRemarks("remark");
msgData.setMemberId(1L);
msgData.setDeviceType(2);
msgData.setAppCode("WEI_XIN_GOLD_PANDA");
dataSyncMsg.setMsg(msgData);
String s = JSON.toJSONString(dataSyncMsg);
amqpTemplate.convertAndSend( "uc.route.key.direct.event.aaa", s);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>member-service-api</module>
<module>member-service-impl</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.topdraw</groupId>
<artifactId>member-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
\ No newline at end of file