328 Commits
v4.1 ... v4.2.1

Author SHA1 Message Date
lifenlong
eda1e841bb Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-18 18:32:22 +08:00
pikachu
9de55088ea 新增站内消息通知模版 2021-07-18 17:12:27 +08:00
lifenlong
d4642d85dd Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-18 13:43:34 +08:00
Chopper
a9c79eedd4 代码结构优化,缩减。一个多次判定问题处理 2021-07-16 10:40:44 +08:00
Chopper
ac5d04ddc2 调整代码结构 2021-07-16 09:55:38 +08:00
Chopper
caacb9e201 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-07-15 14:17:58 +08:00
Chopper
844bff971f 无效代码去除 2021-07-15 14:17:53 +08:00
pikachu
9ee5b4515a 修改积分参数命名规范 2021-07-13 19:55:42 +08:00
pikachu
2246b498d9 解决如果是扣减积分 积分变化错误 2021-07-13 19:43:49 +08:00
pikachu
93e4998b87 修改积分类型字段类型 2021-07-13 18:48:22 +08:00
Chopper
a360fd2eda maven规范补充 2021-07-13 10:39:27 +08:00
lifenlong
e0ca366431 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-13 10:28:48 +08:00
lifenlong
3d3be0b283 查看店铺经营范围 2021-07-13 10:28:04 +08:00
Chopper
86f010b87e maven 规范 2021-07-12 16:33:32 +08:00
Chopper
d29d166ce0 banner 统一 2021-07-12 14:44:11 +08:00
Chopper
3c78a06008 订单取消时,如未支付,则不需要进行退款处理 2021-07-12 12:41:00 +08:00
Chopper
b6a5630021 获取用户问题处理 2021-07-12 12:30:22 +08:00
Chopper
560ab5f102 调整readme 2021-07-10 14:13:53 +08:00
Chopper
da1b2c3aa8 精简readme 2021-07-10 14:08:56 +08:00
Chopper
7db5690a26 更新readme 2021-07-10 14:01:55 +08:00
Chopper
a1fcadf8b2 修改readme 2021-07-09 18:42:00 +08:00
Chopper
8302ca2e3a Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-07-09 14:46:12 +08:00
Chopper
17b977ef94 对索引生成判定进行处理 2021-07-09 14:46:03 +08:00
lifenlong
512a298cc9 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-09 11:56:19 +08:00
lifenlong
86625e9e9d 增加订单申请售后失效、订单投诉申请失效天数。 2021-07-09 11:55:43 +08:00
Chopper
a599fb9d01 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop
# Conflicts:
#	framework/src/main/java/cn/lili/common/security/context/UserContext.java
#	framework/src/main/java/cn/lili/common/security/context/UserContextInit.java
2021-07-09 11:17:08 +08:00
Chopper
89b057dfca 去除无效代码,规范代码 2021-07-09 11:16:11 +08:00
lifenlong
18d2379a19 采用阿里代码规约,对代码进行优化 2021-07-09 08:42:16 +08:00
lifenlong
3e73257922 采用阿里代码规约,对代码进行优化 2021-07-09 01:56:24 +08:00
lifenlong
9e240f22b6 解决售后单列表的排序问题 2021-07-08 09:59:54 +08:00
lifenlong
6aadd00e45 优惠券按照添加时间进行排序 2021-07-08 09:35:25 +08:00
lifenlong
5fc962b29d Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-07 16:18:04 +08:00
lifenlong
00e93c91f5 优化订单商品类型 2021-07-07 16:17:38 +08:00
Chopper
a903160305 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-07-06 14:53:34 +08:00
Chopper
cd2942a96b mq单向消息报错问题,先做还原处理 2021-07-06 14:53:17 +08:00
lifenlong
6235faba96 优化颠婆分类 2021-07-06 10:43:16 +08:00
lifenlong
6e7254e765 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-07-06 10:12:16 +08:00
lifenlong
e338229902 优化秒杀初始化方法 2021-07-06 10:12:07 +08:00
Chopper
9ff40291ee Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-07-05 16:42:31 +08:00
Chopper
4c8375e861 足迹记录mq时,单向发送,不等待mq响应 2021-07-05 16:41:39 +08:00
lifenlong
acc40dc6fc 店铺配送不展示已经禁用的物流公司 2021-07-05 15:45:57 +08:00
lifenlong
177cd86366 支持添加重复名称的商品分类 2021-07-05 11:14:15 +08:00
Chopper
d06b5ceb89 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-07-05 09:25:10 +08:00
Chopper
6926cd583d 商品索引生成是,对索引值的非空处理 2021-07-05 09:25:03 +08:00
Chopper
de2777e244 商品索引包含sku信息问题处理 2021-07-05 09:22:45 +08:00
lifenlong
c10b698aed 支持文章传图 2021-07-03 13:40:18 +08:00
Chopper
256d9e240e 商品参数返回vo处理 2021-07-02 15:05:08 +08:00
lifenlong
eedea676aa 商品详情展示参数 2021-07-01 17:06:13 +08:00
lifenlong
92c3c21e32 商品删除,删除分销商品 2021-07-01 14:31:33 +08:00
lifenlong
bd13a9b150 Merge branch 'master' into Bulbasaur 2021-07-01 11:19:16 +08:00
lifenlong
931276f72b 添加ResultCode 2021-07-01 11:17:18 +08:00
OceansDeep
e38f9aa2ff !13 fix https://gitee.com/beijing_hongye_huicheng/lilishop/issues/I3YFU4
Merge pull request !13 from OceansDeep/feature/pg
2021-07-01 02:16:42 +00:00
paulGao
696e075fcd Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg 2021-07-01 10:12:40 +08:00
paulGao
d25ba76094 fix https://gitee.com/beijing_hongye_huicheng/lilishop/issues/I3YFU4 2021-07-01 10:12:33 +08:00
lifenlong
cce14b4794 同步 2021-07-01 08:35:18 +08:00
lifenlong
f6706d6394 1.使用hutool进行Object to Int格式转换
2.添加部分resultCode
2021-07-01 08:33:19 +08:00
Chopper
7e3a9eb904 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-30 19:59:42 +08:00
Chopper
079437100d 版本好升级 2021-06-30 19:59:36 +08:00
lifenlong
d7ce709ce6 使用hutool进行格式转换 2021-06-30 16:29:19 +08:00
lifenlong
cff2b95c48 同步 2021-06-30 15:47:33 +08:00
lifenlong
1a77b3cec7 商品数据转换问题 2021-06-30 15:46:52 +08:00
lifenlong
346465630c 添加ResultCode 2021-06-30 15:45:33 +08:00
Chopper
23388eff6b 升级项目版本号 2021-06-30 14:53:26 +08:00
lifenlong
800437473d 1.分销员添加结算银行信息
2.电话校验支持手机号
2021-06-30 12:02:35 +08:00
lifenlong
46f216c191 1.店铺关闭,批量下架店铺商品问题。
2.解决实物/虚拟订单发货逻辑判断问题
2021-06-30 10:26:32 +08:00
lifenlong
a60a535708 修改分销可提现金额 2021-06-30 08:41:04 +08:00
lifenlong
888b5e2558 解决直播间时间不正确问题 2021-06-29 17:01:55 +08:00
lifenlong
1431d990f9 解决直播间时间不正确问题 2021-06-29 16:58:54 +08:00
Chopper
f509b8745d token生成时权限过滤问题处理 2021-06-29 16:43:38 +08:00
Chopper
c1b9f287c7 新增管理员即赋予权限无法生效问题处理。直播间未登录用户报错问题处理 2021-06-29 16:26:52 +08:00
Chopper
3ee3e49d0b 用户在请求直播时没有登录抛出异常问题处理。 2021-06-29 15:40:37 +08:00
Chopper
05904b25c4 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-29 11:56:45 +08:00
Chopper
5e54b2f179 规格值字段新增 2021-06-29 11:56:40 +08:00
lifenlong
e6d045c663 同步 2021-06-29 11:29:05 +08:00
lifenlong
50f96727b3 分销商品VO返回GoodsId 2021-06-29 11:24:53 +08:00
Chopper
39e851ee78 aop积分日志记录兼容问题处理 2021-06-29 11:15:27 +08:00
Chopper
5a415ffc77 条件判定语句顺序调整 2021-06-29 10:25:45 +08:00
Chopper
6a9ba13fc0 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-29 10:13:24 +08:00
Chopper
d96d5edcd5 会员提现api注解问题处理 2021-06-29 10:13:18 +08:00
lifenlong
d35eb293dd Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-29 09:23:37 +08:00
lifenlong
fcfa140a0a 添加注释 2021-06-29 09:23:22 +08:00
chopper711
707c4dbec2 !12 会员消息问题整改
Merge pull request !12 from chopper711/qiuqiu
2021-06-29 01:05:15 +00:00
pikachu
13b1c353b9 Merge branch 'master' into qiuqiu 2021-06-29 08:26:22 +08:00
pikachu
8ed54e061f 会员消息修改 2021-06-29 08:25:54 +08:00
lifenlong
d5fab95707 1.优惠券活动由定时器修改为延时任务执行。
2.修改shopEditDTO,不继承ShopDetail
2021-06-28 18:18:23 +08:00
lifenlong
bbf18b7b0a Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-28 16:09:13 +08:00
lifenlong
fe06555a0b 初始化30天的秒杀活动 2021-06-28 16:09:03 +08:00
Chopper
cf9e6a659a qq联合登录openid问题处理 2021-06-28 15:16:32 +08:00
Chopper
c628c0ebb2 店铺入驻字段缺失问题处理 2021-06-28 14:56:34 +08:00
lifenlong
31479bab19 同步 2021-06-28 11:31:42 +08:00
lifenlong
63802a596b 添加秒杀设置 2021-06-28 11:30:37 +08:00
Chopper
84f6f0e7ee 评价判定问题处理 2021-06-28 11:28:09 +08:00
chopper711
98a2da489d !11 商品参数校验,在线充值回调
Merge pull request !11 from chopper711/qiuqiu
2021-06-28 01:03:41 +00:00
pikachu
5786cb9e55 修改商品参数校验以及充值回调接口 2021-06-26 16:48:06 +08:00
lifenlong
1cbab4a219 店铺评价列表,展示当前店铺数据 2021-06-26 15:24:59 +08:00
lifenlong
873a960d3a 店铺直播列表,展示当前店铺数据 2021-06-26 15:23:00 +08:00
lifenlong
80007a6b86 设定默认商家结算日 2021-06-26 14:44:55 +08:00
lifenlong
467e9887d0 本地校验直播间开始、结束时间 2021-06-26 14:38:27 +08:00
lifenlong
2d5c0d6a1f 删除优惠券,删除优惠券活动关联 2021-06-26 14:07:21 +08:00
lifenlong
d047546374 直播间去重复商品 2021-06-26 11:18:14 +08:00
lifenlong
788e9ca239 添加电话校验 2021-06-26 11:04:20 +08:00
lifenlong
4939e31e71 添加电话校验 2021-06-26 11:02:42 +08:00
pikachu
701ea240ab Merge branch 'master' into qiuqiu 2021-06-26 10:58:57 +08:00
Chopper
b5088415ce Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-25 18:30:03 +08:00
Chopper
df44a7ae30 不能使用余额支付进行充值 2021-06-25 18:29:58 +08:00
lifenlong
4b3c2cbea5 微信小程序接口,调用成功统一处理返回 2021-06-25 17:34:00 +08:00
lifenlong
7dfbb164ae Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-25 16:03:18 +08:00
lifenlong
3c2cf69cbe 微信媒体返回 2021-06-25 16:03:14 +08:00
Chopper
0d6d92139b 余额支付错误的判定问题处理 2021-06-25 16:00:23 +08:00
Chopper
f725b64345 微信退款状态无法变更问题处理 2021-06-25 14:56:16 +08:00
Chopper
efb226b37b 投诉展示相关问题完善 2021-06-25 14:32:39 +08:00
Chopper
14ff0a3501 交易支付后不会自动跳转问题处理 2021-06-25 11:43:56 +08:00
Chopper
39d6032152 订单取消异常 2021-06-25 11:40:05 +08:00
Chopper
b6062f4fb9 订单统计时,店铺参数传递后台,统计结果不变问题处理 2021-06-25 11:35:02 +08:00
Chopper
47c42db720 创建订单,校验参数相关流程调整 2021-06-25 10:48:21 +08:00
Chopper
ac68acda50 兼容性问题处理 2021-06-25 10:37:31 +08:00
Chopper
d99a4d2d50 商品参数编辑问题处理 2021-06-25 10:35:22 +08:00
Chopper
1b5add1d13 购物车获取数量问题 2021-06-25 10:31:10 +08:00
Chopper
54320499e5 错误消息完善 2021-06-25 10:17:58 +08:00
Chopper
e4dd156ae7 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-25 09:47:12 +08:00
Chopper
02d23dc217 1、主要解决商品参数后端存储格式问题,结构问题等
2、配送商品超出配送区域提出警告,但是依然可以下单问题处理
2021-06-25 09:46:38 +08:00
lifenlong
4fd8e4ecef 修改虚拟订单售后类型只支持退款 2021-06-24 18:17:16 +08:00
lifenlong
83367ca96d 解决微信媒体返回错误问题。 2021-06-24 17:30:03 +08:00
lifenlong
30846819d8 解决线上、本地开发重复调用微信token的问题 2021-06-24 17:19:17 +08:00
lifenlong
9c574ad9b7 微信上传媒体提示 2021-06-24 16:03:49 +08:00
lifenlong
e6ad65d8c0 如果发行数量是0,则不限制数量 2021-06-24 15:51:14 +08:00
lifenlong
02becd70b2 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-24 15:29:29 +08:00
lifenlong
bd82387a76 虚拟订单不能修改收件人信息 2021-06-24 15:29:23 +08:00
Chopper
158234412c uv统计 2021-06-24 11:18:13 +08:00
Chopper
d185de27dd Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-24 10:57:40 +08:00
Chopper
c9b7ee2c81 商品发布模块更新 2021-06-24 10:57:27 +08:00
OceansDeep
cf1c138fe8 !10 修复分类参数修改索引属性后没有同步到商品参数问题
Merge pull request !10 from OceansDeep/feature/pg
2021-06-24 01:21:39 +00:00
paulGao
0121c546f4 修复分类参数修改索引属性后没有同步到商品参数问题 2021-06-24 09:20:13 +08:00
lifenlong
155c648186 整理之后新版本功能 2021-06-23 18:58:20 +08:00
lifenlong
943d31de9d 显示小程序的客服配置 2021-06-23 18:06:38 +08:00
lifenlong
8a10382787 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-23 17:44:31 +08:00
lifenlong
3aacd1efbd 修改商品模板的详情字段类型 2021-06-23 17:44:24 +08:00
Chopper
f667822daf Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-23 16:47:45 +08:00
Chopper
8d5d902550 管理端验证码登录校验 2021-06-23 16:47:16 +08:00
Chopper
8cecb69c01 异常模块进一步完善 2021-06-23 16:47:05 +08:00
Chopper
7851e8af39 规格代码相关改版 2021-06-23 16:46:52 +08:00
lifenlong
34ed19373b 修改update.sql,添加新增的表结构 2021-06-23 16:06:50 +08:00
lifenlong
abaf32f3dc Merge branch 'master' into Bulbasaur 2021-06-23 15:38:43 +08:00
lifenlong
ae4253d146 Merge branch 'Bulbasaur' of https://gitee.com/beijing_hongye_huicheng/lilishop into Bulbasaur 2021-06-23 15:38:03 +08:00
lifenlong
c1bce3fc3b 直播间删除商品,返回错误 2021-06-23 15:37:49 +08:00
Chopper
a5fa7cadcd 规格搜索以规格id为准 2021-06-23 09:44:53 +08:00
OceansDeep
6419d5b7e8 !9 修复更新商品状态不会更新缓存商品数据问题
Merge pull request !9 from OceansDeep/feature/pg
2021-06-22 14:43:53 +00:00
paulGao
117fe762a8 修复更新商品状态不会 2021-06-22 22:36:28 +08:00
paulGao
bf67a45d53 Merge branch 'feature/pg' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg 2021-06-22 22:34:02 +08:00
paulGao
12238d3989 修复更新商品状态不会更新缓存商品数据问题 2021-06-22 22:33:10 +08:00
Chopper
911df97422 商品规格相关问题处理 2021-06-22 18:58:55 +08:00
Chopper
a3085405fe 消费者配置文件还原 2021-06-22 15:47:44 +08:00
Chopper
d40869fe2a consumer 数据库还原 2021-06-22 15:40:08 +08:00
Chopper
3e237a8488 商品创建订单,提示语问题处理 2021-06-22 15:21:02 +08:00
Chopper
19154aa2b8 虚拟商品重量字段兼容问题处理 2021-06-22 15:08:06 +08:00
Chopper
8f93ac4d49 修改默认错误提示语 2021-06-22 11:50:08 +08:00
Chopper
cfd8bceb10 索引字段问题处理 2021-06-22 09:23:50 +08:00
OceansDeep
5fc1e7b30f !8 修复商品索引参数问题
Merge pull request !8 from OceansDeep/feature/pg
2021-06-21 16:10:17 +00:00
OceansDeep
54408db0f0 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg 2021-06-21 16:10:06 +00:00
paulGao
41a86ff7dc 修复商品索引参数问题 2021-06-22 00:07:33 +08:00
Chopper
65d106e515 商品信息编辑时,参数校验问题处理 2021-06-21 17:30:28 +08:00
Chopper
74ae262e79 商品保存时,部分参数逻辑校验 2021-06-21 17:12:55 +08:00
Chopper
cdbaed22d9 验证码模块提交 2021-06-21 16:38:29 +08:00
Chopper
2db8eb7324 订单查询失败问题处理 2021-06-21 15:37:08 +08:00
Chopper
b8a2e90592 规范sql升级 2021-06-21 14:57:20 +08:00
chopper711
eb1b6fac5c !7 会员站内信功能相关合并
Merge pull request !7 from chopper711/qiuqiu
2021-06-21 14:16:44 +08:00
chopper711
4bd4ba7e08 !6 4.1.0功能合并
Merge pull request !6 from chopper711/Bulbasaur
2021-06-21 14:15:41 +08:00
Chopper
c7e4af6175 注释规范 2021-06-21 14:14:07 +08:00
OceansDeep
8403db9e75 !5 修复拼团商品限购数量问题,添加创建订单流程过后清除缓存key
Merge pull request !5 from OceansDeep/feature/pg
2021-06-21 14:03:22 +08:00
paulGao
337775013e 修复拼团商品限购数量问题,添加创建订单流程过后清除缓存key 2021-06-21 14:02:31 +08:00
paulGao
7564a4627a Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg 2021-06-21 11:56:25 +08:00
Chopper
1943f0ddea Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into Bulbasaur 2021-06-21 11:55:41 +08:00
Chopper
50911137cb 购物车逻辑相关处理 2021-06-21 11:55:08 +08:00
lifenlong
b574dfb04f 解决优惠券活动发送多个优惠券问题。 2021-06-21 11:36:14 +08:00
Chopper
9546807031 流量限制设定更合理 2021-06-21 10:53:04 +08:00
pikachu
aaf53440ac 完善消息注视 2021-06-20 11:05:14 +08:00
lifenlong
d7b0ff4cd1 优惠券动态时间判定。 2021-06-19 17:43:04 +08:00
lifenlong
4e87ad22c1 虚拟订单,订单核验码修改为8位 2021-06-19 14:31:56 +08:00
lifenlong
859689eec2 1.直播商品名称不能超过14位。
2.添加虚拟订单类型
2021-06-19 14:11:57 +08:00
Chopper
738a95edb6 分类信息保存增加校验 2021-06-18 17:33:45 +08:00
Chopper
e5b9280b7e 关闭券活动 2021-06-18 16:36:53 +08:00
lifenlong
c20f3ff04d 查询分类下是否存在商品,去除掉已删除商品 2021-06-18 16:22:49 +08:00
Chopper
c787b4762b 优惠券问题粗粝 2021-06-18 16:20:00 +08:00
Chopper
30d34d69f1 Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into Bulbasaur 2021-06-18 14:23:54 +08:00
Chopper
7113914ccd 交互对象调整 2021-06-18 14:23:51 +08:00
lifenlong
78b5b5a324 冲突 2021-06-18 11:29:46 +08:00
lifenlong
b361fe7d95 展示优惠券活动下的优惠券列表详情 2021-06-18 11:27:38 +08:00
Chopper
daa6236b37 自定义分类无法保存问题处理 2021-06-18 10:27:33 +08:00
lifenlong
24be8f342d 解决冲突 2021-06-18 10:12:15 +08:00
lifenlong
bfc76f7ceb 同步master 2021-06-18 10:03:34 +08:00
pikachu
0cfb196918 Merge branch 'master' into qiuqiu 2021-06-18 07:55:53 +08:00
pikachu
975550374a 新增会员站内信消息 2021-06-18 07:55:25 +08:00
Chopper
cbcadc21a2 xss还原 2021-06-17 16:43:37 +08:00
Chopper
e01c279cfe 支付宝支付h5 无法支付成功,检查时回调参数格式问题,现重新整理上线 2021-06-17 16:31:40 +08:00
Chopper
897600335e 支付title 字符串过滤 2021-06-17 15:06:24 +08:00
Chopper
383dbb2d4e 测试环境短信问题处理 ,默认6个1发送 2021-06-17 15:05:50 +08:00
Chopper
4bc5cb0f1b wap支付失败,看起来是因为超时原因,调试一下 2021-06-17 12:21:41 +08:00
Chopper
4a9d54cbf4 增加日志答应,wap支付3m超时问题尝试解决 2021-06-17 12:12:45 +08:00
lifenlong
67e31bff07 同步master 2021-06-17 11:15:56 +08:00
Chopper
bf023ccad5 去除无效的代码 2021-06-17 10:41:53 +08:00
Chopper
0995a3b75f Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-17 10:38:07 +08:00
Chopper
e4b968e0af 库存扣减,库存回滚问题处理。
之前存在商品取消后,自动回滚库存,可是忽略了商品取消可能是因为库存不足导致的问题。
2021-06-17 10:37:45 +08:00
Chopper
7ce5b517fc 商品评价场景,查询业务重构,代码复用增强,前端可以查看到后端设置隐藏的评价内容问题解决 2021-06-17 10:37:11 +08:00
OceansDeep
9c5cc0bf36 !4 修复拼团商品下单问题和添加商品是否需要索引
Merge pull request !4 from OceansDeep/feature/pg
2021-06-17 09:31:47 +08:00
paulGao
c69cd0c22d 修复拼团商品下单问题和添加商品是否需要索引 2021-06-17 09:11:16 +08:00
lifenlong
fbcd5b7470 app版本修改,过滤当前版本 2021-06-17 00:28:36 +08:00
Chopper
6205693df6 增加下单部分注视,支付宝h5支付日志记录内容 2021-06-16 15:54:54 +08:00
Chopper
00182f5cfb 限制官网地区同步功能 2021-06-16 10:49:17 +08:00
Chopper
841903d2a6 优惠券活动问题处理 2021-06-15 18:10:25 +08:00
Chopper
5f403ec675 合并master业务代码 2021-06-15 16:21:03 +08:00
Chopper
a97b698d8e Merge branch 'master' into Bulbasaur
# Conflicts:
#	consumer/src/main/java/cn/lili/timetask/handler/impl/promotion/PromotionEverydayExecute.java
#	consumer/src/main/java/cn/lili/trigger/executor/PromotionTimeTriggerExecutor.java
#	framework/src/main/java/cn/lili/common/trigger/delay/AbstractDelayQueueMachineFactory.java
#	framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java
#	framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponServiceImpl.java
2021-06-15 15:50:54 +08:00
Chopper
24bb6a4169 代码同步 2021-06-15 15:28:33 +08:00
lifenlong
44d6edd53b 演示站点,支持商品分类添加 2021-06-15 09:59:32 +08:00
lifenlong
10dbed04b6 初始化秒杀活动 2021-06-13 16:27:40 +08:00
lifenlong
a159c0d0db 下载批量发货订单列表 2021-06-13 15:53:19 +08:00
lifenlong
3814b4a9a5 暂提 2021-06-13 14:51:39 +08:00
Chopper
2472cfd93b 批量关闭活动问题处理 2021-06-13 14:48:45 +08:00
lifenlong
5a4f8e2a72 同步 2021-06-13 09:03:16 +08:00
lifenlong
6ef71d9dfe 解决PC页面不传递开启关闭 2021-06-12 15:16:22 +08:00
Chopper
ee01a65d92 买家端登录跳转问题处理 2021-06-11 15:39:55 +08:00
Chopper
8913f37f33 qq联合登录问题处理 2021-06-11 14:48:20 +08:00
Chopper
fcca848e40 去除引用 2021-06-11 12:00:01 +08:00
Chopper
ebebbcac69 延时任务规范,任务调度机制,修改为consumer执行,不再被每个进程监控。 2021-06-11 11:59:21 +08:00
lifenlong
332e287675 修改虚拟订单类型 2021-06-10 20:13:21 +08:00
Chopper
9195292aa9 演示站点部分权限控制 2021-06-10 17:40:53 +08:00
lifenlong
34e5488b9d 创建虚拟订单
由前台处理待发货订单导出
2021-06-10 16:25:40 +08:00
Chopper
89f4b71301 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-10 09:16:36 +08:00
Chopper
fc66db2d13 修改注释 2021-06-10 09:15:31 +08:00
lifenlong
7c8c692e87 去除xss空格过滤 2021-06-09 18:21:11 +08:00
lifenlong
19ae44f851 商品规格添加商品类型 2021-06-09 17:39:57 +08:00
Chopper
590a039f10 商品索引需要手动删除的问题处理 2021-06-09 17:11:21 +08:00
Chopper
f7201342d9 代码规范度问题处理,注释补充。 2021-06-09 16:29:49 +08:00
lifenlong
cf4f9dd6bc 商品模板支持虚拟商品 2021-06-09 16:29:25 +08:00
Chopper
b30a55eafa 收银台参数问题优化,如果不匹配直接跳过。 2021-06-09 09:24:35 +08:00
Chopper
da1863850a 主要完善延时任务相关,缺失的注释信息,log记录的信息完善。目录结构优化。
sql数据过大,展示sql默认为false,需要打开手动打开就好。
2021-06-08 18:40:32 +08:00
Chopper
91baf22841 无效类去除 2021-06-08 09:36:35 +08:00
Chopper
c2367f763f 订单支付金额为0时问题解决。 2021-06-07 17:36:48 +08:00
lifenlong
a51e86fd98 去除e.printStackTrace();使用slf4j实现 2021-06-07 16:49:59 +08:00
Chopper
203abe1087 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-07 16:13:50 +08:00
Chopper
6d7e9e7fdd 阿里sms默认短信验证码配置问题处理 2021-06-07 16:12:07 +08:00
lifenlong
762a7335fe Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-07 15:50:45 +08:00
lifenlong
0bca2d9026 店铺结算设置开始、结束时间 2021-06-07 15:50:36 +08:00
Chopper
0fc179cff2 地区相关问题处理 2021-06-07 15:28:36 +08:00
Chopper
f949896685 地区数据初始化之后,数据无法访问,因为缓存没有更新。现在更新为初始化完成,即清空与地区相关的缓存 2021-06-07 15:27:48 +08:00
lifenlong
86360cf5f8 Merge branch 'master' into Bulbasaur 2021-06-07 15:08:36 +08:00
lifenlong
e176d920cc 店铺结算设置开始、结束时间 2021-06-07 15:08:12 +08:00
Chopper
f9f8cce13e xss防御相关更改策略,调整代码 2021-06-07 15:00:36 +08:00
Chopper
4b8fff1e56 地区初始化数据结构错误问题,提前设置id,构造出父类id 2021-06-07 10:16:16 +08:00
Chopper
03f54f470a Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-06-07 10:13:19 +08:00
Chopper
886ea29c6d 对数据保存做一个判定,如果模型设置id,则不复盖模型原有的id 2021-06-07 10:12:42 +08:00
lifenlong
4849e7d57e 同步 master 2021-06-07 10:02:23 +08:00
lifenlong
7e8ba50970 添加页面,判断是否发布页面 2021-06-07 10:00:07 +08:00
lifenlong
431f7c014f 添加页面,判断是否发布页面
添加update.sql
2021-06-07 09:59:09 +08:00
lifenlong
bbe01e9e67 用户经验值设置 2021-06-05 17:13:04 +08:00
lifenlong
e379a2eb34 导出售后单 2021-06-05 14:48:16 +08:00
lifenlong
b7e439e177 店铺导出订单列表 2021-06-05 14:04:56 +08:00
lifenlong
73002148d4 1.展示店铺的商品数量、收藏数量
2.动态时间优惠券进行状态判断。
3.导出订单API
2021-06-04 15:42:35 +08:00
Chopper
9fedc25f3f 安全问题 2021-06-04 10:55:35 +08:00
Chopper
f11c3205ee 攻击sql阻断解析器 2021-06-04 10:21:54 +08:00
Chopper
94bb98bf1f 去除Mapper 采用注解来实现相关查询 2021-06-03 15:35:20 +08:00
lifenlong
9db40c197d 延时任务修改直播间状态 2021-06-03 10:54:48 +08:00
lifenlong
b842daa609 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop 2021-06-02 17:57:07 +08:00
lifenlong
ce70a93ff5 买家过滤拼团内容 2021-06-02 17:56:59 +08:00
lifenlong
f3faec3f72 买家过滤拼团内容 2021-06-02 17:54:40 +08:00
lifenlong
07b9e413d6 添加秒杀活动设置 2021-06-02 17:30:32 +08:00
Chopper
80ca2b6388 在线人数展示时间字段完整展示 2021-06-02 17:28:43 +08:00
Chopper
571bc0ed93 首页统计排序优化 2021-06-02 16:05:55 +08:00
Chopper
83c86ab1da 优化管理端首页数据统计 2021-06-02 15:42:54 +08:00
Chopper
393c246018 再次缩短在线人数vo的返回日期长度 2021-06-02 14:49:48 +08:00
Chopper
46d937270d 调整返回日期的格式 2021-06-02 14:48:40 +08:00
Chopper
7a4ca67784 会员统计当日数据问题处理 2021-06-02 10:37:01 +08:00
lifenlong
b2d149c714 支持使用促销类型进行筛选订单:拼团、积分、赠品 2021-06-01 22:10:28 +08:00
lifenlong
f802810330 添加直播间状态变化延时任务 2021-06-01 17:23:32 +08:00
lifenlong
6fb7322e3e Merge branch 'master' into Bulbasaur 2021-06-01 15:51:50 +08:00
lifenlong
b70da68761 Merge branch 'Bulbasaur' of https://gitee.com/beijing_hongye_huicheng/lilishop into Bulbasaur 2021-06-01 15:51:30 +08:00
lifenlong
0324951d9a 微信小程序优化 2021-06-01 15:51:19 +08:00
Chopper
d01bd1581e 店铺流水交易趋势问题 2021-06-01 09:43:02 +08:00
Chopper
56c532349b 店铺uv条件判定问题处理 2021-06-01 09:29:03 +08:00
Chopper
79461c3768 uv统计异常问题处理 2021-06-01 09:16:15 +08:00
Chopper
2d1140df40 会员积分默认倒序 2021-06-01 08:52:33 +08:00
Chopper
5b162d0f8c 增加star标记 2021-05-31 11:47:44 +08:00
Chopper
78aee87b45 Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into Bulbasaur 2021-05-31 11:34:47 +08:00
Chopper
e09747c410 支持elk 2021-05-31 11:34:43 +08:00
lifenlong
7fa0fb75b1 订单付款后添加是否支持原路退款。 2021-05-31 08:37:15 +08:00
lifenlong
3639ed731b 虚拟订单核验 2021-05-29 12:31:38 +08:00
lifenlong
e5d4207839 虚拟商品订单创建核验码 2021-05-29 11:37:55 +08:00
lifenlong
969437fc34 添加商品类型:实物商品、虚拟商品、电子卡券 2021-05-28 17:43:55 +08:00
lifenlong
814d118d77 运营后台可设置推荐直播间 2021-05-28 12:10:33 +08:00
Chopper
28d8efb8cb Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-05-27 11:39:15 +08:00
Chopper
fb93625c60 增加环境安装文档 2021-05-27 11:38:55 +08:00
lifenlong
c58524cf94 创建直播商品VO,显示直播商品的库存以及店铺名称 2021-05-26 18:40:54 +08:00
lifenlong
5b5681d748 支持短信验证码登录 2021-05-26 17:57:51 +08:00
lifenlong
99b9e8cf91 导出订单发货Excel,上传Excel订单批量发货 2021-05-26 17:09:55 +08:00
Chopper
f82fef9f3d 授权返回 readme 修改 2021-05-26 09:28:52 +08:00
Chopper
18d3401d01 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop 2021-05-26 09:27:33 +08:00
Chopper
b855cfb5f8 积分商品店铺名称问题处理 2021-05-26 09:27:27 +08:00
lifenlong
5f93ce3851 会员精准发券,更改改分页进行发送 2021-05-26 08:42:12 +08:00
lifenlong
b4240ae2c0 商品去除买家承担运费、卖家承担运费,配送模板增加选项:包邮 2021-05-26 08:18:28 +08:00
lifenlong
a9ec03f0a4 1.增加直播商品
2.同步直播商品状态
3.展示状态展示直播商品列表
2021-05-25 16:10:16 +08:00
lifenlong
d9ccc4a7b7 添加秒杀活动设置 2021-05-25 08:29:07 +08:00
lifenlong
116a52ea14 合并 2021-05-25 08:10:41 +08:00
lifenlong
e7e29da455 秒杀活动增加活动商品数量 2021-05-25 08:02:31 +08:00
lifenlong
00a0edeade 批量添加直播商品 2021-05-24 18:24:19 +08:00
lifenlong
16cc989cdf 设置秒杀活动为自动开启 2021-05-24 18:18:24 +08:00
lifenlong
5c32fd9d7c 优惠券有效期时间判定,如果是1则是当天 2021-05-24 14:06:22 +08:00
lifenlong
639435ec45 新增优惠券有限期设置类型 2021-05-24 14:00:07 +08:00
lifenlong
777226dc95 优惠券活动发送/触发 2021-05-24 11:09:21 +08:00
lifenlong
8924981556 创建优惠券活动 2021-05-21 19:54:25 +08:00
lifenlong
16498a6850 Merge branch 'master' into Bulbasaur 2021-05-21 17:25:15 +08:00
lifenlong
fa59c9ca73 优惠券活动 2021-05-21 09:11:40 +08:00
lifenlong
a15d5d7c36 Merge branch 'master' into Bulbasaur 2021-05-20 16:42:06 +08:00
lifenlong
a8a6506516 同步直播状态、直播间新增商品数量 2021-05-20 14:56:15 +08:00
lifenlong
2326a5963f Merge branch 'master' into Bulbasaur 2021-05-20 11:36:09 +08:00
lifenlong
cd60eba7a4 微信媒体工具类(临时图片上传) 2021-05-20 09:00:46 +08:00
lifenlong
273d0abbc7 解决冲突 2021-05-19 19:38:17 +08:00
lifenlong
250fffab77 merge master 2021-05-19 19:29:51 +08:00
lifenlong
48f24b675b merge master 2021-05-19 14:26:35 +08:00
lifenlong
37a6455e56 会员积分历史 2021-05-19 09:05:44 +08:00
lifenlong
02827a2f8b 微信小程序直播V0.2 2021-05-18 23:34:05 +08:00
lifenlong
0173ba814e Merge branch 'master' into Bulbasaur 2021-05-18 17:35:48 +08:00
lifenlong
0c3a1928ff merge master 2021-05-18 08:17:14 +08:00
lifenlong
910b665d8a 微信小程序直播V0.2 2021-05-17 17:03:28 +08:00
lifenlong
c049552fc7 去除冗余代码 2021-05-17 12:55:40 +08:00
lifenlong
b0f46a78a6 微信小程序直播间创建、微信小程序直播商品添加、删除、查询状态 2021-05-17 12:00:45 +08:00
lifenlong
591ce04e42 会员经验值设置 2021-05-17 09:24:58 +08:00
lifenlong
c8a43573fd 会员积分设置,会员下单赠送积分(非积分订单),订单售后扣除积分 2021-05-17 09:04:10 +08:00
lifenlong
9fae7ac565 Merge branch 'master' into Bulbasaur 2021-05-17 08:18:58 +08:00
lifenlong
57d65f3fd9 会员等级V0.1 2021-05-16 23:41:33 +08:00
779 changed files with 12734 additions and 9184 deletions

