Compare commits

...

474 Commits

Author SHA1 Message Date
GYJ b9c4c25537 分页44 2025-01-02 21:12:22 +08:00
wangw 2025b4c397 分页2 2025-01-02 20:59:32 +08:00
GYJ e8a986e476 分页33 2025-01-02 20:56:19 +08:00
GYJ d56a5df40e 分页22 2025-01-02 20:45:51 +08:00
wangw e3de8c009f 剧集报错sql 2025-01-02 20:08:17 +08:00
GYJ 96aebfdd8b 分页 2025-01-02 19:49:10 +08:00
wangw f5626621f0 分页2 2025-01-02 19:42:30 +08:00
GYJ 297c94110b ParamPageUtils 2025-01-02 19:30:09 +08:00
wangw 2f2bae4aca 分页 2025-01-02 18:54:38 +08:00
wangw f4998e1073 shardingConfig2 2025-01-02 17:40:54 +08:00
wangw 4157bac93f 分4库 配置文件
prod 分库 其它环境不分库
2025-01-02 13:14:06 +08:00
wangw b4c9687f4c 查询订单数量 优化 2025-01-02 11:23:59 +08:00
GYJ 179a9e361d 只是用一个从库 2025-01-02 10:46:17 +08:00
张松 f7a63cdea7 Merge remote-tracking branch 'origin/test' into test 2025-01-02 10:45:01 +08:00
张松 51e3639065 用户收藏sql优化,接口增加缓存 2025-01-02 10:44:39 +08:00
wangw 003db71b7c 配置文件修改
表映射配置 放在application.yml
2025-01-02 10:00:21 +08:00
GYJ 78bf1c8c01 删除定时更新 user vip 2025-01-02 09:59:14 +08:00
GYJ 65dce032fe 配置多个从库 2025-01-02 00:10:31 +08:00
GYJ 9624a3350d Merge branch 'test' into dev 2025-01-01 19:47:55 +08:00
GYJ ab24effd0f 修复验证码问题 2025-01-01 19:42:07 +08:00
wangw dcaf258e9a 空指针 2024-12-31 17:44:36 +08:00
wangw f3284c11f6 日志 2024-12-31 17:32:17 +08:00
张松 bce5111fed Merge branch 'refs/heads/test' into dev
# Conflicts:
#	src/main/java/com/sqx/modules/job/task/TempOrdersTask.java
#	src/main/java/com/sqx/modules/pay/wuyou/BaseResp.java
2024-12-31 17:17:32 +08:00
张松 fb00873494 订单状态同步定时任务修改 2024-12-31 17:14:14 +08:00
wangw 5419dd4102 万能验证码 61626364 2024-12-31 17:08:45 +08:00
张松 77cfa1af49 Merge remote-tracking branch 'origin/dev' into dev 2024-12-31 16:51:07 +08:00
张松 dab8c3cb26 增加定时任务日志 2024-12-31 16:50:59 +08:00
Tankaikai 808d781e8e Merge remote-tracking branch 'origin/test' into dev 2024-12-31 16:34:51 +08:00
张松 9f7cff7431 订单状态同步定时任务修改 2024-12-31 16:31:55 +08:00
Tankaikai fd0c4f5c5e Merge remote-tracking branch 'origin/test' into test 2024-12-31 16:29:53 +08:00
谭凯凯 f5e4e153e2 提现审核列表金额格式化bug 2024-12-31 16:29:48 +08:00
张松 55946abbcb Merge branch 'refs/heads/test' into dev 2024-12-31 15:50:55 +08:00
张松 8052af5f6a Merge branch 'refs/heads/test' into dev 2024-12-31 15:50:00 +08:00
GYJ 48f605ecb1 Merge remote-tracking branch 'origin/test' into test 2024-12-31 15:49:57 +08:00
张松 9160bf0a56 支付回调查询多条报错处理 2024-12-31 15:49:48 +08:00
GYJ f74e29c09f UserIntegral 异常处理 2024-12-31 15:49:48 +08:00
张松 c19cdd95a9 循环依赖解决 2024-12-31 15:06:13 +08:00
张松 de590aa30d 循环依赖解决 2024-12-31 15:06:12 +08:00
张松 ab8087e03d 循环依赖解决 2024-12-31 15:05:29 +08:00
张松 5aacd548c9 循环依赖解决 2024-12-31 15:05:20 +08:00
张松 5f7ee1fd8e Merge branch 'refs/heads/test' into dev 2024-12-31 14:58:34 +08:00
wangw eb3467ad5a 支付成功 无效问题 2024-12-31 14:32:52 +08:00
张松 282b772430 增加调试日志 2024-12-31 14:19:15 +08:00
wangw 65769b71d1 测试环境 万能验证码 147258 2024-12-31 11:44:37 +08:00
wangw 957682ef41 支付与提现 开关 2024-12-31 11:34:00 +08:00
张松 70d66864a3 签到人数接口修改 2024-12-31 11:29:21 +08:00
wangw 40c7bce626 达标奖励
抽奖补偿
2024-12-31 11:20:49 +08:00
张松 084828cd5b Merge branch 'refs/heads/test' into dev 2024-12-31 10:30:54 +08:00
张松 a6949a92a0 达标奖励修改 2024-12-31 10:28:59 +08:00
张松 0908d114a2 达标查询统一更换 2024-12-31 10:14:15 +08:00
张松 52a692ebd9 selectByUserId报错修复 2024-12-31 00:09:53 +08:00
张松 c7242e9ab0 Merge remote-tracking branch 'origin/test' into test 2024-12-30 23:55:30 +08:00
张松 9e74c5656e key设置错误修复 2024-12-30 23:55:21 +08:00
wangw a02d2eb157 Merge branch 'test' into dev 2024-12-30 23:52:45 +08:00
wangw 328298971c 支付宝次数问题 2024-12-30 23:52:03 +08:00
wangw 409365b9db 正式 shardingsphere 2024-12-30 23:46:03 +08:00
wangw f5b2f827d1 积分问题
banner问题
2024-12-30 23:45:45 +08:00
wangw 6671fadc40 积分问题
banner问题
2024-12-30 23:43:41 +08:00
张松 5f3e76fb5c sql报错修复 2024-12-30 23:31:56 +08:00
wangw 1123b518db 正式 shardingsphere 2024-12-30 23:07:28 +08:00
wangw 7e89bb182b Merge branch 'test' into dev
# Conflicts:
#	src/main/java/com/sqx/modules/pay/controller/app/WuyouController.java
2024-12-30 23:00:16 +08:00
张松 7f169ee677 增加pay配置文件 2024-12-30 22:58:26 +08:00
wangw 4c4c469db2 三方订单号 2024-12-30 22:54:42 +08:00
wangw cc18a05b45 三方订单号 2024-12-30 22:51:09 +08:00
张松 380648395c fix: 达标保存修改 2024-12-30 22:47:15 +08:00
wangw b123a059ce 日志打印 2024-12-30 22:05:13 +08:00
wangw a374f41847 关闭支付 2024-12-30 21:51:32 +08:00
Tankaikai e4ae8beb77 Merge remote-tracking branch 'origin/test' into test 2024-12-30 21:49:29 +08:00
谭凯凯 7cb257317c 首页查询优化 2024-12-30 21:49:23 +08:00
wangw 09a0cf09e4 根据id查询短剧详情 2024-12-30 21:43:05 +08:00
wangw 0aed96e92e 日志打印 2024-12-30 21:29:20 +08:00
wangw 435421be0a 子查询 以及 扫描路径 2024-12-30 21:21:49 +08:00
张松 d496efb196 fix: 拦截器增加异步 2024-12-30 21:17:56 +08:00
张松 649f8f0c3f refactor: 更改子查询为join 2024-12-30 21:04:18 +08:00
张松 ddb1c196b3 Merge remote-tracking branch 'origin/test' into test 2024-12-30 20:58:14 +08:00
张松 51e1db2bc4 refactor: 更改子查询为join 2024-12-30 20:58:05 +08:00
Tankaikai a22229b3df Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	src/main/resources/mapper/course/CourseDao.xml
2024-12-30 20:24:52 +08:00
谭凯凯 e5af376cae 分库不支持子查询修改为关联查询 2024-12-30 20:22:49 +08:00
张松 c4852d5e7e refactor: 更改子查询为join 2024-12-30 20:15:43 +08:00
张松 940f41930f refactor: 更改子查询为join 2024-12-30 20:08:39 +08:00
张松 6828c78114 Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	src/main/resources/mapper/course/CourseDao.xml
2024-12-30 20:06:15 +08:00
张松 e2ae91bcd6 refactor: 更改子查询为join 2024-12-30 20:05:04 +08:00
GYJ 808a5f9ce6 Merge remote-tracking branch 'origin/test' into test 2024-12-30 19:21:28 +08:00
GYJ 4355b9f292 sql 报错 2 2024-12-30 19:21:19 +08:00
wangw 52efab0331 意见反馈 2024-12-30 19:12:15 +08:00
wangw 315a341e41 提现次数/金额 2024-12-30 19:08:39 +08:00
谭凯凯 6f1e9e34df 修复无法返回videoUrl的bug 2024-12-30 19:02:01 +08:00
谭凯凯 0223eccd04 首页查询优化 2024-12-30 18:45:50 +08:00
Tankaikai dd59c4577e Merge remote-tracking branch 'origin/test' into test 2024-12-30 18:30:45 +08:00
谭凯凯 291b8e2646 修复无法返回videoUrl的bug 2024-12-30 18:30:39 +08:00
张松 379a6f81e0 Merge remote-tracking branch 'origin/test' into test 2024-12-30 18:28:25 +08:00
张松 99dba02361 feat: 定时任务调用修改 2024-12-30 18:28:17 +08:00
wangw f154973d2d 日期问题 2024-12-30 18:26:40 +08:00
wangw d3241cf504 日志打印 2024-12-30 18:26:10 +08:00
张松 91a1154383 feat: 定时任务调用修改 2024-12-30 18:23:21 +08:00
GYJ 5e06231aaa sql 报错 2024-12-30 18:16:59 +08:00
GYJ 7498922675 查询日期补全方法 2024-12-30 17:55:09 +08:00
张松 e0e53bfd9a feat: 增加根据beanName及方法调用接口 2024-12-30 17:48:28 +08:00
谭凯凯 c677d75feb 首页查询优化 2024-12-30 17:23:27 +08:00
谭凯凯 f8df78b065 首页查询优化 2024-12-30 17:16:08 +08:00
Tankaikai afcb0abc6a Merge remote-tracking branch 'origin/test' into test 2024-12-30 16:47:29 +08:00
谭凯凯 b45006d2f7 首页查询优化 2024-12-30 16:47:23 +08:00
张松 2fc1f1e61c Merge remote-tracking branch 'origin/test' into test 2024-12-30 16:44:35 +08:00
张松 4c1310c089 feat: InviteAchievementMapper字段調整 2024-12-30 16:44:24 +08:00
wangw 769e476b23 请求日志 异步打印 2024-12-30 16:42:32 +08:00
wangw b2eb085472 dev 配置文件 2024-12-30 16:40:14 +08:00
wangw adf0b74627 Merge remote-tracking branch 'origin/test' into test 2024-12-30 16:32:57 +08:00
张松 d475f34a0a Merge remote-tracking branch 'origin/test' into test 2024-12-30 16:31:27 +08:00
张松 95f4a1aab0 feat: 达标奖励查询方式修改 2024-12-30 16:31:11 +08:00
wangw 9bb24f0aba Merge branch 'sharding' into test
# Conflicts:
#	src/main/java/com/sqx/SqxApplication.java
#	src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java
#	src/main/resources/mapper/course/CourseDao.xml
2024-12-30 16:30:04 +08:00
wangw 257bc9e760 云购os移除 2024-12-30 16:23:51 +08:00
谭凯凯 f8e4fbf057 首页查询优化 2024-12-30 16:21:33 +08:00
wangw 41eabc21b5 资源页报错 2024-12-30 16:17:12 +08:00
wangw 8ca14e05a1 定时任务处理 2024-12-30 15:32:56 +08:00
张松 84a93810c5 feat: 达标奖励查询方式增加状态限定 2024-12-30 14:43:00 +08:00
张松 b6c8a07486 feat: 达标奖励查询方式修改 2024-12-30 14:19:53 +08:00
张松 bd6499727e feat: 达标奖励查询方式修改 2024-12-30 14:18:04 +08:00
wangw eca308e06f ShardingConfig 2024-12-30 14:02:26 +08:00
张松 3481ae235b Merge remote-tracking branch 'origin/test' into test 2024-12-30 13:15:07 +08:00
张松 b8c0b8b2d9 feat: 封禁用户状态仅更改一次 2024-12-30 13:14:59 +08:00
GYJ bbb761561a 修改 WuyouPay 为 service 2024-12-30 13:12:59 +08:00
张松 6c02934e08 feat: 增加ip跳动检测 2024-12-30 12:50:06 +08:00
张松 46f1bde62e Merge remote-tracking branch 'origin/test' into test 2024-12-30 11:15:55 +08:00
张松 3386e1f6a4 feat: 增加ip跳动检测 2024-12-30 11:15:32 +08:00
GYJ ea7d51450e 处理浏览历史,保留一条记录 2024-12-30 10:55:04 +08:00
GYJ b5e8d2514b admin 不给分享奖励 2024-12-30 10:17:44 +08:00
GYJ fde0d80a16 bug fix 2024-12-28 19:19:52 +08:00
GYJ acccb9b7df 添加日志 2024-12-28 19:15:04 +08:00
GYJ 71baadec22 bug fix 2024-12-28 19:10:44 +08:00
GYJ 3a9653418f bug fix 2024-12-28 18:59:32 +08:00
GYJ af8a0ece55 Merge remote-tracking branch 'origin/test' into test 2024-12-28 18:55:58 +08:00
GYJ a52dee9bce 补发任务奖励 任务 2024-12-28 18:55:46 +08:00
wangw db4d7327cc 签到页面2 2024-12-28 18:37:57 +08:00
wangw 5e5605c8ea 签到页面 2024-12-28 18:33:08 +08:00
GYJ f95affc036 查询 提现 次数统计 bug 2024-12-28 18:17:59 +08:00
GYJ 3b5c8f0af4 自定义 过分请求异常 2024-12-28 17:39:19 +08:00
wangw 0f12ed5161 抽奖到账机制优化 2024-12-28 16:42:30 +08:00
GYJ 963ad5d223 批量机审 时间修改 2024-12-28 15:57:13 +08:00
wangw d973622445 红包任务 2024-12-28 15:49:21 +08:00
GYJ e77bb19459 提现审核修改 2024-12-28 15:41:36 +08:00
GYJ 3d1b966b11 支付回调增加三方订单号 2024-12-28 14:54:38 +08:00
GYJ 70404d83e8 查询邀请人数 bug 2024-12-28 14:37:20 +08:00
GYJ f11c80b895 查询签到人数 bug 2024-12-28 14:30:33 +08:00
wangw 5a305c2d43 提现问题 2024-12-28 11:59:05 +08:00
GYJ d24826f4bb 批量机审 2024-12-28 11:55:28 +08:00
wangw 55476d4936 全接口 需要登录
数据库线程池大小
获取提现规则
2024-12-28 09:03:34 +08:00
GYJ 8bfa7dd4c4 关闭跨域 2024-12-27 17:21:23 +08:00
GYJ e5d8d37877 打开跨域 2024-12-27 17:16:46 +08:00
谭凯凯 666a347433 提现审核相关接口+支付宝提现统计接口 2024-12-27 16:58:37 +08:00
wangw 3d263960e8 补偿机制3 2024-12-27 16:52:46 +08:00
wangw 9f4820f32f 补偿机制2 2024-12-27 16:40:25 +08:00
wangw fae9df231c 补偿机制 2024-12-27 16:15:48 +08:00
张松 3a15793bfb feat: 手动体现增加次数和金额限制,增加体现类型 2024-12-27 15:35:05 +08:00
谭凯凯 57b2253d9d 提现审核增加成功提现次数和成功提现金额 2024-12-27 14:43:59 +08:00
张松 a58f429783 Merge remote-tracking branch 'origin/test' into test 2024-12-27 14:18:44 +08:00
张松 9469ec3472 feat: 去除首绑支付宝奖励 2024-12-27 14:18:29 +08:00
Tankaikai 1f460ae1e2 Merge remote-tracking branch 'origin/test' into test 2024-12-27 11:54:48 +08:00
谭凯凯 756794d659 获取签到数据接口优化 2024-12-27 11:54:23 +08:00
张松 2d6c93938c feat: 增加单元测试 2024-12-27 11:30:26 +08:00
张松 d70a4dd7f2 fix: 渠道码为空导致奖励不发放修复 2024-12-27 11:27:10 +08:00
谭凯凯 0618f81f82 首页查询优化 2024-12-27 10:43:25 +08:00
张松 bce2fac418 fix: 增加详情错误信息 2024-12-27 09:48:53 +08:00
谭凯凯 5c95fc57ad 首页查询优化 2024-12-26 22:31:31 +08:00
Tankaikai e2554bae0f Merge remote-tracking branch 'origin/test' into test 2024-12-26 22:01:25 +08:00
谭凯凯 8ba258edb4 优化回调 2024-12-26 22:01:20 +08:00
wangw c365f1d6b5 生成订单 支付订单 防抖 2024-12-26 21:33:02 +08:00
Tankaikai 039bcaf262 Merge remote-tracking branch 'origin/test' into test 2024-12-26 21:30:29 +08:00
Tankaikai 0cd1086c79 签到记录 2024-12-26 21:30:22 +08:00
谭凯凯 e5ead76f4f 首页查询优化 2024-12-26 21:27:28 +08:00
wangw bedbdcb0d7 3秒缓存 2024-12-26 20:56:33 +08:00
张松 b39a7f6dc5 Merge branch 'refs/heads/dev' into test 2024-12-26 19:16:00 +08:00
张松 409c3cc81c fix: 体现注释放开 2024-12-26 19:13:26 +08:00
wangw 94add5ee6c 后期发起 state为0的 提现 2024-12-26 19:01:34 +08:00
张松 db5ea43238 fix: 地址更换 2024-12-26 18:55:00 +08:00
Tankaikai 6c72c85bbf Merge remote-tracking branch 'origin/test' into dev 2024-12-26 18:28:31 +08:00
wangw 98433783fa 关闭拦截 2024-12-26 18:25:14 +08:00
Tankaikai da64106678 Merge remote-tracking branch 'origin/test' into test 2024-12-26 18:20:00 +08:00
谭凯凯 eabee5f050 订单刷数据 2024-12-26 18:19:50 +08:00
Tankaikai dd10140147 Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	src/main/java/com/sqx/modules/job/task/TempOrdersTask.java
2024-12-26 18:18:03 +08:00
谭凯凯 48a152085b 订单刷数据 2024-12-26 18:16:29 +08:00
wangw 894ed787a4 接口防抖 2024-12-26 18:15:42 +08:00
张松 e3c5a96ed2 fix: tomcat线程数量修改 2024-12-26 18:11:44 +08:00
wangw 73ef19ead6 缓存 2024-12-26 18:11:15 +08:00
张松 faf89c5a9e fix: tomcat线程数量修改 2024-12-26 18:08:52 +08:00
张松 aaa87b6d50 fix: tomcat线程数量修改 2024-12-26 18:05:19 +08:00
张松 22b6065950 fix: 订单状态定时任务增加失败状态 2024-12-26 17:56:34 +08:00
张松 03c1193cc5 Merge branch 'refs/heads/test' into dev 2024-12-26 17:53:39 +08:00
张松 e97df47287 fix: 订单状态定时任务增加失败状态 2024-12-26 17:53:29 +08:00
张松 05d446a212 fix: 订单状态定时任务增加失败状态 2024-12-26 17:52:08 +08:00
张松 e7e0d6d484 Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	src/main/java/com/sqx/modules/job/task/TempOrdersTask.java
2024-12-26 17:42:10 +08:00
张松 3b925f5070 Merge branch 'refs/heads/dev' into test
# Conflicts:
#	src/main/java/com/sqx/modules/job/task/TempOrdersTask.java
2024-12-26 17:41:42 +08:00
张松 54778f4078 fix: 订单状态定时任务增加失败状态 2024-12-26 17:41:06 +08:00
Tankaikai 2f23e93b03 Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	src/main/java/com/sqx/modules/job/task/TempOrdersTask.java
2024-12-26 17:39:36 +08:00
谭凯凯 b875469beb 订单刷数据测试 2024-12-26 17:38:13 +08:00
张松 372754bb65 Merge remote-tracking branch 'origin/test' into test 2024-12-26 17:13:20 +08:00
张松 4f138ac57b Merge branch 'refs/heads/dev' into test 2024-12-26 17:13:13 +08:00
张松 3f8ca43b71 fix: 订单状态定时任务增加失败状态 2024-12-26 17:12:40 +08:00
Tankaikai f681af7fd8 Merge remote-tracking branch 'origin/test' into test 2024-12-26 17:00:13 +08:00
谭凯凯 93b591fac1 领取满签奖励 2024-12-26 17:00:07 +08:00
张松 85818ffd3d fix: 更改提示 2024-12-26 16:52:47 +08:00
张松 b9564d6e74 fix: 更改提示 2024-12-26 16:52:18 +08:00
张松 0289392f3c Merge remote-tracking branch 'origin/test' into test 2024-12-26 16:24:41 +08:00
张松 b28a5eedff feat: 修改回调前缀 2024-12-26 16:19:51 +08:00
谭凯凯 17b125d14d 提现申请审核 2024-12-26 16:02:04 +08:00
Tankaikai 6afe946441 Merge remote-tracking branch 'origin/test' into test 2024-12-26 15:56:54 +08:00
谭凯凯 82b1526071 提现申请审核 2024-12-26 15:56:49 +08:00
wangw c8cf607a72 swagger 开关 2024-12-26 15:42:53 +08:00
wangw 2a25a4792b 注册 渠道不存在时 2024-12-26 15:02:24 +08:00
张松 5f7c225582 Merge branch 'refs/heads/test' into dev 2024-12-26 14:51:18 +08:00
张松 5f68d4f4ad feat: 体现超限,延缓到明日复审打款 2024-12-26 14:45:34 +08:00
张松 b4cc37b110 feat: 体现超限,延缓到明日复审打款 2024-12-26 14:41:26 +08:00
wangw 05d1b39d4a 提现补发 2024-12-26 14:21:19 +08:00
张松 6bed73e48d Merge remote-tracking branch 'origin/test' into test 2024-12-26 14:11:32 +08:00
张松 ff86d3969b feat: updateOrderStatus异步执行方法增加锁,等待异步方法执行完毕 2024-12-26 14:11:21 +08:00
GYJ 5c7e91a563 Merge branch 'test' into dev 2024-12-26 14:06:36 +08:00
谭凯凯 5b632f80d8 签到记录 2024-12-26 14:01:04 +08:00
Tankaikai 16b158e5e1 Merge remote-tracking branch 'origin/test' into test 2024-12-26 13:57:38 +08:00
谭凯凯 70e0d736ba 签到记录 2024-12-26 13:57:27 +08:00
GYJ d9c1ccee48 修改 api 前缀 2024-12-26 13:40:42 +08:00
wangw a392dc6c59 首次绑定支付宝问题 2024-12-26 13:21:07 +08:00
wangw 81ee291c22 绑定账号问题 2024-12-26 13:12:20 +08:00
张松 650b3bc4ea feat: 体现增加每次体现次数上限 2024-12-26 12:59:09 +08:00
wangw ce9d92508e 重复领取问题 2024-12-26 11:27:10 +08:00
wangw 112bcc15b9 user表 zhi_fu_bao_name 2024-12-26 11:27:05 +08:00
wangw d89ca7bc3a user表 zhifubao_name 2024-12-26 11:27:02 +08:00
wangw 867b3a284e 重复领取问题 2024-12-26 11:25:58 +08:00
wangw 1f3de4c9ae user表 zhi_fu_bao_name 2024-12-26 11:05:37 +08:00
wangw 36531bd0e6 user表 zhifubao_name 2024-12-26 11:01:48 +08:00
wangw 81d823f6ce Merge branch 'test' into dev 2024-12-26 10:48:13 +08:00
wangw 1581c3c530 关闭 提现 2024-12-26 10:46:40 +08:00
wangw cdefd711be 提现问题 2024-12-26 10:21:27 +08:00
GYJ 917f7e3a77 Merge branch 'test' into dev 2024-12-26 02:00:40 +08:00
GYJ 6d2e5f0d2a 注册防抖1 2024-12-26 02:00:24 +08:00
GYJ bacd2694c5 Merge branch 'test' into dev 2024-12-26 01:20:47 +08:00
GYJ 50dab891cc 注册防抖 2024-12-26 01:20:04 +08:00
wangw 184b340111 是否已兑换 2024-12-25 17:04:43 +08:00
wangw 8542e94ed9 生成订单 校验
领奖 记录
2024-12-25 15:36:43 +08:00
Tankaikai 5aecada96e Merge remote-tracking branch 'origin/test' into test 2024-12-25 15:20:51 +08:00
谭凯凯 d00edd861c 奖品兑换需求 2024-12-25 15:20:44 +08:00
wangw f21972b14c 任务奖励 列表 2024-12-25 15:07:25 +08:00
wangw cef4c4a17b 任务奖励 列表 2024-12-25 15:00:00 +08:00
wangw 98c6959fe6 任务奖励添加数量 2024-12-25 14:26:44 +08:00
wangw b3f206ac40 忽略实体 2024-12-25 14:14:36 +08:00
wangw dacf309731 实物领取 2024-12-25 14:09:18 +08:00
wangw 2b0782ddee Merge branch 'test' into dev 2024-12-25 11:20:22 +08:00
wangw 131e022c76 抽奖 随机数生成 2024-12-25 11:19:41 +08:00
GYJ 6178b0440f Merge branch 'test' into dev 2024-12-25 10:55:23 +08:00
GYJ ba5ba7e16b 上级奖励 bug fix 2024-12-25 10:53:53 +08:00
wangw b6d9eaa2de 事务注解 2024-12-25 10:31:00 +08:00
GYJ dc3b8fe67e Merge branch 'test' into dev 2024-12-25 10:16:19 +08:00
GYJ 593b4cc982 Merge branch 'test' into dev 2024-12-25 10:15:55 +08:00
wangw b5584d4c6e 任务奖励 增加图片描述
周任务抽取为 谢谢惠顾的情况
2024-12-25 10:09:02 +08:00
GYJ 1252d63bfd 分享收益查询 fix 2024-12-25 09:43:52 +08:00
wangw 1f4de9490c 余额描述 chassify 2024-12-25 09:43:21 +08:00
wangw 285f1ce4c9 Merge branch 'test' into dev 2024-12-24 18:16:10 +08:00
Tankaikai c0f24ca3ed Merge remote-tracking branch 'origin/test' into test 2024-12-24 18:04:56 +08:00
谭凯凯 40dc17c7dc 奖品兑换需求 2024-12-24 18:04:50 +08:00
wangw f642cbe20f 月任务2 满足时 不展示几/几 2024-12-24 18:03:47 +08:00
wangw 3957ed8c34 抽奖继续 倒叙
月抽奖 次数
2024-12-24 17:52:00 +08:00
Tankaikai 26fbd94cd9 Merge remote-tracking branch 'origin/test' into test 2024-12-24 17:38:47 +08:00
谭凯凯 66ab8a66c5 奖品兑换需求 2024-12-24 17:37:52 +08:00
wangw 75a4c5e4fc 月抽奖
抽奖记录 增加 图片
2024-12-24 17:31:26 +08:00
张松 a684c60b3e Merge remote-tracking branch 'origin/test' into test 2024-12-24 17:00:04 +08:00
张松 cb20edf097 fix: 时间戳溢出导致时间失效修复 2024-12-24 16:59:55 +08:00
GYJ 054ecad4d8 分享收益查询 类型增加 2024-12-24 16:50:18 +08:00
张松 24571a7c64 Merge remote-tracking branch 'origin/test' into test 2024-12-24 15:41:36 +08:00
张松 9129feb204 fix: 广告累计时间不正确修复 2024-12-24 15:41:28 +08:00
谭凯凯 b112da418e 分批次10集购买需求 2024-12-24 15:33:42 +08:00
谭凯凯 8872b6e513 分批次10集购买需求 2024-12-24 15:13:33 +08:00
谭凯凯 4629ec8811 分批次10集购买需求 2024-12-24 14:57:21 +08:00
Tankaikai 6477e48b44 Merge remote-tracking branch 'origin/test' into test 2024-12-24 14:51:05 +08:00
谭凯凯 ebbd658ffb 分批次10集购买需求 2024-12-24 14:49:39 +08:00
张松 310f5b831c fix: 广告回调修改 2024-12-24 14:42:58 +08:00
张松 694a0feac2 Merge remote-tracking branch 'origin/test' into test 2024-12-24 13:58:58 +08:00
张松 bf6864b725 fix: 后台配置免费时长参数秒数改为分钟 2024-12-24 13:57:32 +08:00
谭凯凯 abcdef7b78 分批次10集购买需求 2024-12-24 13:54:47 +08:00
Tankaikai b45f2d6876 Merge remote-tracking branch 'origin/test' into test 2024-12-24 13:52:53 +08:00
谭凯凯 703346253a 分批次10集购买需求 2024-12-24 13:49:39 +08:00
wangw 2c8721e2e8 抽奖 类型问题 2024-12-24 11:44:57 +08:00
wangw 9e923b5d1c 抽奖 类型问题 2024-12-24 11:33:16 +08:00
wangw 062067d4c3 任务 有次数时 不展示 2024-12-24 10:52:46 +08:00
wangw 920d19f8a2 任务 有次数时 不展示 2024-12-24 10:46:44 +08:00
wangw 8ffb5bb329 抽奖次数 2024-12-24 10:39:11 +08:00
wangw 6ffa4d5bf8 抽奖次数 2024-12-24 09:29:33 +08:00
wangw a1f1e9a2de 缓存管理器3 2024-12-23 17:33:56 +08:00
wangw 35c6e4ed23 缓存管理器 2024-12-23 17:27:14 +08:00
wangw ed21f91555 缓存管理器 2024-12-23 17:17:09 +08:00
张松 81da6fa6a3 feat: 1.uni-ad广告回调接入 2.广告奖励免费观看时长 2024-12-23 17:12:38 +08:00
张松 b7e8047b4c Merge remote-tracking branch 'origin/test' into test 2024-12-23 17:07:12 +08:00
张松 45a7224b99 feat: 1.uni-ad广告回调接入 2.广告奖励免费观看时长 2024-12-23 17:07:03 +08:00
wangw e738d98948 生成订单 已存在的情况 2024-12-23 16:30:40 +08:00
张松 f11ae848b0 feat: 1.uni-ad广告回调接入 2.广告奖励免费观看时长 2024-12-23 16:16:36 +08:00
wangw f4e93e748e 任务 抽奖 签到 2024-12-23 16:02:44 +08:00
谭凯凯 4750dca914 分批次10集购买需求 2024-12-23 15:26:05 +08:00
谭凯凯 08dd65e7cb 签到记录需求变更 2024-12-23 15:11:53 +08:00
谭凯凯 73c0510211 分批次10集购买需求 2024-12-23 15:09:57 +08:00
wangw 32fe771c31 Merge branch 'test' into dev 2024-12-23 09:40:20 +08:00
wangw 9dff41383f 事务注解 2024-12-23 09:39:34 +08:00
wangw f131f5b786 任务次数 2024-12-21 18:20:15 +08:00
wangw eabcee6bf5 任务已达标次数
获取大转盘次数
2024-12-21 18:13:00 +08:00
wangw a5d17f7f57 抽奖 奖项概率设置 2024-12-21 17:34:00 +08:00
wangw 49859f9ea6 任务中心 奖励 跳转 2024-12-21 14:11:34 +08:00
Tankaikai 5b4fb7a983 Merge remote-tracking branch 'origin/test' into test 2024-12-21 11:01:17 +08:00
谭凯凯 a664a59286 奖品兑换需求 2024-12-21 11:01:09 +08:00
wangw d0d55ec8d1 大转盘 添加时 概率问题 2024-12-21 10:06:39 +08:00
wangw d6ac80cd1e 大转盘 添加 2024-12-21 09:59:28 +08:00
wangw 2035da163d 大转盘 参数 2024-12-21 09:30:37 +08:00
wangw e751d9b4cc 获取 大转盘 传参 2024-12-20 18:16:08 +08:00
wangw 18f1bf1f9b 每日任务 领取后可点击 2024-12-20 18:02:31 +08:00
wangw 8b6a67e17a 大转盘抽奖
任务中心
2024-12-20 14:44:53 +08:00
谭凯凯 4363e91fa7 首绑支付宝发放现金红包奖励 2024-12-20 14:29:27 +08:00
谭凯凯 c2643cf546 首绑支付宝发放现金红包奖励 2024-12-20 14:24:29 +08:00
谭凯凯 d135eb3c58 首绑支付宝发放现金红包奖励 2024-12-20 14:13:51 +08:00
谭凯凯 0584ef6566 首绑支付宝发放现金红包奖励 2024-12-20 14:02:50 +08:00
谭凯凯 8123d0223e 签到需求相关接口 2024-12-19 15:41:59 +08:00
谭凯凯 d1e6bbe252 签到需求相关接口 2024-12-19 15:32:48 +08:00
wangw dfc06961d9 注册 代理商 2024-12-19 14:16:06 +08:00
wangw e09d2cee39 注册 代理商 2024-12-19 14:14:42 +08:00
wangw 893a37c752 提现问题 2024-12-19 13:31:48 +08:00
wangw 764dcb72ad 提现问题 2024-12-19 11:37:12 +08:00
wangw b8923516e5 注册 不校验token 2024-12-19 11:36:53 +08:00
wangw aba9025464 现金红包抽奖概率设置 2024-12-19 10:43:04 +08:00
wangw 17213fafd9 提现异步回调 执行时间问题 2024-12-19 10:42:26 +08:00
wangw 59dd621bab 提现总次数 提现总金额 2024-12-19 10:41:44 +08:00
Tankaikai c769b9b71d Merge remote-tracking branch 'origin/test' into test 2024-12-19 10:40:24 +08:00
谭凯凯 d6355e37ed 签到需求相关接口 2024-12-19 10:40:16 +08:00
wangw 9550e3d169 注册接口 2024-12-18 18:10:57 +08:00
wangw c510a32e71 登录接口 2024-12-18 17:59:30 +08:00
wangw 48ed1e3d7a 抽奖3次后 修改概率
redis 工具类 新增返回 map<String,List<T>> 格式
2024-12-18 17:49:34 +08:00
wangw 38decaa8f1 提现 增加验证码校验 2024-12-18 17:45:49 +08:00
wangw 297c028985 代理商 注册 2024-12-18 17:45:49 +08:00
张松 c9242db805 feat: 用户累计充值可得免费播放全集权限 2024-12-18 17:25:52 +08:00
张松 5a10f03a4a feat: 用户累计充值可得免费播放全集权限 2024-12-18 17:07:13 +08:00
wangw 4184193ee6 代理平台 提现扣款问题 2024-12-18 15:02:24 +08:00
wangw 616199ed71 代理平台 提现扣款问题 2024-12-18 15:01:53 +08:00
wangw 00d624f9ef 分享达标 代理奖励 2024-12-18 14:30:36 +08:00
wangw 54ea8c91a9 邀请人 签到 记录 2024-12-17 19:11:19 +08:00
wangw bf60074bd4 下级佣金不可大于渠道商佣金 2024-12-17 18:57:01 +08:00
wangw 0a3c890507 下级佣金不可大于渠道商佣金 2024-12-17 18:50:11 +08:00
wangw 8a92e23106 提现返回 2024-12-17 18:22:06 +08:00
wangw 29bc443422 提现记录 2024-12-17 18:02:44 +08:00
wangw 26f12ab48f 邀请用户 金钱到账记录 2024-12-17 17:58:46 +08:00
wangw 1c2243c692 邀请用户 查询是否签到 2024-12-17 17:48:18 +08:00
wangw 58b831b174 邀请用户是否已签到
邀请好友 佣金入账
2024-12-17 17:40:35 +08:00
wangw e6ca889f43 提现问题 2024-12-17 17:17:57 +08:00
wangw 48be3106b8 下级佣金不可大于渠道商佣金 2024-12-17 15:58:49 +08:00
wangw 982e79d268 redis密码 2024-12-17 14:13:35 +08:00
wangw e40068a762 redis密码 2024-12-17 13:42:35 +08:00
wangw ed4720d992 接口访问次数限制 2024-12-17 13:42:04 +08:00
wangw 85f71935cd 接口限制 2024-12-17 11:25:06 +08:00
wangw 42b33c5f0e 提现回调,已驳回的 返回内容 2024-12-17 10:29:11 +08:00
wangw 0bc204460e 分润问题 2024-12-17 09:57:39 +08:00
GYJ 249f857c9e 领取奖励时判断用户是否绑定支付宝 2024-12-16 15:17:41 +08:00
GYJ 12ca117e82 处理手机号未注册登录提示 2024-12-15 18:36:38 +08:00
GYJ 20753f84b3 bug fix1 2024-12-15 17:15:00 +08:00
GYJ 67f9f7bc82 bug fix 2024-12-15 17:11:26 +08:00
GYJ 09952a245e 抽奖次数bug fix 2024-12-14 15:05:34 +08:00
GYJ dec0a17935 查询流水区分类型 2024-12-14 14:33:25 +08:00
GYJ 0fc6bf0d6d 代理金额入账bug fix 2024-12-14 14:08:33 +08:00
GYJ c6692c87cd 积分未入账 2024-12-14 13:28:33 +08:00
GYJ 317f761aea 增加万能验证码 2024-12-14 10:27:01 +08:00
GYJ 88bb7e54a5 Merge remote-tracking branch 'origin/test' into test 2024-12-14 09:37:12 +08:00
GYJ 51e9ef0d91 修改达标奖励重复给的问题
增加万能验证码
2024-12-14 09:36:46 +08:00
GYJ 0973c4bc45 payType 非必填 2024-12-13 18:07:57 +08:00
GYJ c463ab0ae1 修改h5相关支付流程 2024-12-13 17:36:00 +08:00
GYJ ff634f2ded 测试支付回调地址3 2024-12-13 17:24:59 +08:00
GYJ bdd223ee5e 测试支付回调地址2 2024-12-13 17:14:58 +08:00
GYJ aa04da087b 测试支付回调地址1 2024-12-13 15:46:04 +08:00
wangw fcdf71a9b0 redis 缓存问题 2024-12-13 15:25:15 +08:00
GYJ 8879666375 测试支付回调地址 2024-12-13 15:21:33 +08:00
wangw af71811487 redis 缓存问题
id默认问题
2024-12-13 15:04:41 +08:00
wangw 73631f76a7 redis 方法封装
抽奖金额概率 配置
banner 跳转类型
2024-12-13 10:53:40 +08:00
wangw 4227ece60a 统计月签到次数 问题 2024-12-12 17:56:10 +08:00
GYJ 9775cf129a 查询分享收益接口修改 2024-12-12 16:40:41 +08:00
GYJ a6bcb3da8f 修改 收益类型对照关系 2024-12-12 16:24:03 +08:00
GYJ 6d96ea7dbd 修改金豆为金币 2024-12-12 14:45:41 +08:00
GYJ b763d69419 支付回调修改 2024-12-12 14:30:43 +08:00
GYJ 8dce86e874 代理修改账号 密码出错bug 1 2024-12-12 11:10:51 +08:00
GYJ 907b98914f 代理修改账号 密码出错bug 2024-12-12 10:59:15 +08:00
GYJ bc8dc5b0d8 支付处理 价格为0的情况 2024-12-12 10:55:15 +08:00
GYJ 6051d83bbc 支付删除成功回调url 2024-12-12 10:35:35 +08:00
wangw 978c4ff5b6 邀请人员达标人员够?额外奖励 2024-12-12 10:10:25 +08:00
GYJ af6efd83be 查询订单支付状态 2024-12-12 09:52:51 +08:00
wangw a810db24fe 抽奖绑定order id 2024-12-11 18:08:41 +08:00
wangw b4e1fd3826 抽奖值 2024-12-11 17:57:22 +08:00
wangw c9fa6a7185 抽奖值 2024-12-11 17:51:35 +08:00
wangw ac6f6d07c7 一次性任务 领取 2024-12-11 17:30:19 +08:00
wangw 0b0fac8aa1 单词错误 2024-12-11 17:18:47 +08:00
wangw e93e201dd2 单次任务处理 2024-12-11 16:45:06 +08:00
GYJ 211f99c87b 流水区分金豆和钱 2024-12-11 16:10:24 +08:00
wangw 2f73eb9032 抽奖金额修改
订单笔数统计 只统计支付宝支付
增加 一次性任务 新人福利 领取1元
2024-12-11 15:47:47 +08:00
GYJ b36abdd513 分享签到相关修改 2024-12-11 15:24:28 +08:00
wangw 85235ae78b Merge branch 'test' into dev 2024-12-11 11:00:04 +08:00
wangw 1d714f7383 奖励类型 9 为大转盘 2024-12-11 10:59:40 +08:00
wangw dddc343261 已领取后 number置空 2024-12-11 10:52:03 +08:00
wangw 2ededc726f 重复领取问题 2024-12-11 10:49:09 +08:00
wangw 3824038f36 达标 置为null
任务领取
2024-12-11 10:45:49 +08:00
wangw a9ca0f4fb2 达标 置为null 2024-12-11 10:39:42 +08:00
wangw 5607bfcd8e 任务 是否已领取 2024-12-11 10:31:35 +08:00
wangw d001b23e7f 每日次数 永远可点 2024-12-11 10:21:17 +08:00
wangw 0bdf1c585d 剩余次数 2024-12-11 10:13:13 +08:00
wangw d30ed4aba6 Merge branch 'test' into dev 2024-12-11 10:06:09 +08:00
wangw 6bc31b3484 支付笔数 2024-12-11 10:05:39 +08:00
wangw ffc289cc7d 任务剩余次数 2024-12-11 10:00:08 +08:00
wangw 35cc3a6c4d Merge branch 'test' into dev 2024-12-11 09:35:02 +08:00
wangw 5333c8775e 任务剩余次数 2024-12-11 09:34:14 +08:00
wangw 38572e9077 签到任务 剩余 次数 2024-12-10 17:55:11 +08:00
wangw b6c0815a59 顺序问题 2024-12-10 16:30:08 +08:00
wangw 48311dc69e Merge branch 'test' into dev 2024-12-10 10:13:25 +08:00
wangw 742c4e8735 提现问题 2024-12-10 10:10:50 +08:00
GYJ d5078718a6 Merge branch 'test' into dev 2024-12-09 17:38:00 +08:00
GYJ 2546025d70 支付回调处理 2024-12-09 17:37:02 +08:00
GYJ c4790628f0 支付成功回调地址 2024-12-09 17:12:12 +08:00
wangw 7c1685f993 抽奖 金额 2024-12-09 16:45:30 +08:00
wangw 4ed9da9448 Merge branch 'test' into dev 2024-12-09 15:39:34 +08:00
wangw 6771ad1d25 日志打印 避免回填 2024-12-09 15:38:31 +08:00
wangw 357595bda9 任务中心 获得抽奖次数 与订单 次数不冲突 2024-12-09 15:30:53 +08:00
wangw 318d252a32 防抖 2024-12-09 14:51:10 +08:00
GYJ 9696e6e9de 添加提现成功时间 2024-12-09 14:36:04 +08:00
GYJ a241322cb4 统计播放量不要用户id 2024-12-09 14:31:10 +08:00
GYJ fc0bb7795f Merge branch 'test' into dev 2024-12-09 14:14:48 +08:00
GYJ 842cacd88e 金豆购买视频 修复 2024-12-09 14:01:55 +08:00
wangw 3eeaa2b947 内部预留字段 sql执行问题 2024-12-09 13:59:44 +08:00
wangw 32dcd1573e 任务中心问题 2024-12-09 13:54:31 +08:00
wangw 18cf4bd1c5 Merge branch 'test' into dev
# Conflicts:
#	src/main/java/com/sqx/modules/taskCenter/service/TaskCenterService.java
#	src/main/java/com/sqx/modules/taskCenter/service/impl/TaskCenterServiceImpl.java
2024-12-09 11:12:09 +08:00
wangw 03526f7c4a 大转盘 领取奖励修改
提现 修改
任务中心 记录 领取记录 是否可领取
2024-12-09 11:05:22 +08:00
GYJ 02dd3b4587 金豆购买视频 2024-12-07 17:52:08 +08:00
wangw e81d2a1d57 任务中心
任务列表
 任务领取(不包括领取记录)