200
README.md
View File

@@ -1,32 +1,37 @@
## Lilishop B2B2C商城系统
## 🔥Lilishop B2B2C商城系统
##### 🌹官方公众号 & 开源不易如有帮助请点Star
##### 官方qq群 961316482官方公众号/小程序体验,扫描二维码
##### 官方公众号 & 开源不易如有帮助请点Star
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
[![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
  ![github](https://img.shields.io/github/stars/hongyehuicheng/lilishop.svg?style=social&logo=#181717)
### 介绍
### 🔥介绍
**官网**https://pickmall.cn
Lilishop 是一款Java开发基于SpringBoot研发的B2B2C多用户商城前端使用 Vue、uniapp开发 **系统全端全部代码开源**
Lilishop 基于SpringBoot研发的B2B2C多用户商城系统,前端使用 Vue、uniapp开发 **系统全端全部代码开源**
业务兼容O2O商城/B2B商城/B2B2C商城/F2B2C商城/S2B2C商城。支持小程序商城、H5商城、APP商城、 PC商城。
产品前后端分离、支持分布式部署。
商城展示端包含 PC、H5、微信小程序、APP。
商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
系统包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等支持Docker支持k8s。是一款高性能支持高并发等商城系统。
开箱即用,简单配置即可部署一套属于您的系统。
### 文档
**产品文档**需求、架构、使用、部署、开发https://docs.pickmall.cn
### 项目链接(gitee)
### ☃️文档
**产品文档**https://docs.pickmall.cn
### 💧项目链接(gitee)
**Java后台**https://gitee.com/beijing_hongye_huicheng/lilishop.git
@@ -36,7 +41,7 @@ Lilishop 是一款Java开发基于SpringBoot研发的B2B2C多用户商城
**docker一键部署**https://gitee.com/beijing_hongye_huicheng/docker.git
### 项目链接(github)
### 💧项目链接(github)
**Java后台**https://github.com/hongyehuicheng/lilishop.git
@@ -46,24 +51,33 @@ Lilishop 是一款Java开发基于SpringBoot研发的B2B2C多用户商城
**docker一键部署**https://github.com/hongyehuicheng/docker.git
### 演示地址
### 💧演示地址(手机验证码为 111111)
**运营后台**https://admin-b2b2c.pickmall.cn 账号admin/123456
**店铺后台**https://store-b2b2c.pickmall.cn 账号13011111111/111111
**用户前台**https://pc-b2b2c.pickmall.cn
**PC**https://pc-b2b2c.pickmall.cn
**移动端**https://m-b2b2c.pickmall.cn
**WAP**https://m-b2b2c.pickmall.cn
**小程序/公众号**:扫描二维码
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
### 3行命令搭建本地环境
### 🚙3行命令搭建本地环境
温馨提示由于服务较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
温馨提示:由于服务中间件较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
##### 下载docker脚本
##### docker环境安装 [点击跳转](https://docs.pickmall.cn/deploy/%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2.html)
##### 下载docker-compose脚本
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
##### 部署基础环境
`docker-compose up -d`
@@ -72,39 +86,39 @@ Lilishop 是一款Java开发基于SpringBoot研发的B2B2C多用户商城
PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql
PS:单独部署的话,商城数据库文件访问这里https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql
##### 各个地址
##### 商城部署后 API/UI 地址
| API | 地址 |
| -------------- | --------------- |
| 买家API | http://127.0.0.1:8888 |
| 商家API | http://127.0.0.1:8889 |
| 管理端API | http://127.0.0.1:8887 |
| 通用API | http://127.0.0.1:8890 |
| 商城买家API | http://127.0.0.1:8888 |
| 商城商家API | http://127.0.0.1:8889 |
| 商城管理端API | http://127.0.0.1:8887 |
| 商城基础API | http://127.0.0.1:8890 |
| 前端演示 | 地址 |
| -------------- | --------------- |
| PC | http://127.0.0.1:10000 |
| WAP | http://127.0.0.1:10001 |
| 商 | http://127.0.0.1:10002 |
| 管理端 | http://127.0.0.1:10003 |
| 商城PC端 | http://127.0.0.1:10000 |
| 商城WAP | http://127.0.0.1:10001 |
| 商城卖家端 | http://127.0.0.1:10002 |
| 商城管理端 | http://127.0.0.1:10003 |
### 功能列表
### ⚾️功能列表
#### 平台功能
#### 🥎商城平台功能
![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg)
#### 商家端功能
#### 🥎商城卖家功能
![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg)
@@ -112,30 +126,28 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
### 功能展示
### 🧩商城前端功能展示
#### 移动端
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="管理端功能展示" style="zoom:50%;" />
#### ⚽️商城移动端
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" />
#### 管理端
#### ⚽️商城管理端
![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif)
### 技术选型
### 商城技术选型
#### 架构图
#### 🥅架构图
![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png)
##### Java后台
##### 🕹后台技术选型
| 说明 | 框架 | 说明 | |
| -------------- | --------------- | -------------- | ------------- |
@@ -149,7 +161,7 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 短信 | 阿里云短信 | 认证 | JWT |
| 日志处理 | Log4j | 接口规范 | RESTful |
##### 前端-运营后台、店铺后台
##### 🖥前端-运营后台、店铺后台
| 说明 | 框架 | 说明 | 框架 |
| ---------- | ---------- | ---------- | ------- |
@@ -159,119 +171,33 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 基础UI库 | iView | UI界面基于 | iView |
| 网络请求 | axios | | |
##### 前端-移动端
##### 📱前端-移动端
| 说明 | 架构 | 说明 | 架构 |
| --------- | ------- | -------- | ------- |
| 基础UI库 | uViewui | 基础框架 | uni-app |
| CSS预处理 | scss | 地图引擎 | amap |
### 升级计划
#### 计划每个月发布一个版本,具体时间可能有出入
时间2021年6月15日
### 🌟版本升级
```
新增功能:
1.微信小程序直播
2.优惠券活动
3.新人赠券
4.准确发券
5.用户等级
6.数据导出
7.订单批量
8.APP版本升级检测
9.积分商城
功能优化:
1.优惠券有效期增加类型:设置领取后*内有效。
2.秒杀活动设置为每天开启,需设置秒杀活动开启时间。
3.店铺配送模板,配送地区如果选择省份则下方的市级地址不展示。
4.店铺配送模板支持,店铺包邮。
5.普通商品设置去除卖家承担运费。
商城后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
后续会考虑推出微服务商城系统/中台商城等
```
时间2021年7月15日
```
新增功能:
1.会员权益
2.支持用户升级会员
3.供求单
4.IM腾讯云智服
5.服务商品
6.店铺支持订单核销
7.店铺自提点
功能优化:
1.用户分享商城、关注店铺、邀请新用户可获取积分、经验值。
```
时间2021年8月16日
```
新增功能:
1.微淘功能
2.店铺移动端
3.店铺发货单
```
时间2021年9月15日
```
新增功能:
增加供应商功能
```
### 版本升级
```
后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
后续会考虑推出微服务/中台等 企业级版本
```
### 技术亮点
1.后端框架基于Springboot构建基于maven持久层使用MyBatisPlus。使用elasticsearch、redis、mongodb、rocketmq 等各种中间健。都是主流架构,轻松应对各种环境。
2.支持集群、分布式支持docker 轻松部署,解决各种复杂场景!
3.代码模块清晰主要分为三端api买家、卖家、管理各端API互相隔离自己鉴权自己操作业务。
4.使用阿里开源的RocketMQ基于mq解决各种并发场景解决事务一致性解决搞并发延迟场景问题。
5.项目使用多级缓存应用不同场景redis缓存业务数据、mongodb缓存关系型多对多关系问题、nginx缓存高频访问低频修改的页面。
6.支持各种联合登陆,支持各种客户端的支付问题,灵活配置灵活开启。
7.内置完善的楼层装修机制,各种拖拉拽,维护跳转页面或外网,即便是一个什么都不懂的运营也可以轻松掌握。
8.内置阿里短信接口可以在线申请短信模版。内置阿里oss系统可以对文件执行各种操作。oss商家端资源相互隔离。
10.强大的统计报表,统计效果,可以实现各个场景,包含在线人数,历史在线人数,活跃人数等信息。
11.标准Api接口、提供swagger文档快速二开。
12.分布式调度任务中心,解决分布式定时任务多次执行问题。
13.代码注释完善,快速上手。
14.非移动端采用IView框架各种自定义插件、选择器实现。移动端采用uniapp一次编写全端使用
15.已经对接好各种第三方插件,支持各种复杂等联合登陆,联合支付等场景。
### 开源须知
### ⚠️开源须知
1.仅允许用于个人学习研究使用.
2.禁止将本开源的代码和资源进行任何形式任何名义的出售.
3.限制商用如果需要商业使用请联系我们。QQ3409056806.
3.软件受国家计算机软件著作权保护登记号2021SR0805085
### 交流群
4.限制商用如果需要商业使用请联系我们。QQ3409056806.
### 🐧交流群
**QQ群**961316482

View File

@@ -6,7 +6,8 @@
<parent>
<groupId>cn.lili</groupId>
<artifactId>lili-shop-parent</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>admin</artifactId>
@@ -15,7 +16,7 @@
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.3.1</version>
<version>${spring-boot-admin}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@@ -37,11 +37,11 @@ public class AdminApplication {
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeRequests().antMatchers("/instances**").permitAll();
http.authorizeRequests(
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll() // 授予公众对所有静态资产和登录页面的访问权限。
(authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**")).permitAll() //授予公众对所有静态资产和登录页面的访问权限。
.antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated() //其他所有请求都必须经过验证。
).formLogin(
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and() // 配置登录和注销。
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults()) // 启用HTTP基本支持。这是Spring Boot Admin Client注册所必需的。
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler).and() //配置登录和注销。
).logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout"))).httpBasic(Customizer.withDefaults()) //启用HTTP基本支持。这是Spring Boot Admin Client注册所必需的。
.csrf().disable()
.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
}

View File

@@ -3,21 +3,19 @@
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>
<properties>
<enjoy.version>4.3</enjoy.version>
</properties>
<artifactId>buyer-api</artifactId>
<parent>
<groupId>cn.lili</groupId>
<artifactId>lili-shop-parent</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>cn.lili</groupId>
<artifactId>framework</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
</dependency>
<dependency>

View File

@@ -1,23 +0,0 @@
package cn.lili.controller;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration;
/**
* SwaggerBootstrapUiDemoApplication
*
* @author Chopper
* @version v1.0
* 2020-12-09 20:09
*/
@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)
public class SwaggerBootstrapUiDemoApplication implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@@ -1,6 +1,8 @@
package cn.lili.controller.goods;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.distribution.service.DistributionService;
@@ -20,6 +22,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
@@ -37,6 +40,7 @@ import java.util.Map;
* @author Chopper
* @date 2020/11/16 10:06 下午
*/
@Slf4j
@Api(tags = "买家端,商品接口")
@RestController
@RequestMapping("/buyer/goods")
@@ -80,12 +84,18 @@ public class GoodsBuyerController {
@PageViewPoint(type = PageViewEnum.SKU, id = "#id")
public ResultMessage<Map<String, Object>> getSku(@NotNull(message = "商品ID不能为空") @PathVariable("goodsId") String goodsId,
@NotNull(message = "SKU ID不能为空") @PathVariable("skuId") String skuId) {
try {
// 读取选中的列表
Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
return ResultUtil.data(map);
} catch (ServiceException se) {
log.info(se.getMsg(), se);
throw se;
} catch (Exception e) {
log.error(ResultCode.GOODS_ERROR.message(), e);
return ResultUtil.error(ResultCode.GOODS_ERROR);
}
Map<String, Object> map = goodsSkuService.getGoodsSkuDetail(goodsId, skuId);
return ResultUtil.data(map);
}
@ApiOperation(value = "获取商品分页列表")

View File

@@ -36,11 +36,16 @@ public class MemberCollectionController {
@Autowired
private StoreCollectionService storeCollectionService;
/**
* 商品收藏关键字
*/
private String goods="GOODS";
@ApiOperation(value = "查询会员收藏列表")
@ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "path", example = "GOODS:商品,STORE:店铺")
@GetMapping("/{type}")
public ResultMessage<Object> goodsList(@PathVariable String type, PageVO page) {
if (type.equals("GOODS")) {
if (goods.equals(type)) {
return ResultUtil.data(goodsCollectionService.goodsCollection(page));
}
return ResultUtil.data(storeCollectionService.storeCollection(page));
@@ -54,7 +59,7 @@ public class MemberCollectionController {
@PostMapping("/add/{type}/{id}")
public ResultMessage<Object> addGoodsCollection(@PathVariable String type,
@NotNull(message = "值不能为空") @PathVariable String id) {
if (type.equals("GOODS")) {
if (goods.equals(type)) {
return ResultUtil.data(goodsCollectionService.addGoodsCollection(id));
}
return ResultUtil.data(storeCollectionService.addStoreCollection(id));
@@ -69,7 +74,7 @@ public class MemberCollectionController {
@DeleteMapping(value = "/delete/{type}/{id}")
public ResultMessage<Object> deleteGoodsCollection(@PathVariable String type,
@NotNull(message = "值不能为空") @PathVariable String id) {
if (type.equals("GOODS")) {
if (goods.equals(type)) {
return ResultUtil.data(goodsCollectionService.deleteGoodsCollection(id));
}
return ResultUtil.data(storeCollectionService.deleteStoreCollection(id));
@@ -83,7 +88,7 @@ public class MemberCollectionController {
@GetMapping(value = "/isCollection/{type}/{id}")
public ResultMessage<Boolean> isCollection(@PathVariable String type,
@NotNull(message = "值不能为空") @PathVariable String id) {
if (type.equals("GOODS")) {
if (goods.equals(type)) {
return ResultUtil.data(this.goodsCollectionService.isCollection(id));
}
return ResultUtil.data(this.storeCollectionService.isCollection(id));

View File

@@ -1,5 +1,6 @@
package cn.lili.controller.member;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
@@ -55,7 +56,7 @@ public class MemberEvaluationBuyerController {
public ResultMessage<IPage<MemberEvaluation>> queryMineEvaluation(EvaluationQueryParams evaluationQueryParams) {
//设置当前登录会员
evaluationQueryParams.setMemberId(UserContext.getCurrentUser().getId());
return ResultUtil.data(memberEvaluationService.queryByParams(evaluationQueryParams));
return ResultUtil.data(memberEvaluationService.managerQuery(evaluationQueryParams));
}
@ApiOperation(value = "查看某一个商品的评价列表")
@@ -65,7 +66,8 @@ public class MemberEvaluationBuyerController {
@NotNull @PathVariable("goodsId") String goodsId) {
//设置查询查询商品
evaluationQueryParams.setGoodsId(goodsId);
return ResultUtil.data(memberEvaluationService.queryByParams(evaluationQueryParams));
evaluationQueryParams.setStatus(SwitchEnum.OPEN.name());
return ResultUtil.data(memberEvaluationService.managerQuery(evaluationQueryParams));
}
@ApiOperation(value = "查看某一个商品的评价数量")

View File

@@ -1,12 +1,13 @@
package cn.lili.controller.member;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.message.entity.enums.MessageStatusEnum;
import cn.lili.modules.member.entity.dos.MemberMessage;
import cn.lili.modules.member.entity.vo.MemberMessageQueryVO;
import cn.lili.modules.member.service.MemberMessageService;
import cn.lili.modules.message.entity.dos.MemberMessage;
import cn.lili.modules.message.entity.vos.MemberMessageQueryVO;
import cn.lili.modules.message.service.MemberMessageService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -34,21 +35,23 @@ public class MemberMessageBuyerController {
@ApiOperation(value = "分页获取会员站内消息")
@GetMapping
public ResultMessage<IPage<MemberMessage>> page(MemberMessageQueryVO memberMessageQueryVO, PageVO page) {
memberMessageQueryVO.setMemberId(UserContext.getCurrentUser().getId());
return ResultUtil.data(memberMessageService.getPage(memberMessageQueryVO, page));
}
@ApiOperation(value = "消息已读")
@ApiImplicitParam(name = "messageId", value = "会员消息id", required = true, paramType = "path")
@PutMapping
public ResultMessage<Boolean> read(@PathVariable String messageId) {
@PutMapping("/{message_id}")
public ResultMessage<Boolean> read(@PathVariable("message_id") String messageId) {
return ResultUtil.data(memberMessageService.editStatus(MessageStatusEnum.ALREADY_READY.name(), messageId));
}
@ApiOperation(value = "消息删除")
@ApiOperation(value = "消息放入回收站")
@ApiImplicitParam(name = "messageId", value = "会员消息id", required = true, paramType = "path")
@DeleteMapping
public ResultMessage<Boolean> deleteMessage(@PathVariable String messageId) {
return ResultUtil.data(memberMessageService.deleteMessage(messageId));
@DeleteMapping("/{message_id}")
public ResultMessage<Boolean> deleteMessage(@PathVariable("message_id") String messageId) {
return ResultUtil.data(memberMessageService.editStatus(MessageStatusEnum.ALREADY_REMOVE.name(), messageId));
}

View File

@@ -38,8 +38,8 @@ public class MemberWithdrawApplyBuyerController {
public ResultMessage<IPage<MemberWithdrawApply>> getByPage(PageVO page, MemberWithdrawApplyQueryVO memberWithdrawApplyQueryVO) {
memberWithdrawApplyQueryVO.setMemberId(UserContext.getCurrentUser().getId());
//构建查询 返回数据
IPage<MemberWithdrawApply> memberWithdrawApplyIPage = memberWithdrawApplyService.getMemberWithdrawPage(page, memberWithdrawApplyQueryVO);
return ResultUtil.data(memberWithdrawApplyIPage);
IPage<MemberWithdrawApply> memberWithdrawApplyPage = memberWithdrawApplyService.getMemberWithdrawPage(page, memberWithdrawApplyQueryVO);
return ResultUtil.data(memberWithdrawApplyPage);
}
}

View File

@@ -1,8 +1,13 @@
package cn.lili.controller.other;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.system.entity.dos.AppVersion;
import cn.lili.modules.system.service.AppVersionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@@ -33,4 +38,13 @@ public class AppVersionBuyerController {
public ResultMessage<Object> getAppVersion(@PathVariable String appType) {
return ResultUtil.data(appVersionService.getAppVersion(appType));
}
@ApiOperation(value = "获取版本号列表")
@ApiImplicitParam(name = "appType", value = "app类型", required = true, paramType = "path")
@GetMapping("/appVersion/{appType}")
public ResultMessage<IPage<AppVersion>> appVersion(@PathVariable String appType, PageVO pageVO) {
IPage<AppVersion> page = appVersionService.page(PageUtil.initPage(pageVO), new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getType, appType));
return ResultUtil.data(page);
}
}

View File

@@ -0,0 +1,48 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.goods.entity.dos.Studio;
import cn.lili.modules.goods.service.StudioService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 买家端,直播间接口
*
* @author Bulbasaur
* @date: 2021/5/20 12:03 下午
*/
@RestController
@Api(tags = "买家端,直播间接口")
@RequestMapping("/buyer/broadcast/studio")
public class StudioController {
@Autowired
private StudioService studioService;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "recommend", value = "是否推荐", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
})
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO, Integer recommend, String status) {
return ResultUtil.data(studioService.studioList(pageVO, recommend, status));
}
@ApiOperation(value = "获取店铺直播间回放地址")
@GetMapping("/getLiveInfo/{roomId}")
public ResultMessage<Object> getLiveInfo(Integer roomId) {
return ResultUtil.data(studioService.getLiveInfo(roomId));
}
}

View File

@@ -5,6 +5,7 @@ import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.dos.DistributionOrder;
import cn.lili.modules.distribution.entity.dto.DistributionApplyDTO;
import cn.lili.modules.distribution.entity.vos.DistributionOrderSearchParams;
import cn.lili.modules.distribution.service.DistributionOrderService;
import cn.lili.modules.distribution.service.DistributionService;
@@ -39,21 +40,16 @@ public class DistributionBuyerController {
@Autowired
private DistributionOrderService distributionOrderService;
//申请分销员
@ApiOperation(value = "申请分销员")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "姓名", required = true, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "idNumber", value = "身份证号", required = true, paramType = "query", dataType = "String")
})
@PostMapping
public ResultMessage<Object> applyDistribution(@RequestParam String name, @RequestParam String idNumber) {
return ResultUtil.data(distributionService.applyDistribution(name, idNumber));
public ResultMessage<Object> applyDistribution(DistributionApplyDTO distributionApplyDTO) {
return ResultUtil.data(distributionService.applyDistribution(distributionApplyDTO));
}
@ApiOperation(value = "获取分销员分页订单列表")
@GetMapping("/distributionOrder")
public ResultMessage<IPage<DistributionOrder>> distributionOrderPage(DistributionOrderSearchParams distributionOrderSearchParams) {
distributionOrderSearchParams.setDistributionId(UserContext.getCurrentUser().getId());
distributionOrderSearchParams.setDistributionId(distributionService.getDistribution().getId());
return ResultUtil.data(distributionOrderService.getDistributionOrderPage(distributionOrderSearchParams));
}
@@ -66,7 +62,6 @@ public class DistributionBuyerController {
return ResultUtil.data(distributionService.getDistribution());
}
//申请分销员
@ApiOperation(value = "绑定分销员")
@ApiImplicitParam(name = "distributionId", value = "分销员ID", required = true, paramType = "path")
@GetMapping("/bindingDistribution/{distributionId}")

View File

@@ -11,6 +11,7 @@ import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -50,13 +51,25 @@ public class DistributionGoodsBuyerController {
}
@ApiOperation(value = "选择分销商品")
@ApiImplicitParam(name = "distributionGoodsId", value = "分销ID", required = true, dataType = "String", paramType = "path")
@ApiImplicitParams({
@ApiImplicitParam(name = "distributionGoodsId", value = "分销ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "checked", value = "是否选择", required = true, dataType = "boolean", paramType = "query")
})
@GetMapping(value = "/checked/{distributionGoodsId}")
public ResultMessage<Object> distributionCheckGoods(
@NotNull(message = "分销商品不能为空") @PathVariable("distributionGoodsId") String distributionGoodsId) {
if(distributionSelectedGoodsService.add(distributionGoodsId)){
return ResultUtil.success();
@NotNull(message = "分销商品不能为空") @PathVariable("distributionGoodsId") String distributionGoodsId,Boolean checked) {
Boolean result=false;
if(checked){
result=distributionSelectedGoodsService.add(distributionGoodsId);
}else {
result=distributionSelectedGoodsService.delete(distributionGoodsId);
}
throw new ServiceException(ResultCode.ERROR);
//判断操作结果
if(result){
return ResultUtil.success(ResultCode.SUCCESS);
}else{
throw new ServiceException(ResultCode.ERROR);
}
}
}

View File

@@ -63,11 +63,11 @@ public class MemberBuyerController {
public ResultMessage<Object> smsLogin(@NotNull(message = "手机号为空") @RequestParam String mobile,
@NotNull(message = "验证码为空") @RequestParam String code,
@RequestHeader String uuid) {
// if(smsUtil.verifyCode(mobile,VerificationEnums.LOGIN,uuid,code)){
return ResultUtil.data(memberService.mobilePhoneLogin(mobile));
// }else {
// throw new ServiceException("验证码错误");
// }
if (smsUtil.verifyCode(mobile, VerificationEnums.LOGIN, uuid, code)) {
return ResultUtil.data(memberService.mobilePhoneLogin(mobile));
} else {
throw new ServiceException(ResultCode.VERIFICATION_SMS_ERROR);
}
}
@ApiOperation(value = "注册用户")

View File

@@ -17,9 +17,11 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@@ -29,6 +31,7 @@ import java.io.IOException;
* @author Chopper
* @date 2020-11-25 19:29
*/
@Slf4j
@RestController
@Api(tags = "买家端,web联合登录")
@RequestMapping("/buyer/connect")
@@ -60,8 +63,8 @@ public class ConnectBuyerWebController {
@ApiOperation(value = "信任登录统一回调地址", hidden = true)
@GetMapping("/callback/{type}")
public void callBack(@PathVariable String type, AuthCallback callback, HttpServletResponse httpServletResponse) throws IOException {
connectUtil.callback(type, callback, httpServletResponse);
public void callBack(@PathVariable String type, AuthCallback callback, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
connectUtil.callback(type, callback,httpServletRequest, httpServletResponse);
}
@ApiOperation(value = "信任登录响应结果获取")
@@ -92,7 +95,7 @@ public class ConnectBuyerWebController {
try {
return ResultUtil.data(connectService.appLoginCallback(authUser, uuid));
} catch (Exception e) {
e.printStackTrace();
log.error("unionID登录错误",e);
}
return null;
}

View File

@@ -34,6 +34,7 @@ public class MiniProgramBuyerController {
public ConnectService connectService;
@Autowired
public WechatMpCodeUtil wechatMpCodeUtil;
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
@Autowired
public WechatMPMessageService wechatMPMessageService;
@Autowired

View File

@@ -2,17 +2,18 @@ package cn.lili.controller.payment;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.payment.kit.CashierSupport;
import cn.lili.modules.payment.kit.dto.PayParam;
import cn.lili.modules.payment.kit.enums.PaymentClientEnum;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import cn.lili.modules.payment.kit.params.dto.CashierParam;
import cn.lili.modules.payment.service.PaymentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -26,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Chopper
* @date 2020-12-18 16:59
*/
@Slf4j
@RestController
@Api(tags = "买家端,收银台接口")
@RequestMapping("/buyer/cashier")
@@ -33,8 +35,6 @@ public class CashierController {
@Autowired
private CashierSupport cashierSupport;
@Autowired
private PaymentService paymentService;
@ApiImplicitParams({
@@ -65,8 +65,11 @@ public class CashierController {
try {
return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam);
} catch (ServiceException se) {
log.info("支付异常", se);
throw se;
} catch (Exception e) {
e.printStackTrace();
log.error("收银台支付错误", e);
}
return null;

View File

@@ -17,29 +17,29 @@ import java.util.List;
/**
* 买家端,限时抢购接口
* 买家端,秒杀活动接口
*
* @author paulG
* @date 2020/11/17 2:30 下午
*/
@Api(tags = "买家端,限时抢购接口")
@Api(tags = "买家端,秒杀活动接口")
@RestController
@RequestMapping("/buyer/promotion/seckill")
public class SeckillBuyerController {
/**
* 限时抢购
* 秒杀活动
*/
@Autowired
private SeckillApplyService seckillApplyService;
@ApiOperation(value = "获取当天限时抢购信息")
@ApiOperation(value = "获取当天秒杀活动信息")
@GetMapping
public ResultMessage<List<SeckillTimelineVO>> getSeckillTime() {
return ResultUtil.data(seckillApplyService.getSeckillTimeline());
}
@ApiOperation(value = "获取某个时刻的限时抢购商品信息")
@ApiOperation(value = "获取某个时刻的秒杀活动商品信息")
@GetMapping("/{timeline}")
public ResultMessage<List<SeckillGoodsVO>> getSeckillGoods(@PathVariable Integer timeline) {
return ResultUtil.data(seckillApplyService.getSeckillGoods(timeline));

View File

@@ -50,8 +50,17 @@ public class CartController {
public ResultMessage<Object> add(@NotNull(message = "产品id不能为空") String skuId,
@NotNull(message = "购买数量不能为空") @Min(value = 1, message = "加入购物车数量必须大于0") Integer num,
String cartType) {
cartService.add(skuId, num, cartType);
return ResultUtil.success();
try {
//读取选中的列表
cartService.add(skuId, num, cartType);
return ResultUtil.success();
} catch (ServiceException se) {
log.info(se.getMsg(), se);
throw se;
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
}
}
@@ -148,10 +157,11 @@ public class CartController {
@GetMapping("/checked")
public ResultMessage<TradeDTO> cartChecked(@NotNull(message = "读取选中列表") String way) {
try {
// 读取选中的列表
//读取选中的列表
return ResultUtil.data(this.cartService.getCheckedTradeDTO(CartTypeEnum.valueOf(way)));
} catch (ServiceException e) {
throw e;
} catch (ServiceException se) {
log.error(se.getMsg(), se);
throw se;
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
@@ -193,6 +203,9 @@ public class CartController {
try {
cartService.shippingMethod(selleId, shippingMethod, way);
return ResultUtil.success();
} catch (ServiceException se) {
log.error(se.getMsg(), se);
throw se;
} catch (Exception e) {
log.error(ResultCode.CART_ERROR.message(), e);
throw new ServiceException(ResultCode.CART_ERROR);
@@ -226,10 +239,11 @@ public class CartController {
@PostMapping(value = "/create/trade", consumes = "application/json", produces = "application/json")
public ResultMessage<Object> crateTrade(@RequestBody TradeParams tradeParams) {
try {
// 读取选中的列表
//读取选中的列表
return ResultUtil.data(this.cartService.createTrade(tradeParams));
} catch (ServiceException e) {
throw e;
} catch (ServiceException se) {
log.info(se.getMsg(), se);
throw se;
} catch (Exception e) {
log.error(ResultCode.ORDER_ERROR.message(), e);
throw new ServiceException(ResultCode.ORDER_ERROR);

View File

@@ -37,7 +37,8 @@ public class WalletLogBuyerController {
//获取当前登录用户
AuthUser authUser = UserContext.getCurrentUser();
//构建查询 返回数据
IPage<WalletLog> depositLogPage = walletLogService.page(PageUtil.initPage(page), new QueryWrapper<WalletLog>().eq("member_id", authUser.getId()));
IPage<WalletLog> depositLogPage = walletLogService.page(PageUtil.initPage(page),
new QueryWrapper<WalletLog>().eq("member_id", authUser.getId()).orderByDesc("create_time"));
return ResultUtil.data(depositLogPage);
}
}

View File

@@ -67,7 +67,7 @@ public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
//从header中获取jwt
String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
try {
// 如果没有token 则return
//如果没有token 则return
if (StrUtil.isBlank(jwt)) {
chain.doFilter(request, response);
return;
@@ -99,7 +99,7 @@ public class BuyerAuthenticationFilter extends BasicAuthenticationFilter {
String json = claims.get(SecurityEnum.USER_CONTEXT.getValue()).toString();
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
// 校验redis中是否有权限
//校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.MEMBER) + jwt)) {
//构造返回信息
List<GrantedAuthority> auths = new ArrayList<>();

View File

@@ -48,35 +48,35 @@ public class BuyerSecurityConfig extends WebSecurityConfigurerAdapter {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
// 配置的url 不需要授权
//配置的url 不需要授权
for (String url : ignoredUrlsProperties.getUrls()) {
registry.antMatchers(url).permitAll();
}
registry
.and()
// 禁止网页iframe
//禁止网页iframe
.headers().frameOptions().disable()
.and()
.logout()
.permitAll()
.and()
.authorizeRequests()
// 任何请求
//任何请求
.anyRequest()
// 需要身份认证
//需要身份认证
.authenticated()
.and()
// 允许跨域
//允许跨域
.cors().configurationSource((CorsConfigurationSource) SpringContextUtil.getBean("corsConfigurationSource")).and()
// 关闭跨站请求防护
//关闭跨站请求防护
.csrf().disable()
// 前后端分离采用JWT 不需要session
//前后端分离采用JWT 不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 自定义权限拒绝处理类
//自定义权限拒绝处理类
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and()
// 添加JWT认证过滤器
//添加JWT认证过滤器
.addFilter(new BuyerAuthenticationFilter(authenticationManager(), cache));
}

View File

@@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@@ -127,7 +124,7 @@ spring:
props:
#是否打印逻辑SQL语句和实际SQL语句建议调试时打印在生产环境关闭
sql:
show: true
show: false
# 忽略TOKEN 鉴权 的url
ignored:
@@ -138,21 +135,22 @@ ignored:
- /MP_verify_qSyvBPhDsPdxvOhC.txt
- /weixin/**
- /source/**
- /buyer/store/**
- /buyer/mini-program/**
- /buyer/cashier/**
- /buyer/pageData/**
- /buyer/article/**
- /buyer/goods/**
- /buyer/category/**
- /buyer/shop/**
- /buyer/store/**
- /buyer/connect/**
- /buyer/members/**
- /buyer/promotion/pintuan
- /buyer/promotion/seckill
- /buyer/promotion/pintuan/**
- /buyer/promotion/seckill/**
- /buyer/promotion/pointsGoods/**
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /druid/**
- /swagger-ui.html
- /doc.html
@@ -262,7 +260,8 @@ lili:
# account:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group

View File

@@ -1,19 +0,0 @@
___ ___ ___ ___ ________ ________ _______ ________ _____ ______ ___ __ ________ ________ ___ __
|\ \ |\ \|\ \ |\ \ |\ _____\\ __ \|\ ___ \ |\ __ \|\ _ \ _ \|\ \ |\ \|\ __ \|\ __ \|\ \|\ \
\ \ \ \ \ \ \ \ \ \ \ ____________\ \ \__/\ \ \|\ \ \ __/|\ \ \|\ \ \ \\\__\ \ \ \ \ \ \ \ \ \|\ \ \ \|\ \ \ \/ /|_
\ \ \ \ \ \ \ \ \ \ \|\____________\ \ __\\ \ _ _\ \ \_|/_\ \ __ \ \ \\|__| \ \ \ \ __\ \ \ \ \\\ \ \ _ _\ \ ___ \
\ \ \____\ \ \ \ \____\ \ \|____________|\ \ \_| \ \ \\ \\ \ \_|\ \ \ \ \ \ \ \ \ \ \ \ \|\__\_\ \ \ \\\ \ \ \\ \\ \ \\ \ \
\ \_______\ \__\ \_______\ \__\ \ \__\ \ \__\\ _\\ \_______\ \__\ \__\ \__\ \ \__\ \____________\ \_______\ \__\\ _\\ \__\\ \__\
\|_______|\|__|\|_______|\|__| \|__| \|__|\|__|\|_______|\|__|\|__|\|__| \|__|\|____________|\|_______|\|__|\|__|\|__| \|__|
___ ___ ___ ___ ________ ___ ___ ________ ________
|\ \ |\ \|\ \ |\ \ |\ ____\|\ \|\ \|\ __ \|\ __ \
\ \ \ \ \ \ \ \ \ \ \ ____________\ \ \___|\ \ \\\ \ \ \|\ \ \ \|\ \
\ \ \ \ \ \ \ \ \ \ \|\____________\ \_____ \ \ __ \ \ \\\ \ \ ____\
\ \ \____\ \ \ \ \____\ \ \|____________|\|____|\ \ \ \ \ \ \ \\\ \ \ \___|
\ \_______\ \__\ \_______\ \__\ ____\_\ \ \__\ \__\ \_______\ \__\
\|_______|\|__|\|_______|\|__| |\_________\|__|\|__|\|_______|\|__|
\|_________|

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="buyer-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@@ -50,9 +50,9 @@ class CartTest {
@Test
void createTrade() {
// TradeDTO allTradeDTO = cartService.getAllTradeDTO();
// Assert.assertNotNull(allTradeDTO);
// System.out.println(JsonUtil.objectToJson(allTradeDTO));
// TradeDTO allTradeDTO = cartService.getAllTradeDTO();
// Assert.assertNotNull(allTradeDTO);
// System.out.println(JsonUtil.objectToJson(allTradeDTO));
cartService.createTrade(new TradeParams());
}

View File

@@ -5,6 +5,7 @@ import cn.lili.modules.file.plugin.FileManagerPlugin;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.service.BrandService;
import com.xkcoding.http.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +20,7 @@ import java.util.List;
* @author paulG
* @since 2020/11/14
**/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
class FileTest {
@@ -40,10 +42,10 @@ class FileTest {
}
URL url = new URL(brand.getLogo());
InputStream inputStream = url.openStream();
// 上传至第三方云服务或服务器
//上传至第三方云服务或服务器
brand.setLogo(fileManagerPlugin.inputStreamUpload(inputStream, brand.getId() + ".png"));
} catch (IOException e) {
e.printStackTrace();
log.error("上传你文件出错",e);
}
}
brandService.updateBatchById(categoryList);

View File

@@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@@ -124,7 +121,7 @@ spring:
props:
#是否打印逻辑SQL语句和实际SQL语句建议调试时打印在生产环境关闭
sql:
show: true
show: false
# 忽略鉴权url
ignored:

View File

@@ -7,17 +7,17 @@
<parent>
<groupId>cn.lili</groupId>
<artifactId>lili-shop-parent</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>cn.lili</groupId>
<artifactId>common-api</artifactId>
<dependencies>
<dependency>
<groupId>cn.lili</groupId>
<artifactId>framework</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
</dependency>
</dependencies>

View File

@@ -81,6 +81,7 @@ public class FileController {
if (file.getUserEnums().equals(authUser.getRole().name())) {
break;
}
default:
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
fileService.updateById(file);

View File

@@ -2,7 +2,7 @@ package cn.lili.controller.common;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.base.service.RegionService;
import cn.lili.modules.system.service.RegionService;
import cn.lili.modules.system.entity.dos.Region;
import cn.lili.modules.system.entity.vo.RegionVO;
import io.swagger.annotations.Api;

View File

@@ -1,6 +1,7 @@
package cn.lili.controller.common;
import cn.lili.common.aop.limiter.annotation.LimitPoint;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.verification.enums.VerificationEnums;
@@ -8,6 +9,7 @@ import cn.lili.common.verification.service.VerificationService;
import cn.lili.common.vo.ResultMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -17,26 +19,26 @@ import org.springframework.web.bind.annotation.*;
* @author Chopper
* @date 2020/11/26 15:41
*/
@RequestMapping("/common/slider")
@Slf4j
@RestController
@RequestMapping("/common/slider")
@Api(tags = "滑块验证码接口")
public class SliderImageController {
@Autowired
private VerificationService verificationService;
//一分钟同一个ip请求10次
@LimitPoint(name = "slider_image", key = "verification")
@GetMapping("/{verificationEnums}")
@ApiOperation(value = "获取校验接口")
@ApiOperation(value = "获取校验接口,一分钟同一个ip请求10次")
public ResultMessage getSliderImage(@RequestHeader String uuid, @PathVariable VerificationEnums verificationEnums) {
try {
return ResultUtil.data(verificationService.createVerification(verificationEnums, uuid));
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
return null;
log.error("获取校验接口错误", e);
throw new ServiceException(ResultCode.VERIFICATION_EXIST);
}
}

View File

@@ -31,14 +31,13 @@ public class SmsController {
@Autowired
private VerificationService verificationService;
//一分钟同一个ip请求1次
@LimitPoint(name = "sms_send", key = "sms")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "path", dataType = "String", name = "mobile", value = "手机号"),
@ApiImplicitParam(paramType = "header", dataType = "String", name = "uuid", value = "uuid"),
})
@GetMapping("/{verificationEnums}/{mobile}")
@ApiOperation(value = "发送短信验证码")
@ApiOperation(value = "发送短信验证码,一分钟同一个ip请求1次")
public ResultMessage getSmsCode(
@RequestHeader String uuid,
@PathVariable String mobile,

View File

@@ -12,6 +12,7 @@ import cn.lili.common.utils.CommonUtil;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.config.properties.SystemSetting;
import cn.lili.modules.file.entity.File;
import cn.lili.modules.file.plugin.FileManagerPlugin;
import cn.lili.modules.file.service.FileService;
@@ -51,6 +52,9 @@ public class UploadController {
@Autowired
private Cache cache;
@Autowired
private SystemSetting systemSetting;
@ApiOperation(value = "文件上传")
@PostMapping(value = "/file")
public ResultMessage<Object> upload(MultipartFile file,
@@ -69,7 +73,7 @@ public class UploadController {
}
if (StringUtils.isNotBlank(base64)) {
// base64上传
//base64上传
file = Base64DecodeMultipartFile.base64Convert(base64);
}
String result = "";
@@ -77,9 +81,9 @@ public class UploadController {
File newFile = new File();
try {
InputStream inputStream = file.getInputStream();
// 上传至第三方云服务或服务器
//上传至第三方云服务或服务器
result = fileManagerPlugin.inputStreamUpload(inputStream, fileKey);
// 保存数据信息至数据库
//保存数据信息至数据库
newFile.setName(file.getOriginalFilename());
newFile.setFileSize(file.getSize());
newFile.setFileType(file.getContentType());
@@ -96,10 +100,15 @@ public class UploadController {
fileService.save(newFile);
} catch (Exception e) {
log.error("文件上传失败", e);
throw new ServiceException(ResultCode.OSS_EXCEPTION);
throw new ServiceException(ResultCode.OSS_EXCEPTION_ERROR);
}
return ResultUtil.data(result);
}
@ApiOperation(value = "返回licences")
@PostMapping(value = "/licences")
public ResultMessage<Object> licences() {
return ResultUtil.data(systemSetting.getLicences());
}
}

View File

@@ -48,18 +48,18 @@ public class CommonSecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests();
registry
.and()
// 禁止网页iframe
//禁止网页iframe
.headers().frameOptions().disable()
.and()
.authorizeRequests()
// 任何请求
//任何请求
.anyRequest()
// 需要身份认证
//需要身份认证
.permitAll()
.and()
// 允许跨域
//允许跨域
.cors().configurationSource(corsConfigurationSource).and()
// 关闭跨站请求防护
//关闭跨站请求防护
.csrf().disable();
}

View File

@@ -4,9 +4,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@@ -124,7 +121,7 @@ spring:
props:
#是否打印逻辑SQL语句和实际SQL语句建议调试时打印在生产环境关闭
sql:
show: true
show: false
# 忽略鉴权url
ignored:
@@ -212,8 +209,20 @@ jasypt:
password: lili
lili:
#短信模版配置
sms:
#登录
LOGIN: SMS_205755300
#注册
REGISTER: SMS_205755298
#找回密码
FIND_USER: SMS_205755301
#设置密码
UPDATE_PASSWORD: SMS_205755297
#支付密码
WALLET_PASSWORD: SMS_205755301
system:
isDemoSite: true
isTestModel: true
statistics:
# 在线人数统计 X 小时。这里设置48即统计过去48小时每小时在线人数
onlineMember: 48

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="common-api"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@@ -2,9 +2,6 @@ server:
servlet:
context-path: /
# 正式部署时候,解开此处配置,防止文件夹被清除导致的文件上传失败问题
# multipart:
# location: /Users/lifenlong/Desktop/ceshi
tomcat:
uri-encoding: UTF-8
threads:
@@ -147,9 +144,11 @@ ignored:
- /buyer/promotion/pintuan/**
- /buyer/promotion/seckill/**
- /buyer/promotion/pointsGoods/**
- /buyer/promotion/coupon
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /store/login/**
- /manager/user/login
- /manager/user/refresh/**
@@ -165,6 +164,7 @@ ignored:
- /v2/api-docs
- /configuration/ui
- /boot-admin
- /manager/promotion/seckill/init
statics:
- /**/*.js
- /**/*.css
@@ -196,9 +196,9 @@ logging:
# 输出级别
level:
cn.lili: info
# org.hibernate: debug
# org.springframework: debug
# org.springframework.data.mongodb.core: debug
# org.hibernate: debug
# org.springframework: debug
# org.springframework.data.mongodb.core: debug
file:
# 指定路径
path: lili-logs
@@ -212,8 +212,21 @@ jasypt:
password: lili
lili:
#短信模版配置
sms:
#登录
LOGIN: SMS_205755300
#注册
REGISTER: SMS_205755298
#找回密码
FIND_USER: SMS_205755301
#设置密码
UPDATE_PASSWORD: SMS_205755297
#支付密码
WALLET_PASSWORD: SMS_205755301
system:
isDemoSite: false
isTestModel: true
statistics:
# 在线人数统计 X 小时。这里设置48即统计过去48小时每小时在线人数
onlineMember: 48
@@ -239,7 +252,7 @@ lili:
# jwt 细节设定
jwt-setting:
# token过期时间分钟
tokenExpireTime: 60
tokenExpireTime: 30
# 使用Spring @Cacheable注解失效时间
cache:
@@ -263,6 +276,8 @@ lili:
# username: elastic
# password: LiLiShopES
logstash:
server: 192.168.0.116:4560
rocketmq:
promotion-topic: lili_promotion_topic
promotion-group: lili_promotion_group
@@ -282,6 +297,8 @@ lili:
notice-send-group: lili_send_notice_group
rocketmq:
name-server: 192.168.0.116:9876
namesrvAddr: 192.168.0.116:9876
isVIPChannel: false
producer:
group: lili_group
send-message-timeout: 30000

View File

@@ -8,20 +8,21 @@
<parent>
<groupId>cn.lili</groupId>
<artifactId>lili-shop-parent</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>cn.lili</groupId>
<artifactId>framework</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.2.0</version>
<version>${xxl-job}</version>
</dependency>
</dependencies>

View File

@@ -12,23 +12,31 @@ import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 分销订单入库
*
* @author Chopper
* @date 2020-07-03 11:20
*/
@Slf4j
@Service
public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDayExecute, AfterSaleStatusChangeEvent {
//分销订单
/**
* 分销订单
*/
@Autowired
private DistributionOrderService distributionOrderService;
//分销订单持久层
@Autowired
/**
* 分销订单持久层
*/
@Resource
private DistributionOrderMapper distributionOrderMapper;
@@ -46,6 +54,9 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
distributionOrderService.cancelOrder(orderMessage.getOrderSn());
break;
}
default:
log.error("分销订单执行异常:", orderMessage.getOrderSn());
break;
}
}

View File

@@ -14,9 +14,11 @@ import org.springframework.stereotype.Service;
* @date 2020-07-03 11:20
*/
@Service
public class GoodsSkuExecute implements GoodsCommentCompleteEvent {
public class GoodsSkuExecute implements GoodsCommentCompleteEvent {
//商品
/**
* 商品
*/
@Autowired
private GoodsSkuService goodsSkuService;

View File

@@ -0,0 +1,102 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.ExperienceSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员经验值
*
* @author Bulbasaur
* @date: 2021/5/16 11:16 下午
*/
@Service
public class MemberExperienceExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent {
/**
* 配置
*/
@Autowired
private SettingService settingService;
/**
* 会员
*/
@Autowired
private MemberService memberService;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 会员注册赠送经验值
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送经验值" + experienceSetting.getRegister());
}
/**
* 商品评价赠送经验值
*
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//赠送会员经验值
memberService.updateMemberExperience(Long.valueOf(experienceSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送经验值" + experienceSetting.getComment());
}
/**
* 完成订单赠送经验值
*
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if (orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)) {
//获取经验值设置
ExperienceSetting experienceSetting = getExperienceSetting();
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//计算赠送经验值数量
Double point = CurrencyUtil.mul(experienceSetting.getMoney(), order.getFlowPrice(), 0);
//赠送会员经验值
memberService.updateMemberExperience(point.longValue(), true, order.getMemberId(), "会员下单,赠送经验值" + point + "");
}
}
/**
* 获取经验值设置
*
* @return 经验值设置
*/
private ExperienceSetting getExperienceSetting() {
Setting setting = settingService.get(SettingEnum.EXPERIENCE_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), ExperienceSetting.class);
}
}

View File

@@ -1,53 +1,129 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.member.service.MemberWalletService;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.PointSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 会员积分
*
* @author Chopper
* @author Bulbasaur
* @date 2020-07-03 11:20
*/
@Service
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent {
public class MemberPointExecute implements MemberRegisterEvent, GoodsCommentCompleteEvent {
//配置
/**
* 配置
*/
@Autowired
private SettingService settingService;
//会员
/**
* 会员
*/
@Autowired
private MemberService memberService;
/**
* 订单
*/
@Autowired
private OrderService orderService;
/**
* 会员注册赠送积分
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting = getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), 1, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getRegister().longValue()), true, member.getId(), "会员注册,赠送积分" + pointSetting.getRegister() + "");
}
/**
* 会员评价赠送积分
*
* @param memberEvaluation 会员评价
*/
@Override
public void goodsComment(MemberEvaluation memberEvaluation) {
//获取签到积分赠送设置
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
PointSetting pointSetting = new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
//获取积分设置
PointSetting pointSetting = getPointSetting();
//赠送会员积分
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), 1, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
memberService.updateMemberPoint(Long.valueOf(pointSetting.getComment().longValue()), true, memberEvaluation.getMemberId(), "会员评价,赠送积分" + pointSetting.getComment() + "");
}
/**
* 非积分订单订单完成后赠送积分
*
* @param orderMessage 订单消息
*/
@Override
public void orderChange(OrderMessage orderMessage) {
if (orderMessage.getNewStatus().equals(OrderStatusEnum.COMPLETED)) {
//根据订单编号获取订单数据,如果为积分订单则跳回
Order order = orderService.getBySn(orderMessage.getOrderSn());
if (order.getOrderPromotionType().equals(OrderPromotionTypeEnum.POINT.name())) {
return;
}
//获取积分设置
PointSetting pointSetting = getPointSetting();
//计算赠送积分数量
Double point = CurrencyUtil.mul(pointSetting.getMoney(), order.getFlowPrice(), 0);
//赠送会员积分
memberService.updateMemberPoint(point.longValue(), true, order.getMemberId(), "会员下单,赠送积分" + point + "");
}
}
/**
* 提交售后后扣除积分
*
* @param afterSale 售后
*/
@Override
public void afterSaleStatusChange(AfterSale afterSale) {
if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
//获取积分设置
PointSetting pointSetting = getPointSetting();
//计算扣除积分数量
Double point = CurrencyUtil.mul(pointSetting.getMoney(), afterSale.getActualRefundPrice(), 0);
//扣除会员积分
memberService.updateMemberPoint(point.longValue(), false, afterSale.getMemberId(), "会员退款,扣除积分" + point + "");
}
}
/**
* 获取积分设置
*
* @return 积分设置
*/
private PointSetting getPointSetting() {
Setting setting = settingService.get(SettingEnum.POINT_SETTING.name());
return new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
}
}

View File

@@ -11,12 +11,11 @@ import cn.lili.modules.message.service.NoticeMessageService;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -45,7 +44,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(tradeDTO.getMemberId());
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.ORDER_CREATE_SUCCESS);
Map<String, String> params = new HashMap<>();
Map<String, String> params = new HashMap<>(2);
params.put("goods", tradeDTO.getSkuList().get(0).getGoodsSku().getGoodsName());
noticeMessageDTO.setParameter(params);
//保存站内信
@@ -59,8 +58,8 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
//如果订单状态不为空
if (orderDetailVO != null) {
Map<String, String> params = new HashMap<>();
switch (orderMessage.getNewStatus()){
Map<String, String> params = new HashMap<>(2);
switch (orderMessage.getNewStatus()) {
//如果订单新的状态为已取消 则发送取消订单站内信
case CANCELLED:
params.put(NoticeMessageParameterEnum.CANCEL_REASON.getType(), orderDetailVO.getOrder().getCancelReason());
@@ -83,7 +82,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
break;
//如果是拼团订单,发送拼团成功消息
case UNDELIVERED:
if(orderDetailVO.getOrder().getOrderType().equals(OrderTypeEnum.PINTUAN.name())){
if (OrderPromotionTypeEnum.PINTUAN.name().equals(orderDetailVO.getOrder().getOrderPromotionType())) {
//拼团成功消息
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.PINTUAN_SUCCESS);
}
@@ -104,7 +103,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
public void afterSaleStatusChange(AfterSale afterSale) {
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(afterSale.getMemberId());
Map<String, String> params = new HashMap<>();
Map<String, String> params = new HashMap<>(2);
params.put("goods", afterSale.getGoodsName());
params.put("refuse", afterSale.getAuditRemark());
noticeMessageDTO.setParameter(params);
@@ -149,11 +148,14 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
@Override
public void memberPointChange(MemberPointMessage memberPointMessage) {
if (memberPointMessage == null) {
return;
}
//组织站内信参数
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(memberPointMessage.getMemberId());
Map<String, String> params = new HashMap<>();
if (memberPointMessage.getType().equals(1)) {
Map<String, String> params = new HashMap<>(2);
if (memberPointMessage.getType()) {
params.put("expenditure_points", "0");
params.put("income_points", memberPointMessage.getPoint().toString());
} else {
@@ -176,7 +178,7 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
//组织参数
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(memberWithdrawalMessage.getMemberId());
Map<String, String> params = new HashMap<>();
Map<String, String> params = new HashMap<>(2);
params.put("income", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_SUCCESS);

View File

@@ -0,0 +1,31 @@
package cn.lili.event.impl;
import cn.lili.event.TradeEvent;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.service.TradeService;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 订单状态处理类
*
* @author Chopper
* @date 2020-07-03 11:20
**/
@Service
public class OrderStatusHandlerExecute implements TradeEvent {
@Autowired
private TradeService tradeService;
@Override
public void orderCreate(TradeDTO tradeDTO) {
//如果订单需要支付金额为0则将订单步入到下一个流程
if (tradeDTO.getPriceDetailDTO().getFlowPrice() <= 0) {
tradeService.payTrade(tradeDTO.getSn(), PaymentMethodEnum.BANK_TRANSFER.name(), "-1");
}
}
}

View File

@@ -10,8 +10,7 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import cn.lili.modules.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -21,13 +20,13 @@ import org.springframework.stereotype.Service;
* @author Chopper
* @date 2021-03-13 16:58
*/
@Slf4j
@Service
public class PaymentExecute implements OrderStatusChangeEvent {
//支付日志
@Autowired
private PaymentService paymentService;
//订单
/**
* 订单
*/
@Autowired
private OrderService orderService;
@@ -37,11 +36,11 @@ public class PaymentExecute implements OrderStatusChangeEvent {
switch (orderMessage.getNewStatus()) {
case CANCELLED:
Order order = orderService.getBySn(orderMessage.getOrderSn());
//未付款不做处理 直接返回
if (order.getPayStatus() == PayStatusEnum.UNPAID.name()) {
//如果未付款,则不去要退回相关代码执行
if (order.getPayStatus().equals(PayStatusEnum.UNPAID.name())) {
return;
}
PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(order.getPaymentMethod());
//进行退款操作
switch (paymentMethodEnum) {
@@ -69,6 +68,9 @@ public class PaymentExecute implements OrderStatusChangeEvent {
break;
case BANK_TRANSFER:
break;
default:
log.error("订单支付执行异常,订单编号:{}", orderMessage.getOrderSn());
break;
}
break;
default:

View File

@@ -0,0 +1,41 @@
package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.promotion.entity.dos.CouponActivity;
import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.service.CouponActivityService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 注册赠券活动
*
* @author Bulbasaur
* @date: 2021/5/24 10:48 上午
*/
@Component
public class RegisteredCouponActivityExecute implements MemberRegisterEvent {
@Autowired
private CouponActivityService couponActivityService;
/**
* 获取进行中的注册赠券的优惠券活动
* 发送注册赠券
*
* @param member 会员
*/
@Override
public void memberRegister(Member member) {
List<CouponActivity> couponActivities = couponActivityService.list(new LambdaQueryWrapper<CouponActivity>()
.eq(CouponActivity::getCouponActivityType, CouponActivityTypeEnum.REGISTERED.name())
.eq(CouponActivity::getPromotionStatus, PromotionStatusEnum.START.name()));
couponActivityService.registered(couponActivities, member);
}
}

View File

@@ -1,5 +1,6 @@
package cn.lili.event.impl;
import cn.hutool.core.convert.Convert;
import cn.lili.common.cache.Cache;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@@ -12,6 +13,7 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.enums.PromotionTypeEnum;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
@@ -26,24 +28,39 @@ import java.util.List;
* @author Chopper
* @date 2020-07-03 11:20
*/
@Slf4j
@Service
public class StockUpdateExecute implements OrderStatusChangeEvent {
//Redis
/**
* 出库失败消息
*/
static String outOfStockMessage = "库存不足,出库失败";
/**
* Redis
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private DefaultRedisScript<Boolean> quantityScript;
//订单
/**
* 订单
*/
@Autowired
private OrderService orderService;
//规格商品
/**
* 规格商品
*/
@Autowired
private GoodsSkuService goodsSkuService;
//促销商品
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
//缓存
/**
* 缓存
*/
@Autowired
private Cache cache;
@@ -52,7 +69,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
switch (orderMessage.getNewStatus()) {
case PAID: {
//获取订单详情
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
//库存key 和 扣减数量
List<String> keys = new ArrayList<>();
@@ -67,33 +84,41 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray());
//如果库存扣减都成功,则记录成交订单
if (Boolean.TRUE.equals(skuResult)) {
log.info("库存扣减成功,参数为{};{}", keys, values);
//库存确认之后对结构处理
orderService.afterOrderConfirm(orderMessage.getOrderSn());
//成功之后,同步库存
synchroDB(order);
} else {
log.info("库存扣件失败变更缓存key{} 变更缓存value{}", keys, values);
//失败之后取消订单
this.errorOrder(orderMessage.getOrderSn());
}
break;
}
case CANCELLED: {
//获取订单详情
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name())) {
//判定是否已支付 并且 非库存不足导致库存回滚 则需要考虑订单库存返还业务
if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name()) && order.getOrder().getCancelReason().equals(outOfStockMessage)) {
//库存key 和 还原数量
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
//返还商品库存,促销库存不与返还,不然前台展示层有展示逻辑错误
for (OrderItem orderItem : order.getOrderItems()) {
if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
Integer goodsPromotionOriginStock = promotionGoodsService.getPromotionGoodsStock(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
int goodsPromotionStock = goodsPromotionOriginStock + orderItem.getNum();
String promotionGoodsStockCacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
stringRedisTemplate.opsForValue().set(promotionGoodsStockCacheKey, Integer.toString(goodsPromotionStock));
}
String stockCacheKey = GoodsSkuService.getStockCacheKey(orderItem.getSkuId());
Integer goodsOriginStock = goodsSkuService.getStock(orderItem.getSkuId());
int goodsStock = goodsOriginStock + orderItem.getNum();
stringRedisTemplate.opsForValue().set(stockCacheKey, Integer.toString(goodsStock));
keys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
int i = orderItem.getNum();
values.add(Integer.toString(i));
}
//批量脚本执行库存回退
Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray());
//返还失败,则记录日志
if (Boolean.FALSE.equals(skuResult)) {
log.error("库存回退异常keys{},回复库存值为: {}", keys, values);
}
rollbackOrderStock(order);
}
break;
}
@@ -108,7 +133,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
* @param orderSn 失败入库订单信息
*/
private void errorOrder(String orderSn) {
orderService.systemCancel(orderSn, "库存不足,出库失败");
orderService.systemCancel(orderSn, outOfStockMessage);
}
@@ -132,8 +157,9 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
}
}
/**
* 写入需要更改促销库存的商品
* 同步库存和促销库存
*
* @param order 订单
*/
@@ -148,7 +174,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
//促销库存key 集合
List<String> promotionKey = new ArrayList<>();
// 循环订单
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();
@@ -159,6 +185,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) {
PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType());
PromotionGoods pGoods = promotionGoodsService.getPromotionGoods(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId());
//记录需要更新的促销库存信息
promotionKey.add(
PromotionGoodsService.getPromotionGoodsStockCacheKey(
promotionTypeEnum,
@@ -170,10 +197,11 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
goodsSkus.add(goodsSku);
}
//批量获取商品库存
List skuStocks = cache.multiGet(skuKeys);
//循环写入商品库存
for (int i = 0; i < skuStocks.size(); i++) {
goodsSkus.get(i).setQuantity(Integer.parseInt(skuStocks.get(i).toString()));
goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
}
//批量修改商品库存
goodsSkuService.updateBatchById(goodsSkus);
@@ -182,14 +210,47 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
if (!promotionKey.isEmpty()) {
List promotionStocks = cache.multiGet(promotionKey);
for (int i = 0; i < promotionKey.size(); i++) {
promotionGoods.get(i).setQuantity(Integer.parseInt(promotionStocks.get(i).toString()));
promotionGoods.get(i).setQuantity(Convert.toInt(promotionStocks.get(i).toString()));
Integer num = promotionGoods.get(i).getNum();
promotionGoods.get(i).setNum((num != null ? num : 0) + order.getOrder().getGoodsNum());
}
promotionGoodsService.updateBatchById(promotionGoods);
}
//商品库存包含sku库存集合批量更新商品库存相关
goodsSkuService.updateGoodsStuck(goodsSkus);
log.info("订单确认,库存同步:商品信息--{};促销信息---{}", goodsSkus, promotionGoods);
}
/**
* 恢复商品库存
*
* @param order 订单
*/
private void rollbackOrderStock(OrderDetailVO order) {
//sku商品
List<GoodsSku> goodsSkus = new ArrayList<>();
//sku库存key 集合
List<String> skuKeys = new ArrayList<>();
//循环订单
for (OrderItem orderItem : order.getOrderItems()) {
skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId()));
GoodsSku goodsSku = new GoodsSku();
goodsSku.setId(orderItem.getSkuId());
goodsSkus.add(goodsSku);
}
//批量获取商品库存
List skuStocks = cache.multiGet(skuKeys);
//循环写入商品SKU库存
for (int i = 0; i < skuStocks.size(); i++) {
goodsSkus.get(i).setQuantity(Convert.toInt(skuStocks.get(i).toString()));
}
log.info("订单取消,库存还原:{}", goodsSkus);
//批量修改商品库存
goodsSkuService.updateBatchById(goodsSkus);
goodsSkuService.updateGoodsStuck(goodsSkus);
}
}

View File

@@ -0,0 +1,72 @@
package cn.lili.event.impl;
import cn.hutool.core.util.RandomUtil;
import cn.lili.common.utils.CommonUtil;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 虚拟商品
*
* @author Bulbasaur
* @date: 2021/5/29 9:17 上午
*/
@Component
public class VerificationOrderExecute implements OrderStatusChangeEvent {
@Autowired
private OrderService orderService;
@Autowired
private OrderItemService orderItemService;
@Override
public void orderChange(OrderMessage orderMessage) {
//订单状态为待核验,添加订单添加核验码
if (orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE)) {
//获取订单信息
Order order = orderService.getBySn(orderMessage.getOrderSn());
//获取随机数,判定是否存在
String code = getCode(order.getStoreId());
//设置订单验证码
orderService.update(new LambdaUpdateWrapper<Order>()
.set(Order::getVerificationCode, code)
.eq(Order::getSn, orderMessage.getOrderSn()));
//修改虚拟订单货物可以进行售后、投诉
orderItemService.update(new LambdaUpdateWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderMessage.getOrderSn())
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.NOT_APPLIED)
.set(OrderItem::getCommentStatus, OrderComplaintStatusEnum.NO_APPLY));
}
}
/**
* 获取随机数
* 判断当前店铺下是否使用验证码,如果已使用则重新获取
*
* @param storeId 店铺ID
* @return
*/
private String getCode(String storeId) {
//获取八位验证码
String code = Long.toString(RandomUtil.randomLong(10000000, 99999999));
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<Order>()
.eq(Order::getVerificationCode, code)
.eq(Order::getStoreId, storeId);
if (orderService.getOne(lambdaQueryWrapper) == null) {
return code;
} else {
return this.getCode(storeId);
}
}
}

View File

@@ -24,7 +24,9 @@ import java.util.List;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.after-sale-topic}", consumerGroup = "${lili.data.rocketmq.after-sale-group}")
public class AfterSaleMessageListener implements RocketMQListener<MessageExt> {
//售后订单状态
/**
* 售后订单状态
*/
@Autowired
private List<AfterSaleStatusChangeEvent> afterSaleStatusChangeEvents;
@@ -43,6 +45,8 @@ public class AfterSaleMessageListener implements RocketMQListener<MessageExt> {
e);
}
}
default:
log.error("售后状态修改事件执行异常:", new String(messageExt.getBody()));
break;
}

View File

@@ -3,6 +3,10 @@ package cn.lili.listener;
import cn.hutool.json.JSONUtil;
import cn.lili.common.rocketmq.tags.GoodsTagsEnum;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.distribution.entity.dos.DistributionSelectedGoods;
import cn.lili.modules.distribution.service.DistributionGoodsService;
import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
@@ -15,6 +19,7 @@ import cn.lili.modules.member.service.GoodsCollectionService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.store.service.StoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
@@ -36,27 +41,52 @@ import java.util.List;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.goods-topic}", consumerGroup = "${lili.data.rocketmq.goods-group}")
public class GoodsMessageListener implements RocketMQListener<MessageExt> {
//ES商品
/**
* ES商品
*/
@Autowired
private EsGoodsIndexService goodsIndexService;
//店铺
/**
* 店铺
*/
@Autowired
private StoreService storeService;
//商品
/**
* 商品
*/
@Autowired
private GoodsService goodsService;
//商品
/**
* 商品Sku
*/
@Autowired
private GoodsSkuService goodsSkuService;
//用户足迹
/**
* 用户足迹
*/
@Autowired
private FootprintService footprintService;
//商品收藏
/**
* 商品收藏
*/
@Autowired
private GoodsCollectionService goodsCollectionService;
//商品评价
/**
* 商品评价
*/
@Autowired
private List<GoodsCommentCompleteEvent> goodsCommentCompleteEvents;
/**
* 分销商品
*/
@Autowired
private DistributionGoodsService distributionGoodsService;
/**
* 分销员-商品关联表
*/
@Autowired
private DistributionSelectedGoodsService distributionSelectedGoodsService;
@Override
public void onMessage(MessageExt messageExt) {
@@ -77,9 +107,10 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
break;
//审核商品
case GOODS_AUDIT:
break;
//删除商品
case GOODS_DELETE:
storeService.updateStoreGoodsNum(new String(messageExt.getBody()));
deleteGoods(messageExt);
break;
//规格删除
case SKU_DELETE:
@@ -107,38 +138,77 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
break;
//购买商品完成
case BUY_GOODS_COMPLETE:
String goodsCompleteMessageStr = new String(messageExt.getBody());
List<GoodsCompleteMessage> goodsCompleteMessageList = JSONUtil.toList(JSONUtil.parseArray(goodsCompleteMessageStr), GoodsCompleteMessage.class);
for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
Goods goods = goodsService.getById(goodsCompleteMessage.getGoodsId());
if (goods != null) {
// 更新商品购买数量
if (goods.getBuyCount() == null) {
goods.setBuyCount(0);
}
int buyCount = goods.getBuyCount() + goodsCompleteMessage.getBuyNum();
LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Goods::getId, goodsCompleteMessage.getGoodsId());
updateWrapper.set(Goods::getBuyCount, buyCount);
goodsService.update(updateWrapper);
} else {
log.error("商品Id为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}
GoodsSku goodsSku = goodsSkuService.getById(goodsCompleteMessage.getSkuId());
if (goodsSku != null) {
// 更新商品购买数量
if (goodsSku.getBuyCount() == null) {
goodsSku.setBuyCount(0);
}
int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
goodsSku.setBuyCount(buyCount);
goodsSkuService.update(goodsSku);
goodsIndexService.updateIndexBuyNum(goodsCompleteMessage.getSkuId(), buyCount);
} else {
log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}
}
this.goodsBuyComplete(messageExt);
break;
default:
log.error("商品执行异常:", new String(messageExt.getBody()));
break;
}
}
/**
* 删除商品
* 1.更新店铺的商品数量
* 2.删除分销员-分销商品绑定关系
* 3.删除分销商品
*
* @param messageExt 消息
*/
private void deleteGoods(MessageExt messageExt) {
Goods goods = JSONUtil.toBean(new String(messageExt.getBody()), Goods.class);
//更新店铺商品数量
storeService.updateStoreGoodsNum(goods.getStoreId());
//删除获取分销商品
DistributionGoods distributionGoods = distributionGoodsService.getOne(new LambdaQueryWrapper<DistributionGoods>()
.eq(DistributionGoods::getGoodsId, goods.getId()));
//删除分销商品绑定关系
distributionSelectedGoodsService.remove(new LambdaQueryWrapper<DistributionSelectedGoods>()
.eq(DistributionSelectedGoods::getDistributionGoodsId, distributionGoods.getId()));
//删除分销商品
distributionGoodsService.removeById(distributionGoods.getId());
}
/**
* 商品购买完成
* 1.更新商品购买数量
* 2.更新SKU购买数量
* 3.更新索引购买数量
*
* @param messageExt
*/
private void goodsBuyComplete(MessageExt messageExt) {
String goodsCompleteMessageStr = new String(messageExt.getBody());
List<GoodsCompleteMessage> goodsCompleteMessageList = JSONUtil.toList(JSONUtil.parseArray(goodsCompleteMessageStr), GoodsCompleteMessage.class);
for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
Goods goods = goodsService.getById(goodsCompleteMessage.getGoodsId());
if (goods != null) {
//更新商品购买数量
if (goods.getBuyCount() == null) {
goods.setBuyCount(0);
}
int buyCount = goods.getBuyCount() + goodsCompleteMessage.getBuyNum();
goodsService.update(new LambdaUpdateWrapper<Goods>()
.eq(Goods::getId, goodsCompleteMessage.getGoodsId())
.set(Goods::getBuyCount, buyCount));
} else {
log.error("商品Id为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}
GoodsSku goodsSku = goodsSkuService.getById(goodsCompleteMessage.getSkuId());
if (goodsSku != null) {
//更新商品购买数量
if (goodsSku.getBuyCount() == null) {
goodsSku.setBuyCount(0);
}
int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
goodsSku.setBuyCount(buyCount);
goodsSkuService.update(goodsSku);
goodsIndexService.updateIndexBuyNum(goodsCompleteMessage.getSkuId(), buyCount);
} else {
log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}
}
}
}

View File

@@ -30,16 +30,24 @@ import java.util.List;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.member-topic}", consumerGroup = "${lili.data.rocketmq.member-group}")
public class MemberMessageListener implements RocketMQListener<MessageExt> {
//会员签到
/**
* 会员签到
*/
@Autowired
private MemberSignService memberSignService;
//会员积分变化
/**
* 会员积分变化
*/
@Autowired
private List<MemberPointChangeEvent> memberPointChangeEvents;
//会员提现
/**
* 会员提现
*/
@Autowired
private List<MemberWithdrawalEvent> memberWithdrawalEvents;
//会员注册
/**
* 会员注册
*/
@Autowired
private List<MemberRegisterEvent> memberSignEvents;

View File

@@ -3,7 +3,6 @@ package cn.lili.listener;
import cn.hutool.json.JSONUtil;
import cn.lili.modules.message.entity.dto.NoticeMessageDTO;
import cn.lili.modules.message.service.NoticeMessageService;
import lombok.RequiredArgsConstructor;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
@@ -20,7 +19,9 @@ import org.springframework.stereotype.Component;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.notice-topic}", consumerGroup = "${lili.data.rocketmq.notice-group}")
public class NoticeMessageListener implements RocketMQListener<MessageExt> {
//站内信
/**
* 站内信
*/
@Autowired
private NoticeMessageService noticeMessageService;

View File

@@ -1,24 +1,34 @@
package cn.lili.listener;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.rocketmq.tags.OtherTagsEnum;
import cn.lili.common.sms.SmsUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.vo.MemberSearchVO;
import cn.lili.modules.member.mapper.MemberMapper;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.message.entity.dos.MemberMessage;
import cn.lili.modules.message.entity.dos.Message;
import cn.lili.modules.message.entity.dos.StoreMessage;
import cn.lili.modules.message.entity.dto.SmsReachDTO;
import cn.lili.modules.message.entity.enums.MessageSendClient;
import cn.lili.modules.message.entity.enums.MessageStatusEnum;
import cn.lili.modules.message.entity.enums.RangeEnum;
import cn.lili.modules.message.service.MemberMessageService;
import cn.lili.modules.message.service.StoreMessageService;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@@ -32,18 +42,36 @@ import java.util.List;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.notice-send-topic}", consumerGroup = "${lili.data.rocketmq.notice-send-group}")
public class NoticeSendMessageListener implements RocketMQListener<MessageExt> {
//会员
@Autowired
/**
* 会员
*/
@Resource
private MemberMapper memberMapper;
//短信
/**
* 短信
*/
@Autowired
private SmsUtil smsUtil;
//店铺消息
/**
* 店铺消息
*/
@Autowired
private StoreMessageService storeMessageService;
//店铺
/**
* 会员消息
*/
@Autowired
private MemberMessageService memberMessageService;
/**
* 店铺
*/
@Autowired
private StoreService storeService;
/**
* 会员
*/
@Autowired
private MemberService memberService;
@Override
public void onMessage(MessageExt messageExt) {
@@ -51,7 +79,6 @@ public class NoticeSendMessageListener implements RocketMQListener<MessageExt> {
case SMS:
String smsJsonStr = new String(messageExt.getBody());
SmsReachDTO smsReachDTO = JSONUtil.toBean(smsJsonStr, SmsReachDTO.class);
//发送全部会员
if (smsReachDTO.getSmsRange().equals(RangeEnum.ALL.name())) {
//获取所有会员的手机号
@@ -65,38 +92,118 @@ public class NoticeSendMessageListener implements RocketMQListener<MessageExt> {
//管理员发送站内信
case MESSAGE:
Message message = JSONUtil.toBean(new String(messageExt.getBody()), Message.class);
List<StoreMessage> list = new ArrayList<>();
//保存商家记录
if (message.getMessageRange().equals("ALL")) {
List<Store> storeList = storeService.list(new QueryWrapper<Store>().eq("store_disable", "OPEN"));
storeList.forEach(item -> {
StoreMessage storeMessage = new StoreMessage();
storeMessage.setMessageId(message.getId());
storeMessage.setStoreName(item.getStoreName());
storeMessage.setStoreId(item.getId());
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
storeMessage.setTitle(message.getTitle());
storeMessage.setContent(message.getContent());
list.add(storeMessage);
});
// 管理端发送给商家的站内信
if (message.getMessageClient().equals(MessageSendClient.STORE.name().toLowerCase())) {
saveStoreMessage(message);
} else {
int i = 0;
for (String str : message.getUserIds()) {
StoreMessage storeMessage = new StoreMessage();
storeMessage.setMessageId(message.getId());
storeMessage.setStoreId(str);
storeMessage.setStoreName(message.getUserNames()[i]);
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
storeMessage.setTitle(message.getTitle());
storeMessage.setContent(message.getContent());
list.add(storeMessage);
i++;
}
//管理员发送给会员的站内信
saveMemberMessage(message);
}
storeMessageService.save(list);
break;
default:
break;
}
}
/**
* 保存店铺消息
*
* @param message 消息
*/
private void saveStoreMessage(Message message) {
List<StoreMessage> list = new ArrayList<>();
//发送全部商家情况
if ("ALL".equals(message.getMessageRange())) {
List<Store> storeList = storeService.list(new QueryWrapper<Store>().eq("store_disable", "OPEN"));
storeList.forEach(item -> {
StoreMessage storeMessage = new StoreMessage();
storeMessage.setMessageId(message.getId());
storeMessage.setStoreName(item.getStoreName());
storeMessage.setStoreId(item.getId());
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
storeMessage.setTitle(message.getTitle());
storeMessage.setContent(message.getContent());
list.add(storeMessage);
});
} else {
//发送给指定商家情况
int i = 0;
for (String str : message.getUserIds()) {
StoreMessage storeMessage = new StoreMessage();
storeMessage.setMessageId(message.getId());
storeMessage.setStoreId(str);
storeMessage.setStoreName(message.getUserNames()[i]);
storeMessage.setStatus(MessageStatusEnum.UN_READY.name());
storeMessage.setTitle(message.getTitle());
storeMessage.setContent(message.getContent());
list.add(storeMessage);
i++;
}
}
if (list.size() > 0) {
//执行保存
storeMessageService.save(list);
}
}
/**
* 保存会员消息
*
* @param message 消息
*/
private void saveMemberMessage(Message message) {
List<MemberMessage> list = new ArrayList<>();
//如果是给所有会员发送消息
if ("ALL".equals(message.getMessageRange())) {
//查询所有会员总数,因为会员总数比较大 如果一次性查出来会占用数据库资源,所以要分页查询
MemberSearchVO memberSearchVO = new MemberSearchVO();
memberSearchVO.setDisabled(SwitchEnum.OPEN.name());
Integer memberNum = memberService.getMemberNum(memberSearchVO);
//构建分页查询参数
//100条查一次
Integer pageSize = 100;
Integer pageCount = 0;
pageCount = memberNum / pageSize;
pageCount = memberNum % pageSize > 0 ? pageCount + 1 : pageCount;
for (int i = 1; i <= pageCount; i++) {
PageVO pageVO = new PageVO();
pageVO.setPageSize(pageSize);
pageVO.setPageNumber(i);
IPage<Member> page = memberService.getMemberPage(memberSearchVO, pageVO);
//循环要保存的信息
page.getRecords().forEach(item -> {
MemberMessage memberMessage = new MemberMessage();
memberMessage.setContent(message.getContent());
memberMessage.setTitle(message.getTitle());
memberMessage.setMessageId(message.getId());
memberMessage.setMemberId(item.getId());
memberMessage.setMemberName(item.getUsername());
memberMessage.setStatus(MessageStatusEnum.UN_READY.name());
list.add(memberMessage);
});
}
} else {
//如果是给指定会员发送消息
int i = 0;
for (String str : message.getUserIds()) {
MemberMessage memberMessage = new MemberMessage();
memberMessage.setMessageId(message.getId());
memberMessage.setMemberId(str);
memberMessage.setMemberName(message.getUserNames()[i]);
memberMessage.setStatus(MessageStatusEnum.UN_READY.name());
memberMessage.setTitle(message.getTitle());
memberMessage.setContent(message.getContent());
list.add(memberMessage);
i++;
}
}
if (list.size() > 0) {
//执行保存
memberMessageService.save(list);
}
}
}

View File

@@ -27,13 +27,19 @@ import java.util.List;
@RocketMQMessageListener(topic = "${lili.data.rocketmq.order-topic}", consumerGroup = "${lili.data.rocketmq.order-group}")
public class OrderMessageListener implements RocketMQListener<MessageExt> {
//交易
/**
* 交易
*/
@Autowired
private List<TradeEvent> tradeEvent;
//订单状态
/**
* 订单状态
*/
@Autowired
private List<OrderStatusChangeEvent> orderStatusChangeEvents;
//缓存
/**
* 缓存
*/
@Autowired
private Cache<Object> cache;
@@ -44,6 +50,7 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
case ORDER_CREATE:
String key = new String(messageExt.getBody());
TradeDTO tradeDTO = (TradeDTO) cache.get(key);
boolean result = true;
for (TradeEvent event : tradeEvent) {
try {
event.orderCreate(tradeDTO);
@@ -52,8 +59,14 @@ public class OrderMessageListener implements RocketMQListener<MessageExt> {
tradeDTO.getSn(),
event.getClass().getName(),
e);
result = false;
}
}
//如所有步骤顺利完成
if (Boolean.TRUE.equals(result)) {
//清除记录信息的trade cache key
cache.remove(key);
}
break;
//订单状态变更
case STATUS_CHANGE:

View File

@@ -1,15 +1,15 @@
package cn.lili.timetask.handler.impl.bill;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
import cn.lili.modules.store.mapper.StoreDetailMapper;
import cn.lili.modules.store.service.BillService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -21,11 +21,15 @@ import java.util.List;
@Component
public class BillExecute implements EveryDayExecute {
//结算单
/**
* 结算单
*/
@Autowired
private BillService billService;
//店铺详情
@Autowired
/**
* 店铺详情
*/
@Resource
private StoreDetailMapper storeDetailMapper;
/**
@@ -36,20 +40,22 @@ public class BillExecute implements EveryDayExecute {
@Override
public void execute() {
//获取当前时间的前一
String day = "," + DateUtil.date().dayOfMonth() + ",";
//获取当前天
int day = DateUtil.date().dayOfMonth();
//获取待结算商家列表
List<StoreSettlementDay> storeList = storeDetailMapper.getSettlementStore(new QueryWrapper<StoreSettlementDay>().like("settlement_cycle", day));
List<StoreSettlementDay> storeList = storeDetailMapper.getSettlementStore(day);
//获取当前时间
DateTime endTime =DateUtil.date();
//批量商家结算
for (StoreSettlementDay storeSettlementDay : storeList) {
//生成结算单
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay());
billService.createBill(storeSettlementDay.getStoreId(), storeSettlementDay.getSettlementDay(),endTime);
//修改店铺结算时间
storeDetailMapper.updateSettlementDay(storeSettlementDay.getStoreId(), DateUtil.date());
storeDetailMapper.updateSettlementDay(storeSettlementDay.getStoreId(), endTime);
}
}
}

View File

@@ -0,0 +1,25 @@
package cn.lili.timetask.handler.impl.broadcast;
import cn.lili.modules.goods.service.CommodityService;
import cn.lili.timetask.handler.EveryHourExecute;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 小程序直播状态获取
*
* @author Bulbasaur
* @date: 2021/5/20 2:52 下午
*/
@Component
public class BroadcastExecute implements EveryHourExecute {
@Autowired
private CommodityService commodityService;
@Override
public void execute() {
//同步直播商品状态
commodityService.getGoodsWareHouse();
}
}

View File

@@ -0,0 +1,38 @@
package cn.lili.timetask.handler.impl.coupon;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.service.MemberCouponService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 优惠券状态监测
*
* @author Bulbasaur
* @date: 2021/5/24 10:08 上午
*/
@Component
public class CouponExecute implements EveryDayExecute {
@Autowired
private MemberCouponService memberCouponService;
/**
* 检测优惠券的使用时间,超期未使用则失效
* 此方法用于领取*天后失效优惠券使用
*/
@Override
public void execute() {
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
.le(MemberCoupon::getEndTime, DateUtil.date())
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
this.memberCouponService.update(updateWrapper);
}
}

View File

@@ -1,5 +1,6 @@
package cn.lili.timetask.handler.impl.goods;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.modules.goods.mapper.GoodsMapper;
@@ -7,9 +8,9 @@ import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.mapper.MemberEvaluationMapper;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@@ -21,11 +22,15 @@ import java.util.Map;
*/
@Component
public class GoodsExecute implements EveryDayExecute {
//会员评价
@Autowired
/**
* 会员评价
*/
@Resource
private MemberEvaluationMapper memberEvaluationMapper;
//商品
@Autowired
/**
* 商品
*/
@Resource
private GoodsMapper goodsMapper;
/**
@@ -39,9 +44,8 @@ public class GoodsExecute implements EveryDayExecute {
new QueryWrapper<MemberEvaluation>()
.between("create_time", DateUtil.yesterday(), new DateTime()));
System.out.println("评论数量" + list.size());
for (Map<String, Object> map : list) {
goodsMapper.addGoodsCommentNum(Integer.parseInt(map.get("num").toString()), map.get("goods_id").toString());
goodsMapper.addGoodsCommentNum(Convert.toInt(map.get("num").toString()), map.get("goods_id").toString());
}
}

View File

@@ -12,7 +12,6 @@ import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryMinuteExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -28,12 +27,15 @@ import java.util.stream.Collectors;
**/
@Slf4j
@Component
public class CancelOrderTaskExecute implements EveryMinuteExecute {
//订单
/**
* 订单
*/
@Autowired
private OrderService orderService;
//设置
/**
* 设置
*/
@Autowired
private SettingService settingService;
@@ -43,11 +45,11 @@ public class CancelOrderTaskExecute implements EveryMinuteExecute {
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
if (orderSetting != null && orderSetting.getAutoCancel() != null) {
// 订单自动取消时间 = 当前时间 - 自动取消时间分钟数
//订单自动取消时间 = 当前时间 - 自动取消时间分钟数
DateTime cancelTime = DateUtil.offsetMinute(DateUtil.date(), -orderSetting.getAutoCancel());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.UNPAID.name());
// 订单创建时间 <= 订单自动取消时间
//订单创建时间 <= 订单自动取消时间
queryWrapper.le(Order::getCreateTime, cancelTime);
List<Order> list = orderService.list(queryWrapper);
List<String> cancelSnList = list.stream().map(Order::getSn).collect(Collectors.toList());

View File

@@ -3,13 +3,19 @@ package cn.lili.timetask.handler.impl.order;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.member.entity.dto.MemberEvaluationDTO;
import cn.lili.modules.member.entity.enums.EvaluationGradeEnum;
import cn.lili.modules.member.service.MemberEvaluationService;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.CommentStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderComplaintStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.mapper.OrderItemMapper;
import cn.lili.modules.order.order.service.AfterSaleService;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.entity.dos.Setting;
@@ -18,12 +24,13 @@ import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@@ -36,35 +43,53 @@ import java.util.stream.Collectors;
public class OrderEveryDayTaskExecute implements EveryDayExecute {
//订单
/**
* 订单
*/
@Autowired
private OrderService orderService;
//订单货物
/**
* 订单货物
*/
@Autowired
private OrderItemService orderItemService;
//设置
@Resource
private OrderItemMapper orderItemMapper;
/**
* 设置
*/
@Autowired
private SettingService settingService;
//会员评价
/**
* 会员评价
*/
@Autowired
private MemberEvaluationService memberEvaluationService;
@Autowired
private AfterSaleService afterSaleService;
/**
* 执行每日任务
*/
@Override
public void execute() {
Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
//自动确认收货
//订单设置
OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
if (orderSetting == null) {
throw new ServiceException("系统配置异常");
throw new ServiceException(ResultCode.ORDER_SETTING_ERROR);
}
//自动确认收货
completedOrder(orderSetting);
//自动好评
memberEvaluation(orderSetting);
//关闭允许售后申请
closeAfterSale(orderSetting);
//关闭允许投诉
closeComplaint(orderSetting);
}
/**
@@ -73,21 +98,21 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
* @param orderSetting 订单设置
*/
private void completedOrder(OrderSetting orderSetting) {
// 订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.DELIVERED.name());
// 订单发货时间 >= 订单自动收货时间
//订单发货时间 >= 订单自动收货时间
queryWrapper.ge(Order::getLogisticsTime, receiveTime);
List<Order> list = orderService.list(queryWrapper);
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
if (!receiveSnList.isEmpty()) {
LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(Order::getSn, receiveSnList);
updateWrapper.set(Order::getOrderStatus, OrderStatusEnum.COMPLETED.name()).set(Order::getCompleteTime, new Date());
boolean update = orderService.update(updateWrapper);
if (Boolean.FALSE.equals(update)) {
log.error("自动收货订单失败!订单编号为[{}]", receiveSnList);
//判断是否有符合条件的订单,进行订单完成处理
if (!list.isEmpty()) {
List<String> receiveSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
for (String orderSn : receiveSnList) {
orderService.complete(orderSn);
}
}
}
@@ -98,27 +123,94 @@ public class OrderEveryDayTaskExecute implements EveryDayExecute {
* @param orderSetting 订单设置
*/
private void memberEvaluation(OrderSetting orderSetting) {
// 订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoReceive());
// 订单完成时间 <= 订单自动好评时间
List<OrderItem> orderItems = orderItemService.waitEvaluate(receiveTime);
//订单自动收货时间 = 当前时间 - 自动收货时间天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
for (OrderItem orderItem : orderItems) {
//订单完成时间 <= 订单自动好评时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.ge("o.complete_time", receiveTime);
queryWrapper.eq("oi.comment_status", CommentStatusEnum.UNFINISHED.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
MemberEvaluationDTO memberEvaluationDTO = new MemberEvaluationDTO();
memberEvaluationDTO.setOrderItemSn(orderItem.getSn());
memberEvaluationDTO.setContent("系统默认好评");
memberEvaluationDTO.setGoodsId(orderItem.getGoodsId());
memberEvaluationDTO.setSkuId(orderItem.getSkuId());
memberEvaluationDTO.setGrade(EvaluationGradeEnum.GOOD.name());
memberEvaluationDTO.setDeliveryScore(5);
memberEvaluationDTO.setDescriptionScore(5);
memberEvaluationDTO.setServiceScore(5);
memberEvaluationService.addMemberEvaluation(memberEvaluationDTO);
//判断是否有符合条件的订单,进行自动评价处理
if (!orderItems.isEmpty()) {
for (OrderItem orderItem : orderItems) {
MemberEvaluationDTO memberEvaluationDTO = new MemberEvaluationDTO();
memberEvaluationDTO.setOrderItemSn(orderItem.getSn());
memberEvaluationDTO.setContent("系统默认好评");
memberEvaluationDTO.setGoodsId(orderItem.getGoodsId());
memberEvaluationDTO.setSkuId(orderItem.getSkuId());
memberEvaluationDTO.setGrade(EvaluationGradeEnum.GOOD.name());
memberEvaluationDTO.setDeliveryScore(5);
memberEvaluationDTO.setDescriptionScore(5);
memberEvaluationDTO.setServiceScore(5);
memberEvaluationService.addMemberEvaluation(memberEvaluationDTO);
}
}
}
/**
* 关闭允许售后申请
*
* @param orderSetting 订单设置
*/
private void closeAfterSale(OrderSetting orderSetting) {
//订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getAutoEvaluation());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.ge("o.complete_time", receiveTime);
queryWrapper.eq("oi.after_sale_status", OrderItemAfterSaleStatusEnum.NOT_APPLIED.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
//判断是否有符合条件的订单,关闭允许售后申请处理
if (!orderItems.isEmpty()) {
//获取订单货物ID
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
//修改订单售后状态
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
.in(OrderItem::getId, orderItemIdList);
orderItemService.update(lambdaUpdateWrapper);
}
}
/**
* 关闭允许交易投诉
*
* @param orderSetting 订单设置
*/
private void closeComplaint(OrderSetting orderSetting) {
//订单关闭交易投诉申请时间 = 当前时间 - 自动关闭交易投诉申请天数
DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(), -orderSetting.getCloseComplaint());
//关闭售后订单=未售后订单+小于订单关闭售后申请时间
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.ge("o.complete_time", receiveTime);
queryWrapper.eq("oi.complain_status", OrderComplaintStatusEnum.NO_APPLY.name());
List<OrderItem> orderItems = orderItemMapper.waitOperationOrderItem(queryWrapper);
//判断是否有符合条件的订单,关闭允许售后申请处理
if (!orderItems.isEmpty()) {
//获取订单货物ID
List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
//修改订单投诉状态
LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
.set(OrderItem::getComplainStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
.in(OrderItem::getId, orderItemIdList);
orderItemService.update(lambdaUpdateWrapper);
}
}
}

View File

@@ -3,15 +3,22 @@ package cn.lili.timetask.handler.impl.promotion;
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
import cn.lili.modules.promotion.entity.vos.CouponVO;
import cn.lili.modules.promotion.entity.vos.PintuanVO;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.SeckillSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -28,114 +35,197 @@ import java.util.List;
* @author Chopper
* @date 2021/3/18 3:23 下午
*/
@Slf4j
@Component
public class PromotionEverydayExecute implements EveryDayExecute {
//Mongo
/**
* Mongo
*/
@Autowired
private MongoTemplate mongoTemplate;
//es
/**
* ES商品索引
*/
@Autowired
private EsGoodsIndexService esGoodsIndexService;
//满额活动
/**
* 满额活动
*/
@Autowired
private FullDiscountService fullDiscountService;
//拼团
/**
* 拼团
*/
@Autowired
private PintuanService pintuanService;
//优惠券
/**
* 优惠券
*/
@Autowired
private CouponService couponService;
//会员优惠券
/**
* 会员优惠券
*/
@Autowired
private MemberCouponService memberCouponService;
//促销商品
/**
* 促销商品
*/
@Autowired
private PromotionGoodsService promotionGoodsService;
/**
* 系统设置
*/
@Autowired
private SettingService settingService;
/**
* 秒杀活动
*/
@Autowired
private SeckillService seckillService;
/**
* 将已过期的促销活动置为结束
*/
@Override
public void execute() {
//mongo查询条件
Query query = new Query();
// 结束条件 活动关闭/活动结束
//结束条件 活动关闭/活动结束
query.addCriteria(Criteria.where("promotionStatus").ne(PromotionStatusEnum.END.name())
.orOperator(Criteria.where("promotionStatus").ne(PromotionStatusEnum.CLOSE.name())));
//结束条件 活动结束时间大于当前时间
query.addCriteria(Criteria.where("endTime").lt(new Date()));
List<String> promotionIds = new ArrayList<>();
//结束满减活动
endFullDiscount(query);
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
promotionIds.addAll(ids);
}
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
//准备修改活动的id
List<String> ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
pintuanService.update(this.getUpdatePromotionWrapper(ids));
promotionIds.addAll(ids);
}
endPintuan(query);
//关闭优惠券活动
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
for (CouponVO vo : couponVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
couponService.update(this.getUpdatePromotionWrapper(ids));
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
memberCouponService.update(memberCouponLambdaUpdateWrapper);
promotionIds.addAll(ids);
}
//结束优惠券
endCoupon(query);
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(promotionIds));
//定时创建活动
addSeckill();
}
/**
* 结束优惠券活动
*
* @param query
*/
private void endCoupon(Query query) {
try {
//关闭优惠券活动
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
if (!couponVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
// //关闭的优惠券活动
for (CouponVO vo : couponVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
couponService.update(this.getUpdatePromotionWrapper(ids));
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
memberCouponService.update(memberCouponLambdaUpdateWrapper);
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("优惠券活动关闭错误", e);
}
}
/**
* 结束拼团活动
*
* @param query
*/
private void endPintuan(Query query) {
try {
//关闭拼团活动
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
if (!pintuanVOS.isEmpty()) {
//准备修改活动的id
List<String> ids = new ArrayList<>();
for (PintuanVO vo : pintuanVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
pintuanService.update(this.getUpdatePromotionWrapper(ids));
//将活动商品对照表进行结束处理
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(ids));
}
} catch (Exception e) {
log.error("拼团活动关闭错误", e);
}
}
/**
* 结束满减活动
*
* @param query
*/
private void endFullDiscount(Query query) {
try {
//关闭满减活动
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
if (!fullDiscountVOS.isEmpty()) {
List<String> ids = new ArrayList<>();
//循环活动 关闭活动
for (FullDiscountVO vo : fullDiscountVOS) {
vo.setPromotionStatus(PromotionStatusEnum.END.name());
if (vo.getPromotionGoodsList() != null && !vo.getPromotionGoodsList().isEmpty()) {
for (PromotionGoods promotionGoods : vo.getPromotionGoodsList()) {
promotionGoods.setPromotionStatus(PromotionStatusEnum.END.name());
esGoodsIndexService.deleteEsGoodsPromotionByPromotionId(promotionGoods.getSkuId(), vo.getId());
}
}
mongoTemplate.save(vo);
ids.add(vo.getId());
}
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
}
} catch (Exception e) {
log.error("满减活动关闭错误", e);
}
}
/**
* 添加秒杀活动
* 从系统设置中获取秒杀活动的配置
* 添加30天后的秒杀活动
*/
private void addSeckill() {
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
Seckill seckill = new Seckill(30, seckillSetting.getHours(), seckillSetting.getSeckillRule());
seckillService.saveSeckill(seckill);
}
/**
* 获取促销修改查询条件 修改活动状态
* @param ids
* @return
*
* @param ids 促销活动ID
* @return 促销活动商品查询Wrapper
*/
private UpdateWrapper getUpdatePromotionWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();
@@ -143,10 +233,12 @@ public class PromotionEverydayExecute implements EveryDayExecute {
updateWrapper.set("promotion_status", PromotionStatusEnum.END.name());
return updateWrapper;
}
/**
* 获取商品的促销修改查询条件 修改商品状态
* @param ids
* @return
*
* @param ids 促销活动ID
* @return 促销活动商品修改Wrapper
*/
private UpdateWrapper getUpdatePromotionGoodsWrapper(List<String> ids) {
UpdateWrapper updateWrapper = new UpdateWrapper<>();

View File

@@ -20,7 +20,9 @@ import java.util.Date;
@Component
public class MemberStatisticsExecute implements EveryDayExecute {
//会员统计
/**
* 会员统计
*/
@Autowired
private MemberStatisticsDataService memberStatisticsDataService;

View File

@@ -24,10 +24,14 @@ import java.util.stream.Collectors;
@Component
public class OnlineMemberStatistics implements EveryHourExecute {
//缓存
/**
* 缓存
*/
@Autowired
private Cache cache;
//统计小时
/**
* 统计小时
*/
@Autowired
private StatisticsProperties statisticsProperties;

View File

@@ -11,10 +11,10 @@ import cn.lili.timetask.handler.EveryDayExecute;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -25,11 +25,15 @@ import java.util.List;
*/
@Component
public class StoreRatingExecute implements EveryDayExecute {
//店铺
/**
* 店铺
*/
@Autowired
private StoreService storeService;
//会员评价
@Autowired
/**
* 会员评价
*/
@Resource
private MemberEvaluationMapper memberEvaluationMapper;
@@ -39,10 +43,10 @@ public class StoreRatingExecute implements EveryDayExecute {
List<Store> storeList = storeService.list(new LambdaQueryWrapper<Store>().eq(Store::getStoreDisable, StoreStatusEnum.OPEN.name()));
for (Store store : storeList) {
//店铺所有开启的评价
LambdaQueryWrapper<MemberEvaluation> QueryWrapper = Wrappers.lambdaQuery();
QueryWrapper.eq(MemberEvaluation::getStoreId, store.getId());
QueryWrapper.eq(MemberEvaluation::getStatus, SwitchEnum.OPEN.name());
StoreRatingVO storeRatingVO = memberEvaluationMapper.getStoreRatingVO(QueryWrapper);
LambdaQueryWrapper<MemberEvaluation> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(MemberEvaluation::getStoreId, store.getId());
lambdaQueryWrapper.eq(MemberEvaluation::getStatus, SwitchEnum.OPEN.name());
StoreRatingVO storeRatingVO = memberEvaluationMapper.getStoreRatingVO(lambdaQueryWrapper);
if (storeRatingVO != null) {
//保存评分

View File

@@ -1,9 +1,9 @@
package cn.lili.timetask.handler.impl.view;
import cn.hutool.core.convert.Convert;
import cn.lili.common.cache.Cache;
import cn.lili.common.cache.CachePrefix;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.DateUtil;
import cn.lili.modules.statistics.model.dos.PlatformViewData;
import cn.lili.modules.statistics.service.PlatformViewDataService;
import cn.lili.timetask.handler.EveryDayExecute;
@@ -28,10 +28,14 @@ import java.util.List;
@Slf4j
@Component
public class PageViewStatisticsExecute implements EveryDayExecute {
//缓存
/**
* 缓存
*/
@Autowired
private Cache cache;
//平台PV统计
/**
* 平台PV统计
*/
@Autowired
private PlatformViewDataService platformViewDataService;
@@ -167,15 +171,15 @@ class PageViewStatistics {
//将字符串解析成需要的对象
str = str.substring(str.indexOf("}") + 2);
String[] dateStr = str.split("-");
Integer year = Integer.parseInt(dateStr[0]);
Integer month = Integer.parseInt(dateStr[1]);
Integer year = Convert.toInt(dateStr[0]);
Integer month = Convert.toInt(dateStr[1]);
Integer day;
//是否有店铺id
if (dateStr.length > 3) {
day = Integer.parseInt(dateStr[2]);
day = Convert.toInt(dateStr[2]);
this.storeId = dateStr[3];
} else {
day = Integer.parseInt(dateStr[2]);
day = Convert.toInt(dateStr[2]);
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
@@ -186,7 +190,6 @@ class PageViewStatistics {
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
this.date = calendar.getTime();
System.out.println(DateUtil.toString(date,DateUtil.STANDARD_FORMAT));
}
}

View File

@@ -1,6 +1,7 @@
package cn.lili.common.delayqueue;
package cn.lili.trigger;
import cn.lili.common.utils.RedisUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.cache.Cache;
import cn.lili.common.utils.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -8,7 +9,6 @@ import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.Calendar;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -19,48 +19,35 @@ import java.util.concurrent.TimeUnit;
* @since 2020/11/7
**/
@Slf4j
public abstract class AbstractDelayQueueMachineFactory {
public abstract class AbstractDelayQueueListen {
@Autowired
private RedisUtil redisUtil;
private Cache cache;
/**
* 插入任务id
*
* @param jobId 任务id(队列内唯一)
* @param time 延时时间(单位 :)
* @return 是否插入成功
*/
public boolean addJobId(String jobId, Integer time) {
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND, time);
long delaySeconds = instance.getTimeInMillis() / 1000;
boolean result = redisUtil.zadd(setDelayQueueName(), delaySeconds, jobId);
log.info("redis add delay, key {}, delay time {}", setDelayQueueName(), time);
return result;
}
/**
* 延时队列机器开始运作
*/
private void startDelayQueueMachine() {
log.info(String.format("延时队列机器{%s}开始运作", setDelayQueueName()));
log.info("延时队列机器{}开始运作", setDelayQueueName());
// 发生异常捕获并且继续不能让战斗停下来
//监听redis队列
while (true) {
try {
// 获取当前时间的时间戳
//获取当前时间的时间戳
long now = System.currentTimeMillis() / 1000;
// 获取当前时间前的任务列表
Set<DefaultTypedTuple> tuples = redisUtil.zrangeByScoreWithScores(setDelayQueueName(), 0, now);
// 如果不为空则遍历判断其是否满足取消要求
if (!CollectionUtils.isEmpty(tuples)) {
for (DefaultTypedTuple tuple : tuples) {
//获取当前时间前需要执行的任务列表
Set<DefaultTypedTuple> tuples = cache.zRangeByScore(setDelayQueueName(), 0, now);
//如果任务不为空
if (!CollectionUtils.isEmpty(tuples)) {
log.info("执行任务:{}", JSONUtil.toJsonStr(tuples));
for (DefaultTypedTuple tuple : tuples) {
String jobId = (String) tuple.getValue();
Long num = redisUtil.zremove(setDelayQueueName(), jobId);
// 如果移除成功, 则执行
//移除缓存如果移除成功则表示当前线程处理了延时任务则执行延时任务
Long num = cache.zRemove(setDelayQueueName(), jobId);
//如果移除成功, 则执行
if (num > 0) {
ThreadPoolUtil.execute(() -> invoke(jobId));
}
@@ -68,9 +55,9 @@ public abstract class AbstractDelayQueueMachineFactory {
}
} catch (Exception e) {
log.error(String.format("处理延时任务发生异常,异常原因为{%s}", e.getMessage()), e);
log.error("处理延时任务发生异常,异常原因为{}", e.getMessage(), e);
} finally {
// 间隔一秒钟搞一次
//间隔一秒钟搞一次
try {
TimeUnit.SECONDS.sleep(5L);
} catch (InterruptedException e) {
@@ -92,13 +79,17 @@ public abstract class AbstractDelayQueueMachineFactory {
/**
* 要实现延时队列的名字
* @return 促销延时队列名称
*/
public abstract String setDelayQueueName();
/**
* 监听队列
*/
@PostConstruct
public void init() {
new Thread(this::startDelayQueueMachine).start();
ThreadPoolUtil.getPool().execute(this::startDelayQueueMachine);
}
}

View File

@@ -2,9 +2,8 @@ package cn.lili.trigger;
import cn.hutool.json.JSONUtil;
import cn.lili.common.cache.Cache;
import cn.lili.common.trigger.interfaces.TimeTriggerExecutor;
import cn.lili.common.trigger.model.TimeTriggerMsg;
import cn.lili.common.trigger.util.TimeTriggerUtil;
import cn.lili.common.trigger.util.DelayQueueTools;
import cn.lili.common.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
@@ -28,7 +27,7 @@ public class TimeTriggerConsumer implements RocketMQListener<TimeTriggerMsg> {
@Override
public void onMessage(TimeTriggerMsg timeTriggerMsg) {
try {
String key = TimeTriggerUtil.generateKey(timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getTriggerTime(), timeTriggerMsg.getUniqueKey());
String key = DelayQueueTools.generateKey(timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getTriggerTime(), timeTriggerMsg.getUniqueKey());
if (cache.get(key) == null) {
log.info("执行器执行被取消:{} | 任务标识:{}", timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getUniqueKey());

View File

@@ -1,15 +1,16 @@
package cn.lili.common.trigger.interfaces;
package cn.lili.trigger;
/**
* 延时任务执行器接口
* @author Chopper
*
* @author Chopper
*/
public interface TimeTriggerExecutor {
/**
* 执行任务
*
* @param object 任务参数
*/
void execute(Object object);

View File

@@ -0,0 +1,36 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.BroadcastMessage;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.modules.goods.service.StudioService;
import cn.lili.trigger.TimeTriggerExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 直播间事件触发
*
* @author Bulbasaur
* @date: 2021/6/1 5:02 下午
*/
@Slf4j
@Component(TimeExecuteConstant.BROADCAST_EXECUTOR)
public class BroadcastTimeTriggerExecutor implements TimeTriggerExecutor {
@Autowired
private StudioService studioService;
@Override
public void execute(Object object) {
//直播间订单消息
BroadcastMessage broadcastMessage = JSONUtil.toBean(JSONUtil.parseObj(object), BroadcastMessage.class);
if (broadcastMessage != null && broadcastMessage.getStudioId() != null) {
log.info("直播间消费:{}", broadcastMessage);
//修改直播间状态
studioService.updateStudioStatus(broadcastMessage);
}
}
}

View File

@@ -1,13 +1,12 @@
package cn.lili.trigger.executor;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.PintuanOrderMessage;
import cn.lili.common.delayqueue.PromotionMessage;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import cn.lili.common.trigger.interfaces.TimeTriggerExecutor;
import cn.lili.trigger.TimeTriggerExecutor;
import cn.lili.common.trigger.message.PintuanOrderMessage;
import cn.lili.common.trigger.message.PromotionMessage;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.common.trigger.model.TimeTriggerMsg;
import cn.lili.common.utils.DateUtil;
import cn.lili.config.rocketmq.RocketmqCustomProperties;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
@@ -26,16 +25,24 @@ import org.springframework.stereotype.Component;
@Slf4j
@Component(TimeExecuteConstant.PROMOTION_EXECUTOR)
public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
//促销
/**
* 促销
*/
@Autowired
private PromotionService promotionService;
//Rocketmq
/**
* RocketMQ
*/
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
//延时任务
/**
* 延时任务
*/
@Autowired
private TimeTrigger timeTrigger;
//订单
/**
* 订单
*/
@Autowired
private OrderService orderService;
@@ -43,23 +50,25 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
@Override
public void execute(Object object) {
PromotionMessage promotionMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PromotionMessage.class);
// 促销延时信息
//促销延时信息
if (promotionMessage != null && promotionMessage.getPromotionId() != null) {
log.info("促销活动信息消费:{}", promotionMessage);
// 如果为促销活动开始,则需要发布促销活动结束的定时任务
//如果为促销活动开始,则需要发布促销活动结束的定时任务
if (PromotionStatusEnum.START.name().equals(promotionMessage.getPromotionStatus())) {
if (!promotionService.updatePromotionStatus(promotionMessage)) {
log.error("开始促销活动失败: {}", promotionMessage);
return;
}
// 促销活动开始后,设置促销活动结束的定时任务
//促销活动开始后,设置促销活动结束的定时任务
promotionMessage.setPromotionStatus(PromotionStatusEnum.END.name());
String uniqueKey = "{TIME_TRIGGER_" + promotionMessage.getPromotionType() + "}_" + promotionMessage.getPromotionId();
// 结束时间(延时一分钟)
//结束时间(延时一分钟)
long closeTime = promotionMessage.getEndTime().getTime() + 60000;
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR, closeTime, promotionMessage, uniqueKey, rocketmqCustomProperties.getPromotionTopic());
timeTrigger.addDelay(timeTriggerMsg, DateUtil.getDelayTime(promotionMessage.getEndTime().getTime()));
//添加延时任务
timeTrigger.addDelay(timeTriggerMsg);
} else {
//不是开始,则修改活动状态
promotionService.updatePromotionStatus(promotionMessage);
}
return;
@@ -68,7 +77,7 @@ public class PromotionTimeTriggerExecutor implements TimeTriggerExecutor {
PintuanOrderMessage pintuanOrderMessage = JSONUtil.toBean(JSONUtil.parseObj(object), PintuanOrderMessage.class);
if (pintuanOrderMessage != null && pintuanOrderMessage.getPintuanId() != null) {
log.info("拼团订单信息消费:{}", pintuanOrderMessage);
// 拼团订单自动处理
//拼团订单自动处理
orderService.agglomeratePintuanOrder(pintuanOrderMessage.getPintuanId(), pintuanOrderMessage.getOrderSn());
}
}

View File

@@ -1,34 +1,34 @@
package cn.lili.common.trigger.delay;
package cn.lili.trigger.listen;
import cn.hutool.json.JSONUtil;
import cn.lili.common.delayqueue.AbstractDelayQueueMachineFactory;
import cn.lili.common.trigger.enums.DelayQueueEnums;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import cn.lili.common.trigger.model.TimeTriggerMsg;
import cn.lili.trigger.AbstractDelayQueueListen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 促销延迟队列
* PromotionTimeTriggerListen
*
* @author paulG
* @version v4.1
* @date 2020/11/17 7:19 下午
* @description
* @since 1
* @author Chopper
* @version v1.0
* 2021-06-11 10:47
*/
@Component
public class PromotionDelayQueue extends AbstractDelayQueueMachineFactory {
public class PromotionDelayQueueListen extends AbstractDelayQueueListen {
@Autowired
private TimeTrigger timeTrigger;
@Override
public void invoke(String jobId) {
timeTrigger.add(JSONUtil.toBean(jobId, TimeTriggerMsg.class));
timeTrigger.execute(JSONUtil.toBean(jobId, TimeTriggerMsg.class));
}
@Override
public String setDelayQueueName() {
return "promotion_delay";
return DelayQueueEnums.PROMOTION.name();
}
}

View File

@@ -124,7 +124,7 @@ spring:
props:
#是否打印逻辑SQL语句和实际SQL语句建议调试时打印在生产环境关闭
sql:
show: true
show: false
# 忽略鉴权url
ignored:

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--应用名称-->
<property name="APP_NAME" value="consumer"/>
<!--日志文件保存路径-->
<property name="LOG_FILE_PATH" value="lili-logs"/>
<contextName>${APP_NAME}</contextName>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--输出到elk的LOGSTASH-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- 配置elk日志收集 配饰的是 LOGSTASH 的地址-->
<destination>192.168.0.116:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
</providers>
<!--自定义字段 区分项目-->
<customFields>{"appName":"${APP_NAME}"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>

View File

@@ -7,85 +7,14 @@
<parent>
<groupId>cn.lili</groupId>
<artifactId>lili-shop-parent</artifactId>
<version>1.0.1</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>framework</artifactId>
<packaging>jar</packaging>
<properties>
<swagger-bootstrap-ui-version>1.9.6</swagger-bootstrap-ui-version>
<alipay-sdk-version>4.13.40.ALL</alipay-sdk-version>
<mysql-connector-version>5.1.48</mysql-connector-version>
<mybatis-plus-version>3.3.1.tmp</mybatis-plus-version>
<Hutool-version>5.5.8</Hutool-version>
<TinyPinyin-verions>2.0.3.RELEASE</TinyPinyin-verions>
<jasypt-version>3.0.0</jasypt-version>
<neetl-version>2.9.10</neetl-version>
<lombok-version>1.18.10</lombok-version>
<minio-version>6.0.11</minio-version>
<aliyun-version>4.5.18</aliyun-version>
<aliyun-sdk-oss-version>3.11.1</aliyun-sdk-oss-version>
<aliyun-sdk-dysms-version>2.0.1</aliyun-sdk-dysms-version>
<rocketmq-version>2.1.1</rocketmq-version>
<jwt-version>0.10.7</jwt-version>
<antlr4-runtime-version>4.7.2</antlr4-runtime-version>
<sharding-jdbc-version>4.0.0</sharding-jdbc-version>
<druid-version>1.1.20</druid-version>
<simple-http-version>1.0.3</simple-http-version>
<antlr4-version>4.7.2</antlr4-version>
<okhttp-version>4.4.1</okhttp-version>
<httpclient-version>4.5.12</httpclient-version>
<beetl-version>2.9.10</beetl-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
<knife4j.version>2.0.8</knife4j.version>
<de.codecentric>2.3.1</de.codecentric>
<userAgentUtils>1.21</userAgentUtils>
<interceptor-api>1.2</interceptor-api>
</properties>
<dependencies>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>2.2.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -356,23 +285,11 @@
<artifactId>simple-http</artifactId>
<version>${simple-http-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr4-runtime-version}</version>
</dependency>
<!-- http client -->
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents</groupId>-->
<!-- <artifactId>httpclient</artifactId>-->
<!-- <version>${httpclient-version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okhttp3</groupId>-->
<!-- <artifactId>okhttp</artifactId>-->
<!-- <version>${okhttp-version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
@@ -385,6 +302,59 @@
<artifactId>UserAgentUtils</artifactId>
<version>${userAgentUtils}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml-version}</version>
</dependency>
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder}</version>
</dependency>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${interceptor-api}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${de.codecentric}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api}</version>
</dependency>
<!-- 开源多维码生成工具 -->
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>${xk-time}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text}</version>
</dependency>
</dependencies>

View File

@@ -29,7 +29,10 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
this.setFieldValByName("deleteFlag", false, metaObject);
}
if (metaObject.hasGetter("id")) {
this.setFieldValByName("id", String.valueOf(SnowFlake.getId()), metaObject);
//如果已经配置id则不再写入
if (metaObject.getValue("id") == null) {
this.setFieldValByName("id", String.valueOf(SnowFlake.getId()), metaObject);
}
}
}

View File

@@ -9,13 +9,23 @@ import org.springframework.context.annotation.Configuration;
* @author Chopper
*/
@Configuration
@MapperScan({"cn.lili.modules.*.*.mapper","cn.lili.modules.*.mapper"})
@MapperScan({"cn.lili.modules.*.*.mapper", "cn.lili.modules.*.mapper"})
public class MybatisPlusConfig {
/**
* 分页插件,自动识别数据库类型
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
//阻断解析器,测试环境使用
// PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//
// List<ISqlParser> sqlParserList = new ArrayList<>();
// //攻击 SQL 阻断解析器、加入解析链
// sqlParserList.add(new BlockAttackSqlParser());
// paginationInterceptor.setSqlParserList(sqlParserList);
// return paginationInterceptor;
}
}

View File

@@ -1,13 +1,13 @@
package cn.lili.common.aop.limiter;
import cn.lili.common.aop.limiter.annotation.LimitPoint;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
@@ -17,10 +17,10 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* 流量拦截
*
* @author Chopper
*/
@Aspect
@@ -41,46 +41,49 @@ public class LimitInterceptor {
this.limitScript = limitScript;
}
@Around("execution(public * *(..)) && @annotation(cn.lili.common.aop.limiter.annotation.LimitPoint)")
public Object interceptor(ProceedingJoinPoint pjp) {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
LimitPoint limitPointAnnotation = method.getAnnotation(LimitPoint.class);
@Before("@annotation(limitPointAnnotation)")
public void interceptor(LimitPoint limitPointAnnotation) {
LimitType limitType = limitPointAnnotation.limitType();
String name = limitPointAnnotation.name();
String key;
int limitPeriod = limitPointAnnotation.period();
int limitCount = limitPointAnnotation.limit();
switch (limitType) {
case IP:
key = limitPointAnnotation.key() + getIpAddress();
break;
case CUSTOMER:
key = limitPointAnnotation.key();
break;
default:
key = StringUtils.upperCase(method.getName());
key = limitPointAnnotation.key() + getIpAddress();
}
ImmutableList<String> keys = ImmutableList.of(StringUtils.join(limitPointAnnotation.prefix(), key));
try {
Number count = redisTemplate.execute(limitScript, keys, limitCount, limitPeriod);
log.info("Access try count is {} for name={} and key = {}", count, name, key);
if (count != null && count.intValue() <= limitCount) {
return pjp.proceed();
} else {
throw new RuntimeException("访问过于频繁,请稍后再试");
}
} catch (Throwable e) {
if (e instanceof RuntimeException) {
throw new RuntimeException(e.getLocalizedMessage());
log.info("限制请求{}, 当前请求{},缓存key{}", limitCount, count.intValue(), key);
//如果缓存里没有值,或者他的值小于限制频率
if (count.intValue() >= limitCount) {
throw new ServiceException(ResultCode.LIMIT_ERROR);
}
}
//如果从redis中执行都值判定为空则这里跳过
catch (NullPointerException e) {
return;
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("服务器异常,请稍后再试");
}
}
/**
* 默认unknown常量值
*/
private static final String UNKNOWN = "unknown";
/**
* 获取ip
* @return ip
*/
public String getIpAddress() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getHeader("x-forwarded-for");

View File

@@ -7,7 +7,7 @@ import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.IpHelper;
import cn.lili.common.utils.SpelUtil;
import cn.lili.common.utils.ThreadPoolUtil;
import cn.lili.modules.base.entity.systemlog.SystemLogVO;
import cn.lili.modules.permission.entity.vo.SystemLogVO;
import cn.lili.modules.connect.util.IpUtils;
import cn.lili.modules.permission.service.SystemLogService;
import lombok.extern.slf4j.Slf4j;
@@ -39,7 +39,7 @@ public class SystemLogAspect {
/**
* 启动线程异步记录日志
*/
private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<>("SYSTEM-LOG");
private static final ThreadLocal<Date> BEGIN_TIME_THREAD_LOCAL = new NamedThreadLocal<>("SYSTEM-LOG");
@Autowired
private SystemLogService systemLogService;
@@ -61,7 +61,7 @@ public class SystemLogAspect {
*/
@Before("controllerAspect()")
public void doBefore() {
beginTimeThreadLocal.set(new Date());
BEGIN_TIME_THREAD_LOCAL.set(new Date());
}
@@ -102,7 +102,7 @@ public class SystemLogAspect {
//请求参数
systemLogVO.setMapToParams(logParams);
//响应参数 此处数据太大了,所以先注释掉
// systemLogVO.setResponseBody(JSONUtil.toJsonStr(rvt));
// systemLogVO.setResponseBody(JSONUtil.toJsonStr(rvt));
//请求IP
systemLogVO.setIp(IpUtils.getIpAddress(request));
//IP地址
@@ -110,7 +110,7 @@ public class SystemLogAspect {
//写入自定义日志内容
systemLogVO.setCustomerLog(customerLog);
//请求开始时间
long beginTime = beginTimeThreadLocal.get().getTime();
long beginTime = BEGIN_TIME_THREAD_LOCAL.get().getTime();
long endTime = System.currentTimeMillis();
//请求耗时
Long usedTime = endTime - beginTime;
@@ -157,7 +157,7 @@ public class SystemLogAspect {
*/
private static Map<String, String> spelFormat(JoinPoint joinPoint, Object rvt) {
Map<String, String> result = new HashMap<>();
Map<String, String> result = new HashMap<>(2);
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
SystemLogPoint systemLogPoint = signature.getMethod().getAnnotation(SystemLogPoint.class);
String description = systemLogPoint.description();

View File

@@ -164,6 +164,7 @@ public interface Cache<T> {
* 如需清零按照普通key 移除即可
*
* @param key
* @param value
* @return
*/
Long cumulative(Object key, Object value);
@@ -232,4 +233,35 @@ public interface Cache<T> {
* @return
*/
Set<ZSetOperations.TypedTuple<Object>> reverseRangeWithScores(String sortedSetName, Integer start, Integer end);
/**
* 向Zset里添加成员
*
* @param key key值
* @param score 分数
* @param value 值
* @return 增加状态
*/
boolean zAdd(String key, long score, String value);
/**
* 获取 某key 下 某一分值区间的队列
*
* @param key 缓存key
* @param from 开始时间
* @param to 结束时间
* @return 数据
*/
Set<ZSetOperations.TypedTuple<Object>> zRangeByScore(String key, int from, long to);
/**
* 移除 Zset队列值
*
* @param key key值
* @param value 删除的集合
* @return 删除数量
*/
Long zRemove(String key, String... value);
}

View File

@@ -177,7 +177,7 @@ public enum CachePrefix {
/**
* 店铺管理员角色权限对照表
*/
SHOP_URL_ROLE,
STORE_URL_ROLE,
/**
* 手机验证标识
@@ -219,7 +219,7 @@ public enum CachePrefix {
STORE_ID_FULL_DISCOUNT,
/**
* 限时抢购活动缓存key前缀
* 秒杀活动活动缓存key前缀
*/
STORE_ID_SECKILL,
@@ -449,25 +449,44 @@ public enum CachePrefix {
/**
* 文章
*/
ARTICLE_CACHE
;
ARTICLE_CACHE,
/**
* 店铺分类
*/
STORE_CATEGORY;
public static String removePrefix(String str) {
return str.substring(str.lastIndexOf("}_") + 2);
}
//通用获取缓存key值
/**
* 通用获取缓存key值
*
* @return 缓存key值
*/
public String getPrefix() {
return "{" + this.name() + "}_";
}
//通用获取缓存key值
/**
* 通用获取缓存key值
*
* @param typeEnum 促销枚举
* @return 缓存key值
*/
public String getPrefix(PromotionTypeEnum typeEnum) {
return "{" + this.name() + "_" + typeEnum.name() + "}_";
}
//获取缓存key值 + 用户端例如三端都有用户体系需要分别登录如果用户名一致则redis中的权限可能会冲突出错
/**
* 获取缓存key值 + 用户端
* 例如三端都有用户体系需要分别登录如果用户名一致则redis中的权限可能会冲突出错
*
* @param user 角色
* @return 缓存key值 + 用户端
*/
public String getPrefix(UserEnums user) {
return "{" + this.name() + "_" + user.name() + "}_";
}

View File

@@ -1,6 +1,7 @@
package cn.lili.common.cache.impl;
import cn.lili.common.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
@@ -18,6 +19,7 @@ import java.util.function.Consumer;
*
* @author Chopepr
*/
@Slf4j
@Component
public class RedisCache implements Cache {
@@ -158,7 +160,7 @@ public class RedisCache implements Cache {
return null;
} catch (IOException e) {
e.printStackTrace();
log.error("scan错误", e);
throw new RuntimeException(e);
}
});
@@ -168,7 +170,7 @@ public class RedisCache implements Cache {
@Override
public Long cumulative(Object key, Object value) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// add 方法对应 PFADD 命令
//add 方法对应 PFADD 命令
return operations.add(key, value);
}
@@ -177,7 +179,7 @@ public class RedisCache implements Cache {
public Long counter(Object key) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// add 方法对应 PFADD 命令
//add 方法对应 PFADD 命令
return operations.size(key);
}
@@ -196,7 +198,7 @@ public class RedisCache implements Cache {
@Override
public Long mergeCounter(Object... key) {
HyperLogLogOperations<Object, Object> operations = redisTemplate.opsForHyperLogLog();
// 计数器合并累加
//计数器合并累加
return operations.union(key[0], key);
}
@@ -204,8 +206,8 @@ public class RedisCache implements Cache {
public Long incr(String key, long liveTime) {
RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
Long increment = entityIdCounter.getAndIncrement();
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
//初始设置过期时间
if ((null == increment || increment.longValue() == 0) && liveTime > 0) {
entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
}
@@ -221,7 +223,7 @@ public class RedisCache implements Cache {
*/
@Override
public void incrementScore(String sortedSetName, String keyword) {
// x 的含义请见本方法的注释
//x 的含义请见本方法的注释
double x = 1.0;
this.redisTemplate.opsForZSet().incrementScore(sortedSetName, keyword, x);
}
@@ -240,4 +242,46 @@ public class RedisCache implements Cache {
public Set<ZSetOperations.TypedTuple<Object>> reverseRangeWithScores(String sortedSetName, Integer start, Integer end) {
return this.redisTemplate.opsForZSet().reverseRangeWithScores(sortedSetName, start, end);
}
/**
* 向Zset里添加成员
*
* @param key key值
* @param score 分数,通常用于排序
* @param value 值
* @return 增加状态
*/
@Override
public boolean zAdd(String key, long score, String value) {
return redisTemplate.opsForZSet().add(key, value, score);
}
/**
* 获取 某key 下 某一分值区间的队列
*
* @param key 缓存key
* @param from 开始时间
* @param to 结束时间
* @return 数据
*/
@Override
public Set<ZSetOperations.TypedTuple<Object>> zRangeByScore(String key, int from, long to) {
Set<ZSetOperations.TypedTuple<Object>> set = redisTemplate.opsForZSet().rangeByScoreWithScores(key, from, to);
return set;
}
/**
* 移除 Zset队列值
*
* @param key key值
* @param value 删除的集合
* @return 删除数量
*/
@Override
public Long zRemove(String key, String... value) {
return redisTemplate.opsForZSet().remove(key, value);
}
}

View File

@@ -1,22 +0,0 @@
package cn.lili.common.delayqueue;
/**
* 延时任务工具类
*
* @author paulG
* @since 2021/5/7
**/
public class DelayQueueTools {
/**
* 组装延时任务唯一键
*
* @param type 延时任务类型
* @param id id
* @return 唯一键
*/
public static String wrapperUniqueKey(DelayQueueType type, String id) {
return "{TIME_TRIGGER_" + type.name() + "}_" + id;
}
}

View File

@@ -1,30 +0,0 @@
package cn.lili.common.delayqueue;
/**
* 延时任务类型
*
* @author paulG
* @since 2021/5/7
**/
public enum DelayQueueType {
/**
* 促销活动
*/
PROMOTION("促销活动"),
/**
* 拼团订单
*/
PINTUAN_ORDER("拼团订单");
private final String description;
DelayQueueType(String des) {
this.description = des;
}
public String description() {
return this.description;
}
}

View File

@@ -44,7 +44,7 @@ public abstract class BaseElasticsearchService {
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 默认缓冲限制为100MB此处修改为30MB。
//默认缓冲限制为100MB此处修改为30MB。
builder.setHttpAsyncResponseConsumerFactory(new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
@@ -88,7 +88,7 @@ public abstract class BaseElasticsearchService {
protected void createIndexRequest(String index) {
try {
CreateIndexRequest request = new CreateIndexRequest(index);
// Settings for this index
//Settings for this index
request.settings(Settings.builder().put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards()).put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas()));
//创建索引
@@ -98,7 +98,7 @@ public abstract class BaseElasticsearchService {
log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}", createIndexResponse.isShardsAcknowledged());
return;
} catch (Exception e) {
e.printStackTrace();
log.error("创建索引错误",e);
throw new ElasticsearchException("创建索引 {" + index + "} 失败:" + e.getMessage());
}
}
@@ -308,13 +308,6 @@ public abstract class BaseElasticsearchService {
PutMappingRequest request = new PutMappingRequest(index)
.source(source, XContentType.JSON);
// AcknowledgedResponse putMappingResponse = client.indices().putMapping(request,
// RequestOptions.DEFAULT);
//
// boolean acknowledged = putMappingResponse.isAcknowledged();
// if (acknowledged) {
// log.error("Succeed to put mapping");
// }
CountDownLatch latch = new CountDownLatch(1);
AtomicReference response = new AtomicReference<AcknowledgedResponse>();
client.indices().putMappingAsync(
@@ -420,7 +413,7 @@ public abstract class BaseElasticsearchService {
try {
searchResponse = client.search(searchRequest, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
log.error("es 搜索错误",e);
}
return searchResponse;
}

View File

@@ -1,4 +1,4 @@
package cn.lili.modules.base.entity.enums;
package cn.lili.common.enums;
/**
@@ -10,10 +10,25 @@ package cn.lili.modules.base.entity.enums;
public enum ClientTypeEnum {
/**
* "移动端"
*/
H5("移动端"),
/**
* "PC端"
*/
PC("PC端"),
/**
* "小程序端"
*/
WECHAT_MP("小程序端"),
/**
* "移动应用端"
*/
APP("移动应用端"),
/**
* "未知"
*/
UNKNOWN("未知");
private final String clientName;

View File

@@ -17,7 +17,7 @@ public enum ResultCode {
/**
* 失败返回码
*/
ERROR(400, "失败"),
ERROR(400, "服务器繁忙,请稍后重试"),
/**
* 失败返回码
@@ -32,8 +32,11 @@ public enum ResultCode {
/**
* 系统异常
*/
WECHAT_CONNECT_NOT_EXIST(1001, "微信联合登录未配置"),
VERIFICATION_EXIST(1002, "验证码服务异常"),
LIMIT_ERROR(1003, "访问过于频繁,请稍后再试"),
ILLEGAL_REQUEST_ERROR(1004, "非法请求,请重新刷新页面操作"),
IMAGE_FILE_EXT_ERROR(1005, "不支持图片格式"),
/**
* 分类
*/
@@ -46,16 +49,30 @@ public enum ResultCode {
CATEGORY_SAVE_ERROR(10007, "此类别下存在商品不能删除"),
CATEGORY_PARAMETER_SAVE_ERROR(10008, "分类绑定参数组添加失败"),
CATEGORY_PARAMETER_UPDATE_ERROR(10009, "分类绑定参数组添加失败"),
CATEGORY_DELETE_FLAG_ERROR(10010, "子类状态不能与父类不一致!"),
CATEGORY_COMMISSION_RATE_ERROR(10011, "分类的佣金不正确!"),
/**
* 商品
*/
GOODS_ERROR(11001, "商品异常,请稍后重试"),
GOODS_NOT_EXIST(11001, "商品已下架"),
GOODS_NAME_ERROR(11002, "商品名称不正确名称应为2-50字符"),
GOODS_UNDER_ERROR(11003, "商品下架失败"),
GOODS_UPPER_ERROR(11004, "商品上架失败"),
GOODS_AUTH_ERROR(11005, "商品审核失败"),
POINT_GOODS_ERROR(11006, "积分商品业务异常,请稍后重试"),
GOODS_SKU_SN_ERROR(11007, "商品SKU编号不能为空"),
GOODS_SKU_PRICE_ERROR(11008, "商品SKU价格不能小于等于0"),
GOODS_SKU_COST_ERROR(11009, "商品SKU成本价不能小于等于0"),
GOODS_SKU_WEIGHT_ERROR(11010, "商品重量不能为负数"),
GOODS_SKU_QUANTITY_ERROR(11011, "商品库存数量不能为负数"),
GOODS_SKU_QUANTITY_NOT_ENOUGH(11011, "商品库存不足"),
MUST_HAVE_GOODS_SKU(11012, "规格必须要有一个!"),
GOODS_PARAMS_ERROR(11013, "商品参数错误,刷新后重试"),
PHYSICAL_GOODS_NEED_TEMP(11014, "实物商品需选择配送模板"),
VIRTUAL_GOODS_NOT_NEED_TEMP(11015, "实物商品需选择配送模板"),
GOODS_TYPE_ERROR(11016, "需选择商品类型"),
/**
* 参数
@@ -77,6 +94,9 @@ public enum ResultCode {
BRAND_UPDATE_ERROR(14002, "品牌修改失败"),
BRAND_DISABLE_ERROR(14003, "品牌禁用失败"),
BRAND_DELETE_ERROR(14004, "品牌删除失败"),
BRAND_NAME_EXIST_ERROR(20002, "品牌名称重复!"),
BRAND_USE_DISABLE_ERROR(20003, "当前品牌下存在分类不可禁用"),
BRAND_NOT_EXIST(20004, "品牌不存在"),
/**
* 用户
@@ -97,8 +117,14 @@ public enum ResultCode {
USER_RECEIPT_NOT_EXIST(20014, "会员发票信息不存在"),
USER_EDIT_ERROR(20015, "用户修改失败"),
USER_OLD_PASSWORD_ERROR(20016, "旧密码不正确"),
USER_COLLECTION_EXIST(2001, "无法重复收藏"),
DELETE_EXIST(2001, "无法重复收藏"),
USER_COLLECTION_EXIST(20017, "无法重复收藏"),
USER_GRADE_IS_DEFAULT(20018, "会员等级为默认会员等级"),
DELETE_EXIST(20019, "无法重复收藏"),
USER_NOT_BINDING(20020, "未绑定用户"),
USER_AUTO_REGISTER_ERROR(20021, "自动注册失败,请稍后重试"),
USER_OVERDUE_CONNECT_ERROR(20022, "授权信息已过期,请重新授权/登录"),
USER_CONNECT_BANDING_ERROR(20023, "当前联合登陆方式,已绑定其他账号,需进行解绑操作"),
USER_CONNECT_NOT_EXIST_ERROR(20024, "暂无联合登陆信息,无法实现一键注册功能,请点击第三方登录进行授权"),
/**
* 权限
@@ -124,7 +150,10 @@ public enum ResultCode {
* 购物车
*/
CART_ERROR(30001, "读取结算页的购物车异常"),
CART_PINTUAN_NOT_EXIST_ERROR(30002, "拼团活动不存在错误"),
CART_PINTUAN_LIMIT_ERROR(30003, "购买数量超过拼团活动限制数量"),
SHIPPING_NOT_APPLY(30005, "购物商品不支持当前收货地址配送"),
/**
* 订单
*/
@@ -137,10 +166,17 @@ public enum ResultCode {
ORDER_NOT_USER(31007, "非当前会员的订单"),
ORDER_TAKE_ERROR(31008, "当前订单无法核销"),
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
ORDER_NOT_SUPPORT_DISTRIBUTION(31011, "购物车中包含不支持配送的商品,请重新选择收货地址,或者重新选择商品"),
ORDER_CAN_NOT_CANCEL(31012, "当前订单状态不可取消"),
ORDER_BATCH_DELIVER_ERROR(31013, "批量发货,文件读取失败"),
ORDER_ITEM_NOT_EXIST(31014, "当前订单项不存在!"),
/**
* 支付
*/
PAY_UN_WANTED(32000, "当前订单不需要付款,返回订单列表等待系统订单出库即可"),
PAY_SUCCESS(32001, "支付成功"),
PAY_INCONSISTENT_ERROR(32002, "付款金额和应付金额不一致"),
PAY_DOUBLE_ERROR(32003, "订单已支付,不能再次进行支付"),
@@ -152,6 +188,8 @@ public enum ResultCode {
PAY_CLIENT_TYPE_ERROR(32009, "错误的客户端"),
PAY_POINT_ENOUGH(32010, "积分不足,不能兑换"),
PAY_NOT_EXIST_ORDER(32011, "支付订单不存在"),
CAN_NOT_RECHARGE_WALLET(32012, "不能使用余额进行充值"),
/**
* 售后
@@ -162,6 +200,7 @@ public enum ResultCode {
AFTER_SALES_DOUBLE_ERROR(33004, "售后已审核,无法重复操作"),
AFTER_SALES_LOGISTICS_ERROR(33005, "物流公司错误,请重新选择"),
AFTER_STATUS_ERROR(33006, "售后状态错误,请刷新页面"),
RETURN_MONEY_OFFLINE_BANK_ERROR(33007, "当账号类型为银行转账时,银行信息不能为空"),
/**
* 投诉
@@ -169,6 +208,10 @@ public enum ResultCode {
COMPLAINT_ORDER_ITEM_EMPTY_ERROR(33100, "订单不存在"),
COMPLAINT_SKU_EMPTY_ERROR(33101, "商品已下架,如需投诉请联系平台客服"),
COMPLAINT_ERROR(33102, "投诉异常,请稍后重试"),
COMPLAINT_NOT_EXIT(33103, "当前投诉记录不存在"),
COMPLAINT_ARBITRATION_RESULT_ERROR(33104, "结束订单投诉时,仲裁结果不能为空"),
COMPLAINT_APPEAL_CONTENT_ERROR(33105, "商家申诉时,申诉内容不能为空"),
/**
* 余额
@@ -186,9 +229,16 @@ public enum ResultCode {
EVALUATION_DOUBLE_ERROR(35001, "无法重复提交评价"),
/**
* 签到
* 活动
*/
MEMBER_SIGN_REPEAT(40001, "请勿重复签到"),
PROMOTION_GOODS_NOT_EXIT(40001, "当前促销商品不存在!"),
PROMOTION_SAME_ACTIVE_EXIST(40002, "当前时间内已存在同类活动"),
PROMOTION_START_TIME_ERROR(40003, "活动起始时间不能大于活动结束时间"),
PROMOTION_TIME_ERROR(40004, "活动起始时间必须大于当前时间"),
PROMOTION_SAME_ERROR(40005, "当前时间段已存在相同活动!"),
PROMOTION_GOODS_ERROR(40006, "请选择要参与活动的商品"),
PROMOTION_STATUS_END(40007, "当前活动已停止"),
PROMOTION_UPDATE_ERROR(40008, "当前活动已开始/结束,无法编辑!"),
/**
* 优惠券
@@ -197,6 +247,19 @@ public enum ResultCode {
COUPON_CANCELLATION_SUCCESS(41002, "会员优惠券作废成功"),
COUPON_EXPIRED(41003, "优惠券已使用/已过期,不能使用"),
COUPON_EDIT_STATUS_ERROR(41004, "优惠券修改状态失败!"),
COUPON_RECEIVE_ERROR(41005, "当前优惠券状态不可领取"),
COUPON_NUM_INSUFFICIENT_ERROR(41006, "优惠券剩余领取数量不足"),
COUPON_NOT_EXIST(41007, "当前优惠券不存在"),
COUPON_LIMIT_NUM_LESS_THAN_0(41008, "领取限制数量不能为负数"),
COUPON_LIMIT_GREATER_THAN_PUBLISH(41009, "领取限制数量超出发行数量"),
COUPON_DISCOUNT_ERROR(41010, "优惠券折扣必须小于10且大于0"),
COUPON_SCOPE_TYPE_GOODS_ERROR(41011, "当前关联范围类型为指定商品时,商品列表不能为空"),
COUPON_SCOPE_TYPE_CATEGORY_ERROR(41012, "当前关联范围类型为部分商品分类时范围关联的id不能为空"),
COUPON_SCOPE_TYPE_STORE_ERROR(41013, "当前关联范围类型为部分店铺分类时范围关联的id不能为空"),
COUPON_SCOPE_ERROR(41014, "指定商品范围关联id无效"),
COUPON_MEMBER_NOT_EXIST(41015, "没有当前会员优惠券"),
COUPON_MEMBER_STATUS_ERROR(41016, "当前会员优惠券已过期/作废无法变更状态!"),
/**
* 拼团
@@ -211,19 +274,65 @@ public enum ResultCode {
PINTUAN_ADD_ERROR(42008, "添加拼团活动失败"),
PINTUAN_EDIT_ERROR(42009, "修改拼团活动失败"),
PINTUAN_DELETE_ERROR(42010, "删除拼团活动失败"),
PINTUAN_JOIN_ERROR(42011, "不能参与自己发起的拼团活动!"),
PINTUAN_LIMIT_NUM_ERROR(42012, "购买数量超过拼团活动限制数量!"),
PINTUAN_NOT_EXIST_ERROR(42013, "当前拼团商品不存在!"),
/**
* 满额活动
*/
FULL_DISCOUNT_EDIT_SUCCESS(43001, "修改满优惠活动成功"),
FULL_DISCOUNT_EDIT_DELETE(43002, "删除满优惠活动成功"),
FULL_DISCOUNT_MODIFY_ERROR(43003, "当前编辑的满优惠活动已经开始或者已经结束,无法修改"),
FULL_DISCOUNT_NOT_EXIST_ERROR(43004, "当前要操作的满优惠活动不存在!"),
FULL_DISCOUNT_WAY_ERROR(43005, "请选择一种优惠方式!"),
FULL_DISCOUNT_GIFT_ERROR(43006, "请选择赠品!"),
FULL_DISCOUNT_COUPON_TIME_ERROR(43007, "赠送的优惠券有效时间必须大于活动时间"),
FULL_DISCOUNT_MONEY_ERROR(43008, "请填写满减金额"),
FULL_DISCOUNT_MONEY_GREATER_THAN_MINUS(43009, "满减金额不能大于优惠门槛"),
FULL_RATE_NUM_ERROR(43010, "请填写打折数值"),
/**
* 直播
*/
STODIO_GOODS_EXIST_ERROR(44001, "直播商品已存在"),
COMMODITY_ERROR(44002, "添加直播商品失败"),
/**
* 秒杀
*/
SECKILL_NOT_EXIST_ERROR(45001, "当前参与的秒杀活动不存在!"),
SECKILL_UPDATE_ERROR(45002, "当前秒杀活动活动已经开始,无法修改!"),
SECKILL_PRICE_ERROR(45003, "活动价格不能大于商品原价"),
SECKILL_TIME_ERROR(45004, "时刻参数异常"),
SECKILL_DELETE_ERROR(45005, "该秒杀活动活动的状态不能删除"),
SECKILL_CLOSE_ERROR(45006, "该秒杀活动活动的状态不能关闭"),
/**
* 优惠券活动
*/
COUPON_ACTIVITY_START_TIME_ERROR(46001, "活动时间小于当前时间,不能进行编辑删除操作"),
COUPON_ACTIVITY_MEMBER_ERROR(46002, "指定精准发券则必须指定会员,会员不可以为空"),
COUPON_ACTIVITY_ITEM_ERROR(46003, "优惠券活动必须指定优惠券,不能为空"),
COUPON_ACTIVITY_ITEM_MUST_NUM_ERROR(46004, "优惠券活动最多指定10个优惠券"),
COUPON_ACTIVITY_ITEM_NUM_ERROR(46005, "赠券数量必须大于0"),
/**
* 其他促销
*/
MEMBER_SIGN_REPEAT(47001, "请勿重复签到"),
POINT_GOODS_ACTIVE_STOCK_ERROR(47002, "活动库存数量不能高于商品库存"),
/**
* 店铺
*/
STORE_NOT_EXIST(50001, "此店铺不存在"),
STORE_NAME_EXIST_ERROR(50002, "店铺名称已存在!"),
STORE_APPLY_DOUBLE_ERROR(50003, "已有店铺,无需重复申请!"),
STORE_NOT_OPEN(50004, "该会员未开通店铺"),
STORE_NOT_LOGIN_ERROR(50005, "未登录店铺"),
STORE_CLOSE_ERROR(50006, "店铺关闭,请联系管理员"),
/**
* 结算单
@@ -255,49 +364,60 @@ public enum ResultCode {
* 设置
*/
SETTING_NOT_TO_SET(70001, "该参数不需要设置"),
/**
* 短信
*/
SMS_SIGN_EXIST_ERROR(80001, "短信签名已存在"),
ALIPAY_NOT_SETTING(70002, "支付宝支付未配置"),
ALIPAY_EXCEPTION(70003, "支付宝支付错误,请稍后重试"),
ALIPAY_PARAMS_EXCEPTION(70004, "支付宝参数异常"),
LOGISTICS_NOT_SETTING(70005, "您还未配置快递查询"),
ORDER_SETTING_ERROR(70006, "系统订单配置异常"),
ALI_SMS_SETTING_ERROR(70007, "您还未配置阿里云短信"),
SMS_SIGN_EXIST_ERROR(70008, "短信签名已存在"),
/**
* 站内信
*/
NOTICE_NOT_EXIST(80101, "当前消息模板不存在"),
NOTICE_ERROR(80102, "修改站内信异常,请稍后重试"),
NOTICE_NOT_EXIST(80001, "当前消息模板不存在"),
NOTICE_ERROR(80002, "修改站内信异常,请稍后重试"),
NOTICE_SEND_ERROR(80003, "发送站内信异常,请检查系统日志"),
/**
* OSS
*/
OSS_NOT_EXIST(80201, "OSS未配置"),
OSS_EXCEPTION(80202, "文件上传失败,请稍后重试"),
OSS_NOT_EXIST(80101, "OSS未配置"),
OSS_EXCEPTION_ERROR(80102, "文件上传失败,请稍后重试"),
OSS_DELETE_ERROR(80102, "图片删除失败"),
/**
* 验证码
*/
VERIFICATION_SEND_SUCCESS(80301, "短信验证码,发送成功"),
VERIFICATION_ERROR(80302, "验证失败"),
VERIFICATION_SMS_ERROR(80303, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80304, "验证码已失效,请重新校验"),
/**
* 配置错误
*/
ALIPAY_NOT_SETTING(80401, "支付宝支付未配置"),
ALIPAY_EXCEPTION(80402, "支付宝支付错误,请稍后重试"),
ALIPAY_PARAMS_EXCEPTION(80403, "支付宝参数异常"),
VERIFICATION_SEND_SUCCESS(80201, "短信验证码,发送成功"),
VERIFICATION_ERROR(80202, "验证失败"),
VERIFICATION_SMS_ERROR(80203, "短信验证码错误,请重新校验"),
VERIFICATION_SMS_EXPIRED_ERROR(80204, "验证码已失效,请重新校验"),
/**
* 微信相关异常
*/
WECHAT_CONNECT_NOT_SETTING(80500, "微信联合登陆信息未配置"),
WECHAT_PAYMENT_NOT_SETTING(80501, "微信支付信息未配置"),
WECHAT_QRCODE_ERROR(80502, "微信二维码生成异常"),
WECHAT_MP_MESSAGE_ERROR(80503, "微信小程序小消息订阅异常"),
WECHAT_CONNECT_NOT_SETTING(80300, "微信联合登陆信息未配置"),
WECHAT_PAYMENT_NOT_SETTING(80301, "微信支付信息未配置"),
WECHAT_QRCODE_ERROR(80302, "微信二维码生成异常"),
WECHAT_MP_MESSAGE_ERROR(80303, "微信小程序小消息订阅异常"),
WECHAT_JSAPI_SIGN_ERROR(80304, "微信JsApi签名异常"),
WECHAT_CERT_ERROR(80305, "证书获取失败"),
WECHAT_MP_MESSAGE_TMPL_ERROR(80306, "未能获取到微信模版消息id"),
WECHAT_ERROR(80307, "微信接口异常"),
APP_VERSION_EXIST(80307, "APP版本已存在"),
/**
* 其他
*/
CUSTOM_WORDS_EXIST_ERROR(90000, "当前自定义分词已存在!"),
CUSTOM_WORDS_NOT_EXIST_ERROR(90001, "当前自定义分词不存在!"),
CUSTOM_WORDS_SECRET_KEY_ERROR(90002, "秘钥验证失败!"),
CONNECT_NOT_EXIST(90000, "登录方式不存在"),
APP_VERSION_EXIST(80600, "APP版本已存在")
;
private final Integer code;
private final String message;

View File

@@ -56,7 +56,12 @@ public class ResultUtil<T> {
}
//抽象静态方法,返回结果集
/**
* 抽象静态方法,返回结果集
* @param t
* @param <T>
* @return
*/
public static <T> ResultMessage<T> data(T t) {
return new ResultUtil<T>().setData(t);
}

View File

@@ -44,10 +44,21 @@ public class GlobalControllerExceptionHandler {
//如果是自定义异常,则获取异常,返回自定义错误消息
if (e instanceof ServiceException) {
ResultCode resultCode = ((ServiceException) e).getResultCode();
ServiceException serviceException = ((ServiceException) e);
ResultCode resultCode = serviceException.getResultCode();
Integer code = null;
String message = null;
if (resultCode != null) {
return ResultUtil.error(resultCode.code(), resultCode.message());
code = resultCode.code();
message = resultCode.message();
}
//如果有扩展消息,则输出异常中,跟随补充异常
if (!serviceException.getMsg().equals(ServiceException.DEFAULT_MESSAGE)) {
message += ":" + serviceException.getMsg();
}
return ResultUtil.error(code, message);
}
//默认错误消息
@@ -67,24 +78,24 @@ public class GlobalControllerExceptionHandler {
return ResultUtil.error(ResultCode.ERROR);
}
// /**
// * 通用的接口映射异常处理方
// */
// @Override
// protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
// if (ex instanceof MethodArgumentNotValidException) {
// MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
// }
// if (ex instanceof MethodArgumentTypeMismatchException) {
// MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
// logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
// + ",信息:" + exception.getLocalizedMessage());
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("参数转换失败"), status);
// }
// ex.printStackTrace();
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("未知异常,请联系管理员"), status);
// }
// /**
// * 通用的接口映射异常处理方
// */
// @Override
// protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
// if (ex instanceof MethodArgumentNotValidException) {
// MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
// }
// if (ex instanceof MethodArgumentTypeMismatchException) {
// MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
// logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
// + ",信息:" + exception.getLocalizedMessage());
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("参数转换失败"), status);
// }
// ex.printStackTrace();
// return new ResponseEntity<>(new ResultUtil<>().setErrorMsg("未知异常,请联系管理员"), status);
// }
/**
* bean校验未通过异常

View File

@@ -4,13 +4,23 @@ import cn.lili.common.enums.ResultCode;
import lombok.Data;
/**
* 全局业务异常类
*
* @author Chopper
*/
@Data
public class ServiceException extends RuntimeException {
private String msg;
public static String DEFAULT_MESSAGE = "网络错误,请稍后重试!";
/**
* 异常消息
*/
private String msg = DEFAULT_MESSAGE;
/**
* 错误码
*/
private ResultCode resultCode;
public ServiceException(String msg) {
@@ -19,8 +29,7 @@ public class ServiceException extends RuntimeException {
}
public ServiceException() {
super("网络错误,请稍后重试!");
this.msg = "网络错误,请稍后重试!";
super();
}
public ServiceException(ResultCode resultCode) {

View File

@@ -1,12 +1,20 @@
package cn.lili.common.rocketmq.tags;
/**
* 售后标签枚举
*
* @author paulG
* @since 2020/12/9
**/
public enum AfterSaleTagsEnum {
/**
* "售后退款"
*/
REFUND("售后退款"),
/**
* "售后单状态改变"
*/
AFTER_SALE_STATUS_CHANGE("售后单状态改变");
private final String description;

View File

@@ -6,13 +6,37 @@ package cn.lili.common.rocketmq.tags;
**/
public enum GoodsTagsEnum {
/**
* "生成商品索引"
*/
GENERATOR_GOODS_INDEX("生成商品索引"),
/**
* "删除商品"
*/
GOODS_DELETE("删除商品"),
/**
* "审核商品"
*/
GOODS_AUDIT("审核商品"),
/**
* "收藏商品"
*/
GOODS_COLLECTION("收藏商品"),
/**
* "购买商品完成"
*/
BUY_GOODS_COMPLETE("购买商品完成"),
/**
* "删除商品SKU"
*/
SKU_DELETE("删除商品SKU"),
/**
* "查看商品"
*/
VIEW_GOODS("查看商品"),
/**
* "商品评价"
*/
GOODS_COMMENT_COMPLETE("商品评价");
private final String description;

View File

@@ -1,14 +1,27 @@
package cn.lili.common.rocketmq.tags;
/**
* 会员操作枚举
*
* @author paulG
* @since 2020/12/9
**/
public enum MemberTagsEnum {
/**
* 会员注册
*/
MEMBER_REGISTER("会员注册"),
/**
* 会员签到
*/
MEMBER_SING("会员签到"),
/**
* 会员提现
*/
MEMBER_WITHDRAWAL("会员提现"),
/**
* 会员积分变动
*/
MEMBER_POINT_CHANGE("会员积分变动");
private final String description;

View File

@@ -1,18 +1,23 @@
package cn.lili.common.rocketmq.tags;
/**
* 订单操作枚举
*
* @author paulG
* @since 2020/12/9
**/
public enum MqOrderTagsEnum {
/**
* 订单创建
*/
ORDER_CREATE("订单创建"),
/**
* 订单状态改变
*/
STATUS_CHANGE("订单状态改变");
private final String description;
MqOrderTagsEnum(String description) {

View File

@@ -1,12 +1,19 @@
package cn.lili.common.rocketmq.tags;
/**
* 其他操作枚举
*
* @author paulG
* @since 2020/12/9
**/
public enum OtherTagsEnum {
/**
* 站内消息提醒
*/
MESSAGE("站内消息提醒"),
/**
* 短信消息提醒
*/
SMS("短信消息提醒");
private final String description;

View File

@@ -9,6 +9,10 @@ import cn.lili.common.token.SecretKeyUtil;
import com.google.gson.Gson;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 用户上下文
@@ -20,15 +24,18 @@ import io.jsonwebtoken.Jwts;
*/
public class UserContext {
private static AuthenticationHandler authenticationHandler;
public static void setHolder(AuthenticationHandler authenticationHandler) {
UserContext.authenticationHandler = authenticationHandler;
}
/**
* 根据request获取用户信息
*
* @return
*/
public static AuthUser getCurrentUser() {
return authenticationHandler.getAuthUser();
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String accessToken = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
return getAuthUser(accessToken);
}
return null;
}
@@ -44,6 +51,20 @@ public class UserContext {
if (cache.keys("*" + accessToken).size() == 0) {
throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
}
return getAuthUser(accessToken);
} catch (Exception e) {
return null;
}
}
/**
* 根据jwt获取token重的用户信息
*
* @param accessToken token
* @return
*/
public static AuthUser getAuthUser(String accessToken) {
try {
//获取token的信息
Claims claims
= Jwts.parser()

View File

@@ -31,6 +31,6 @@ public class UserContextInit implements ApplicationRunner {
*/
@Override
public void run(ApplicationArguments args) {
UserContext.setHolder(authenticationHandler);
//UserContext.setHolder(authenticationHandler);
}
}

View File

@@ -0,0 +1,39 @@
package cn.lili.common.security.filter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 防止XSS攻击过滤器
*
* @author Chopper
* @version v1.0
* 2021-06-04 10:37
*/
@WebFilter
@Component
public class XssFilter implements Filter {
FilterConfig filterConfig = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//对请求进行拦截,防xss处理
chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
}
@Override
public void destroy() {
this.filterConfig = null;
}
}

View File

@@ -0,0 +1,132 @@
package cn.lili.common.security.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.regex.Pattern;
/**
* 防止Xss
*
* @author Chopper
* @version v1.0
* 2021-06-04 10:39
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
/**
* 对数组参数进行特殊字符过滤
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
/**
* 对参数中特殊字符进行过滤
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return cleanXSS(value);
}
/**
* 获取attribute,特殊字符过滤
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value != null && value instanceof String) {
cleanXSS((String) value);
}
return value;
}
/**
* 对请求头部进行特殊字符过滤
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return cleanXSS(value);
}
/**
* 转义字符,使用该方法存在一定的弊端
*
* @param value
* @return
*/
private String cleanXSS2(String value) {
//移除特殊标签
value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
value = value.replaceAll("'", "&#39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
return value;
}
private static final Pattern SCRIPT_PATTERN1 = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
private static final Pattern SCRIPT_PATTERN2 = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
private static final Pattern SCRIPT_PATTERN3 = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern SCRIPT_PATTERN4 = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
private static final Pattern SRC_PATTERN = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern EVAL_PATTERN = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern E_­_XPRESSION_PATTERN = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private static final Pattern VB_SCRIPT_PATTERN = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
private static final Pattern ONLOAD_PATTERN = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
private String cleanXSS(String value) {
if (value != null) {
//推荐使用ESAPI库来避免脚本攻击,value = ESAPI.encoder().canonicalize(value);
//避免script 标签
value = SCRIPT_PATTERN1.matcher(value).replaceAll("");
//删除单个的 </script> 标签
value = SCRIPT_PATTERN2.matcher(value).replaceAll("");
//删除单个的<script ...> 标签
value = SCRIPT_PATTERN3.matcher(value).replaceAll("");
//避免 javascript: 表达式
value = SCRIPT_PATTERN4.matcher(value).replaceAll("");
//避免src形式的表达式
value = SRC_PATTERN.matcher(value).replaceAll("");
//避免 eval(...) 形式表达式
value = EVAL_PATTERN.matcher(value).replaceAll("");
//避免 e­xpression(...) 表达式
value = E_­_XPRESSION_PATTERN.matcher(value).replaceAll("");
//避免 vbscript:表达式
value = VB_SCRIPT_PATTERN.matcher(value).replaceAll("");
//避免 onload= 表达式
value = ONLOAD_PATTERN.matcher(value).replaceAll("");
}
return value;
}
}

Some files were not shown because too many files have changed in this diff Show More