签到
2024-12-07 17:19:01 +08:00
wangw 1b1a1e6c49 任务中心
任务列表
 任务领取(不包括领取记录)
签到
2024-12-07 17:17:53 +08:00
wangw 53f6a8c24e Merge branch 'test' into dev
# Conflicts:
#	src/main/java/com/sqx/modules/discSpinning/controller/DiscSpinningController.java
2024-12-07 15:48:26 +08:00
wangw ed2774907e 根据订单落地 抽奖记录 2024-12-07 15:46:42 +08:00
wangw 9c40748e3f 抽奖 maps为空 2024-12-07 15:35:23 +08:00
wangw 2c8cc45ce0 抽奖 maps为空 2024-12-07 15:33:28 +08:00
wangw 387af834ae 抽奖 2024-12-07 15:22:45 +08:00
GYJ 09c68c015b 修改用户信息bug修复 2024-12-07 13:50:51 +08:00
GYJ 8c22e7ed95 红包抽奖次数提示 2024-12-07 11:36:09 +08:00
wangw 94159c174e 分享达标
大转盘 获取次数区分
抽奖 区分
统计 订单数统一接口
2024-12-07 11:04:15 +08:00
GYJ a297859b47 代理商提现 2024-12-07 10:56:22 +08:00
wangw db80169234 任务中心 接口路径修改 2024-12-07 09:37:48 +08:00
wangw b781a7f670 拦截器 2024-12-06 18:27:37 +08:00
wangw 125e2b59a3 sessionCreated 报错问题 2024-12-06 17:30:28 +08:00
wangw b8282bc471 sessionCreated 报错问题 2024-12-06 17:27:59 +08:00
wangw beb963d785 提现额度过低问题 2024-12-06 17:17:17 +08:00
wangw b7c2e95298 sessionCreated 报错问题 2024-12-06 17:13:48 +08:00
GYJ 17fbb078f2 代理商固定分润 2024-12-06 17:04:10 +08:00
wangw af7a1f14a4 提现失败 描述 2024-12-06 16:17:34 +08:00
wangw 383867e7a2 用户为空 2024-12-06 16:01:34 +08:00
wangw ce8c9f38e0 异步领取 奖项 2024-12-06 15:54:27 +08:00
wangw 0f2cac26b7 异步注解启动 2024-12-06 15:41:50 +08:00
wangw ad1f5d2df2 接口执行时间
领取过慢
2024-12-06 15:35:01 +08:00
wangw 3a66ec6eda 接口执行时间 2024-12-06 15:19:18 +08:00
GYJ 12ed8f03d3 支付回调去除签名校验 2024-12-06 15:09:33 +08:00
wangw a0e9582233 任务中心 /app 2024-12-06 14:22:16 +08:00
wangw 5b50aa54b7 任务中心 2024-12-06 14:21:01 +08:00
wangw 6f89ce84fe 提现 字段 存入 问题 2024-12-06 11:50:54 +08:00
wangw 793e6eefe8 提现 字段 存入 问题 2024-12-06 11:49:01 +08:00
wangw 8bfe18f6d8 钱包 明细 2024-12-06 11:37:13 +08:00
wangw 858bf4fc79 提现 失败 情况 处理 2024-12-06 11:21:59 +08:00
wangw c6dae69abc Merge branch 'dev' into test
# Conflicts:
#	src/main/java/com/sqx/modules/discSpinning/controller/DiscSpinningController.java
2024-12-06 11:17:20 +08:00
GYJ 16a823d330 提现失败 处理 2024-12-06 11:14:08 +08:00
wangw 5ea41773c7 抽奖 获取抽奖次数 2024-12-06 10:53:51 +08:00
wangw 436c2afcd7 抽奖 获取抽奖次数 2024-12-06 10:42:42 +08:00
wangw ece33e9299 抽奖 获取抽奖次数 2024-12-06 10:04:16 +08:00
GYJ f6d6603f8d Merge branch 'test' into dev 2024-12-05 18:16:41 +08:00
GYJ ada714d68e 统计播放量 和 完播量 2024-12-05 17:32:04 +08:00
wangw 8672a9f2c7 提现获取 userId 2024-12-05 17:15:31 +08:00
wangw 96c333fcc4 提现 2024-12-05 17:02:41 +08:00
GYJ 2c07d98be9 修改无忧支付配置 2024-12-05 17:01:32 +08:00
wangw 2d9a74158a 我的钱包 2024-12-05 16:45:31 +08:00
wangw 2379cae506 我的钱包
通用日志
2024-12-05 16:42:41 +08:00
wangw 2ea9a4d813 全局 日志
领取红包 返回
2024-12-05 16:06:50 +08:00
wangw 07a75fdfe7 Merge branch 'master' into dev 2024-12-05 14:51:04 +08:00
wangw 3416b0ef7f Merge branch 'master' into test 2024-12-05 14:50:24 +08:00
GYJ ded4804ca4 修改配置文件 2024-12-05 14:47:38 +08:00
267 changed files with 11086 additions and 3974 deletions

View File

@ -249,7 +249,7 @@ INSERT INTO `common_info` VALUES (420, '2023-08-28 11:23:02', NULL, '一级佣
INSERT INTO `common_info` VALUES (421, '2024-03-05 16:55:37', NULL, '二级佣金比例', 421, '0.04', 'fuwufei');
INSERT INTO `common_info` VALUES (450, '2024-02-02 18:12:27', NULL, '剧导入模板', 450, 'https://duanju.xianmxkj.com/剧导入模板.xlsx', 'xitong');
INSERT INTO `common_info` VALUES (451, '2024-02-02 18:12:49', NULL, '集导入模板', 451, 'https://duanju.xianmxkj.com/集导入模板.xlsx', 'xitong');
INSERT INTO `common_info` VALUES (500, '2020-02-25 20:44:15', NULL, '付费须知说明', 500, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xieyi');
INSERT INTO `common_info` VALUES (500, '2020-02-25 20:44:15', NULL, '付费须知说明', 500, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xieyi');
INSERT INTO `common_info` VALUES (800, '2024-05-30 18:08:11', NULL, '腾讯云oss AccessKey', 800, '', 'oss');
INSERT INTO `common_info` VALUES (801, '2024-05-30 18:08:06', NULL, '腾讯云oss SecretKey', 801, '', 'oss');
INSERT INTO `common_info` VALUES (802, '2024-05-30 18:08:17', NULL, '腾讯云oss bucket地域', 802, 'ap-shanghai', 'oss');
@ -274,7 +274,7 @@ INSERT INTO `common_info` VALUES (821, '2024-01-06 11:40:25', NULL, '抖音原
INSERT INTO `common_info` VALUES (822, '2024-06-26 16:07:33', NULL, '小程序AppKey', 822, '', 'xitong');
INSERT INTO `common_info` VALUES (823, '2024-06-26 16:07:18', NULL, '微信虚拟支付OfferID', 823, '', 'xitong');
INSERT INTO `common_info` VALUES (824, '2024-07-08 02:19:39', NULL, '微信虚拟支付环境 0正式环境 1沙盒环境', 824, '0', 'xitong');
INSERT INTO `common_info` VALUES (825, '2024-01-06 11:40:25', NULL, '充值提示', 825, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xitong');
INSERT INTO `common_info` VALUES (825, '2024-01-06 11:40:25', NULL, '充值提示', 825, '一经购买不予退款未满18岁需在监护人的指导、同意下进行付费操作', 'xitong');
INSERT INTO `common_info` VALUES (826, '2024-06-26 16:07:54', NULL, '小程序Token', 826, '', 'weixin');
INSERT INTO `common_info` VALUES (827, '2024-06-26 16:07:44', NULL, '小程序EncodingAESKey ', 827, '', 'weixin');
INSERT INTO `common_info` VALUES (828, '2020-02-25 20:43:59', NULL, '快手AppId', 828, '', 'xitong');

99
pom.xml
View File

@ -35,12 +35,14 @@
<qiniu.version>7.2.23</qiniu.version>
<aliyun.oss.version>3.4.0</aliyun.oss.version>
<qcloud.cos.version>4.4</qcloud.cos.version>
<swagger.version>2.7.0</swagger.version>
<!-- <swagger.version>2.7.0</swagger.version>-->
<swagger.version>2.9.2</swagger.version>
<joda.time.version>2.9.9</joda.time.version>
<gson.version>2.8.5</gson.version>
<fastjson.version>1.2.83</fastjson.version>
<hutool.version>4.6.10</hutool.version>
<lombok.version>1.18.4</lombok.version>
<shardingsphere.version>4.1.1</shardingsphere.version>
<!--wagon plugin 配置-->
<!--<service-path>/work/sz</service-path>
@ -67,11 +69,23 @@
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.274</version>
<exclusions>
<exclusion>
<artifactId>aws-java-sdk-simpleworkflow</artifactId>
<groupId>com.amazonaws</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version>
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>org.javassist</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.qcloudsms</groupId>
@ -91,13 +105,6 @@
</exclusions>
</dependency>
<!--云购os支付-->
<dependency>
<groupId>com.yungouos.pay</groupId>
<artifactId>yungouos-pay-sdk</artifactId>
<version>2.0.10</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
@ -123,11 +130,11 @@
<version>5.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid</artifactId>-->
<!-- <version>1.1.10</version>-->
<!-- </dependency>-->
<!-- 苹果工具类 -->
<dependency>
<groupId>com.auth0</groupId>
@ -177,6 +184,12 @@
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.4.0</version>
<exclusions>
<exclusion>
<artifactId>aliyun-java-sdk-core</artifactId>
<groupId>com.aliyun</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
@ -241,16 +254,40 @@
</exclusion>
</exclusions>
</dependency>
<!--动态数据库切换-->
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>dynamic-datasource-spring-boot-starter</artifactId>-->
<!-- <version>4.1.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--oracle驱动-->
<!-- <dependency>-->
<!-- <groupId>com.oracle</groupId>-->
<!-- <artifactId>ojdbc6</artifactId>-->
<!-- <version>${oracle.version}</version>-->
<!-- </dependency>-->
<!-- 用于定义sharding-jdbc 分片规则 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-api</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${shardingsphere.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--mssql驱动-->
<dependency>
@ -259,10 +296,10 @@
<version>${mssql.version}</version>
</dependency>
<!--postgresql驱动-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.postgresql</groupId>-->
<!-- <artifactId>postgresql</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
@ -321,14 +358,25 @@
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
@ -419,7 +467,12 @@
<artifactId>restful-sdk</artifactId>
<version>1.0.0.1</version>
</dependency>
<!--<dependency>-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>com.baidu.aip</groupId>-->
<!--            <artifactId>java-sdk</artifactId>-->
<!--            <version>4.11.3</version>-->

View File

@ -2,8 +2,16 @@ package com.sqx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Map;
/**
* @author GYJ
*/
@EnableCaching
@EnableScheduling
@SpringBootApplication
public class SqxApplication {
@ -11,13 +19,13 @@ public class SqxApplication {
public static void main(String[] args) {
SpringApplication.run(SqxApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+
" _ \n" +
" | | \n" +
" ___ | | __\n" +
" / _ \\| |/ /\n" +
"| (_) | < \n" +
" \\___/|_|\\_\\");
" _ \n" +
" | | \n" +
" ___ | | __\n" +
" / _ \\| |/ /\n" +
"| (_) | < \n" +
" \\___/|_|\\_\\");
}
}
}

View File

@ -0,0 +1,24 @@
package com.sqx.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
/**
* @author ww
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Debounce {
// 防抖时间间隔默认2秒
long interval() default 2000;
// 时间单位默认毫秒
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
// 用于指定基于的入参表达式为空时对整个方法防抖
// 格式为 #入参键. 例如 #receive.id
// 多个参数 使用逗号进行拼接 例如: #receive.id,#receive.name
String value() default "";
}

View File

@ -0,0 +1,74 @@
package com.sqx.common.aspect;
import cn.hutool.core.thread.ThreadUtil;
import com.google.gson.Gson;
import com.sqx.common.utils.HttpContextUtils;
import com.sqx.common.utils.IPUtils;
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.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 方法调用统一切面处理
*/
@Aspect
@Component
@Slf4j
public class AppApiMethodAspect {
@Pointcut("!execution(public * (com.sqx.modules.sys.controller.SysLoginController).*(..)) " +
"&& execution(public * (com.sqx.modules.*.controller..*).*(..)))")
public void pkg() {
}
@Around("pkg()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
//避免回填
Object[] args = pjp.getArgs();
// 如果请求参数中包含HttpServletRequest剔除HttpServletRequest
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof HttpServletRequest) {
args[i] = null;
}
}
String params = new Gson().toJson(args);
// 执行被拦截的方法
Object result = pjp.proceed();
long end = System.currentTimeMillis();
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
String method = request.getMethod();
String requestUrl = request.getRequestURL().toString();
String requestIp = IPUtils.getIpAddr(request);
long useTime = end - start;
ThreadUtil.execAsync(() -> {
//请求的参数
String resultJson = new Gson().toJson(result);
try {
if (StringUtils.isNotBlank(resultJson) && !"null".equals(resultJson)) {
log.info("\n>>>>>> {} {}" +
"\n>>>>>> IP: {} " +
"\n>>>>>> execute time:{}ms " +
"\n>>>>>> Request: {}" +
"\n>>>>>> Response: {}",
method, requestUrl, requestIp, useTime,
params,
resultJson
);
}
} catch (Exception e) {
log.error("Request 为空" + e.getMessage());
}
});
return result;
}
}

View File

@ -0,0 +1,117 @@
package com.sqx.common.aspect;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.SpelUtil;
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.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* 防抖切面
* @author ww
*/
@Aspect
@Component
public class DebounceAspect {
@Pointcut("@annotation(com.sqx.common.annotation.Debounce)")
public void logPointCut() {
}
// 用于存储基于方法和入参情况的上次执行时间结构为方法签名 -> (入参值 -> 上次执行时间)
private static final ConcurrentHashMap<String, ConcurrentHashMap<Object, Long>> executionTimeMap = new ConcurrentHashMap<>();
private static final ReentrantLock lock = new ReentrantLock();
@Around("logPointCut()")
public Object aroundDebounce(ProceedingJoinPoint joinPoint) throws Throwable {
cleanExpiredRecords();
String methodSignature = joinPoint.getSignature().toLongString();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Debounce annotation = signature.getMethod().getAnnotation(Debounce.class);
long interval = annotation.interval();
TimeUnit timeUnit = annotation.timeUnit();
String value = annotation.value();
if (StringUtils.isBlank(value)) {
// 没有指定入参表达式按照整个方法进行防抖
return debounceForWholeMethod(joinPoint, methodSignature, interval, timeUnit);
}
String[] split = value.split(",");
StringBuilder values = new StringBuilder();
for (String str : split) {
values.append(SpelUtil.generateKeyBySpEL(str, joinPoint));
}
// 解析入参表达式获取对应入参的值
if (StringUtils.isBlank(values.toString())) {
// 如果解析失败或值为null按照整个方法进行防抖
return debounceForWholeMethod(joinPoint, methodSignature, interval, timeUnit);
}
// 根据方法签名和入参值进行防抖判断
return debounceForSpecificValue(joinPoint, methodSignature, interval, timeUnit, values.toString());
}
private Object debounceForWholeMethod(ProceedingJoinPoint joinPoint, String methodSignature, long interval, TimeUnit timeUnit) throws Throwable {
ConcurrentHashMap<Object, Long> methodExecutionTimeMap = executionTimeMap.computeIfAbsent(methodSignature, k -> new ConcurrentHashMap<>());
long currentTime = System.currentTimeMillis();
Long lastTime = methodExecutionTimeMap.get(methodSignature);
if (lastTime == null) {
// 如果不存在对应键值对设置初始值这里设置为一个表示很久之前的时间戳比如0
lastTime = 0L;
}
if (lastTime == null || currentTime - timeUnit.toMillis(interval) >= lastTime) {
// 满足防抖间隔更新上次执行时间并执行目标方法
methodExecutionTimeMap.put(methodSignature, currentTime);
return joinPoint.proceed();
}
// 在防抖间隔内不执行目标方法直接返回
return null;
}
private Object debounceForSpecificValue(ProceedingJoinPoint joinPoint, String methodSignature, long interval, TimeUnit timeUnit, Object targetValue) throws Throwable {
ConcurrentHashMap<Object, Long> methodExecutionTimeMap = executionTimeMap.computeIfAbsent(methodSignature, k -> new ConcurrentHashMap<>());
long currentTime = System.currentTimeMillis();
Long lastTime = methodExecutionTimeMap.get(targetValue);
if (lastTime == null || currentTime - timeUnit.toMillis(interval) >= lastTime) {
// 满足防抖间隔更新上次执行时间并执行目标方法
methodExecutionTimeMap.put(targetValue, currentTime);
return joinPoint.proceed();
}
// 在防抖间隔内不执行目标方法直接返回
return null;
}
public void cleanExpiredRecords() {
long expirationTime = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(10);
lock.lock();
try {
for (Entry<String, ConcurrentHashMap<Object, Long>> outerEntry : executionTimeMap.entrySet()) {
String methodSignature = outerEntry.getKey();
ConcurrentHashMap<Object, Long> innerMap = outerEntry.getValue();
ConcurrentHashMap<Object, Long> keysToRemove = new ConcurrentHashMap<>();
for (Entry<Object, Long> innerEntry : innerMap.entrySet()) {
if (innerEntry.getValue() < expirationTime) {
keysToRemove.put(innerEntry.getKey(), innerEntry.getValue());
}
}
innerMap.keySet().removeAll(keysToRemove.keySet());
if (innerMap.isEmpty()) {
executionTimeMap.remove(methodSignature);
}
}
} finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,10 @@
package com.sqx.common.exception;
/**
* @author GYJoker
*/
public class CzgException extends Exception {
public CzgException(String message) {
super(message);
}
}

View File

@ -5,6 +5,8 @@ import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@ -68,6 +70,12 @@ public class SqxExceptionHandler {
return Result.error();
}
@ExceptionHandler(CzgException.class)
public ResponseEntity<Void> handleCzgException() {
// 响应状态码为 444 表示无法处理的异常
return new ResponseEntity<>(HttpStatus.TOO_MANY_REQUESTS);
}
private void logErrorInfo(WebRequest webRequest) {
if (webRequest instanceof ServletWebRequest) {
ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;

View File

@ -0,0 +1,193 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
import java.util.function.Supplier;
/**
* 接口访问次数 月为单位
*/
@Component
@Slf4j
public class ApiAccessLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:";
private static RedisUtils redisUtils;
private static final int DEFAULT_ACCESS_COUNT = 5;
private static final String DATE_TIME_FORMAT = "month";
@Autowired
public void setRedisUtils(RedisUtils redisUtils) {
ApiAccessLimitUtil.redisUtils = redisUtils;
}
/**
* 默认 当月5次
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @return
*/
public static boolean isAccessAllowed(String id, String key) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认月 month//自然月
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param count 次数限制
* @return
*/
public static boolean isAccessAllowed(String id, String key, Integer count) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认 5次
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String id, String key, String timeFormat) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* @param id 唯一值
* @param key 接口名称 sys:limit:接口名称
* @param count 次数限制
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String id, String key, Integer count, String timeFormat) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
public static<T> T runFunAndCheckKey(Supplier<T> supplier, String lockKey, Integer seconds) {
try{
// 创建线程id, 用作判断
String clientId = UUID.randomUUID().toString();
// 设置分布式锁
boolean lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
int count = 0;
while (!lock) {
if (count++ > 100) {
throw new RuntimeException("系统繁忙, 稍后再试");
}
Thread.sleep(20);
lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
}
return supplier.get();
} catch (RuntimeException e){
log.error("执行出错", e);
throw e;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally{
redisUtils.delete(lockKey);
}
}
public static boolean isAccessAllowed(String id, String key, Integer count, Integer seconds) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
redisUtils.set(redisKey, 1, seconds);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key, String id) {
return ACCESS_COUNT_KEY_PREFIX + key + ":" + id;
}
private static long calculateExpireAt(String timePeriod) {
Date now = DateUtil.beginOfDay(DateUtil.date());
Date expireDate = null;
if ("day".equals(timePeriod)) {
expireDate = DateUtil.endOfDay(now);
} else if ("week".equals(timePeriod)) {
expireDate = DateUtil.endOfWeek(now);
} else if ("month".equals(timePeriod)) {
expireDate = DateUtil.endOfMonth(now);
} else if ("year".equals(timePeriod)) {
expireDate = DateUtil.endOfYear(now);
}
long endTimeStamp = DateUtil.endOfDay(expireDate).getTime() / 1000L;
long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp;
}
}

View File

@ -0,0 +1,154 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 数据出现次数
*/
@Component
public class DataLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:data:";
private static RedisUtils redisUtils;
private static final int DEFAULT_ACCESS_COUNT = 5;
private static final String DATE_TIME_FORMAT = "month";
@Autowired
public void setRedisUtils(RedisUtils redisUtils) {
DataLimitUtil.redisUtils = redisUtils;
}
/**
* 默认 当月5次
*
* @param key 名称 sys:data:名称
* @return
*/
public static boolean isAccessAllowed(String key) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认月 month//自然月
*
* @param key 名称 sys:data:名称
* @param count 次数限制
* @return
*/
public static boolean isAccessAllowed(String key, Integer count) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(DATE_TIME_FORMAT);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
/**
* 默认 5次
*
* @param key 名称 sys:data:名称
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String key, String timeFormat) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if ((int) countObj < DEFAULT_ACCESS_COUNT) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
public static boolean isAllowed(String key, int seconds) {
String redisKey = generateRedisKey(key);
if (!redisUtils.hasKey(key)) {
redisUtils.set(redisKey, 1, seconds);
return true;
}
return false;
}
/**
* @param key 名称 sys:data:名称
* @param count 次数限制
* @param timeFormat day//自然天 week//本周日 month//自然月 year//自然年
* @return
*/
public static boolean isAccessAllowed(String key, Integer count, String timeFormat) {
String redisKey = generateRedisKey(key);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
long expireAt = calculateExpireAt(timeFormat);
redisUtils.set(redisKey, 1, expireAt);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key) {
return ACCESS_COUNT_KEY_PREFIX + key;
}
private static long calculateExpireAt(String timePeriod) {
Date now = DateUtil.beginOfDay(DateUtil.date());
Date expireDate = null;
if ("day".equals(timePeriod)) {
expireDate = DateUtil.endOfDay(now);
} else if ("week".equals(timePeriod)) {
expireDate = DateUtil.endOfWeek(now);
} else if ("month".equals(timePeriod)) {
expireDate = DateUtil.endOfMonth(now);
} else if ("year".equals(timePeriod)) {
expireDate = DateUtil.endOfYear(now);
}
long endTimeStamp = DateUtil.endOfDay(expireDate).getTime() / 1000L;
long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp;
}
}

View File

@ -1,5 +1,6 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@ -159,4 +160,17 @@ public class DateUtils {
DateTime dateTime = new DateTime(date);
return dateTime.plusYears(years).toDate();
}
//获取当日剩余秒数
public static long todayAfterSecond() {
Date now = new Date();
// 获取当天结束时间即当天23:59:59对应的Date对象
Date endOfDay = DateUtil.endOfDay(now);
// 计算时间差单位为毫秒
long diffMillis = endOfDay.getTime() - now.getTime();
// 将毫秒转换为秒
long diffSeconds = diffMillis / 1000;
return diffSeconds;
}
}

View File

@ -1,6 +1,6 @@
package com.sqx.common.utils;
import com.alibaba.druid.util.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -1,101 +1,120 @@
package com.sqx.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import java.io.Serializable;
import java.util.List;
/**
* 分页工具类
*
*/
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
/**
* 分页
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
}
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private int totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int currPage;
/**
* 列表数据
*/
private List<?> list;
private List<?> records;
/**
* 分页
*/
public PageUtils(IPage<?> page) {
this.list = page.getRecords();
this.totalCount = (int)page.getTotal();
this.pageSize = (int)page.getSize();
this.currPage = (int)page.getCurrent();
this.totalPage = (int)page.getPages();
}
public int getTotalCount() {
return totalCount;
}
public PageUtils() {
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
/**
* 分页
*
* @param list 列表数据
* @param totalCount 总记录数
* @param pageSize 每页记录数
* @param currPage 当前页数
*/
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.currPage = currPage;
this.totalPage = (int) Math.ceil((double) totalCount / pageSize);
}
public int getPageSize() {
return pageSize;
}
public static PageUtils page(PageInfo<?> page) {
return page(page,false);
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public static PageUtils page(PageInfo<?> page, boolean isRecords) {
PageUtils pageUtils = new PageUtils();
if (isRecords) {
pageUtils.records = page.getList();
} else {
pageUtils.list = page.getList();
}
pageUtils.totalCount = (int) page.getTotal();
pageUtils.pageSize = page.getSize();
pageUtils.currPage = page.getPageNum();
pageUtils.totalPage = page.getPages();
return pageUtils;
}
public int getTotalPage() {
return totalPage;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getCurrPage() {
return currPage;
}
public int getPageSize() {
return pageSize;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List<?> getList() {
return list;
}
public int getTotalPage() {
return totalPage;
}
public void setList(List<?> list) {
this.list = list;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrPage() {
return currPage;
}
public void setCurrPage(int currPage) {
this.currPage = currPage;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
public List<?> getRecords() {
return records;
}
public void setRecords(List<?> records) {
this.records = records;
}
}

View File

@ -1,68 +0,0 @@
package com.sqx.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.xss.SQLFilter;
import org.apache.commons.lang.StringUtils;
import java.util.Map;
/**
* 查询参数
*
*/
public class Query<T> {
public IPage<T> getPage(Map<String, Object> params) {
return this.getPage(params, null, false);
}
public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
//分页参数
long curPage = 1;
long limit = 10;
if(params.get(Constant.PAGE) != null){
curPage = Long.parseLong(String.valueOf(params.get(Constant.PAGE)));
}
if(params.get(Constant.LIMIT) != null){
limit = Long.parseLong(String.valueOf(params.get(Constant.LIMIT)));
}
//分页对象
Page<T> page = new Page<>(curPage, limit);
//分页参数
params.put(Constant.PAGE, page);
//排序字段
//防止SQL注入因为sidxorder是通过拼接SQL实现排序的会有SQL注入风险
String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
String order = (String)params.get(Constant.ORDER);
//前端字段排序
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
if(Constant.ASC.equalsIgnoreCase(order)) {
return page.addOrder(OrderItem.asc(orderField));
}else {
return page.addOrder(OrderItem.desc(orderField));
}
}
//没有排序字段则不排序
if(StringUtils.isBlank(defaultOrderField)){
return page;
}
//默认排序
if(isAsc) {
page.addOrder(OrderItem.asc(defaultOrderField));
}else {
page.addOrder(OrderItem.desc(defaultOrderField));
}
return page;
}
}

View File

@ -1,12 +1,54 @@
package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil;
/**
* Redis所有Keys
*
*/
public class RedisKeys {
public static final String FREE_WATCH_KEY = "free:watch:";
public static final String LOCK_KEY = "SYS:LOCK:";
public static final String RATE_LIMIT = "RATE:z";
public static String getSysConfigKey(String key){
return "sys:config:" + key;
}
public static String getDateKey(String key){
return "date:" + key;
}
public static String getFreeWatchKey(Long userId, boolean isPermanently) {
if (isPermanently) {
return FREE_WATCH_KEY + userId;
}
return FREE_WATCH_KEY + DateUtil.today() + ":" + userId;
}
public static void main(String[] args) {
System.out.println(DateUtil.today());
}
public static String getLockKey(String sign, Object... args) {
StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":");
for (Object arg : args) {
if (arg != null) {
key.append(":").append(arg);
}
}
return key.toString();
}
public static String getUserIpRateKey(long userId, String ip) {
return RATE_LIMIT + "user:" + userId + ":ip:" + ip;
}
public static String getUserUrlRateKey(long userId, String url) {
return RATE_LIMIT + "user:" + userId + ":url:" + url;
}
}

View File

@ -1,18 +1,29 @@
package com.sqx.common.utils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.sqx.modules.redisService.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*
*/
@Component
public class RedisUtils {
@Autowired
private RedisService redisService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
@ -25,38 +36,169 @@ public class RedisUtils {
private SetOperations<String, Object> setOperations;
@Autowired
private ZSetOperations<String, Object> zSetOperations;
/** 默认过期时长,单位:秒 */
/**
* 默认过期时长单位
*/
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/** 不设置过期时长 */
/**
* 不设置过期时长
*/
public final static long NOT_EXPIRE = -1;
private final static Gson Gson = new Gson();
public void set(String key, Object value, long expire){
valueOperations.set(key, toJson(value));
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
public <T> Map<String, List<T>> getMapData(String key, String method, Class<T> clazz) {
String jsonStr = getDate(key, method);
ObjectMapper objectMapper = new ObjectMapper();
try {
JsonNode jsonNode = objectMapper.readTree(jsonStr);
return jsonNodeToMap(jsonNode, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void set(String key, Object value){
public <T> List<T> getListData(String key, Class<T> clazz, String method) {
String jsonStr = getDate(key, method);
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将JSON字符串转换为List<T>
return objectMapper.readValue(jsonStr, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取缓存里的数据 如果不存在 则插入 并返回
*
* @param key redis Key
* @param clazz 返回类型
* @param method RedisService调用的方法名 如果数据不存在会执行该调用方法
*/
public <T> T getObjectDate(String key, Class<T> clazz, String method) {
String jsonStr = getDate(key, method);
return this.fromJson(jsonStr, clazz);
}
public <T> T getObjectDate(String key, Class<T> clazz) {
String jsonStr = get(key);
return this.fromJson(jsonStr, clazz);
}
public String getDate(String key, String method) {
if (!this.hasKey(key)) {
try {
// 获取Lookup对象
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 构建方法类型这里假设方法无参数返回类型为void
MethodType methodType = MethodType.methodType(void.class, String.class);
// 获取方法句柄
MethodHandle methodHandle = lookup.findVirtual(redisService.getClass(), method, methodType);
// 调用方法句柄
methodHandle.invoke(redisService, key);
} catch (Exception e) {
e.printStackTrace();
return null;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
return this.get(key);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
public void set(String key, Object value, long expire) {
valueOperations.set(key, toJson(value));
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
public boolean setIfAbsent(String key, Object value, long expire){
Boolean absent = valueOperations.setIfAbsent(key, toJson(value));
if (Boolean.FALSE.equals(absent)) {
return false;
}
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return true;
}
public void set(String key, Object value) {
set(key, value, DEFAULT_EXPIRE);
}
public void expire(String key, long seconds){
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
public <T> T get(String key, Class<T> clazz, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
// 判断键是否设置了过期时间
public boolean isExpiredSet(String key) {
// 获取过期时间单位是秒
Long expireTime = redisTemplate.getExpire(key);
if (expireTime == null) {
return false; // 如果返回 null表示键不存在
}
return expireTime != -1; // 如果是 -1说明没有设置过期时间
}
public Long getExpire(String key) {
Long currentExpireTime = redisTemplate.getExpire(key);
if (currentExpireTime == null || currentExpireTime == -2 || currentExpireTime == -1) {
return null;
}
return currentExpireTime;
}
// 累加过期时间
public boolean extendExpireTime(String key, long additionalTimeInSeconds) {
// 获取当前键的剩余过期时间单位
Long currentExpireTime = redisTemplate.getExpire(key);
if (currentExpireTime == null || currentExpireTime == -2) {
// 键不存在或已经过期无法进行累加
return false;
}
if (currentExpireTime == -1) {
redisTemplate.expire(key, additionalTimeInSeconds, java.util.concurrent.TimeUnit.SECONDS);
}
// 累加剩余过期时间和新增时间
long newExpireTime = currentExpireTime + additionalTimeInSeconds;
// 设置新的过期时间
return Boolean.TRUE.equals(redisTemplate.expire(key, newExpireTime, TimeUnit.SECONDS));
}
public <T> T get(String key, Class<T> clazz) {
return get(key, clazz, NOT_EXPIRE);
}
public String get(String key, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
@ -66,6 +208,21 @@ public class RedisUtils {
return get(key, NOT_EXPIRE);
}
/**
* 对指定的键执行自增操作返回自增后的值
*
* @param key 要自增的键
* @return 自增后的值如果键不存在则初始化为1后返回1如果出现异常返回null
*/
public Long incr(String key) {
try {
return redisTemplate.opsForValue().increment(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void delete(String key) {
redisTemplate.delete(key);
}
@ -73,9 +230,9 @@ public class RedisUtils {
/**
* Object转成JSON数据
*/
private String toJson(Object object){
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String){
private String toJson(Object object) {
if (object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String) {
return String.valueOf(object);
}
return Gson.toJson(object);
@ -84,7 +241,25 @@ public class RedisUtils {
/**
* JSON数据转成Object
*/
private <T> T fromJson(String json, Class<T> clazz){
private <T> T fromJson(String json, Class<T> clazz) {
return Gson.fromJson(json, clazz);
}
public <T> Map<String, List<T>> jsonNodeToMap(JsonNode jsonNode, Class<T> clazz) {
Map<String, List<T>> resultMap = new HashMap<>();
ObjectMapper objectMapper = new ObjectMapper();
if (jsonNode.isObject()) {
// 获取字段名也就是键的迭代器
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode elementNode = jsonNode.get(key);
resultMap.put(key, objectMapper.convertValue(elementNode,
objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)));
}
}
return resultMap;
}
}

View File

@ -0,0 +1,52 @@
package com.sqx.common.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.lang.reflect.Method;
public class SpelUtil {
/**
* 用于SpEL表达式解析.
*/
private static final SpelExpressionParser parser = new SpelExpressionParser();
/**
* 用于获取方法参数定义名字.
*/
private static final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
/**
* 解析SpEL表达式
*
* @param spELStr
* @param joinPoint
* @return
*/
public static String generateKeyBySpEL(String spELStr, ProceedingJoinPoint joinPoint) {
// 通过joinPoint获取被注解方法
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
// 使用Spring的DefaultParameterNameDiscoverer获取方法形参名数组
String[] paramNames = nameDiscoverer.getParameterNames(method);
// // 解析过后的Spring表达式对象
Expression expression = parser.parseExpression(spELStr);
// Spring的表达式上下文对象
EvaluationContext context = new StandardEvaluationContext();
// 通过joinPoint获取被注解方法的形参
Object[] args = joinPoint.getArgs();
// 给上下文赋值
for (int i = 0; i < args.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
if(expression.getValue(context)==null){
return "";
}
return expression.getValue(context).toString();
}
}

View File

@ -1,12 +1,20 @@
package com.sqx.config;
import com.sqx.common.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* Redis配置
*
@ -16,6 +24,18 @@ public class RedisConfig {
@Autowired
private RedisConnectionFactory factory;
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30))
// 设置缓存过期时间为30分钟
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(cacheConfiguration)
.build();
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
@ -51,4 +71,10 @@ public class RedisConfig {
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
@Bean
public RedisUtils redisUtils() {
// 根据实际情况初始化RedisUtils实例可能需要传入相关配置参数如Redis连接信息等
return new RedisUtils();
}
}

View File

@ -0,0 +1,237 @@
package com.sqx.config;
import com.sqx.sharding.MasterSlaveRules;
import com.sqx.sharding.ShardingDataBase;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
/**
* sharding-jdbc 配置文件
*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.shardingsphere")
public class ShardingConfig {
@Value("${spring.profiles.active}")
private String activeProfile;
/**
* 读取数据源信息
*/
private Map<String, ShardingDataBase> datasource;
/**
* 读写分离的配置
*/
private Map<String, MasterSlaveRules> masterSlaveRules;
/**
* 显示sharding-jdbc的sql
*/
private String showSql;
/**
* 中心库的节点
*/
private String centerTablesDataNode;
/**
* 中心表,不进行分库操作
*/
private Set<String> centerTables;
/**
* 区域库的节点
*/
private String regionTablesDataNode;
/**
* 区域表分库策略的字段
*/
private String regionTablesShardingDatabaseColumn;
/**
* 区域表分库的算法
*/
private String regionTablesShardingDatabaseAlgorithm;
/**
* 分库表,通过userId进行分库
*/
private Set<String> regionTables;
/**
* 区域表分库策略的字段
*/
private String courseDetailsShardingDatabaseColumn;
/**
* 区域表分库的算法
*/
private String courseDetailsShardingDatabaseAlgorithm;
/**
* 分库表,通过userId进行分库
*/
private Set<String> courseDetails;
/**
* 配置sharding-jdbc数据源
*/
@Bean
public DataSource dataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
// 配置数据库主从
shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs());
// 配置表的切分策略
shardingRuleConfig.setTableRuleConfigs(addTableRuleConfigs());
// 配置表绑定规则
List<Set<String>> sets = new ArrayList<>();
sets.add(regionTables);
shardingRuleConfig.setBindingTableGroups(bindingTableGroups(sets));
// 配置是否显示sql
Properties props = new Properties();
props.put("sql.show", showSql);
// 配置数据源
Map<String, DataSource> dataSourceMap = getShardingDataBase();
return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props);
}
/**
* 配置
*/
private Set<TableRuleConfiguration> addTableRuleConfigs() {
Set<TableRuleConfiguration> sets = new HashSet<>();
for (String centerTable : centerTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable,
String.format(centerTablesDataNode, centerTable));
sets.add(tableRuleConfig);
}
if ("prod".equals(activeProfile)) {
// 定义区域表的分库规则
InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration(
regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm);
for (String regionTable : regionTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig);
sets.add(tableRuleConfig);
}
// 定义区域表的分库规则
InlineShardingStrategyConfiguration courseDetailsShardingStrategyConfig = new InlineShardingStrategyConfiguration(
courseDetailsShardingDatabaseColumn, courseDetailsShardingDatabaseAlgorithm);
for (String regionTable : courseDetails) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
tableRuleConfig.setDatabaseShardingStrategyConfig(courseDetailsShardingStrategyConfig);
sets.add(tableRuleConfig);
}
}else {
for (String centerTable : regionTables) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable,
String.format(centerTablesDataNode, centerTable));
sets.add(tableRuleConfig);
}
for (String centerTable : courseDetails) {
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable,
String.format(centerTablesDataNode, centerTable));
sets.add(tableRuleConfig);
}
}
return sets;
}
/**
* 配置数据源
*/
private Map<String, DataSource> getShardingDataBase() {
String testQuery = "SELECT 1";
Map<String, DataSource> map = new HashMap<>();
datasource.forEach((datasourceName, shardingDataBase) -> {
HikariConfig config = new HikariConfig();
config.setDriverClassName(shardingDataBase.getDriverClassName());
config.setJdbcUrl(shardingDataBase.getJdbcUrl());
config.setUsername(shardingDataBase.getUsername());
config.setPassword(shardingDataBase.getPassword());
config.setPoolName(datasourceName);
config.setMinimumIdle(shardingDataBase.getMinimumIdle());
config.setMaximumPoolSize(shardingDataBase.getMaximumPoolSize());
config.setIdleTimeout(shardingDataBase.getIdleTimeout());
config.setMaxLifetime(shardingDataBase.getMaxLifetime());
config.setConnectionTimeout(shardingDataBase.getConnectionTimeout());
config.setConnectionTestQuery(testQuery);
map.put(datasourceName, new HikariDataSource(config));
});
return map;
}
/**
* 配置读写分离
*/
private Set<MasterSlaveRuleConfiguration> masterSlaveRuleConfigs() {
Set<MasterSlaveRuleConfiguration> sets = new HashSet<>();
masterSlaveRules.forEach((databaseName, masterSlaveRules) -> {
MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration(databaseName,
masterSlaveRules.getMasterDataSourceName(), masterSlaveRules.getSlaveDataSourceNames());
sets.add(masterSlaveRuleConfig);
});
return sets;
}
/**
* 绑定表的分片规则
*/
public static Set<String> bindingTableGroups(List<Set<String>> sets) {
if (sets != null && !sets.isEmpty()) {
Set<String> tableGroups = new HashSet<>();
for (Set<String> set : sets) {
String tableNames = bindingTable(set.toArray(new String[0]));
if (StringUtils.isNotBlank(tableNames)) {
tableGroups.add(tableNames);
}
}
return tableGroups;
}
return null;
}
/**
* 批量绑定表规则
*
* @param tables 批量绑定的标规则
* @return tableNames
*/
private static String bindingTable(String... tables) {
StringBuilder tableNames = new StringBuilder();
if (tables != null && tables.length != 0) {
for (String table : tables) {
tableNames.append(table).append(",");
}
tableNames.deleteCharAt(tableNames.length() - 1);
}
return tableNames.toString();
}
}

View File

@ -41,6 +41,7 @@ public class ShiroConfig {
shiroFilter.setFilters(filters);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/uniCallBack/**", "anon");
filterMap.put("/course/synCourse", "anon");
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
@ -49,6 +50,7 @@ public class ShiroConfig {
filterMap.put("/banner/**", "anon");
filterMap.put("/courseClassification/selectCourseClassification", "anon");
filterMap.put("/sys/login", "anon");
filterMap.put("/sys/registered", "anon");
filterMap.put("/swagger/**", "anon");
filterMap.put("/alioss/**", "anon");
filterMap.put("/v2/api-docs", "anon");
@ -57,6 +59,7 @@ public class ShiroConfig {
filterMap.put("/captcha.jpg", "anon");
filterMap.put("/aaa.txt", "anon");
filterMap.put("/search/**", "anon");
filterMap.put("/cashOutAudit/batchCashOutOrder", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);

View File

@ -1,53 +1,85 @@
package com.sqx.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//加了ApiOperation注解的类才生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//包下的类才生成接口文档
//.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(security());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("")
.description("sqx-fast文档")
.termsOfServiceUrl("")
.version("3.0.0")
.build();
}
private List<ApiKey> security() {
return newArrayList(
new ApiKey("token", "token", "header")
);
}
}
//package com.sqx.config;
//
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Profile;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//import springfox.documentation.builders.ApiInfoBuilder;
//import springfox.documentation.builders.PathSelectors;
//import springfox.documentation.builders.RequestHandlerSelectors;
//import springfox.documentation.service.ApiInfo;
//import springfox.documentation.service.ApiKey;
//import springfox.documentation.spi.DocumentationType;
//import springfox.documentation.spring.web.plugins.Docket;
//import springfox.documentation.swagger2.annotations.EnableSwagger2;
//
//import java.util.List;
//
//import static com.google.common.collect.Lists.newArrayList;
//
////@Configuration
////@EnableSwagger2
////public class SwaggerConfig implements WebMvcConfigurer {
////
//// @Value("${swagger.enabled}")
//// private boolean enabled;
////
//// @Bean
//// public Docket createRestApi() {
//// return new Docket(DocumentationType.SWAGGER_2)
//// .enable(enabled)
//// .apiInfo(apiInfo())
//// .select()
//// //加了ApiOperation注解的类才生成接口文档
//// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//// //包下的类才生成接口文档
//// //.apis(RequestHandlerSelectors.basePackage("com.sqx.controller"))
//// .paths(PathSelectors.any())
//// .build()
//// .securitySchemes(security());
//// }
////
//// private ApiInfo apiInfo() {
//// return new ApiInfoBuilder()
//// .title("")
//// .description("sqx-fast文档")
//// .termsOfServiceUrl("")
//// .version("3.0.0")
//// .build();
//// }
////
//// private List<ApiKey> security() {
//// return newArrayList(
//// new ApiKey("token", "token", "header")
//// );
//// }
////
////}
//
//@Configuration
//@EnableSwagger2
//@Profile({"local", "dev"})
//public class SwaggerConfig {
//
// @Bean
// public Docket api() {
// return new Docket(DocumentationType.SWAGGER_2)
// .apiInfo(apiInfo())
// .select()
// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .paths(PathSelectors.any())
// .build();
// }
//
// private ApiInfo apiInfo() {
// return new ApiInfoBuilder()
// .title("悠车位后台API接口文档")
// .description("悠车位服务端后台API接口文档")
// .version("1.0")
// .build();
// }
//}

View File

@ -1,14 +0,0 @@
package com.sqx.datasource.annotation;
import java.lang.annotation.*;
/**
* 多数据源注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource {
String value() default "";
}

View File

@ -1,61 +0,0 @@
package com.sqx.datasource.aspect;
import com.sqx.datasource.annotation.DataSource;
import com.sqx.datasource.config.DynamicContextHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 多数据源切面处理类
*/
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DataSourceAspect {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.sqx.datasource.annotation.DataSource) " +
"|| @within(com.sqx.datasource.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Class targetClass = point.getTarget().getClass();
Method method = signature.getMethod();
DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
DataSource methodDataSource = method.getAnnotation(DataSource.class);
if(targetDataSource != null || methodDataSource != null){
String value;
if(methodDataSource != null){
value = methodDataSource.value();
}else {
value = targetDataSource.value();
}
DynamicContextHolder.push(value);
logger.debug("set datasource is {}", value);
}
try {
return point.proceed();
} finally {
DynamicContextHolder.poll();
logger.debug("clean datasource");
}
}
}

View File

@ -1,47 +0,0 @@
package com.sqx.datasource.config;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* 多数据源上下文
*/
public class DynamicContextHolder {
@SuppressWarnings("unchecked")
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
@Override
protected Object initialValue() {
return new ArrayDeque();
}
};
/**
* 获得当前线程数据源
*
* @return 数据源名称
*/
public static String peek() {
return CONTEXT_HOLDER.get().peek();
}
/**
* 设置当前线程数据源
*
* @param dataSource 数据源名称
*/
public static void push(String dataSource) {
CONTEXT_HOLDER.get().push(dataSource);
}
/**
* 清空当前线程数据源
*/
public static void poll() {
Deque<String> deque = CONTEXT_HOLDER.get();
deque.poll();
if (deque.isEmpty()) {
CONTEXT_HOLDER.remove();
}
}
}

View File

@ -1,15 +0,0 @@
package com.sqx.datasource.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 多数据源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicContextHolder.peek();
}
}

View File

@ -1,53 +0,0 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import com.sqx.datasource.properties.DynamicDataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* 配置多数据源
*/
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceConfig {
@Autowired
private DynamicDataSourceProperties properties;
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(getDynamicDataSource());
//默认数据源
DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
return dynamicDataSource;
}
private Map<Object, Object> getDynamicDataSource(){
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
dataSourcePropertiesMap.forEach((k, v) -> {
DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
targetDataSources.put(k, druidDataSource);
});
return targetDataSources;
}
}

View File

@ -1,44 +0,0 @@
package com.sqx.datasource.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.sqx.datasource.properties.DataSourceProperties;
import java.sql.SQLException;
/**
* DruidDataSource
*
*/
public class DynamicDataSourceFactory {
public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(properties.getDriverClassName());
druidDataSource.setUrl(properties.getUrl());
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setInitialSize(properties.getInitialSize());
druidDataSource.setMaxActive(properties.getMaxActive());
druidDataSource.setMinIdle(properties.getMinIdle());
druidDataSource.setMaxWait(properties.getMaxWait());
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
druidDataSource.setValidationQuery(properties.getValidationQuery());
druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
try {
druidDataSource.setFilters(properties.getFilters());
druidDataSource.init();
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
}

View File

@ -1,192 +0,0 @@
package com.sqx.datasource.properties;
/**
* 多数据源属性
*
*/
public class DataSourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
/**
* Druid默认参数
*/
private int initialSize = 2;
private int maxActive = 10;
private int minIdle = -1;
private long maxWait = 60 * 1000L;
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
private String validationQuery = "select 1";
private int validationQueryTimeout = -1;
private boolean testOnBorrow = false;
private boolean testOnReturn = false;
private boolean testWhileIdle = true;
private boolean poolPreparedStatements = false;
private int maxOpenPreparedStatements = -1;
private boolean sharePreparedStatements = false;
private String filters = "stat,wall";
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public long getMaxWait() {
return maxWait;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public long getMaxEvictableIdleTimeMillis() {
return maxEvictableIdleTimeMillis;
}
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public int getValidationQueryTimeout() {
return validationQueryTimeout;
}
public void setValidationQueryTimeout(int validationQueryTimeout) {
this.validationQueryTimeout = validationQueryTimeout;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxOpenPreparedStatements() {
return maxOpenPreparedStatements;
}
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
}
public boolean isSharePreparedStatements() {
return sharePreparedStatements;
}
public void setSharePreparedStatements(boolean sharePreparedStatements) {
this.sharePreparedStatements = sharePreparedStatements;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
}

View File

@ -1,22 +0,0 @@
package com.sqx.datasource.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 多数据源属性
*/
@ConfigurationProperties(prefix = "dynamic")
public class DynamicDataSourceProperties {
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
public Map<String, DataSourceProperties> getDatasource() {
return datasource;
}
public void setDatasource(Map<String, DataSourceProperties> datasource) {
this.datasource = datasource;
}
}

View File

@ -1,8 +1,9 @@
package com.sqx.modules.app.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.App;
import com.sqx.modules.app.service.AppService;
@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* APP登录授权
@ -30,8 +32,10 @@ public class AppUpgradeController {
@ApiOperation("管理平台升级详情")
@ResponseBody
public Result list(Integer page,Integer limit) {
IPage<App> pages =new Page<>(page,limit);
return Result.success().put("data",iAppService.page(pages));
PageHelper.startPage(page,limit);
List<App> list = iAppService.list();
PageInfo<App> pageInfo = new PageInfo<>(list);
return Result.success().put("data", PageUtils.page(pageInfo, true));
}

View File

@ -0,0 +1,54 @@
package com.sqx.modules.app.controller;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.Map;
@RestController
@RequestMapping("/app/userPrizeExchange")
@AllArgsConstructor
@Api(value = "用户奖品兑换", tags = {"用户奖品兑换"})
public class AppUserPrizeExchangeController {
private final UserPrizeExchangeService userPrizeExchangeService;
@Login
@GetMapping("/page")
@ApiOperation("分页")
@ApiImplicitParams({
@ApiImplicitParam(name = Constant.PAGE, value = "当前页码从1开始", paramType = "query", required = true, dataType = "int"),
@ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", required = true, dataType = "int"),
})
public Result page(@RequestAttribute("userId") Long userId, @ApiIgnore @RequestParam Map<String, Object> params) {
params.put("userId", userId);
PageUtils page = userPrizeExchangeService.page(params);
return Result.success().put("page", page);
}
@Login
@PostMapping("/exchange")
@ApiOperation("兑换")
public Result exchange(@RequestAttribute("userId") Long userId, @RequestBody UserPrizeExchange entity) {
userPrizeExchangeService.exchange(userId, entity);
return Result.success();
}
@Login
@PostMapping("/receive")
@ApiOperation("领取满签奖励")
public Result receive(@RequestAttribute("userId") Long userId) {
userPrizeExchangeService.receive(userId);
return Result.success();
}
}

View File

@ -1,8 +1,8 @@
package com.sqx.modules.app.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity;
@ -23,6 +23,7 @@ import com.sqx.modules.pay.service.PayDetailsService;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.EasyPoi.ExcelUtils;
import com.sqx.modules.utils.TimeCompleteUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -74,7 +75,7 @@ public class UserController {
public Result selectUserByInvitationCode(String invitationCode) {
Map<String, Object> map = new HashMap<>();
UserEntity userEntity = userService.queryByInvitationCode(invitationCode);
Long userId=userEntity.getUserId();
Long userId = userEntity.getUserId();
//查询用户钱包
// Double money = cashOutDao.selectMayMoney(userId);
InviteMoney inviteMoney = inviteMoneyService.selectInviteMoneyByUserId(userId);
@ -88,7 +89,7 @@ public class UserController {
//查询邀请人数
int count = userService.queryInviterCount(userEntity.getInvitationCode());
UserVip userVip = userVipService.selectUserVipByUserId(userId);
if(userVip!=null){
if (userVip != null) {
userEntity.setMember(userVip.getIsVip());
userEntity.setEndTime(userVip.getEndTime());
userEntity.setVipType(userVip.getVipType());
@ -120,7 +121,7 @@ public class UserController {
//查询邀请人数
int count = userService.queryInviterCount(userEntity.getInvitationCode());
UserVip userVip = userVipService.selectUserVipByUserId(userId);
if(userVip!=null){
if (userVip != null) {
userEntity.setMember(userVip.getIsVip());
userEntity.setEndTime(userVip.getEndTime());
userEntity.setVipType(userVip.getVipType());
@ -136,12 +137,12 @@ public class UserController {
@RequestMapping(value = "/selectUserList", method = RequestMethod.GET)
@ApiOperation("查询所有用户列表")
@ResponseBody
public Result selectUserList(Integer page, Integer limit,String phone,Integer sex,String platform,
String sysPhone,Integer status, Integer member, String inviterCode,
public Result selectUserList(Integer page, Integer limit, String phone, Integer sex, String platform,
String sysPhone, Integer status, Integer member, String inviterCode,
String userName, String invitationCode, String startTime, String endTime,
String qdCode,String sysUserName,Integer vipType) {
String qdCode, String sysUserName, Integer vipType) {
return Result.success().put("data", userService.selectUserPage(page, limit, phone, sex, platform, sysPhone, status, member,
inviterCode, userName, invitationCode, startTime, endTime,qdCode,sysUserName,vipType));
inviterCode, userName, invitationCode, startTime, endTime, qdCode, sysUserName, vipType));
}
@GetMapping("/userListExcel")
@ -163,17 +164,28 @@ public class UserController {
@ApiOperation("修改用户")
@ResponseBody
public Result updateUserByUserId(@RequestBody UserEntity userEntity) {
if(StringUtils.isNotEmpty(userEntity.getPhone())){
if (StringUtils.isNotEmpty(userEntity.getPhone())) {
UserEntity phoneUser = userService.queryByPhone(userEntity.getPhone());
if(phoneUser!=null && !phoneUser.getUserId().equals(userEntity.getUserId())){
if (phoneUser != null && !phoneUser.getUserId().equals(userEntity.getUserId())) {
return Result.error("手机号已被其他用户绑定!");
}
}
if(StringUtils.isNotEmpty(userEntity.getQdCode())){
SysUserEntity sysUserEntity = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("qd_code", userEntity.getQdCode()));
if(sysUserEntity==null){
UserEntity userEntity2 = userService.queryByUserId(userEntity.getUserId());
if (StringUtils.isNotEmpty(userEntity2.getQdCode())) {
SysUserEntity sysUserEntity = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("qd_code", userEntity2.getQdCode()));
if (sysUserEntity == null) {
return Result.error("渠道码不正确!");
}
if (userEntity.getRate() != null) {
if (sysUserEntity.getQdRate().compareTo(userEntity.getRate()) < 0) {
return Result.error("下级佣金不可大于渠道商佣金");
}
}
if (userEntity.getTwoRate() != null) {
if (sysUserEntity.getQdRate().compareTo(userEntity.getTwoRate()) < 0) {
return Result.error("下级佣金不可大于渠道商佣金");
}
}
}
userService.updateById(userEntity);
return Result.success();
@ -224,28 +236,28 @@ public class UserController {
@GetMapping("/homeMessage")
@ApiOperation("信息分析")
public Result homeMessage(Long sysUserId) {
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
}
HomeMessageResponse homeMessageResponse = new HomeMessageResponse();
// 0查总 1查天 2查月 3查年
//设置总用户人数
homeMessageResponse.setTotalUsers(userService.queryUserCount(0, null,null,qdCode));
homeMessageResponse.setTotalUsers(userService.queryUserCount(0, null, null, qdCode));
//设置今日新增
homeMessageResponse.setNewToday(userService.queryUserCount(1, null,null,qdCode));
homeMessageResponse.setNewToday(userService.queryUserCount(1, null, null, qdCode));
//设置本月新增
homeMessageResponse.setNewMonth(userService.queryUserCount(2, null,null,qdCode));
homeMessageResponse.setNewMonth(userService.queryUserCount(2, null, null, qdCode));
//设置本年新增
homeMessageResponse.setNewYear(userService.queryUserCount(3, null,null,qdCode));
homeMessageResponse.setNewYear(userService.queryUserCount(3, null, null, qdCode));
//设置总收入
homeMessageResponse.setTotalRevenue(userService.queryPayMoney(0,qdCode));
homeMessageResponse.setTotalRevenue(userService.queryPayMoney(0, qdCode));
//设置今日收入
homeMessageResponse.setTodayRevenue(userService.queryPayMoney(1,qdCode));
homeMessageResponse.setTodayRevenue(userService.queryPayMoney(1, qdCode));
//设置本月收入
homeMessageResponse.setMonthRevenue(userService.queryPayMoney(2,qdCode));
homeMessageResponse.setMonthRevenue(userService.queryPayMoney(2, qdCode));
//设置本年收入
homeMessageResponse.setYearRevenue(userService.queryPayMoney(3,qdCode));
homeMessageResponse.setYearRevenue(userService.queryPayMoney(3, qdCode));
//查询指定日期下的短剧购买的
return Result.success().put("data", homeMessageResponse);
}
@ -257,10 +269,9 @@ public class UserController {
*/
@GetMapping("/courseMessage")
@ApiOperation("短剧分析")
public Result courseMessage(Long page, Long limit, String date, int type,Long sysUserId) {
Page<Map<String, Object>> iPage = new Page<>(page, limit);
IPage<Map<String, Object>> mapIPage = userService.queryCourseOrder(iPage, type, date,sysUserId);
return Result.success().put("data", new PageUtils(mapIPage));
public Result courseMessage(Long page, Long limit, String date, int type, Long sysUserId) {
PageUtils pageUtils = userService.queryCourseOrder(page, limit, type, TimeCompleteUtils.completeStartTime(date), sysUserId);
return Result.success().put("data", pageUtils);
}
/**
@ -268,55 +279,57 @@ public class UserController {
*/
@GetMapping("/userMessage")
@ApiOperation("用户分析")
public Result userMessage(String date, int type,Long sysUserId) {
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
public Result userMessage(String date, int type, Long sysUserId) {
date = TimeCompleteUtils.completeStartTime(date);
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
}
int sumUserCount = userService.queryUserCount(type, date,null,qdCode);
int h5Count = userService.queryUserCount(type, date,"h5",qdCode);
int appCount = userService.queryUserCount(type, date,"app",qdCode);
int wxCount = userService.queryUserCount(type, date,"小程序",qdCode);
int dyCount = userService.queryUserCount(type, date,"抖音",qdCode);
int giveMemberCount = userService.userMessage(date, type,qdCode,1);
int moneyMemberCount = userService.userMessage(date, type,qdCode,2);
int memberCount = userService.userMessage(date, type,qdCode,null);
int userCount = sumUserCount-memberCount;
Map<String,Integer> result=new HashMap<>();
result.put("sumUserCount",sumUserCount);
result.put("h5Count",h5Count);
result.put("appCount",appCount);
result.put("wxCount",wxCount);
result.put("dyCount",dyCount);
result.put("memberCount",memberCount);
result.put("giveMemberCount",giveMemberCount);
result.put("moneyMemberCount",moneyMemberCount);
result.put("userCount",userCount);
int sumUserCount = userService.queryUserCount(type, date, null, qdCode);
int h5Count = userService.queryUserCount(type, date, "h5", qdCode);
int appCount = userService.queryUserCount(type, date, "app", qdCode);
int wxCount = userService.queryUserCount(type, date, "小程序", qdCode);
int dyCount = userService.queryUserCount(type, date, "抖音", qdCode);
int giveMemberCount = userService.userMessage(date, type, qdCode, 1);
int moneyMemberCount = userService.userMessage(date, type, qdCode, 2);
int memberCount = userService.userMessage(date, type, qdCode, null);
int userCount = sumUserCount - memberCount;
Map<String, Integer> result = new HashMap<>();
result.put("sumUserCount", sumUserCount);
result.put("h5Count", h5Count);
result.put("appCount", appCount);
result.put("wxCount", wxCount);
result.put("dyCount", dyCount);
result.put("memberCount", memberCount);
result.put("giveMemberCount", giveMemberCount);
result.put("moneyMemberCount", moneyMemberCount);
result.put("userCount", userCount);
return Result.success().put("data", result);
}
@PostMapping("addCannotMoney/{userId}/{money}")
@ApiOperation("添加金")
@ApiOperation("添加金")
public Result addCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
userMoneyService.updateMoney(1, userId, money);
//inviteMoneyDao.updateInviteMoneySum(money,userId);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(userId);
userMoneyDetails.setTitle("[增加金豆]平台增加金豆" + money);
userMoneyDetails.setContent("[增加金豆]平台增加金豆" + money);
userMoneyDetails.setTitle("[增加金币]平台增加金币" + money);
userMoneyDetails.setContent("[增加金币]平台增加金币" + money);
userMoneyDetails.setType(1);
userMoneyDetails.setClassify(1);
//
userMoneyDetails.setClassify(8);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetails.setMoneyType(2);
userMoneyDetailsService.save(userMoneyDetails);
PayDetails payDetails=new PayDetails();
PayDetails payDetails = new PayDetails();
payDetails.setState(1);
payDetails.setCreateTime(sdf.format(new Date()));
payDetails.setUserId(userId);
payDetails.setMoney(money);
payDetails.setClassify(9);
payDetails.setType(1);
payDetails.setPayTime(sdf.format(new Date()));
payDetailsDao.insert(payDetails);
@ -324,39 +337,43 @@ public class UserController {
}
@PostMapping("subCannotMoney/{userId}/{money}")
@ApiOperation("减少金")
@ApiOperation("减少金")
public Result subCannotMoney(@PathVariable("userId") Long userId, @PathVariable("money") Double money) {
userMoneyService.updateMoney(2, userId, money);
//inviteMoneyDao.updateInviteMoneySumSub(money,userId);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(userId);
userMoneyDetails.setTitle("[减少金豆]平台减少金豆" + money);
userMoneyDetails.setContent("平台减少金" + money);
userMoneyDetails.setTitle("[减少金币]平台减少金币" + money);
userMoneyDetails.setContent("平台减少金" + money);
userMoneyDetails.setType(1);
userMoneyDetails.setClassify(1);
//
userMoneyDetails.setClassify(8);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetails.setMoneyType(2);
userMoneyDetailsService.save(userMoneyDetails);
return Result.success();
}
@PostMapping("/updateSysUserMoney")
@ApiOperation("修改金")
public Result updateSysUserMoney(Long userId, Double money,Integer type) {
@ApiOperation("修改金")
public Result updateSysUserMoney(Long userId, Double money, Integer type) {
userMoneyService.updateSysMoney(type, userId, money);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setSysUserId(userId);
if(type==1){
userMoneyDetails.setTitle("[增加金豆]平台增加金豆" + money);
userMoneyDetails.setContent("[增加金豆]平台增加金豆" + money);
}else{
userMoneyDetails.setTitle("[减少金豆]平台减少金豆" + money);
userMoneyDetails.setContent("[减少金豆]平台减少金豆" + money);
if (type == 1) {
userMoneyDetails.setTitle("[增加金币]平台增加金币" + money);
userMoneyDetails.setContent("[增加金币]平台增加金币" + money);
} else {
userMoneyDetails.setTitle("[减少金币]平台减少金币" + money);
userMoneyDetails.setContent("[减少金币]平台减少金币" + money);
}
userMoneyDetails.setMoneyType(2);
userMoneyDetails.setType(type);
userMoneyDetails.setClassify(1);
//
userMoneyDetails.setClassify(8);
userMoneyDetails.setMoney(new BigDecimal(money));
userMoneyDetails.setCreateTime(sdf.format(new Date()));
userMoneyDetailsService.save(userMoneyDetails);
@ -365,27 +382,27 @@ public class UserController {
@GetMapping("/selectInviteUserList")
@ApiOperation("邀请用户排行榜")
public Result selectInviteUserList(Integer page,Integer limit,String phone,String userName){
public Result selectInviteUserList(Integer page, Integer limit, String phone, String userName) {
return userService.selectInviteUserList(page, limit, userName, phone);
}
@GetMapping("/selectUserOnLineCount")
@ApiOperation("统计当前在线人数")
public Result selectUserCount(Long sysUserId){
String qdCode=null;
if(sysUserId!=null){
qdCode=sysUserService.getById(sysUserId).getQdCode();
public Result selectUserCount(Long sysUserId) {
String qdCode = null;
if (sysUserId != null) {
qdCode = sysUserService.getById(sysUserId).getQdCode();
}
return userService.selectUserOnLineCount(qdCode);
}
@GetMapping("/selectUserCountStatisticsByTime")
@ApiOperation("用户统计")
public Result selectUserCountStatisticsByTime(String startTime,String endTime){
List<Integer> userCountList=new ArrayList<>();
List<String> year=new ArrayList<>();
public Result selectUserCountStatisticsByTime(String startTime, String endTime) {
List<Integer> userCountList = new ArrayList<>();
List<String> year = new ArrayList<>();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
Date parse = null;
try {
parse = simpleDateFormat.parse(startTime);
@ -393,22 +410,21 @@ public class UserController {
e.printStackTrace();
}
calendar.setTime(parse);
while (true){
while (true) {
String dateTime = simpleDateFormat.format(calendar.getTime());
int i = userService.queryUserCount(1, dateTime,null,null);
int i = userService.queryUserCount(1, dateTime, null, null);
userCountList.add(i);
year.add(dateTime);
if(dateTime.equals(endTime)){
if (dateTime.equals(endTime)) {
break;
}
calendar.add(Calendar.DATE,1);
calendar.add(Calendar.DATE, 1);
}
Map<String,Object> result=new HashMap<>();
result.put("userCountList",userCountList);
result.put("year",year);
return Result.success().put("data",result);
Map<String, Object> result = new HashMap<>();
result.put("userCountList", userCountList);
result.put("year", year);
return Result.success().put("data", result);
}
}
}

View File

@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/moneyDetails")
@AllArgsConstructor
@Api("钱包明细")
@Api(value = "钱包明细", tags = {"钱包明细"})
public class UserMoneyDetailsController {
private UserMoneyDetailsService userMoneyDetailsService;
private UserMoneyService userMoneyService;
@ -21,8 +21,8 @@ public class UserMoneyDetailsController {
@ApiOperation("钱包明细")
@GetMapping("/queryUserMoneyDetails")
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId, Long userId,Integer classify,Integer type) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit, sysUserId, userId,classify,type);
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId, Long userId,Integer classify,Integer type, Integer moneyType) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit, sysUserId, userId,classify,type, moneyType, 0);
}
@GetMapping("/selectUserMoney")

View File

@ -1,6 +1,8 @@
package com.sqx.modules.app.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@RestController
@Api(value = "会员管理", tags = {"会员管理"})
@ -89,7 +92,10 @@ public class VipDetailsController {
@ApiParam("查询会员列表")
@GetMapping("/selectVipDetailsList")
public Result selectVipDetailsList(Integer page,Integer limit) {
return Result.success().put("data",new PageUtils(vipDetailsService.page(new Page<>(page,limit))));
PageHelper.startPage(page,limit);
List<VipDetails> list = vipDetailsService.list();
PageInfo<VipDetails> pageInfo = new PageInfo<>(list);
return Result.success().put("data", PageUtils.page(pageInfo));
}
}

View File

@ -0,0 +1,33 @@
package com.sqx.modules.app.controller.app;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.service.AdService;
import com.sqx.modules.callback.service.UniAdCallbackRecordService;
import com.sqx.modules.sys.controller.AbstractController;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/app/ad")
public class AdController extends AbstractController {
private final UniAdCallbackRecordService callbackRecordService;
private final AdService adService;
public AdController(UniAdCallbackRecordService callbackRecordService, AdService adService) {
this.callbackRecordService = callbackRecordService;
this.adService = adService;
}
@Login
@GetMapping("/state")
public Result getAdState(@RequestParam String extraKey, @RequestAttribute Long userId) {
return Result.success(callbackRecordService.getStateByExtraKey(userId, extraKey));
}
@Login
@GetMapping("/detail")
public Result getAdDetail(@RequestAttribute Long userId) {
return Result.success(adService.getDetail(userId));
}
}

View File

@ -1,13 +1,19 @@
package com.sqx.modules.app.controller.app;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.DataLimitUtil;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.annotation.LoginUser;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.AppService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.service.CommonInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
@ -18,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
/**
* APP登录授权
*
*/
@RestController
@RequestMapping("/app/user")
@ -29,17 +34,19 @@ public class AppController {
private UserService userService;
@Autowired
private AppService appService;
@Autowired
private CommonInfoService commonRepository;
@PostMapping("/authenticationRegister")
@ApiOperation("认证创建账号")
public Result authenticationRegister(@RequestBody JSONObject jsonObject, HttpServletRequest request){
return userService.authenticationRegister(jsonObject,request);
public Result authenticationRegister(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
return userService.authenticationRegister(jsonObject, request);
}
@Login
@PostMapping("/getNewUserRed")
@ApiOperation("领取新用户红包")
public Result getNewUserRed(@RequestAttribute Long userId){
public Result getNewUserRed(@RequestAttribute Long userId) {
return userService.getNewUserRed(userId);
}
@ -47,11 +54,11 @@ public class AppController {
@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
@ResponseBody
@ApiOperation("用户端修改密码")
public Result updatePwd(@LoginUser UserEntity user,String pwd,String oldPwd) {
if(!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))){
public Result updatePwd(@LoginUser UserEntity user, String pwd, String oldPwd) {
if (!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))) {
return Result.error("原始密码不正确!");
}
if(pwd.equals(oldPwd)){
if (pwd.equals(oldPwd)) {
return Result.error("新密码不能与旧密码相同!");
}
user.setPassword(DigestUtils.sha256Hex(pwd));
@ -63,30 +70,60 @@ public class AppController {
@RequestMapping(value = "/updatePhone", method = RequestMethod.POST)
@ApiOperation("用户端换绑手机号")
@ResponseBody
public Result updatePhone(@RequestAttribute("userId") Long userId,@RequestParam String phone, @RequestParam String msg) {
return userService.updatePhone(phone, msg,userId);
public Result updatePhone(@RequestAttribute("userId") Long userId, @RequestParam String phone, @RequestParam String msg) {
return userService.updatePhone(phone, msg, userId);
}
@Login
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
@ApiOperation("用户修改个人信息")
@ResponseBody
public Result updateUserImageUrl(@RequestAttribute("userId") Long userId,String zhiFuBao,String zhiFuBaoName) {
UserEntity userEntity=new UserEntity();
@Debounce(interval = 3000, value = "#userId")
public Result updateUserImageUrl(@RequestAttribute("userId") Long userId, String zhiFuBao, String zhiFuBaoName) {
if (StrUtil.isEmpty(zhiFuBao) || StrUtil.isEmpty(zhiFuBaoName)) {
return Result.error("支付宝账户及姓名不能为空!");
}
if (!DataLimitUtil.isAccessAllowed(zhiFuBao+zhiFuBaoName, Integer.parseInt(commonRepository.findOne(924).getValue()), "month")) {
return Result.error("修改失败,相同支付宝账号每月可绑定次数已用完");
}
int count = userService.count(new QueryWrapper<UserEntity>()
.ne("user_id", userId)
.eq("zhi_fu_bao_name", zhiFuBaoName)
.eq("zhi_fu_bao", zhiFuBao));
if (count > 0) {
return Result.error("一个支付宝账号仅可绑定一个用户");
}
if (!ApiAccessLimitUtil.isAccessAllowed(userId.toString(), "updateZFB", Integer.parseInt(commonRepository.findOne(925).getValue()), "month")) {
return Result.error("每月可修改次数已用完,请联系管理员");
}
UserEntity old = userService.getById(userId);
String accountNo = old.getZhiFuBao();
String accountName = old.getZhiFuBaoName();
boolean isFirstBind = false;
if (StrUtil.isEmpty(accountNo) && StrUtil.isEmpty(accountName)) {
isFirstBind = true;
}
UserEntity userEntity = new UserEntity();
userEntity.setZhiFuBao(zhiFuBao);
userEntity.setZhiFuBaoName(zhiFuBaoName);
userEntity.setUserId(userId);
userService.updateById(userEntity);
old.setZhiFuBao(userEntity.getZhiFuBao());
old.setZhiFuBaoName(userEntity.getZhiFuBaoName());
boolean bool = userService.updateById(userEntity);
// 去除首绑支付宝奖励
// if (bool && isFirstBind) {
// userService.firstBindAwardsMoney(old);
// }
return Result.success();
}
@Login
@RequestMapping(value = "/updateUsers", method = RequestMethod.POST)
@ApiOperation("用户修改个人信息")
@ResponseBody
public Result updateUsers(@RequestAttribute("userId") Long userId,@RequestBody UserEntity userEntity) {
public Result updateUsers(@RequestAttribute("userId") Long userId, @RequestBody UserEntity userEntity) {
userEntity.setUserId(userId);
userService.updateById(userEntity);
return Result.success();
@ -112,7 +149,7 @@ public class AppController {
@RequestMapping(value = "/updateUserImageUrl", method = RequestMethod.POST)
@ApiOperation("用户修改头像")
@ResponseBody
public Result updateUserImageUrl(@LoginUser UserEntity user,String avatar) {
public Result updateUserImageUrl(@LoginUser UserEntity user, String avatar) {
user.setAvatar(avatar);
userService.updateById(user);
return Result.success();
@ -122,7 +159,7 @@ public class AppController {
@RequestMapping(value = "/updateUserName", method = RequestMethod.POST)
@ApiOperation("用户修改昵称")
@ResponseBody
public Result updateUserName(@LoginUser UserEntity user,String userName) {
public Result updateUserName(@LoginUser UserEntity user, String userName) {
user.setUserName(userName);
userService.updateById(user);
return Result.success();
@ -133,7 +170,7 @@ public class AppController {
@ApiOperation("获取用户详细信息")
@ResponseBody
public Result selectUserById(@LoginUser UserEntity user) {
return Result.success().put("data",user);
return Result.success().put("data", user);
}
@ -141,21 +178,21 @@ public class AppController {
@ApiOperation("升级检测")
@ResponseBody
public Result selectNewApp() {
return Result.success().put("data",appService.selectNewApp());
return Result.success().put("data", appService.selectNewApp());
}
@GetMapping("/openId/{code:.+}/{userId}")
@ApiOperation("根据code获取openid")
public Result getOpenid(@PathVariable("code") String code,@PathVariable("userId")Long userId) {
return userService.getOpenId(code,userId);
public Result getOpenid(@PathVariable("code") String code, @PathVariable("userId") Long userId) {
return userService.getOpenId(code, userId);
}
@RequestMapping(value = "/updateClientId", method = RequestMethod.GET)
@ApiOperation("绑定ClientId")
@ResponseBody
public Result updateClientId(String clientId,Long userId,Integer sysPhone ) {
public Result updateClientId(String clientId, Long userId, Integer sysPhone) {
userService.updateUserClientIdIsNull(clientId);
UserEntity userEntity=new UserEntity();
UserEntity userEntity = new UserEntity();
userEntity.setSysPhone(sysPhone);
userEntity.setUserId(userId);
userEntity.setClientid(clientId);

View File

@ -3,6 +3,7 @@ package com.sqx.modules.app.controller.app;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.IAppleService;
@ -143,6 +144,7 @@ public class AppLoginController {
@RequestMapping(value = "/registerCode", method = RequestMethod.POST)
@ApiOperation("app或h5注册或登录")
@ResponseBody
@Debounce(interval = 2500, value = "#phone")
public Result registerCode(@RequestParam String phone,String msg,String platform,Integer sysPhone,
String password,String inviterCode,String wxId,String qdCode) {
return userService.registerCode(phone,msg,platform,sysPhone,password,inviterCode,wxId,qdCode);

View File

@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/app/moneyDetails")
@AllArgsConstructor
@Api("钱包明细")
@Api(value = "钱包明细app版本", tags = {"钱包明细app版本"})
public class AppUserMoneyDetailsController {
private UserMoneyDetailsService userMoneyDetailsService;
@ -25,8 +25,9 @@ public class AppUserMoneyDetailsController {
@Login
@ApiOperation("钱包明细")
@GetMapping("/queryUserMoneyDetails")
public Result queryUserMoneyDetails(Integer page, Integer limit, @RequestAttribute Long userId,Integer classify,Integer type) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit,null, userId,1,type);
public Result queryUserMoneyDetails(Integer page, Integer limit, @RequestAttribute Long userId,Integer classify,
Integer type, Integer moneyType, Integer viewType) {
return userMoneyDetailsService.queryUserMoneyDetails(page, limit,null, userId,classify,type, moneyType ,viewType);
}
@Login

View File

@ -0,0 +1,51 @@
package com.sqx.modules.app.controller.app;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.service.UserSignRecordService;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tankaikai
* @since 2024-12-19 15:23
*/
@Slf4j
@RestController
@Api(value = "用户签到", tags = {"用户签到"})
@RequestMapping(value = "/app/userSignRecord")
public class AppUserSignController {
@Autowired
private UserSignRecordService userSignRecordService;
/**
* 获取用户连续签到数据
*/
@Login
@GetMapping("/getUserSignData")
@ApiOperation("获取用户连续签到数据")
public Result getUserSignData(@RequestAttribute("userId") Long userId) {
UserSignDTO data = userSignRecordService.getUserSignData(userId);
return Result.success().put("data", data);
}
/**
* 获取连续签到奖励配置
*/
@Login
@GetMapping("/getUserSignAwardConfig")
@ApiOperation(value = "获取连续签到奖励配置", notes = "如:[7,7] = 连续签到7天奖励7元")
public Result getUserSignAwardConfig() {
String[] data = userSignRecordService.getUserSignAwardConfig();
return Result.success().put("data", data);
}
}

View File

@ -1,8 +1,6 @@
package com.sqx.modules.app.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.app.entity.UserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -17,7 +15,7 @@ import java.util.Map;
public interface UserDao extends BaseMapper<UserEntity> {
IPage<UserEntity> selectUserPage(@Param("page") Page<UserEntity> page, @Param("search") String search, @Param("sex") Integer sex, @Param("platform") String platform,
List<UserEntity> selectUserPage(@Param("search") String search, @Param("sex") Integer sex, @Param("platform") String platform,
@Param("sysPhone") String sysPhone, @Param("status") Integer status, @Param("member") Integer member,
@Param("inviterCode") String inviterCode, @Param("userName") String userName,
@Param("invitationCode") String invitationCode, @Param("startTime") String startTime,
@ -31,13 +29,13 @@ public interface UserDao extends BaseMapper<UserEntity> {
Double queryPayMoney(@Param("type") int type, @Param("date") String date,String qdCode);
IPage<Map<String, Object>> queryCourseOrder(Page iPage,@Param("type") int type, @Param("date") String date,Long sysUserId);
List<Map<String, Object>> queryCourseOrder(@Param("type") int type, @Param("start") String start, @Param("end") String end,Long sysUserId);
int userMessage( String date, int type,String qdCode,Integer vipType);
int insertUser(UserEntity userEntity);
IPage<UserEntity> selectInviteUserList(Page<UserEntity> page,String userName,String phone);
List<UserEntity> selectInviteUserList(String userName,String phone);
int selectUserOnLineCount(String qdCode);

View File

@ -9,8 +9,9 @@ public interface UserMoneyDao extends BaseMapper<UserMoney> {
void updateMayMoney(@Param("type") Integer type, @Param("userId")Long userId, @Param("money") Double money);
void updateMayAmount(@Param("type") Integer type, @Param("userId")Long userId, @Param("money") Double amount);
void updateMayAmount(@Param("type") Integer type, @Param("userId")Long userId, @Param("amount") Double amount);
void updateSysMoney(@Param("type") Integer type, @Param("sysUserId")Long sysUserId, @Param("money") Double money);
void updateSysAmount(@Param("type") Integer type, @Param("sysUserId")Long sysUserId, @Param("amount") Double amount);
}

View File

@ -4,10 +4,21 @@ import com.sqx.modules.app.entity.UserMoneyDetails;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
@Mapper
public interface UserMoneyDetailsDao extends BaseMapper<UserMoneyDetails> {
Double monthIncome(@Param("date") String date,@Param("userId") Long userId);
/**
* 查询用户邀请收益
*/
Double queryUserInviteMoney(@Param("userId") Long userId);
/**
* 查询用户邀请金币
*/
Double queryUserInviteGoldMoney(@Param("userId") Long userId);
}

View File

@ -0,0 +1,15 @@
package com.sqx.modules.app.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.app.entity.UserPrizeExchange;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户奖品兑换
*
* @author tankaikai
* @since 2024-12-20 18:11
*/
@Mapper
public interface UserPrizeExchangeDao extends BaseMapper<UserPrizeExchange> {
}

View File

@ -0,0 +1,59 @@
package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
*
* @TableName invite_achievement
*/
@TableName(value ="invite_achievement")
@Data
@EqualsAndHashCode
@ToString
public class InviteAchievement implements Serializable {
/**
*
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户id
*/
private Long userId;
/**
* 上级邀请用户id
*/
private Long sourceUserId;
/**
* 达标次数
*/
private Integer count;
/**
* 是否首次达标
*/
private Integer state;
/**
* 创建时间
*/
private Date createTime;
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -11,7 +11,7 @@ public class UserDetails {
*/
private int monthlyOrderNum;
/**
* 本月充值金
* 本月充值金
*/
private BigDecimal monthlyRechargeMoney;
/**
@ -19,7 +19,7 @@ public class UserDetails {
*/
private int monthWithdrawalNum;
/**
* 本月提现金
* 本月提现金
*/
private BigDecimal monthlyWithdrawalMoney;

View File

@ -156,6 +156,7 @@ public class UserEntity implements Serializable {
private String zhiFuBao;
@Excel(name = "支付宝名称", orderNum = "8", width = 18)
@TableField("zhi_fu_bao_name")
private String zhiFuBaoName;
@Excel(name = "一级推广收益比例", orderNum = "8", width = 18)

View File

@ -27,13 +27,13 @@ public class UserMoney implements Serializable {
private Long id;
/**
* 钱包金
* 钱包金
*/
@ApiModelProperty("钱包金")
@ApiModelProperty("钱包金")
private BigDecimal money;
/**
* 钱包金
* 钱包金
*/
@ApiModelProperty("钱包余额 钱")
private BigDecimal amount;

View File

@ -1,5 +1,7 @@
package com.sqx.modules.app.entity;
import cn.hutool.core.date.DateUtil;
import com.amazonaws.services.dynamodbv2.xspec.L;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@ -15,7 +17,6 @@ import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_money_details")
@ApiModel("钱包详情")
public class UserMoneyDetails implements Serializable {
@ -38,6 +39,8 @@ public class UserMoneyDetails implements Serializable {
@ApiModelProperty("渠道用户id")
@TableField("sys_user_id")
private Long sysUserId;
@ApiModelProperty("源id")
private Long sourceId;
/**
* 对应用户id
@ -50,10 +53,29 @@ public class UserMoneyDetails implements Serializable {
*/
@ApiModelProperty("标题")
private String title;
/**
* 1注册 2首次购买 3购买 4提现
/***
* 1 注册 上级
* 2 充值
* 3 购买
* 4 提现
* 5 现金大转盘
* 6 分享达标
* 7 任务领取
* 8 平台操作
* 9 订单退款
* 10 渠道推广
*/
@ApiModelProperty("1充值钱包明细 2提现钱包明细")
@ApiModelProperty(" * 1 注册 (上级)\n" +
" * 2 充值\n" +
" * 3 购买\n" +
" * 4 提现\n" +
" * 5 现金大转盘\n" +
" * 6 分享达标\n" +
" * 7 任务领取\n" +
" * 8 平台操作\n" +
" * 9 订单退款\n" +
" * 10 渠道推广")
private Integer classify;
/**
* 类别1充值2支出
@ -66,15 +88,19 @@ public class UserMoneyDetails implements Serializable {
@ApiModelProperty("状态 1待支付 2已到账 3取消")
private Integer state;
/**
*
*
*/
@ApiModelProperty("")
@ApiModelProperty("")
private BigDecimal money;
/**
* 内容
*/
@ApiModelProperty("内容")
private String content;
@ApiModelProperty("金额类型: 1 红包2金币")
private Integer moneyType;
/**
* 创建时间
*/
@ -82,5 +108,48 @@ public class UserMoneyDetails implements Serializable {
@ApiModelProperty("创建时间")
private String createTime;
public UserMoneyDetails() {
}
/**
* @param userId 用户Id tb_user的id
* @param sysUserId 系统用户Id tb_sys_user的id
* @param byUserId 对应用户Id
* @param title 标题
* @param classify 1 注册 上级2 充值 3 购买 4 提现 5 现金大转盘 6 分享达标 7 任务领取 8 平台操作 9 订单退款 10 渠道推广
* @param type 类别1充值2支出
* @param state 状态 1待支付 2已到账 3取消
* @param money 金额
* @param content 内容描述
*/
public UserMoneyDetails(Long userId, Long sysUserId, Long byUserId, String title, Integer classify, Integer type,
Integer state, BigDecimal money, String content, Integer moneyType,Long sourceId) {
this.userId = userId;
this.sysUserId = sysUserId;
this.byUserId = byUserId;
this.title = title;
this.classify = classify;
this.type = type;
this.state = state;
this.money = money;
this.content = content;
this.createTime = DateUtil.now();
this.moneyType = moneyType;
this.sourceId = sourceId;
}
public UserMoneyDetails(Long userId, Long sysUserId, Long byUserId, String title, Integer classify, Integer type,
Integer state, BigDecimal money, String content, Integer moneyType) {
this.userId = userId;
this.sysUserId = sysUserId;
this.byUserId = byUserId;
this.title = title;
this.classify = classify;
this.type = type;
this.state = state;
this.money = money;
this.content = content;
this.createTime = DateUtil.now();
this.moneyType = moneyType;
}
}

View File

@ -0,0 +1,76 @@
package com.sqx.modules.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 用户奖品兑换
*
* @author tankaikai
* @since 2024-12-20 17:52
*/
@Data
@TableName("user_prize_exchange")
public class UserPrizeExchange implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 奖品记录
*/
@TableId(type = IdType.ID_WORKER)
private Long id;
/**
* 奖品引用id
*/
private Long foreignId;
/**
* 活动类型 task-任务奖励 spinning-大转盘
*/
private String foreignType;
/**
* 奖品名称
*/
private String prizeName;
/**
* 奖品图片地址
*/
private String imgUrl;
/**
* 用户id
*/
private Long userId;
/**
* 用户名
*/
private String userName;
/**
* 手机号
*/
private String phone;
/**
* 收货地址
*/
private String address;
/**
* 备注
*/
private String remark;
/**
* 状态 0-待发放 1-已发放
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@ -1,14 +1,21 @@
package com.sqx.modules.app.interceptor;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sqx.common.exception.CzgException;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.IPUtils;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.redisService.RedisService;
import io.jsonwebtoken.Claims;
import com.sqx.modules.app.annotation.Login;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@ -21,54 +28,89 @@ import java.util.Date;
/**
* 权限(Token)验证
*
*/
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = LoggerFactory.getLogger(AuthorizationInterceptor.class);
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserService userService;
private final RedisService redisService;
public static final String USER_KEY = "userId";
public AuthorizationInterceptor(RedisService redisService) {
this.redisService = redisService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Login annotation;
if(handler instanceof HandlerMethod) {
if (handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
}else{
} else {
return true;
}
if(annotation == null){
if (annotation == null) {
return true;
}
//获取用户凭证
// 获取用户凭证
String token = request.getHeader(jwtUtils.getHeader());
if(StringUtils.isBlank(token)){
if (StringUtils.isBlank(token)) {
token = request.getParameter(jwtUtils.getHeader());
}
//凭证为空
if(StringUtils.isBlank(token)){
// 凭证为空
if (StringUtils.isBlank(token)) {
throw new SqxException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
}
Claims claims = jwtUtils.getClaimByToken(token);
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
if (claims == null || jwtUtils.isTokenExpired(claims.getExpiration())) {
throw new SqxException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
}
//设置userId到request里后续根据userId获取用户信息
long userId = Long.parseLong(claims.getSubject());
request.setAttribute(USER_KEY, userId);
//记录用户最后一次调用接口的时间
UserEntity userEntity=new UserEntity();
userEntity.setUserId(userId);
userEntity.setOnLineTime(DateUtils.format(new Date()));
userService.updateById(userEntity);
String ip = IPUtils.getIpAddr(request); // 获取用户的 IP 地址
// 检查用户是否超过限流
if (redisService.checkIpJumpLimit(userId, ip)) {
log.warn("用户地址跳动频繁,封禁: {}", userId);
if (!redisService.isSetUserState(userId)) {
ThreadUtil.execAsync(() -> {
userService.update(null, new LambdaUpdateWrapper<UserEntity>()
.eq(UserEntity::getUserId, userId)
.set(UserEntity::getStatus, 0));
});
}
throw new CzgException("ip跳动过于频繁请联系管理员解封");
}
ThreadUtil.execAsync(() -> {
redisService.recordUrlVisitCountWithIp(userId, request.getRequestURI(), ip);
});
// 设置 userId request 后续根据 userId 获取用户信息
UserEntity user = userService.selectUserById(userId);
if (user != null && user.getStatus().equals(0)) {
throw new CzgException("异常行为用户: {}" + user.getUserId());
}
if (redisService.isRecordUserOnLineTime(userId)) {
ThreadUtil.execAsync(() -> {
// 记录用户最后一次调用接口的时间
UserEntity userEntity = new UserEntity();
userEntity.setUserId(userId);
userEntity.setOnLineTime(DateUtils.format(new Date()));
userService.updateById(userEntity);
});
}
return true;
}
}

View File

@ -0,0 +1,31 @@
package com.sqx.modules.app.mapper;
import com.sqx.modules.app.entity.InviteAchievement;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Mapper
* @createDate 2024-12-30 13:26:18
* @Entity com.sqx.modules.app.entity.InviteAchievement
*/
@Mapper
public interface InviteAchievementMapper extends BaseMapper<InviteAchievement> {
@Update("update invite_achievement set count = count + #{i}, update_time=now() where id = #{id}")
int incrCount(Integer id, int i);
@Insert("INSERT INTO invite_achievement (user_id, source_user_id, count, state, create_time)\n" +
"SELECT #{userId}, #{sourceUserId}, #{count}, #{state}, #{createTime} " +
"WHERE NOT EXISTS ( " +
" SELECT 1 FROM invite_achievement WHERE user_id = #{userId} " +
");")
boolean insertNotExists(InviteAchievement inviteAchievement);
}

View File

@ -19,7 +19,7 @@ public class CourseOrderResponse implements Serializable {
*/
private int coursenum;
/**
* 售卖金
* 售卖金
*/
private Double coursemoney;
}

View File

@ -0,0 +1,7 @@
package com.sqx.modules.app.service;
import java.util.HashMap;
public interface AdService {
HashMap<String, Object> getDetail(Long userId);
}

View File

@ -0,0 +1,25 @@
package com.sqx.modules.app.service;
import com.sqx.modules.app.entity.InviteAchievement;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Service
* @createDate 2024-12-30 13:26:18
*/
public interface InviteAchievementService extends IService<InviteAchievement> {
int countByUserId(Long userId);
InviteAchievement getByUserId(Long userId);
int incrCount(Integer id, int i);
boolean insertNotExists(InviteAchievement inviteAchievement);
int countBySourceUserId(Long userId);
int countNum(Long userId, Integer signCount);
}

View File

@ -4,7 +4,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserMoneyDetails;
import java.util.Map;
public interface UserMoneyDetailsService extends IService<UserMoneyDetails> {
Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type);
Double monthIncome(String date,Long userId);
Result queryUserMoneyDetails(Integer page, Integer limit, Long sysUserId, Long userId, Integer classify,
Integer type, Integer moneyType, Integer viewType);
Double monthIncome(String date, Long userId);
Map<String, Double> queryUserTotalEarning(Long userId);
}

View File

@ -15,4 +15,6 @@ public interface UserMoneyService extends IService<UserMoney> {
void updateSysMoney(int i, Long userId, double money);
void updateSysAmount(int i, Long userId, double amount);
}

View File

@ -0,0 +1,44 @@
package com.sqx.modules.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.entity.UserPrizeExchange;
import java.util.Map;
/**
* 用户奖品兑换Service
*
* @author tankaikai
* @since 2024-12-20 18:04
*/
public interface UserPrizeExchangeService extends IService<UserPrizeExchange> {
/**
* 分页查询
*
* @param params
* @return
*/
PageUtils page(Map<String, Object> params);
/**
* 兑换奖品
*
* @param entity
*/
void exchange(Long currentUserId, UserPrizeExchange entity);
/**
* 发放奖品
*
* @param dto
*/
void deliver(UserPrizeExchange dto);
/**
* 领取满签奖励现金红包
* @param currentUserId
*/
void receive(Long currentUserId);
}

View File

@ -2,7 +2,6 @@ package com.sqx.modules.app.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.common.utils.PageUtils;
@ -214,7 +213,7 @@ public interface UserService extends IService<UserEntity> {
Double queryPayMoney(int type,String qdCode);
IPage<Map<String, Object>> queryCourseOrder(Page<Map<String, Object>> iPage, int type, String date,Long sysUserId);
PageUtils queryCourseOrder(Long page, Long limit, int type, String date,Long sysUserId);
int userMessage( String date, int type,String qdCode,Integer vipType);
@ -227,4 +226,6 @@ public interface UserService extends IService<UserEntity> {
int updateUserClientIdIsNull(String clientid);
void firstBindAwardsMoney(UserEntity entity);
}

View File

@ -0,0 +1,29 @@
package com.sqx.modules.app.service.impl;
import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.app.service.AdService;
import com.sqx.modules.redisService.impl.RedisServiceImpl;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class AdServiceImpl implements AdService {
private final RedisServiceImpl redisServiceImpl;
public AdServiceImpl(RedisServiceImpl redisServiceImpl) {
this.redisServiceImpl = redisServiceImpl;
}
@Override
public HashMap<String, Object> getDetail(Long userId) {
Long freeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, false);
Long permanentlyFreeWatchRemainTime = redisServiceImpl.getFreeWatchRemainTime(userId, true);
return new HashMap<String, Object>(){{
put("adFreeWatchTime", permanentlyFreeWatchRemainTime);
put("payFreeWatchTime", freeWatchRemainTime);
put("totalFreeWatchTime", freeWatchRemainTime + permanentlyFreeWatchRemainTime);
}};
}
}

View File

@ -0,0 +1,54 @@
package com.sqx.modules.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.modules.app.entity.InviteAchievement;
import com.sqx.modules.app.service.InviteAchievementService;
import com.sqx.modules.app.mapper.InviteAchievementMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表invite_achievement的数据库操作Service实现
* @createDate 2024-12-30 13:26:18
*/
@Service
public class InviteAchievementServiceImpl extends ServiceImpl<InviteAchievementMapper, InviteAchievement>
implements InviteAchievementService{
@Override
public int countByUserId(Long userId) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getUserId, userId));
}
@Override
public InviteAchievement getByUserId(Long userId) {
return getOne(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getUserId, userId));
}
@Override
public int incrCount(Integer id, int i) {
return baseMapper.incrCount(id,i);
}
@Override
public boolean insertNotExists(InviteAchievement inviteAchievement) {
return baseMapper.insertNotExists(inviteAchievement);
}
@Override
public int countBySourceUserId(Long userId) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getState, 1)
.eq(InviteAchievement::getSourceUserId, userId));
}
@Override
public int countNum(Long userId, Integer signCount) {
return count(new LambdaQueryWrapper<InviteAchievement>()
.eq(InviteAchievement::getSourceUserId, userId)
.ge(InviteAchievement::getCount, signCount));
}
}

View File

@ -1,40 +1,67 @@
package com.sqx.modules.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.UserMoneyDetailsDao;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserMoneyDetailsServiceImpl extends ServiceImpl<UserMoneyDetailsDao, UserMoneyDetails> implements UserMoneyDetailsService {
@Override
public Result queryUserMoneyDetails(Integer page, Integer limit,Long sysUserId,Long userId,Integer classify,Integer type) {
IPage<UserMoneyDetails> page1 = new Page(page, limit);
public Result queryUserMoneyDetails(Integer page, Integer limit, Long sysUserId, Long userId, Integer classify,
Integer type, Integer moneyType, Integer viewType) {
PageHelper.startPage(page, limit);
QueryWrapper<UserMoneyDetails> queryWrapper = new QueryWrapper();
if(sysUserId!=null){
if (sysUserId != null) {
queryWrapper.eq("sys_user_id", sysUserId);
}
if(userId!=null){
if (userId != null) {
queryWrapper.eq("user_id", userId);
}
if(classify!=null){
if (classify != null) {
queryWrapper.eq("classify", classify);
}
if(type!=null){
if (type != null) {
queryWrapper.eq("type", type);
}
if (moneyType != null) {
queryWrapper.eq("money_type", moneyType);
}
if (viewType == 1) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(6);
queryWrapper.in("classify", arrayList);
}
queryWrapper.orderByDesc("create_time");
return Result.success().put("data", baseMapper.selectPage(page1, queryWrapper));
return Result.success().put("data", PageUtils.page(new PageInfo<>(baseMapper.selectList(queryWrapper))));
}
@Override
public Double monthIncome(String date, Long userId) {
return baseMapper.monthIncome(date,userId);
return baseMapper.monthIncome(date, userId);
}
@Override
public Map<String, Double> queryUserTotalEarning(Long userId) {
Double inviteMoney = baseMapper.queryUserInviteMoney(userId);
Double inviteGoldMoney = baseMapper.queryUserInviteGoldMoney(userId);
Map<String, Double> map = new HashMap<>(2);
map.put("inviteMoney", inviteMoney == null ? 0 : inviteMoney);
map.put("inviteGoldMoney", inviteGoldMoney == null ? 0 : inviteGoldMoney);
return map;
}
}

View File

@ -30,6 +30,12 @@ public class UserMoneyServiceImpl extends ServiceImpl<UserMoneyDao, UserMoney> i
baseMapper.updateSysMoney(i,userId,money);
}
@Override
public void updateSysAmount(int i, Long userId, double amount){
selectSysUserMoneyByUserId(userId);
baseMapper.updateSysAmount(i,userId,amount);
}
@Override
public UserMoney selectUserMoneyByUserId(Long userId){
UserMoney userMoney = baseMapper.selectOne(new QueryWrapper<UserMoney>().eq("user_id", userId));

View File

@ -0,0 +1,273 @@
package com.sqx.modules.app.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.tea.ValidateException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.dao.UserPrizeExchangeDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.dao.DiscSpinningRecordDao;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import com.sqx.modules.taskCenter.dao.TaskCenterRecordDao;
import com.sqx.modules.taskCenter.dao.TaskCenterRewardDao;
import com.sqx.modules.taskCenter.entity.TaskCenterRecord;
import com.sqx.modules.taskCenter.entity.TaskCenterReward;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.service.UserSignRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* @author tankaikai
* @since 2024-12-20 18:10
*/
@Slf4j
@Service
public class UserPrizeExchangeServiceImpl extends ServiceImpl<UserPrizeExchangeDao, UserPrizeExchange> implements UserPrizeExchangeService {
@Resource
private DiscSpinningRecordDao discSpinningRecordDao;
@Resource
private TaskCenterRecordDao taskCenterRecordDao;
@Resource
private TaskCenterRewardDao taskCenterRewardDao;
@Resource
private CommonInfoService commonRepository;
@Resource
private UserMoneyService userMoneyService;
@Resource
private UserMoneyDetailsService userMoneyDetailsService;
@Resource
private UserSignRecordService userSignRecordService;
@Resource
private UserDao userDao;
@Override
public PageUtils page(Map<String, Object> params) {
MapProxy proxy = MapProxy.create(params);
Long foreignId = proxy.getLong("foreignId");
String foreignType = proxy.getStr("foreignType");
Long userId = proxy.getLong("userId");
String userName = proxy.getStr("userName");
String prizeName = proxy.getStr("prizeName");
Integer status = proxy.getInt("status");
String phone = proxy.getStr("phone");
String remark = proxy.getStr("remark");
String beginDate = proxy.getStr("beginDate");
String endDate = proxy.getStr("endDate");
LambdaQueryWrapper<UserPrizeExchange> wrapper = Wrappers.lambdaQuery();
wrapper.eq(foreignId != null, UserPrizeExchange::getForeignId, foreignId);
wrapper.eq(StrUtil.isNotEmpty(foreignType), UserPrizeExchange::getForeignType, foreignType);
wrapper.eq(userId != null, UserPrizeExchange::getUserId, userId);
wrapper.like(StrUtil.isNotEmpty(userName), UserPrizeExchange::getUserName, userName);
wrapper.like(StrUtil.isNotEmpty(prizeName), UserPrizeExchange::getPrizeName, prizeName);
wrapper.eq(status != null, UserPrizeExchange::getStatus, status);
wrapper.like(StrUtil.isNotEmpty(phone), UserPrizeExchange::getPhone, phone);
wrapper.like(StrUtil.isNotEmpty(remark), UserPrizeExchange::getRemark, remark);
if (StrUtil.isNotEmpty(beginDate)) {
wrapper.apply("create_time >= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", beginDate + " 00:00:00");
}
if (StrUtil.isNotEmpty(endDate)) {
wrapper.apply("create_time <= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", endDate + " 23:59:59");
}
wrapper.orderByDesc(UserPrizeExchange::getId);
long pageNum = proxy.getLong(Constant.PAGE, 1L);
long pageSize = proxy.getLong(Constant.LIMIT, 10L);
PageHelper.startPage((int) pageNum, (int) pageSize);
return PageUtils.page(new PageInfo<>(this.list(wrapper)));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void exchange(Long currentUserId, UserPrizeExchange dto) {
if (dto.getForeignId() == null) {
throw new SqxException("中奖记录ID不能为空");
}
if (StrUtil.isEmpty(dto.getForeignType())) {
throw new SqxException("活动类型不能为空");
}
if (!ArrayUtil.contains(new String[]{"spinning", "task"}, dto.getForeignType())) {
throw new SqxException("仅限大转盘、任务活动兑换奖品");
}
if (StrUtil.isBlank(dto.getPhone())) {
throw new SqxException("用户手机号码不能为空");
}
try {
Validator.isMobile(dto.getPhone());
} catch (ValidateException e) {
throw new SqxException("用户手机号码不合法");
}
Dict dict = Dict.create();
if ("spinning".equals(dto.getForeignType())) {
DiscSpinningRecord record = discSpinningRecordDao.selectById(dto.getForeignId());
if (record == null) {
throw new SqxException("中奖记录不存在");
}
dict.put("userId", record.getUserId());
dict.put("name", record.getName());
dict.put("imgUrl", record.getImgUrl());
dict.put("type", record.getType());
} else if ("task".equals(dto.getForeignType())) {
TaskCenterRecord record = taskCenterRecordDao.selectById(dto.getForeignId());
if (record == null) {
throw new SqxException("中奖记录不存在");
}
if (record.getSourceId() == null) {
throw new SqxException("中奖记录未关联奖品");
}
TaskCenterReward reward = taskCenterRewardDao.selectById(record.getSourceId());
if (reward == null) {
throw new SqxException("对应的奖品信息不存在");
}
dict.put("userId", record.getUserId());
dict.put("name", record.getName());
dict.put("imgUrl", reward.getImg());
dict.put("type", reward.getType());
}
Long userId = dict.getLong("userId");
String name = dict.getStr("name");
String imgUrl = dict.getStr("imgUrl");
Integer type = dict.getInt("type");
if (userId == null) {
throw new SqxException("中奖用户数据不完整");
}
if (currentUserId == null) {
throw new SqxException("未获取当前登录用户id");
}
if (!currentUserId.equals(userId)) {
throw new SqxException("兑奖用户和获奖用户不一致");
}
UserEntity user = userDao.selectById(userId);
if (user == null) {
throw new SqxException("兑奖用户不存在");
}
if (ArrayUtil.contains(new int[]{1, 2}, type)) {
throw new SqxException("仅限兑换实物、会员卡等奖项");
}
Integer count = baseMapper.selectCount(Wrappers.<UserPrizeExchange>lambdaQuery()
.eq(UserPrizeExchange::getForeignId, dto.getForeignId())
.eq(UserPrizeExchange::getForeignType, dto.getForeignType())
);
if (count != null && count > 0) {
throw new SqxException("奖品已兑换,请勿重复操作");
}
dto.setPrizeName(name);
dto.setUserId(userId);
dto.setUserName(user.getUserName());
dto.setStatus(0);
dto.setCreateTime(new Date());
dto.setImgUrl(imgUrl);
baseMapper.insert(dto);
if ("spinning".equals(dto.getForeignType())) {
discSpinningRecordDao.update(null,
Wrappers.<DiscSpinningRecord>lambdaUpdate()
.set(DiscSpinningRecord::getTarget, "3")
.set(DiscSpinningRecord::getTargetId, dto.getId())
.eq(DiscSpinningRecord::getId, dto.getForeignId())
);
} else if ("task".equals(dto.getForeignType())) {
taskCenterRecordDao.update(null,
Wrappers.<TaskCenterRecord>lambdaUpdate()
.set(TaskCenterRecord::getTargetId, dto.getId())
.eq(TaskCenterRecord::getId, dto.getForeignId())
);
}
}
@Override
public void deliver(UserPrizeExchange dto) {
Long id = dto.getId();
if (id == null) {
throw new SqxException("兑奖id不能为空");
}
UserPrizeExchange entity = baseMapper.selectById(id);
if (entity == null) {
throw new SqxException("兑奖订单不存在");
}
entity.setStatus(1);
if (StrUtil.isNotEmpty(dto.getAddress())) {
entity.setAddress(dto.getAddress());
}
if (StrUtil.isNotEmpty(dto.getRemark())) {
entity.setRemark(dto.getRemark());
}
entity.setUpdateTime(new Date());
baseMapper.updateById(entity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public synchronized void receive(Long currentUserId) {
if (currentUserId == null) {
throw new SqxException("未获取当前登录用户id");
}
UserEntity userEntity = userDao.selectById(currentUserId);
if (userEntity == null) {
throw new SqxException("该用户信息不存在");
}
CommonInfo one = commonRepository.findOne(918);
if (one == null) {
throw new SqxException("奖品配置信息不存在");
}
String value = one.getValue();
String signDays = value.split(",")[0];
String moneyStr = value.split(",")[1];
UserSignDTO userSignData = userSignRecordService.getUserSignData(currentUserId);
if (userSignData.getSignDays() < Convert.toInt(signDays)) {
throw new SqxException(StrUtil.format("连续签到天数不足{}天,无法领取奖励", signDays));
}
int count = userMoneyDetailsService.count(
Wrappers.<UserMoneyDetails>lambdaQuery()
.eq(UserMoneyDetails::getUserId, currentUserId)
.eq(UserMoneyDetails::getType, 1)
.eq(UserMoneyDetails::getClassify, 7)
.eq(UserMoneyDetails::getMoneyType, 1)
.likeLeft(UserMoneyDetails::getTitle, "[连续签到")
.likeRight(UserMoneyDetails::getTitle, "天]")
);
if (count > 0) {
throw new SqxException("已经领取过连续签到奖励,无需重复操作");
}
BigDecimal money = new BigDecimal(moneyStr);
userMoneyService.updateAmount(1, currentUserId, money.doubleValue());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
userMoneyDetails.setUserId(currentUserId);
userMoneyDetails.setTitle(StrUtil.format("[连续签到{}天]", signDays));
userMoneyDetails.setContent("现金红包奖励:" + moneyStr + "");
// 充值
userMoneyDetails.setType(1);
// 任务领取
userMoneyDetails.setClassify(7);
userMoneyDetails.setMoney(money);
userMoneyDetails.setCreateTime(DateUtil.now());
userMoneyDetails.setMoneyType(1);
userMoneyDetailsService.save(userMoneyDetails);
}
}

View File

@ -17,9 +17,9 @@ public class UserVipServiceImpl extends ServiceImpl<UserVipDao, UserVip> impleme
return baseMapper.selectOne(queryWrapper);
}
@Scheduled(cron="0 */1 * * * ?")
// @Scheduled(cron="0 */1 * * * ?")
public void getEndVip() {
baseMapper.updateUserVipByEndTime();
// baseMapper.updateUserVipByEndTime();
}
}

View File

@ -3,6 +3,8 @@ package com.sqx.modules.banner.controller.app;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.banner.entity.Banner;
@ -13,6 +15,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author fang
* @date 2020/7/9
@ -38,7 +42,10 @@ public class AppBannerController {
@ApiOperation("查询所有banner图")
@ResponseBody
public Result selectBannerPage(Integer page,Integer limit,Integer classify) {
return Result.success().put("data", new PageUtils(bannerService.page(new Page<>(page,limit),new QueryWrapper<Banner>().eq("classify",classify))));
PageHelper.startPage(page,limit);
List<Banner> classify1 = bannerService.list(new QueryWrapper<Banner>().eq("classify", classify));
PageInfo<Banner> pageInfo = new PageInfo<>(classify1);
return Result.success().put("data", PageUtils.page(pageInfo));
}
@RequestMapping(value = "/clickBanner", method = RequestMethod.GET)
@ -49,4 +56,4 @@ public class AppBannerController {
}
}
}

View File

@ -1,8 +1,6 @@
package com.sqx.modules.banner.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.banner.entity.Banner;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -19,8 +17,8 @@ public interface BannerDao extends BaseMapper<Banner> {
List<Banner> selectLists(@Param("classify") Integer classify);
List<Banner> selectList(@Param("classify") Integer classify);
// List<Banner> selectList(@Param("classify") Integer classify);
IPage<Banner> selectBannerPage(Page<Banner> page,@Param("classify") Integer classify);
List<Banner> selectBanner(@Param("classify") Integer classify);
}

View File

@ -53,6 +53,10 @@ public class Banner implements Serializable {
* 分类 1 banner图 2 首页分类
*/
private Integer classify;
/**
* 跳转类型 1 内部 2 外部
*/
private Integer jumpType;
/**
* 跳转地址

View File

@ -1,9 +1,9 @@
package com.sqx.modules.banner.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.banner.dao.BannerDao;
@ -13,6 +13,9 @@ import com.sqx.modules.course.dao.CourseDao;
import com.sqx.modules.course.dao.CourseDetailsDao;
import com.sqx.modules.course.entity.Course;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
@ -23,6 +26,7 @@ import java.util.List;
* banner图
*/
@Service
@CacheConfig(cacheNames = "banner")
public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements BannerService {
@Autowired
@ -34,23 +38,26 @@ public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements
@Override
@Cacheable(key = "#classify")
public List<Banner> selectBannerList(Integer classify) {
return bannerDao.selectList(classify);
return bannerDao.selectList(new QueryWrapper<Banner>().eq("classify", classify).eq("state", 1).orderByDesc("sort"));
}
@Override
@Cacheable(key = "#classify")
public List<Banner> selectBannerLists(Integer classify) {
return bannerDao.selectLists(classify);
}
@Override
public PageUtils selectBannerPage(Integer page,Integer limit,Integer classify) {
Page<Banner> pages=new Page<>(page,limit);
return new PageUtils(bannerDao.selectBannerPage(pages,classify));
public PageUtils selectBannerPage(Integer page, Integer limit, Integer classify) {
PageHelper.startPage(page, limit);
return PageUtils.page(new PageInfo<>(bannerDao.selectBanner(classify)));
}
@Override
@CacheEvict(cacheNames = "banner", allEntries = true)
public int saveBody(String image, String url, Integer sort) {
Banner banner = new Banner();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@ -64,6 +71,7 @@ public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements
}
@Override
@CacheEvict(cacheNames = "banner", allEntries = true)
public int insertBanner(Banner banner) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
@ -74,12 +82,13 @@ public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements
@Override
public Result clickBanner(Integer bannerId, int page, int limit) {
Page<Course> page1 = new Page<>(page, limit);
PageHelper.startPage(page, limit);
QueryWrapper<Course> queryWrapper = new QueryWrapper();
//查询banner 对应短剧
queryWrapper.eq("banner_id", bannerId);
IPage<Course> coursePage = courseDao.selectPage(page1, queryWrapper);
return Result.success().put("data", coursePage);
List<Course> coursePage = courseDao.selectList(queryWrapper);
PageInfo<Course> pageInfo = new PageInfo<>(coursePage);
return Result.success().put("data", PageUtils.page(pageInfo, true));
}
@ -89,11 +98,13 @@ public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements
}
@Override
@CacheEvict(cacheNames = "banner", allEntries = true)
public int deleteBannerById(Long id) {
return bannerDao.deleteById(id);
}
@Override
@CacheEvict(cacheNames = "banner", allEntries = true)
public Result updateBannerStateById(Long id) {
Banner banner = selectBannerById(id);
if (banner != null) {
@ -110,6 +121,7 @@ public class BannerServiceImpl extends ServiceImpl<BannerDao, Banner> implements
}
@Override
@CacheEvict(cacheNames = "banner", allEntries = true)
public int updateBannerById(Banner banner) {
return bannerDao.updateById(banner);
}

View File

@ -0,0 +1,40 @@
package com.sqx.modules.callback;
import com.sqx.common.exception.CzgException;
import com.sqx.modules.callback.service.UniAdCallbackRecordService;
import lombok.extern.slf4j.Slf4j;
import com.sqx.modules.callback.dao.UniAdCallBackDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/uniCallBack")
@Slf4j
public class UniCallBackController {
private final UniAdCallbackRecordService uniCallBackService;
public UniCallBackController(UniAdCallbackRecordService uniCallBackService) {
this.uniCallBackService = uniCallBackService;
}
@GetMapping("/adCallBack")
public ResponseEntity<?> adCallBack(@RequestParam String adpid, @RequestParam String provider,
@RequestParam String platform, @RequestParam String sign, @RequestParam String trans_id,
@RequestParam String user_id, @RequestParam(required = false) String extra) {
UniAdCallBackDTO dto = new UniAdCallBackDTO();
dto.setAdpid(adpid);
dto.setProvider(provider);
dto.setPlatform(platform);
dto.setSign(sign);
dto.setTrans_id(trans_id);
dto.setUser_id(user_id);
dto.setExtra(extra);
log.info("接收到uni-ad广告完播回调回调信息: {}", dto);
return ResponseEntity.ok(uniCallBackService.adCallBack(dto));
}
@GetMapping("/testException")
public String testException() throws CzgException {
throw new CzgException("测试异常");
}
}

View File

@ -0,0 +1,16 @@
package com.sqx.modules.callback.dao;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class UniAdCallBackDTO {
private String adpid;
private String provider;
private String platform;
private String sign;
private String trans_id;
private String user_id;
private String extra;
}

View File

@ -0,0 +1,141 @@
package com.sqx.modules.callback.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName uni_ad_callback_record
*/
@TableName(value ="uni_ad_callback_record")
@Data
public class UniAdCallbackRecord implements Serializable {
/**
*
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 平台
*/
private String platform;
/**
* 交易id
*/
private String transId;
/**
* DCloud广告位id
*/
private String adpid;
/**
* 广告服务商
*/
private String provider;
/**
*
*/
private String sign;
/**
* 调用SDK传入并透传自定义数据
*/
private String extra;
/**
* 是否播放完毕
*/
private Integer isEnded;
/**
* 回调时间
*/
private Date createTime;
/**
* 错误信息
*/
private String errMsg;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
UniAdCallbackRecord other = (UniAdCallbackRecord) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
&& (this.getPlatform() == null ? other.getPlatform() == null : this.getPlatform().equals(other.getPlatform()))
&& (this.getTransId() == null ? other.getTransId() == null : this.getTransId().equals(other.getTransId()))
&& (this.getAdpid() == null ? other.getAdpid() == null : this.getAdpid().equals(other.getAdpid()))
&& (this.getProvider() == null ? other.getProvider() == null : this.getProvider().equals(other.getProvider()))
&& (this.getSign() == null ? other.getSign() == null : this.getSign().equals(other.getSign()))
&& (this.getExtra() == null ? other.getExtra() == null : this.getExtra().equals(other.getExtra()))
&& (this.getIsEnded() == null ? other.getIsEnded() == null : this.getIsEnded().equals(other.getIsEnded()))
&& (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
&& (this.getErrMsg() == null ? other.getErrMsg() == null : this.getErrMsg().equals(other.getErrMsg()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
result = prime * result + ((getPlatform() == null) ? 0 : getPlatform().hashCode());
result = prime * result + ((getTransId() == null) ? 0 : getTransId().hashCode());
result = prime * result + ((getAdpid() == null) ? 0 : getAdpid().hashCode());
result = prime * result + ((getProvider() == null) ? 0 : getProvider().hashCode());
result = prime * result + ((getSign() == null) ? 0 : getSign().hashCode());
result = prime * result + ((getExtra() == null) ? 0 : getExtra().hashCode());
result = prime * result + ((getIsEnded() == null) ? 0 : getIsEnded().hashCode());
result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
result = prime * result + ((getErrMsg() == null) ? 0 : getErrMsg().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", userId=").append(userId);
sb.append(", platform=").append(platform);
sb.append(", transId=").append(transId);
sb.append(", adpid=").append(adpid);
sb.append(", provider=").append(provider);
sb.append(", sign=").append(sign);
sb.append(", extra=").append(extra);
sb.append(", isEnded=").append(isEnded);
sb.append(", createTime=").append(createTime);
sb.append(", errMsg=").append(errMsg);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

View File

@ -0,0 +1,20 @@
package com.sqx.modules.callback.mapper;
import com.sqx.modules.callback.entity.UniAdCallbackRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Administrator
* @description 针对表uni_ad_callback_record的数据库操作Mapper
* @createDate 2024-12-23 10:37:52
* @Entity com.sqx.modules.callback.entity.UniAdCallbackRecord
*/
@Mapper
public interface UniAdCallbackRecordMapper extends BaseMapper<UniAdCallbackRecord> {
}

View File

@ -0,0 +1,20 @@
package com.sqx.modules.callback.service;
import com.sqx.modules.callback.dao.UniAdCallBackDTO;
import com.sqx.modules.callback.entity.UniAdCallbackRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.HashMap;
import java.util.Map;
/**
* @author Administrator
* @description 针对表uni_ad_callback_record的数据库操作Service
* @createDate 2024-12-23 10:37:52
*/
public interface UniAdCallbackRecordService extends IService<UniAdCallbackRecord> {
Map<String, Object> adCallBack(UniAdCallBackDTO callBackDTO);
HashMap<String, Object> getStateByExtraKey(Long userId, String extraKey);
}

View File

@ -0,0 +1,136 @@
package com.sqx.modules.callback.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.callback.dao.UniAdCallBackDTO;
import com.sqx.modules.callback.entity.UniAdCallbackRecord;
import com.sqx.modules.callback.service.UniAdCallbackRecordService;
import com.sqx.modules.callback.mapper.UniAdCallbackRecordMapper;
import com.sqx.modules.common.dao.CommonInfoDao;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.redisService.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @author Administrator
* @description 针对表uni_ad_callback_record的数据库操作Service实现
* @createDate 2024-12-23 10:37:52
*/
@Service
@Slf4j
public class UniAdCallbackRecordServiceImpl extends ServiceImpl<UniAdCallbackRecordMapper, UniAdCallbackRecord>
implements UniAdCallbackRecordService{
@Value("${sqx.uni.adSecret}")
private String adSecurity;
private final UserDao userDao;
private final CommonInfoDao commonInfoDao;
private final RedisService redisService;
public UniAdCallbackRecordServiceImpl(UserDao userDao, CommonInfoDao commonInfoDao, RedisService redisService) {
this.userDao = userDao;
this.commonInfoDao = commonInfoDao;
this.redisService = redisService;
}
private String getBaseErrInfo(UniAdCallbackRecord callbackRecord) {
return StrUtil.format("广告获取免费观看时长回调异常: {}, 用户id: {}, 广告播放回调trans_id: {}",
callbackRecord.getErrMsg(), callbackRecord.getUserId(), callbackRecord.getTransId());
}
// 生成签名
public static String generateSign(String secret, String transId) {
// 生成待加密的字符串
String data = secret + ":" + transId;
// 使用SHA-256生成签名
return DigestUtil.sha256Hex(data);
}
// 验证签名
public static boolean validateSign(String secret, String transId, String providedSign) {
// 生成系统计算出来的签名
String generatedSign = generateSign(secret, transId);
// 比较计算出来的签名和提供的签名
return StrUtil.equalsIgnoreCase(generatedSign, providedSign);
}
@Override
public Map<String, Object> adCallBack(UniAdCallBackDTO callBackDTO) {
HashMap<String, Object> respData = new HashMap<>();
UniAdCallbackRecord one = getOne(new LambdaQueryWrapper<UniAdCallbackRecord>()
.eq(UniAdCallbackRecord::getTransId, callBackDTO.getTrans_id()));
if (one != null) {
log.warn("回调重复, {}", one.getTransId());
respData.put("isValid", false);
return respData;
}
UniAdCallbackRecord callbackRecord = new UniAdCallbackRecord();
callbackRecord.setUserId(Long.valueOf(callBackDTO.getUser_id()));
callbackRecord.setPlatform(callBackDTO.getPlatform());
callbackRecord.setTransId(callBackDTO.getTrans_id());
callbackRecord.setAdpid(callBackDTO.getAdpid());
callbackRecord.setProvider(callBackDTO.getProvider());
callbackRecord.setSign(callBackDTO.getSign());
callbackRecord.setExtra(callBackDTO.getExtra());
callbackRecord.setCreateTime(DateUtil.date());
callbackRecord.setIsEnded(1);
boolean flag = validateSign(adSecurity, callBackDTO.getTrans_id(), callBackDTO.getSign());
if (!flag) {
callbackRecord.setErrMsg("签名验证失败");
log.warn(getBaseErrInfo(callbackRecord));
save(callbackRecord);
respData.put("isValid", false);
return respData;
}
UserEntity userEntity = userDao.selectById(callBackDTO.getUser_id());
if (userEntity == null) {
callbackRecord.setErrMsg("用户不存在");
log.warn(getBaseErrInfo(callbackRecord));
save(callbackRecord);
respData.put("isValid", false);
return respData;
}
CommonInfo info = commonInfoDao.findOne(921);
if (info == null || StrUtil.isBlank(info.getValue())){
callbackRecord.setErrMsg("CommonInfo时长时间未配置");
log.warn(getBaseErrInfo(callbackRecord));
save(callbackRecord);
respData.put("isValid", false);
return respData;
}
redisService.setFreeWatchTime(callbackRecord.getUserId(), Integer.parseInt(info.getValue()) * 60, true);
save(callbackRecord);
respData.put("isValid", true);
return respData;
}
@Override
public HashMap<String, Object> getStateByExtraKey(Long userId, String extraKey) {
UniAdCallbackRecord one = getOne(new LambdaQueryWrapper<UniAdCallbackRecord>().eq(UniAdCallbackRecord::getUserId, userId)
.eq(UniAdCallbackRecord::getExtra, extraKey));
return new HashMap<String, Object>(){{
put("isEnded", one == null ? 0 : 1);
}};
}
}

View File

@ -1,6 +1,7 @@
package com.sqx.modules.common.controller.app;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.common.service.CommonInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

View File

@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.common.entity.CommonInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import java.util.List;
@ -13,12 +15,12 @@ import java.util.List;
* @date 2020/7/8
*/
@Mapper
@CacheConfig(cacheNames = "common")
public interface CommonInfoDao extends BaseMapper<CommonInfo> {
List<CommonInfo> findByCondition(@Param("condition") String condition);
@Cacheable(key = "#type")
CommonInfo findOne(@Param("type") int type);
}
}

View File

@ -7,6 +7,10 @@ import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.course.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
@ -16,6 +20,7 @@ import java.util.Date;
* @author fang
* @date 2020/7/8
*/
@CacheConfig(cacheNames = "common")
@Service
public class CommonInfoServiceImpl extends ServiceImpl<CommonInfoDao, CommonInfo> implements CommonInfoService {
@ -25,7 +30,7 @@ public class CommonInfoServiceImpl extends ServiceImpl<CommonInfoDao, CommonInfo
private CourseService courseService;
@CacheEvict(key = "#commonInfo.id")
@Override
public Result update(CommonInfo commonInfo) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@ -43,19 +48,19 @@ public class CommonInfoServiceImpl extends ServiceImpl<CommonInfoDao, CommonInfo
return Result.success();
}
@Override
public CommonInfo findOne(int type) {
return commonInfoDao.findOne(type);
}
@CacheEvict(key = "#id")
@Override
public Result delete(long id) {
commonInfoDao.deleteById(id);
return Result.success();
}
@CacheEvict(key = "#commonInfo.id")
@Override
public Result updateBody(CommonInfo commonInfo) {
commonInfoDao.updateById(commonInfo);

View File

@ -0,0 +1,65 @@
package com.sqx.modules.complet.controller;
import cn.hutool.core.date.DateUtil;
import com.sqx.modules.complet.entity.CompletAward;
import com.sqx.modules.complet.service.CompletAwardService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.Result;
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.*;
import java.util.Date;
@Slf4j
@RestController
@Api(value = "达标奖励", tags = {"达标奖励表(邀请人员 几个人达标后的额外奖励)"})
@RequestMapping(value = "/completAward")
public class CompletAwardController {
/**
* 服务对象
*/
@Autowired
private CompletAwardService completAwardService;
@PostMapping("/insertCompletAward")
@ApiOperation("添加达标奖励")
public Result insertCompletAward(@RequestBody CompletAward completAward) {
completAward.setCreateTime(DateUtil.now());
completAwardService.save(completAward);
return Result.success();
}
@GetMapping("/{id}")
@ApiOperation("通过Id查询详情")
public Result selectOne(@PathVariable Integer id) {
return Result.success().put("data", completAwardService.getById(id));
}
@PostMapping("/updateCompletAward")
@ApiOperation("修改达标奖励")
public Result updateCompletAward(@RequestBody CompletAward completAward) {
completAward.setUpdateTime(DateUtil.now());
completAwardService.updateById(completAward);
return Result.success();
}
@PostMapping("/deleteCompletAward")
@ApiOperation("删除达标奖励")
public Result deleteCompletAward(Long id) {
completAwardService.removeById(id);
return Result.success();
}
@GetMapping("/selectCompletAward")
@ApiOperation("查询达标奖励")
public Result selectCompletAward(Integer page, Integer limit) {
return Result.success().put("data", completAwardService.page(new Page<>(page, limit), new QueryWrapper<CompletAward>().orderByAsc("id")));
}
}

View File

@ -0,0 +1,11 @@
package com.sqx.modules.complet.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sqx.modules.complet.entity.CompletAward;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CompletAwardDao extends BaseMapper<CompletAward> {
}

View File

@ -0,0 +1,42 @@
package com.sqx.modules.complet.entity;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
/**
* 达标奖励表(邀请人员 几个人达标后的额外奖励)(CompletAward)表实体类
*
* @author ww
* @since 2024-12-12 09:36:13
*/
@Data
@TableName("complet_award")
@ApiModel(value = "达标奖励表(邀请人员 几个人达标后的额外奖励) 实体类")
public class CompletAward extends Model<CompletAward> {
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("人数")
private Integer inviteCount;
@ApiModelProperty("1 金币 2 红包")
private Integer type;
@ApiModelProperty("奖励数量")
private BigDecimal awardNumber;
@ApiModelProperty("状态 0 关闭 1 开启")
private Integer status;
@ApiModelProperty("创建时间")
private String createTime;
@ApiModelProperty("更新时间")
private String updateTime;
}

View File

@ -0,0 +1,11 @@
package com.sqx.modules.complet.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.modules.complet.entity.CompletAward;
import java.util.Map;
public interface CompletAwardService extends IService<CompletAward> {
}

View File

@ -0,0 +1,19 @@
package com.sqx.modules.complet.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.modules.complet.dao.CompletAwardDao;
import com.sqx.modules.complet.entity.CompletAward;
import com.sqx.modules.complet.service.CompletAwardService;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
@Service
public class CompletAwardServiceImpl extends ServiceImpl<CompletAwardDao, CompletAward> implements CompletAwardService {
}

View File

@ -22,7 +22,7 @@ public class Coupon implements Serializable {
*/
private String couponName;
/**
* 可抵扣金
* 可抵扣金
*/
private BigDecimal money;

View File

@ -22,7 +22,7 @@ public class CouponUser implements Serializable {
*/
private Long userId;
/**
* 优惠券金
* 优惠券金
*/
private BigDecimal couponMoney;
/**

View File

@ -1,9 +1,8 @@
package com.sqx.modules.coupon.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.sqx.common.utils.Result;
import com.sqx.modules.coupon.dao.CouponDao;
import com.sqx.modules.coupon.entity.Coupon;
@ -34,13 +33,12 @@ public class CouponServiceImpl extends ServiceImpl<CouponDao, Coupon> implements
@Override
public Result selectCoupon(Integer page, Integer limit, String couponName) {
IPage<Coupon> pages = new Page<>(page, limit);
PageHelper.startPage(page,limit);
QueryWrapper<Coupon> queryWrapper1 = new QueryWrapper<>();
if(couponName!=null){
queryWrapper1.eq("coupon_name",couponName);
}
pages=baseMapper.selectPage(pages,queryWrapper1);
return Result.success().put("data",pages.getRecords());
return Result.success().put("data",baseMapper.selectList(queryWrapper1));
}
@Override

View File

@ -181,6 +181,8 @@ public class AliossCourseController {
courseDetails.setTitleImg(image);
courseDetails.setContent(courseDetailsName);
courseDetails.setGoodNum(goodNum);
courseDetails.setViewCount(0L);
courseDetails.setPlayCompleteCount(0L);
if(i<=freeNum){
courseDetails.setPrice(BigDecimal.ZERO);
courseDetails.setIsPrice(2);

View File

@ -61,11 +61,11 @@ public class CourseController extends AbstractController {
}
@GetMapping("/selectCourseUserbyid")
@ApiOperation("我的短剧")
public Result selectCourseUser(Integer page, Integer limit, Long userId) {
return courseUserService.selectCourseUser(page, limit, userId);
}
// @GetMapping("/selectCourseUserbyid")
// @ApiOperation("我的短剧")
// public Result selectCourseUser(Integer page, Integer limit, Long userId) {
// return courseUserService.selectCourseUser(page, limit, userId);
// }
@GetMapping("/updateCourse")
@ApiOperation("修改状态")

View File

@ -1,8 +1,11 @@
package com.sqx.modules.course.controller.app;
import com.alibaba.fastjson.JSONObject;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.RedisUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.course.entity.Course;
import com.sqx.modules.course.service.CourseDetailsService;
import com.sqx.modules.course.service.CourseService;
import com.sqx.modules.sys.controller.AbstractController;
@ -23,72 +26,100 @@ public class AppCourseController extends AbstractController {
private CourseService courseService;
@Autowired
private CourseDetailsService courseDetailsService;
@Autowired
private RedisUtils redisUtils;
@Login
@GetMapping("/selectCourse")
@ApiOperation("查询短剧信息")
public Result selectCourse(@ApiParam("") Integer page, @ApiParam("") Integer limit, @ApiParam("分类id") Long classifyId,
@ApiParam("搜索内容") String title, Long bannerId, Integer sort, String token, Integer isPrice,
Integer over,Integer wxCourse,Integer dyCourse,Integer wxShow,Integer dyShow, HttpServletRequest request) {
if(StringUtils.isEmpty(token)){
Integer over, Integer wxCourse, Integer dyCourse, Integer wxShow, Integer dyShow, HttpServletRequest request) {
if (StringUtils.isEmpty(token)) {
token = request.getHeader("Token");
if(StringUtils.isBlank(token)){
if (StringUtils.isBlank(token)) {
token = request.getParameter("Token");
}
}
return courseService.selectCourse(page, limit, classifyId, title,null,1,bannerId,sort,token,isPrice,
null, over,wxCourse,dyCourse,wxShow,dyShow);
return courseService.selectCourse(page, limit, classifyId, title, null, 1, bannerId, sort, token, isPrice,
null, over, wxCourse, dyCourse, wxShow, dyShow);
}
@Login
@GetMapping("/selectCourseDetailsById")
@ApiOperation("根据id查询短剧详情")
public Result selectCourseDetailsById(Long id,String token,String courseDetailsId){
return courseDetailsService.selectCourseDetailsById(id,token,courseDetailsId);
public Result selectCourseDetailsById(@RequestAttribute("userId") Long userId, Long id, String token, String courseDetailsId) {
String redisKey = RedisKeys.getDateKey("course:") + userId + "-" + id;
Object week = redisUtils.getObjectDate(redisKey,Course.class);
if (week != null) {
return Result.success().put("data", week);
}
Result result = courseDetailsService.selectCourseDetailsById(id, token, courseDetailsId);
if (result.get("code").equals(0)) {
redisUtils.set(redisKey, result.get("data"), 3);
}
return result;
}
@Login
@GetMapping("/getRedEnvelopeTips")
@ApiOperation("获取抽奖红包提示")
public Result getRedEnvelopeTips(@RequestAttribute("userId") Long userId) {
return courseService.getRedEnvelopeTips(userId);
}
@GetMapping("/selectCourseDetailsList")
@ApiOperation("查询推荐视频")
public Result selectCourseDetailsList(Integer page,Integer limit,String token,String randomNum,Integer wxShow,Integer dyShow){
return courseDetailsService.selectCourseDetailsList(page, limit, token,randomNum,wxShow,dyShow);
public Result selectCourseDetailsList(Integer page, Integer limit, String token, String randomNum, Integer wxShow, Integer dyShow) {
return courseDetailsService.selectCourseDetailsList(page, limit, token, randomNum, wxShow, dyShow);
}
@Login
@GetMapping("/selectCourseTitle")
@ApiOperation("模糊根据短剧标题查询短剧")
public Result selectCourseTitle(@ApiParam("") Integer page, @ApiParam("") Integer limit, @ApiParam("分类id") Long classifyId,
@ApiParam("搜索内容") String title,Long bannerId,Integer sort,String token, Integer isPrice,Integer over,
Integer wxCourse,Integer dyCourse,Integer wxShow,Integer dyShow) {
return courseService.selectCourse(page, limit, classifyId, title,null,1,bannerId,sort,token,isPrice,
null, over,wxCourse,dyCourse,wxShow,dyShow);
@ApiParam("搜索内容") String title, Long bannerId, Integer sort, String token, Integer isPrice, Integer over,
Integer wxCourse, Integer dyCourse, Integer wxShow, Integer dyShow) {
return courseService.selectCourse(page, limit, classifyId, title, null, 1, bannerId, sort, token, isPrice,
null, over, wxCourse, dyCourse, wxShow, dyShow);
}
@GetMapping("/selectCourseTitles")
@ApiOperation("模糊根据短剧标题查询短剧")
public Result selectCourseTitles(@ApiParam("") Integer page, @ApiParam("") Integer limit, @ApiParam("分类id") Long classifyId,
@ApiParam("搜索内容") String title,Long bannerId,Integer sort,String token, Integer isPrice,Integer over,
Integer wxCourse,Integer dyCourse,Integer wxShow,Integer dyShow) {
return courseService.selectCourse(page, limit, classifyId, title,null,1,bannerId,sort,token,isPrice,
null, over,wxCourse,dyCourse,wxShow,dyShow);
@ApiParam("搜索内容") String title, Long bannerId, Integer sort, String token, Integer isPrice, Integer over,
Integer wxCourse, Integer dyCourse, Integer wxShow, Integer dyShow) {
return courseService.selectCourse(page, limit, classifyId, title, null, 1, bannerId, sort, token, isPrice,
null, over, wxCourse, dyCourse, wxShow, dyShow);
}
@Login
@PostMapping("/courseNotify")
@ApiOperation("看广告解锁视频")
public Result courseNotify(@RequestAttribute Long userId, Long courseId, Long courseDetailsId){
public Result courseNotify(@RequestAttribute Long userId, Long courseId, Long courseDetailsId) {
return courseService.courseNotify(userId, courseId, courseDetailsId);
}
@PostMapping("/notifyUrl")
@ApiOperation("抖音视频回调")
public JSONObject notifyUrl(@RequestBody JSONObject jsonObject){
public JSONObject notifyUrl(@RequestBody JSONObject jsonObject) {
return courseService.notifyUrl(jsonObject);
}
@PostMapping("/selectWxVideoUrl")
@ApiOperation("查询微信短剧播放链接")
public Result selectWxVideoUrl(@RequestBody JSONObject jsonObject){
public Result selectWxVideoUrl(@RequestBody JSONObject jsonObject) {
String wxCourseDetailsIds = jsonObject.getString("wxCourseDetailsIds");
return courseService.selectWxVideoUrl(wxCourseDetailsIds);
}
@GetMapping("/viewCourse")
@ApiOperation("查看短剧")
public Result viewCourse(@ApiParam("短剧id") Long courseId,
@ApiParam("剧集id") Long courseDetailsId,
@ApiParam("统计类型start 开始end 结束") String type) {
return courseService.viewCourse(courseId, courseDetailsId, type);
}
}

View File

@ -19,12 +19,12 @@ public class AppCourseUserController extends AbstractController {
@Autowired
private CourseUserService courseUserService;
@Login
@GetMapping("/selectCourseUser")
@ApiOperation("App我的短剧")
public Result selectCourseUser(Integer page, Integer limit, Long userId) {
return courseUserService.selectCourseUser(page, limit, userId);
}
// @Login
// @GetMapping("/selectCourseUser")
// @ApiOperation("App我的短剧")
// public Result selectCourseUser(Integer page, Integer limit, Long userId) {
// return courseUserService.selectCourseUser(page, limit, userId);
// }
@Login
@GetMapping("/updateTime")
@ -33,12 +33,12 @@ public class AppCourseUserController extends AbstractController {
courseUserService.updateTime(courseId);
}
@Login
@GetMapping("/selectLatelyCourse")
@ApiOperation("最近学习")
public Result selectLatelyCourse(Integer page, Integer limit, Long userId) {
return courseUserService.selectLatelyCourse(page, limit, userId);
}
// @Login
// @GetMapping("/selectLatelyCourse")
// @ApiOperation("最近学习")
// public Result selectLatelyCourse(Integer page, Integer limit, Long userId) {
// return courseUserService.selectLatelyCourse(page, limit, userId);
// }

View File

@ -1,8 +1,6 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.CourseClassification;
import com.sqx.modules.course.response.ClassificationResponse;
import com.sqx.modules.course.response.CurriculumResponse;
@ -14,10 +12,7 @@ import java.util.Map;
@Mapper
public interface CourseClassificationDao extends BaseMapper<CourseClassification> {
IPage<Map<String, Object>> selectCourseClassificationPage(Page<Map<String, Object>> pages, @Param("classificationName") String classificationName);
IPage<Map<String, Object>> selectCourseClassificationList(@Param("classificationName") String classificationName);
List<Map<String, Object>> selectCourseClassificationList(@Param("classificationName") String classificationName);
int updateDelete(@Param("id") Long id);

View File

@ -1,18 +1,17 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.Course;
import com.sqx.modules.course.entity.CourseCollect;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
public interface CourseCollectDao extends BaseMapper<CourseCollect> {
IPage<Course> selectCourseByCollect(Page<Course> page, @Param("userId") Long userId,@Param("classify") Integer classify);
List<Course> selectCourseByCollect(@Param("userId") Long userId, @Param("classify") Integer classify);
}

View File

@ -1,12 +1,11 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.CourseComment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
@ -14,7 +13,7 @@ public interface CourseCommentDao extends BaseMapper<CourseComment> {
int updateCourseComment(@Param("type") Integer type, @Param("courseCommentId") Long courseCommentId);
IPage<CourseComment> selectCourseComment(Page<CourseComment> page, @Param("courseId") Long courseId,@Param("userId") Long userId);
List<CourseComment> selectCourseComment(@Param("courseId") Long courseId, @Param("userId") Long userId);
/**
* 删除评论的点赞关联
@ -22,8 +21,8 @@ public interface CourseCommentDao extends BaseMapper<CourseComment> {
* @return
*/
int deleteCommentGood(@Param("courseCommentId") Long courseCommentId);
IPage<Map<String,Object>> selectCourseCommentByUserId(Page<Map<String,Object>> page,@Param("userId") Long userId);
List<Map<String,Object>> selectCourseCommentByUserId(@Param("userId") Long userId);
}

View File

@ -1,12 +1,11 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.Course;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
@ -14,16 +13,16 @@ public interface CourseDao extends BaseMapper<Course> {
int updateDelete(@Param("id") Long id);
IPage<Map<String, Object>> selectCourse(Page<Map<String, Object>> pages, @Param("classifyId") Long classifyId,
@Param("title") String title,@Param("isRecommend") Integer isRecommend,
@Param("status") Integer status,@Param("bannerId") Long bannerId,
@Param("sort") Integer sort,@Param("startTime") String startTime,
@Param("endTime") String endTime,@Param("userId") Long userId,
@Param("isPrice") Integer isPrice,@Param("over") Integer over,
@Param("wxCourse") Integer wxCourse,@Param("dyCourse") Integer dyCourse,
@Param("wxShow") Integer wxShow,@Param("dyShow") Integer dyShow);
List<Map<String, Object>> selectCourse(@Param("classifyId") Long classifyId,
@Param("title") String title, @Param("isRecommend") Integer isRecommend,
@Param("status") Integer status, @Param("bannerId") Long bannerId,
@Param("sort") Integer sort, @Param("startTime") String startTime,
@Param("endTime") String endTime, @Param("userId") Long userId,
@Param("isPrice") Integer isPrice, @Param("over") Integer over,
@Param("wxCourse") Integer wxCourse, @Param("dyCourse") Integer dyCourse,
@Param("wxShow") Integer wxShow, @Param("dyShow") Integer dyShow);
IPage<Map<String, Object>> selectCourseAdmin(Page<Map<String, Object>> pages, @Param("classifyId") Long classifyId,
List<Map<String, Object>> selectCourseAdmin(@Param("classifyId") Long classifyId,
@Param("title") String title,@Param("isRecommend") Integer isRecommend,
@Param("status") Integer status,@Param("bannerId") Long bannerId,
@Param("sort") Integer sort,@Param("startTime") String startTime,
@ -34,10 +33,9 @@ public interface CourseDao extends BaseMapper<Course> {
/**
* 根据title 模糊查询短剧
* @param pages
* @param title
* @return
*/
IPage<Map<String, Object>> selectCourseTitle(Page<Map<String, Object>> pages, @Param("title")String title);
List<Map<String, Object>> selectCourseTitle(@Param("title")String title);
}

View File

@ -1,8 +1,6 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.CourseDetails;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -14,12 +12,12 @@ public interface CourseDetailsDao extends BaseMapper<CourseDetails> {
List<CourseDetails> findByCourseId(@Param("id") Long id,@Param("userId") Long userId);
IPage<CourseDetails> selectCoursePageByCourseId(Page<CourseDetails> page, @Param("id") Long id,@Param("good") Integer good);
List<CourseDetails> selectCoursePageByCourseId(@Param("id") Long id,@Param("good") Integer good);
List<CourseDetails> findByCourseIdNotUrl(@Param("id") Long id,@Param("userId") Long userId);
int deleteCourseDetails(String[] ids);
IPage<CourseDetails> selectCourseDetailsList(Page<CourseDetails> page,String randomNum,Integer wxShow,Integer dyShow);
List<CourseDetails> selectCourseDetailsList(String randomNum,Integer wxShow,Integer dyShow);
}

View File

@ -1,9 +1,6 @@
package com.sqx.modules.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.modules.course.entity.Course;
import com.sqx.modules.course.entity.CourseUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -12,11 +9,6 @@ import java.util.List;
@Mapper
public interface CourseUserDao extends BaseMapper<CourseUser> {
IPage<Course> selectLatelyCourse(Page<Course> pages, @Param("userId") Long userId);
IPage<Course> selectCourseByCourseUser(Page<Course> pages, @Param("userId") Long userId);
/**
* 查询用户是否订购
*

View File

@ -49,6 +49,11 @@ public class Course implements Serializable {
*/
private BigDecimal price;
/**
* 10集购买价格
*/
private BigDecimal wholesalePrice;
/**
* 上下架 1上架 2下架
*/

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ -14,6 +15,7 @@ import java.io.Serializable;
* @date 2021-03-27
*/
@Data
@Accessors(chain = true)
@TableName("course_collect")
public class CourseCollect implements Serializable {

View File

@ -10,8 +10,8 @@ import java.io.Serializable;
import java.math.BigDecimal;
/**
* @description course_details 短剧目录
* @author fang
* @description course_details 短剧目录
* @date 2021-03-27
*/
@Data
@ -133,6 +133,16 @@ public class CourseDetails implements Serializable {
*/
private Integer advertising;
/**
* 播放量
*/
private Long viewCount;
/**
* 完播量
*/
private Long playCompleteCount;
@TableField(exist = false)
private Integer isCollect;
@ -145,5 +155,4 @@ public class CourseDetails implements Serializable {
@TableField(exist = false)
private String wxUrl;
public CourseDetails() {}
}

View File

@ -59,4 +59,8 @@ public interface CourseService extends IService<Course> {
Result courseListExcelIn(MultipartFile file) throws IOException;
Result viewCourse(Long courseId, Long courseDetailsId, String type);
Result getRedEnvelopeTips(Long userId);
}

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