274 Commits

Author SHA1 Message Date
3c2b4ffc48 TASK: 画布数据 回参添加返回crossOrigin 2025-07-22 11:31:26 +08:00
b90df7468e TASK:管理员权限变更 2025-07-18 17:32:03 +08:00
370d9402f2 TASK: 试用邮件通知权限变更 2025-07-02 10:08:54 +08:00
4d518d05b9 TASK: 管理员页面访问权限变动 2025-07-02 09:18:22 +08:00
13514b277b BUGFIX:用户注册后重发验证码,验证不通过 2025-06-24 19:30:20 +08:00
d6c5d0e95d TASK:查询交易记录 添加显示总金额和付款者邮箱 2025-06-23 10:53:30 +08:00
301a62a563 TASK:添加管理员访问人员 2025-06-19 17:39:18 +08:00
22e5a97143 BUGFIX: 优惠券的佣金计算,统计时间边界问题优化 2025-06-13 11:18:55 +08:00
765d404845 TASK: 将generate,用户输入中的中文字符转换为英文字符 2025-06-11 15:34:00 +08:00
d5cf4e9d3f TASK: 添加“新增试用用户”通知对象chelseayu@code-create.com.hk 2025-06-08 09:19:36 +08:00
4b7fd649a3 TASK: 推广码 添加开始生效时间;优化数据计算类型,使用BigDecimal替换float;更新paidCommission后自动计算unpaidCommission 2025-06-06 19:37:38 +08:00
6249d53b7b BUGFIX: modifySketch 除library以外的地方修改,originalIdSource允许不传 2025-06-04 22:04:09 +08:00
b445f1f11e BUGFIX: modifySketch 在library中修改后需要保存到library 2025-06-04 15:49:55 +08:00
5c66ece467 1.关闭续订前七天邮件提醒
2.优化订阅邮件提醒,向redis存储已发送的邮件类型
2025-05-23 17:16:19 +08:00
3b6b0c7e2c TASK: prom code 开启佣金计费定时器和商家邮件通知 2025-05-22 16:37:41 +08:00
9a81fb7ee4 TASK:将PromotionCode合并到生产-test 2025-05-20 16:53:48 +08:00
31bb29f2fd Affiliate 允许为不同的用户设置不同的affiliate
Stripe 添加优惠券删除接口;限制优惠券只能在订阅时使用

(cherry picked from commit 200c0adfba)
2025-05-20 11:30:42 +08:00
c7b46229b5 删除优惠券
(cherry picked from commit 58af5c5570)
2025-05-19 17:29:06 +08:00
1482bb6ab2 Stripe推广码 部分功能完善
(cherry picked from commit 218d828e0d)
2025-05-19 17:28:52 +08:00
eae4087b3e Stripe支付--添加推广码功能及相应佣金计算
(cherry picked from commit 0ba28588da)
2025-05-19 17:13:28 +08:00
faf98607c4 优惠券查询DTO
(cherry picked from commit 1ce6c74f2c)
2025-05-19 17:04:51 +08:00
c19e9094d1 BUGFIX: generate mode字段传递不准确导致生成结果与图片没有关联 2025-05-09 17:03:42 +08:00
db55c5597f undividedLayers数据保存失败原因查找 2025-05-09 00:18:00 +08:00
0c79739867 BUGFIX: design之后,未分割图片的保存问题 2025-05-08 15:26:06 +08:00
e484f22788 BUGFIX : design 未分割图层保存问题 2025-05-08 14:54:12 +08:00
6a694cee18 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-05-08 14:19:41 +08:00
1a077edf0c designSingle 取消颜色限制 2025-05-08 14:19:26 +08:00
shahaibo
68926757dc Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-05-07 22:04:21 +08:00
shahaibo
eea57435e5 TASK:minio地址修改; 2025-05-07 22:04:10 +08:00
1f0e8f9cf2 BUGFIX: designSingle时,添加相同类型的服装导致未分割图层获取混乱 2025-05-07 14:10:42 +08:00
shahaibo
63ee41e3b8 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-03-31 17:47:33 +08:00
shahaibo
08072001a7 BUGFIX:dislike合并逻辑去除; 2025-03-31 17:47:25 +08:00
6b4d82a67d AiDA 8折优惠活动恢复 2025-03-31 17:45:16 +08:00
5612b5b1d4 AiDA 8折优惠活动 2025-03-31 09:48:09 +08:00
1d46a3b6d4 修改本地缓存的过期时间 2025-03-27 15:38:25 +08:00
0500557dca BUGFIX: 获取pantone值为空时返回rgb和hsv 2025-03-18 18:47:05 +08:00
654a3829c6 BUGFIX: 获取RGB对应的PanTone数据失败,导致返回颜色为空 2025-03-18 17:39:39 +08:00
fccafba438 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-03-18 15:33:38 +08:00
8cd4cfb36d getDetail 添加日志,打印入参回参 2025-03-18 15:33:24 +08:00
shahaibo
7e55b1f85e BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-13 17:53:35 +08:00
shahaibo
a043db2de5 BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-12 22:48:18 +08:00
shahaibo
d3ee0e5f4f BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-12 22:06:39 +08:00
shahaibo
484a8d1d93 BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-12 22:00:07 +08:00
shahaibo
7839ac3322 BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-12 21:54:23 +08:00
shahaibo
e16f494cf4 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-03-12 21:26:33 +08:00
shahaibo
6fc22784b8 BUGFIX: 隐藏加载不出minio的相关数据; 2025-03-12 21:26:24 +08:00
52bafa95e3 关闭默认从Code-Create创建游客账号的定时器 2025-03-03 21:17:14 +08:00
377c86e390 Stripe 回调判空并直接返回 2025-02-28 14:30:35 +08:00
d809362ea7 Merge branch 'dev/dev' into release/3.0 2025-02-25 11:42:51 +08:00
c08987a781 Merge branch 'dev/dev_xp' into dev/dev 2025-02-24 10:37:14 +08:00
e60c3d7aa3 Stripe webhook charge回调处理 2025-02-24 10:36:42 +08:00
614b8d0948 to prod 2025-02-21 17:56:50 +08:00
8834b906f4 Merge branch 'dev/dev_xp' into dev/dev 2025-02-21 17:39:35 +08:00
828a022768 漏传 2025-02-21 17:39:12 +08:00
26c8d08d04 Merge branch 'dev/dev_xp' into dev/dev 2025-02-21 17:35:35 +08:00
68a9b2281a 管理员系统部分优化、stripe异常通知优化 2025-02-21 17:16:44 +08:00
63df493d33 切换dev支付环境为测试环境,回调端点为dev端点 2025-02-21 13:02:30 +08:00
b7110c80b5 切换dev支付回调端点 2025-02-21 12:51:11 +08:00
c4dbd10a85 to dev 2025-02-20 11:10:00 +08:00
041a407978 Merge branch 'release/3.0' into dev/dev 2025-02-20 11:00:41 +08:00
f73c997c38 Merge branch 'dev/dev_xp' into dev/dev 2025-02-20 10:59:58 +08:00
db2a955dea 生成结果均低于输出标准时的提示语句更换 2025-02-20 10:57:43 +08:00
a91643d2ec to prod 2025-02-19 17:44:14 +08:00
269cf7ea03 关闭merchant邮箱,test支付环境不通知商家 2025-02-19 16:40:12 +08:00
e3aa964db8 切换支付环境为test 2025-02-19 16:32:28 +08:00
fa2fa66d4a 打开商家邮箱 用于接收邮件通知 2025-02-19 14:54:24 +08:00
6d2a189fef 更换支付方式 2025-02-19 14:43:42 +08:00
2033f61c7e 切换支付环境为live 2025-02-19 14:28:07 +08:00
4e2222966f 修改邮件模板ID 2025-02-19 14:23:43 +08:00
fbe9dc87e9 Stripe 回调添加异常处理和异常情况下邮件通知 2025-02-19 14:14:20 +08:00
d6f078ab60 添加判断,确认邮件是否发送成功 2025-02-18 17:07:16 +08:00
a940863799 stripe 一次订阅 bug修复 2025-02-18 15:00:57 +08:00
11ffa66851 stripe 一次订阅 添加日志打印 2025-02-18 14:09:27 +08:00
fc3fa22bee 更换stripe-webhook回调密钥 2025-02-18 11:31:49 +08:00
37ff60fcfb Stripe 添加一次订阅服务(默认关闭自动续订功能) 2025-02-17 17:14:30 +08:00
d2d5eebe12 to dev 2025-02-17 10:52:11 +08:00
9cfb5aa344 Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2025-02-17 10:19:17 +08:00
5e7f898840 BUGFIX: 用户支付后获取账号到期时间为空,无法更新账号信息 2025-02-17 10:18:57 +08:00
shahaibo
6d3253aed3 BUGFIX: bindEmail; 2025-02-14 11:49:37 +08:00
shahaibo
52e5f246ce Merge branch 'dev/dev' into release/3.0 2025-02-13 12:57:37 +08:00
shahaibo
6222377bc5 BUGFIX: dev恢复toProductImage、relight消费; 2025-02-13 11:57:00 +08:00
shahaibo
2d10f57643 BUGFIX: dev关闭toProductImage、relight消费; 2025-02-13 11:42:45 +08:00
shahaibo
5f27a95498 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-13 11:07:02 +08:00
shahaibo
7fdf832f44 BUGFIX: toProductImage、relight; 2025-02-13 11:06:19 +08:00
43d2f83677 BUGFIX:For input string: "[0.3400879, 0.3400879]" 2025-02-12 13:20:12 +08:00
e882a15aa0 Merge branch 'dev/dev' into release/3.0 2025-02-12 13:07:25 +08:00
1a3f16119b Merge branch 'dev/dev_xp' into dev/dev 2025-02-12 12:13:52 +08:00
8e2e515af3 BUGFIX:印花 不等比缩放适配历史数据 2025-02-12 12:13:25 +08:00
f1a2495431 Merge branch 'dev/dev' into release/3.0 2025-02-12 10:34:02 +08:00
c66b794daa Merge branch 'dev/dev_xp' into dev/dev 2025-02-12 10:33:39 +08:00
b9f7ea2722 BUGFIX: 多个印花 不等比缩放适配历史数据 2025-02-12 10:33:11 +08:00
455e17d4b1 Merge branch 'dev/dev' into release/3.0 2025-02-12 10:19:45 +08:00
a1a6a78dac Merge branch 'dev/dev_xp' into dev/dev 2025-02-12 10:14:17 +08:00
07f91aef74 BUGFIX: 印花不等比缩放适配历史数据 2025-02-12 10:13:54 +08:00
shahaibo
079ab4d98f BUGFIX: name 信息绑定邮箱录入; 2025-02-12 09:56:55 +08:00
shahaibo
6e53bc3ca5 TASK: 定时任务; 2025-02-12 09:28:04 +08:00
shahaibo
5e8eb716b1 TASK: name信息; 2025-02-11 20:50:22 +08:00
shahaibo
34ee8fa11d TASK: name信息; 2025-02-11 13:08:00 +08:00
shahaibo
b7dc95af26 TASK:name信息; 2025-02-11 11:35:57 +08:00
shahaibo
297391d57e BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-11 11:27:08 +08:00
shahaibo
aff870fba7 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-11 10:25:08 +08:00
7b1ac47228 Merge branch 'dev/dev_xp' into dev/dev 2025-02-10 16:15:20 +08:00
7eb9abbdb5 优化接收Stripe回调时数据重复存储问题(添加唯一索引) 2025-02-10 16:11:59 +08:00
521bd5071a Merge branch 'dev/dev_xp' into dev/dev
# Conflicts:
#	src/main/java/com/ai/da/mapper/primary/entity/DesignItemDetailPrint.java
#	src/main/java/com/ai/da/model/vo/DesignSinglePrint.java
#	src/main/java/com/ai/da/python/PythonService.java
#	src/main/java/com/ai/da/python/vo/DesignPythonItemElement.java
#	src/main/java/com/ai/da/python/vo/DesignPythonItemPrint.java
#	src/main/java/com/ai/da/service/impl/DesignServiceImpl.java
2025-02-10 11:21:52 +08:00
ab7e1705c4 修改print scale的数据结构 2025-02-10 11:18:04 +08:00
shahaibo
a2390a6ab2 BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-10 10:34:01 +08:00
shahaibo
8dc5dcb1bd BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-10 10:11:59 +08:00
shahaibo
5d010d2f77 BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-10 10:08:48 +08:00
shahaibo
cec5544472 BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-10 10:05:57 +08:00
shahaibo
5f79c3276a BUGFIX:试用订单邮件 订单更新时间判断; 2025-02-10 10:03:28 +08:00
aadb717c9f to dev 2025-02-07 15:03:24 +08:00
e2e9201fdd 修改印花scale数据类型为数组 2025-02-07 14:57:28 +08:00
shahaibo
9053bdf10c BUGFIX:试用注册; 2025-02-07 12:48:37 +08:00
shahaibo
b14297d1af Merge branch 'dev/dev' into release/3.0 2025-02-07 11:58:36 +08:00
shahaibo
e90979bbdc BUGFIX:试用注册; 2025-02-07 11:58:12 +08:00
shahaibo
e02c278e7a Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-07 10:25:20 +08:00
shahaibo
e60d9483a3 BUGFIX:试用订单邮件信息; 2025-02-07 10:25:11 +08:00
shahaibo
ba49312fd5 BUGFIX:试用订单邮件信息; 2025-02-07 10:23:41 +08:00
ba3c98771f BUGFIX: 新建订阅时更新订阅不更新账号信息 2025-02-06 18:39:06 +08:00
4c738cc61d BUGFIX: 返回最新的订阅号 2025-02-06 17:35:35 +08:00
d648a79ec4 BUGFIX: 订阅付款失败时仍有新建订阅 2025-02-06 16:36:07 +08:00
c325927418 to prod 2025-02-06 14:46:50 +08:00
dba5625446 正式支付环境下区分生产分支与测试分支 2025-02-06 14:42:45 +08:00
91189968e9 在dev测试生产环境的Stripe支付功能 2025-02-06 14:37:06 +08:00
433d8a460e to dev 2025-02-06 14:22:27 +08:00
ec9857fe73 Merge branch 'dev/dev_xp' into dev/dev 2025-02-06 14:09:53 +08:00
a9b01566e1 优化积分购买 2025-02-06 14:09:15 +08:00
shahaibo
a384aba4df TASK:定时任务开启; 2025-02-06 10:04:30 +08:00
e587ad3ca1 1、支付环境切换为prod
2、邮件通知对象添加Kim
3、打开定时任务
2025-02-06 09:53:03 +08:00
shahaibo
6a7c8b3d28 Merge branch 'dev/dev' into release/3.0 2025-02-05 14:26:33 +08:00
shahaibo
6f52c956ec TASK:新的试用订单生成; 2025-02-05 14:20:22 +08:00
shahaibo
9e5d2f47e2 BUGFIX:绑定谷歌; 2025-02-05 13:38:10 +08:00
shahaibo
627f264ef3 BUGFIX:绑定谷歌; 2025-02-05 13:02:26 +08:00
shahaibo
464de4ee5a Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-05 12:05:07 +08:00
shahaibo
cf76235123 TASK:谷歌微信快捷区分登录注册; 2025-02-05 12:04:53 +08:00
8d9f51f50f 不再清空游客的到期时间 2025-02-05 11:22:45 +08:00
d840185ec7 测试 code-create DB最大连接时长 2025-02-05 10:56:17 +08:00
9f4ab20b9d 测试 code-create DB最大连接时长 2025-02-05 10:49:10 +08:00
0877ff8f66 支付 测试 2025-02-05 10:05:23 +08:00
78046e8707 支付 测试 2025-02-04 15:29:22 +08:00
shahaibo
9fb8bc989d Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-04 14:29:32 +08:00
shahaibo
3c89670dae BUGFIX:design重复回退; 2025-02-04 14:29:22 +08:00
21b73d55f7 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-02-04 14:04:17 +08:00
9199cdf7e2 支付 to prod 2025-02-04 14:04:01 +08:00
shahaibo
8589216a77 TASK:绑定邮箱; 2025-02-04 13:53:50 +08:00
shahaibo
87768c6b53 TASK:绑定邮箱、绑定微信; 2025-02-04 11:39:42 +08:00
shahaibo
ca320f4334 TASK:测试dev分支; 2025-02-04 11:00:31 +08:00
shahaibo
7697ab59fa BUGFIX:重复停止组装; 2025-02-04 10:58:35 +08:00
e5e6f360dc Merge branch 'dev/dev_xp' into dev/dev 2025-01-27 16:39:54 +08:00
68a9462714 交易记录下载 返回文件流改为返回文件下载地址 2025-01-27 16:39:19 +08:00
b185a94fcc Merge branch 'dev/dev_xp' into dev/dev 2025-01-27 11:00:10 +08:00
708280ca14 交易记录下载post请求改get请求 2025-01-27 10:58:35 +08:00
0ab1e7eef7 Merge branch 'dev/dev_xp' into dev/dev 2025-01-24 15:50:15 +08:00
c7b1d46b18 maven 依赖冲突解决 2025-01-24 15:49:34 +08:00
9357a62f0c Merge branch 'dev/dev_xp' into dev/dev 2025-01-24 14:28:54 +08:00
c5b25e9a16 优化 删除多余代码 2025-01-24 14:28:21 +08:00
a35d057146 优化 导出交易记录文件 2025-01-24 14:25:32 +08:00
7fc495eec9 Merge branch 'dev/dev_xp' into dev/dev 2025-01-24 13:27:50 +08:00
46f37942d2 将交易记录导出为excel文件 2025-01-24 13:26:53 +08:00
e75196c904 Merge branch 'dev/dev_xp' into dev/dev 2025-01-23 14:15:38 +08:00
bdfa249c2e token过期 日志打印优化 2025-01-23 14:15:12 +08:00
d0e5f7da61 Merge branch 'dev/dev_xp' into dev/dev 2025-01-23 13:57:26 +08:00
d8320ba83d 新增自定义异常 2025-01-23 13:56:48 +08:00
23460800d6 优化请求未携带token时的日志打印 2025-01-23 13:55:48 +08:00
58c8b644bc 佣金计算 打印日志 2025-01-22 16:41:40 +08:00
c4c04aecb6 affiliateIncome 添加字段paymentInfoId 2025-01-22 16:37:40 +08:00
bb7c98c094 affiliate 佣金计算统计 2025-01-22 15:32:09 +08:00
dcdb0d06c4 Merge branch 'dev/dev_xp' into dev/dev 2025-01-15 10:49:08 +08:00
b6a66bed41 查询交易记录 添加付款人字段 2025-01-15 10:45:51 +08:00
shahaibo
5f277ed815 BUGFIX:toproductimage 打光积分不足提示修改; 2025-01-13 15:12:54 +08:00
shahaibo
845a553097 BUGFIX:微信名解析、toproductimage 打光积分不足code码修改; 2025-01-13 14:11:03 +08:00
74f89c8b2d 只填写国家和职业(不发送验证码) 2025-01-13 11:15:31 +08:00
cff8227228 Merge branch 'dev/dev_xp' into dev/dev 2025-01-13 11:13:31 +08:00
51e2c9af02 只填写国家和职业(不发送验证码) 2025-01-13 11:11:01 +08:00
cd89a77189 漏传 2025-01-13 10:56:06 +08:00
ab303cfeef 绑定邮箱时添加国家、职业信息 2025-01-13 10:55:08 +08:00
shahaibo
07004a7415 TASK:去日志; 2025-01-13 10:20:14 +08:00
shahaibo
d2069a3e7f TASK:去日志; 2025-01-13 10:12:04 +08:00
shahaibo
501cee0057 TASK:去日志; 2025-01-13 10:05:38 +08:00
ac2454fd0e 绑定邮箱时添加国家、职业信息 2025-01-10 17:16:08 +08:00
931a4cf807 to dev 2025-01-10 17:01:59 +08:00
cb7099264e 绑定邮箱时需要填写国家和职业 2025-01-10 16:54:44 +08:00
e7aa951e89 漏传 2025-01-10 16:19:53 +08:00
ef70598180 修改查询交易记录接口
1、添加按id排序
2、添加查询所有国家
3、添加接口,更新用户国家、职业信息
2025-01-10 16:13:45 +08:00
698fca8787 查询各平台交易记录 2025-01-10 13:27:27 +08:00
2f86090f21 Merge branch 'dev/dev' into dev/dev_xp 2025-01-10 13:05:26 +08:00
2988a3b34e 修改code-create数据库 sql语句修改 2025-01-09 13:50:08 +08:00
shahaibo
4fe5f65867 TASK:AiDA design like sort 2025-01-08 16:56:02 +08:00
shahaibo
4bb1953d4a Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-01-08 15:39:32 +08:00
shahaibo
57a8260f03 TASK:AiDA design like sort 2025-01-08 15:38:29 +08:00
e4936a23bc 编辑用户名,改为当前月允许修改5次 2025-01-08 14:20:12 +08:00
9f37cb3f8d Merge branch 'release/3.0' into dev/dev
# Conflicts:
#	src/main/java/com/ai/da/controller/ConvenientInquiryController.java
#	src/main/java/com/ai/da/model/dto/DesignCollectionDTO.java
#	src/main/java/com/ai/da/service/impl/DesignServiceImpl.java
2025-01-08 10:33:49 +08:00
b128b2436d 限制人员添加用户 2025-01-08 10:24:51 +08:00
66158e94dd 限制人员添加用户 2025-01-08 10:12:43 +08:00
f6b489d950 添加管理员页面访问者 2025-01-08 09:50:13 +08:00
30312caf82 添加管理员访问者 2025-01-07 17:27:29 +08:00
1d0dd65f5e Merge branch 'dev/dev_xp' into dev/dev 2025-01-07 17:21:54 +08:00
shahaibo
0b245f62af TASK:AiDA design like sort、moodboardPosition 2025-01-07 17:16:45 +08:00
50d90af3a5 添加管理员访问者 2025-01-07 17:15:22 +08:00
shahaibo
49b8585522 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-01-07 15:30:33 +08:00
shahaibo
b49f098a5e TASK:AiDA design like sort、moodboardPosition 2025-01-07 15:29:46 +08:00
e9a15b950e Merge branch 'dev/dev_xp' into dev/dev 2025-01-07 14:37:28 +08:00
ee676614f8 统一多种支付方式创建订单的入参 2025-01-07 14:31:43 +08:00
710abf2323 修改积分价格,for test 2025-01-07 11:47:33 +08:00
1a9f06d259 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-01-07 11:26:16 +08:00
shahaibo
eaaa99a946 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-01-07 11:16:14 +08:00
shahaibo
c8e4d624b7 TASK:AiDA design like sort 2025-01-07 11:15:25 +08:00
f08e36d100 Merge branch 'dev/dev_xp' into dev/dev 2025-01-07 11:12:30 +08:00
de73536d1c 解析所有发起购买的客户端ip地址 2025-01-07 11:09:22 +08:00
6a861305d6 解析所有发起购买的客户端ip地址 2025-01-07 11:07:49 +08:00
shahaibo
367fa130c0 BUGFIX:moodboard edit; 2025-01-07 10:58:57 +08:00
shahaibo
d04987a3e2 BUGFIX:moodboard edit; 2025-01-07 09:58:36 +08:00
b0fa185d36 更改积分刷新task 2025-01-06 14:58:46 +08:00
094718e67f Merge branch 'dev/dev_xp' into dev/dev 2025-01-06 14:47:40 +08:00
e4a8bf80e9 1、用户详细信息添加国家、职业、用户名修改剩余次数
2、积分不够 返回异常提示类型更改
3、添加根据ip解析地理位置测试接口
4、更新积分刷新机制(每月1号0点刷新年费用户积分)
2025-01-06 14:42:08 +08:00
shahaibo
c04b102a81 TASK:AiDA design like sort 2025-01-06 11:49:47 +08:00
shahaibo
da9b3a04b4 TASK:AiDA design like sort 2025-01-06 11:35:54 +08:00
shahaibo
234a030801 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2025-01-06 10:49:39 +08:00
shahaibo
5ea8e851d7 TASK:AiDA design like sort 2025-01-06 10:46:51 +08:00
shahaibo
afeeef4af7 TASK:试用订单接收名单添加; 2025-01-04 21:35:21 +08:00
ee1e2f8556 获取所有标签 2025-01-02 17:32:49 +08:00
1157b41730 积分购买 添加邮件通知 2024-12-31 11:38:12 +08:00
ca4d75c63f BUGFIX:用户订阅后更新用户身份和积分 2024-12-27 14:29:07 +08:00
f45bd7acc4 develop 环境webhook_secret变更 2024-12-27 10:46:52 +08:00
7bdd62d4a9 Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2024-12-27 10:32:09 +08:00
b01ee9129b develop 环境webhook_secret变更 2024-12-27 10:31:27 +08:00
shahaibo
214c93923c Merge remote-tracking branch 'origin/dev/dev' into dev/dev 2024-12-24 14:01:34 +08:00
shahaibo
bfa1d67b5c BUGFIX:Collection not found 2024-12-24 14:00:44 +08:00
a0a1a1a06a Merge branch 'dev/dev_xp' into dev/dev 2024-12-23 17:31:53 +08:00
468ad385d7 用户登录时,不校验游客账号有效期 2024-12-23 17:29:48 +08:00
fa94667c0f 游客到期时间不置空 2024-12-23 16:07:05 +08:00
c997fbf1cb Merge branch 'dev/dev_xp' into dev/dev 2024-12-23 14:35:29 +08:00
7283ace072 getAffiliateList 添加返回用户名 2024-12-23 14:31:48 +08:00
shahaibo
69743d4ef0 BUGFIX:谷歌快捷登录 2024-12-23 10:27:01 +08:00
shahaibo
e033671ffb TASK:AiDA 2024-12-20 16:11:52 +08:00
shahaibo
15cde37af7 TASK:AiDA 2024-12-20 11:44:21 +08:00
shahaibo
7fb74bc7d8 TASK:AiDA 2024-12-19 17:52:14 +08:00
43968995ea generate去除额外prompt 2024-12-19 17:37:28 +08:00
0574180e4b generate去除额外prompt 2024-12-19 17:26:16 +08:00
5b653272ee 覆盖代码恢复-获取个人信息 2024-12-19 17:15:55 +08:00
d28a6051f1 Merge branch 'release/3.0' into dev/dev 2024-12-19 16:02:59 +08:00
f9063ad26e generate print翻译输入修改 2024-12-19 16:01:35 +08:00
2f4d060ca3 generate print翻译输入修改 2024-12-19 15:59:18 +08:00
fcd0cf4836 Merge branch 'release/3.0' into dev/dev 2024-12-19 15:32:10 +08:00
26f50c2acb generate print翻译输入修改 2024-12-19 15:26:27 +08:00
c3eb1fc78c Merge branch 'dev/dev_xp' into dev/dev 2024-12-19 14:04:28 +08:00
b15cc542e1 按id查询订单 2024-12-19 13:56:17 +08:00
shahaibo
ec094d7471 TASK:AiDA 2024-12-19 13:31:01 +08:00
shahaibo
3dc432131c TASK:AiDA 2024-12-19 11:13:30 +08:00
shahaibo
1a19604163 TASK:AiDA 2024-12-19 10:51:38 +08:00
fdebb2b215 Merge branch 'dev/dev_xp' into dev/dev
# Conflicts:
#	src/main/java/com/ai/da/model/vo/AccountLoginVO.java
#	src/main/java/com/ai/da/service/impl/AccountServiceImpl.java
2024-12-18 14:02:06 +08:00
7d8f047087 Affiliate功能-数据库表设计更新 2024-12-18 11:53:41 +08:00
bf8af41f3f 添加Affiliate功能 2024-12-16 10:26:02 +08:00
shahaibo
cdf29d2b0d TASK:AiDA 2024-12-13 16:07:21 +08:00
shahaibo
7194049127 TASK:prompt修改; 2024-12-13 11:32:42 +08:00
shahaibo
e34cec812f Merge remote-tracking branch 'origin/release/3.0' into release/3.0 2024-12-13 10:35:17 +08:00
shahaibo
11a5b53d2a BUGFIX:prompt重复拼接; 2024-12-13 10:34:14 +08:00
efe22de0a0 Merge branch 'refs/heads/dev/dev' into dev/dev_xp
# Conflicts:
#	src/main/java/com/ai/da/common/utils/SendEmailUtil.java
#	src/main/java/com/ai/da/mapper/primary/entity/Account.java
2024-12-11 16:52:16 +08:00
shahaibo
82f7571612 TASK:AiDA 2024-12-11 16:21:18 +08:00
shahaibo
2ac54a50ec TASK:AiDA 2024-12-11 14:21:29 +08:00
5dd1e10b61 to dev 2024-12-10 10:09:21 +08:00
e9e8e87719 Merge branch 'release/3.0' into dev/dev 2024-12-10 10:04:27 +08:00
3c0fa205d1 BUGFIX:code-create注册的新用户自动添加为aida的游客,去重bug修改 2024-12-09 18:17:09 +08:00
47ca7bde41 Affiliate-新增、查询、佣金计算等 2024-12-09 16:53:29 +08:00
shahaibo
1a568621ca BUGFIX:重复申请试用; 2024-12-03 11:51:01 +08:00
eecefee674 Merge branch 'dev/dev' into release/3.0 2024-12-02 14:54:00 +08:00
徐佩
f7113601f3 Merge branch 'dev/dev' into release/3.0 2024-12-01 20:27:58 +08:00
徐佩
23b864d378 to prod 2024-12-01 17:37:52 +08:00
1b15aed6a2 支付优化-续订失败邮件通知 2024-11-28 10:43:06 +08:00
5019fbd3fc 支付优化 2024-11-25 10:53:09 +08:00
2ea19dcf03 Merge branch 'refs/heads/dev/dev' into dev/dev_xp 2024-11-19 17:09:36 +08:00
4d756d5624 支付优化 2024-11-19 17:08:16 +08:00
f6f759110f 支付优化--修改积分购买相应功能 2024-11-19 16:00:30 +08:00
8d27b5b51e 新增功能 -- 产品订阅 年度/月度 2024-11-18 16:20:25 +08:00
142 changed files with 8290 additions and 1937 deletions

View File

@@ -151,9 +151,15 @@
<version>3.0.3</version> <version>3.0.3</version>
</dependency> </dependency>
<!-- /**发送邮件**/--> <!-- /**发送邮件**/-->
<!-- <dependency>-->
<!-- <groupId>com.tencentcloudapi</groupId>-->
<!-- <artifactId>tencentcloud-sdk-java-ses</artifactId>-->
<!-- <version>3.1.572</version>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>com.tencentcloudapi</groupId> <groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java-ses</artifactId> <artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.572</version> <version>3.1.572</version>
</dependency> </dependency>

View File

@@ -6,6 +6,7 @@ import com.ai.da.common.utils.RedisUtil;
import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.dto.GenerateThroughImageTextDTO;
import com.ai.da.model.vo.GenerateResultVO; import com.ai.da.model.vo.GenerateResultVO;
import com.ai.da.service.GenerateService; import com.ai.da.service.GenerateService;
import com.ai.da.service.UserLikeGroupService;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
@@ -17,6 +18,7 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
@@ -31,6 +33,9 @@ public class GenerateConsumer {
@Resource @Resource
private GenerateService generateService; private GenerateService generateService;
@Resource
private UserLikeGroupService userLikeGroupService;
@Autowired @Autowired
private RabbitMQProperties rabbitMQProperties; private RabbitMQProperties rabbitMQProperties;
@@ -167,6 +172,9 @@ public class GenerateConsumer {
String taskId = generateResult.get("tasks_id"); String taskId = generateResult.get("tasks_id");
String category = generateResult.get("category"); String category = generateResult.get("category");
generateService.processToProductImageResult(taskId, url, category); generateService.processToProductImageResult(taskId, url, category);
} else if (generateResult.get("status").equals("NO_FACE")) {
String taskId = generateResult.get("tasks_id");
userLikeGroupService.toProduct(taskId);
} else { } else {
// 修改redis中的数据状态为exception // 修改redis中的数据状态为exception
String key = toProductImageResultKey + ":" + generateResult.get("tasks_id"); String key = toProductImageResultKey + ":" + generateResult.get("tasks_id");
@@ -214,6 +222,9 @@ public class GenerateConsumer {
String taskId = generateResult.get("tasks_id"); String taskId = generateResult.get("tasks_id");
String category = generateResult.get("category"); String category = generateResult.get("category");
generateService.processRelightResult(taskId, url, category); generateService.processRelightResult(taskId, url, category);
} else if (generateResult.get("status").equals("NO_FACE")) {
String taskId = generateResult.get("tasks_id");
userLikeGroupService.relight(taskId);
} else { } else {
// 修改redis中的数据状态为exception // 修改redis中的数据状态为exception
String key = relightResultKey + ":" + generateResult.get("tasks_id"); String key = relightResultKey + ":" + generateResult.get("tasks_id");

View File

@@ -9,6 +9,7 @@ import com.ai.da.mapper.secondary.AttributeRetrievalMapper;
import com.ai.da.model.enums.StyleEnum; import com.ai.da.model.enums.StyleEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
@@ -41,6 +42,7 @@ public class MyTaskScheduler {
public void test() { public void test() {
// clearMinio(); // clearMinio();
// addSystemFileStyle(); // addSystemFileStyle();
// sendTrialOrderExcelToManagements();
} }
@Resource @Resource
@@ -51,7 +53,7 @@ public class MyTaskScheduler {
// 定时任务,每十五天执行一次 // 定时任务,每十五天执行一次
// @Scheduled(cron = "0 0 0 ? * MON") // @Scheduled(cron = "0 0 0 ? * MON")
// @Scheduled(cron = "0 0 0 */15 * ?") @Scheduled(cron = "0 0 0 */15 * ?")
public void checkExpiry() { public void checkExpiry() {
// 检测正式用户是否快要过期 // 检测正式用户是否快要过期
QueryWrapper<Account> qw = new QueryWrapper<>(); QueryWrapper<Account> qw = new QueryWrapper<>();
@@ -85,10 +87,11 @@ public class MyTaskScheduler {
} }
} }
} }
// @Scheduled(cron = "0 0 9 * * ?") @Scheduled(cron = "0 0 9 * * ?")
public void sendTrialOrderExcelToManagements() { public void sendTrialOrderExcelToManagements() {
// 获取前一天日期 // 获取前一天日期
LocalDate yesterday = LocalDate.now().minusDays(1); LocalDate yesterday = LocalDate.now().minusDays(1);
// LocalDate before = LocalDate.now().minusDays(4);
// 查询前一天的试用订单 // 查询前一天的试用订单
QueryWrapper<TrialOrder> qw = new QueryWrapper<>(); QueryWrapper<TrialOrder> qw = new QueryWrapper<>();
@@ -128,7 +131,9 @@ public class MyTaskScheduler {
row.createCell(6).setCellValue(trialOrder.getCountry()); row.createCell(6).setCellValue(trialOrder.getCountry());
row.createCell(7).setCellValue(trialOrder.getOccupation()); row.createCell(7).setCellValue(trialOrder.getOccupation());
row.createCell(8).setCellValue(trialOrder.getCreateTime().format(formatter)); row.createCell(8).setCellValue(trialOrder.getCreateTime().format(formatter));
row.createCell(9).setCellValue(trialOrder.getUpdateTime().format(formatter)); if (!ObjectUtils.isEmpty(trialOrder.getUpdateTime())) {
row.createCell(9).setCellValue(trialOrder.getUpdateTime().format(formatter));
}
row.createCell(10).setCellValue(trialOrder.getStatus()); row.createCell(10).setCellValue(trialOrder.getStatus());
} }
@@ -136,19 +141,27 @@ public class MyTaskScheduler {
String fileName = "trialOrder-" + yesterday.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx"; String fileName = "trialOrder-" + yesterday.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xlsx";
try (FileOutputStream fileOut = new FileOutputStream(fileName)) { try (FileOutputStream fileOut = new FileOutputStream(fileName)) {
workbook.write(fileOut); workbook.write(fileOut);
SendEmailUtil.sendExcelEmail("1023316923@qq.com", null, Files.readAllBytes(Paths.get(fileName)), fileName); // SendEmailUtil.sendExcelEmail("1023316923@qq.com", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("calvinwong@aidlab.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName); SendEmailUtil.sendExcelEmail("calvinwong@aidlab.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("kaicpang.pang@connect.polyu.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName); SendEmailUtil.sendExcelEmail("kaicpang.pang@connect.polyu.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("kimwong@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName); SendEmailUtil.sendExcelEmail("kimwong@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
// SendEmailUtil.sendExcelEmail("ningning@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("johnnyho@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("ringolau@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
SendEmailUtil.sendExcelEmail("chelseayu@code-create.com.hk", null, Files.readAllBytes(Paths.get(fileName)), fileName);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
}else { }else {
SendEmailUtil.sendNoExcelEmail("1023316923@qq.com", null); // SendEmailUtil.sendNoExcelEmail("1023316923@qq.com", null);
SendEmailUtil.sendNoExcelEmail("calvinwong@aidlab.hk", null); SendEmailUtil.sendNoExcelEmail("calvinwong@aidlab.hk", null);
SendEmailUtil.sendNoExcelEmail("kaicpang.pang@connect.polyu.hk", null); SendEmailUtil.sendNoExcelEmail("kaicpang.pang@connect.polyu.hk", null);
SendEmailUtil.sendNoExcelEmail("kimwong@code-create.com.hk", null); SendEmailUtil.sendNoExcelEmail("kimwong@code-create.com.hk", null);
// SendEmailUtil.sendNoExcelEmail("ningning@code-create.com.hk", null);
SendEmailUtil.sendNoExcelEmail("johnnyho@code-create.com.hk", null);
SendEmailUtil.sendNoExcelEmail("ringolau@code-create.com.hk", null);
SendEmailUtil.sendNoExcelEmail("chelseayu@code-create.com.hk", null);
} }
} }

View File

@@ -0,0 +1,12 @@
package com.ai.da.common.config.exception;
public class TokenMissingOrExpiredException extends RuntimeException {
public TokenMissingOrExpiredException(String message) {
super(message);
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}

View File

@@ -13,6 +13,8 @@ public class CommonConstant {
public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60; public static final Integer MINIO_IMAGE_EXPIRE_TIME = 24 * 60;
// 单位 秒 一天过期 in redis // 单位 秒 一天过期 in redis
public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L; public static final Long GENERATE_RESULT_EXPIRE_TIME = 24 * 60 * 60L;
// 单位 秒 7天过期
public static final Long REDIS_SET_EXPIRE_TIME = 24 * 60 * 60 * 7L;
public static class Numbers{ public static class Numbers{
public static final Integer NUMBER_10 = 10; public static final Integer NUMBER_10 = 10;
@@ -75,5 +77,11 @@ public class CommonConstant {
public static final String PORTFOLIO_DELETED_CN = "作品已删除"; public static final String PORTFOLIO_DELETED_CN = "作品已删除";
public static final String TIME_FORMAT_MMM_dd_yyyy_EEEE = "MMM. dd, yyyy, EEEE";
public static final String TIME_FORMAT_MMM_dd_yyyy = "MMM. dd, yyyy";
public static final String TIME_FORMAT_yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
public static final String AFFILIATE_LINK = "https://www.aida.com.hk?ref=";
} }

View File

@@ -27,7 +27,13 @@ public enum AuthenticationOperationTypeEnum {
/** /**
* 更改邮箱 * 更改邮箱
*/ */
CHANGE_MAILBOX; CHANGE_MAILBOX,
/**
* 填写用户国家和职业
*/
UPDATE_USERINFO,
REGISTER;
public static AuthenticationOperationTypeEnum of(String name) { public static AuthenticationOperationTypeEnum of(String name) {
return Stream.of(AuthenticationOperationTypeEnum.values()).filter(v -> v.name().equals(name)).findFirst().orElse(null); return Stream.of(AuthenticationOperationTypeEnum.values()).filter(v -> v.name().equals(name)).findFirst().orElse(null);

View File

@@ -8,9 +8,11 @@ import lombok.Getter;
public enum CreditsEventsEnum { public enum CreditsEventsEnum {
PRICE("price","6"), PRICE("price","6"),
// PRICE("price","1"),// for test
// PRICE("price","0.1"), // PRICE("price","0.1"),
BUY_CREDITS("Buy Credits","60"), BUY_CREDITS("Buy Credits","60"),
// BUY_CREDITS("Buy Credits","10"),// for test
REFUND("Refund","60"), REFUND("Refund","60"),
// BUY_CREDITS("Buy Credits","10"), // BUY_CREDITS("Buy Credits","10"),
@@ -20,6 +22,7 @@ public enum CreditsEventsEnum {
INIT_MONTHLY("init_monthly", "5000"), INIT_MONTHLY("init_monthly", "5000"),
INIT_TRIAL("init_trial", "100"), INIT_TRIAL("init_trial", "100"),
INIT_WEEKLY("init_weekly","6000"), INIT_WEEKLY("init_weekly","6000"),
RESET_YEAR_CREDITS("reset_year_credits","6000"),
// SUPER_RESOLUTION("Super Resolution","30"), // SUPER_RESOLUTION("Super Resolution","30"),
SUPER_RESOLUTION("Super Resolution","10"), SUPER_RESOLUTION("Super Resolution","10"),

View File

@@ -10,38 +10,34 @@ public enum OrderStatusEnum {
* 未支付 * 未支付
*/ */
NOT_PAY("未支付"), NOT_PAY("未支付"),
/** /**
* 支付成功 * 支付成功
*/ */
SUCCESS("支付成功"), SUCCESS("支付成功"),
/**
* 支付失败
*/
FAILURE("支付失败"),
/** /**
* 已关闭 * 已关闭
*/ */
TIMEOUT_CLOSED("超时已关闭"), TIMEOUT_CLOSED("超时已关闭"),
/** /**
* 已取消 * 已取消
*/ */
CANCEL("用户已取消"), CANCEL("用户已取消"),
/** /**
* 退款中 * 退款中
*/ */
REFUND_PROCESSING("退款中"), REFUND_PROCESSING("退款中"),
/** /**
* 已退款 * 已退款
*/ */
REFUND_SUCCESS("已退款"), REFUND_SUCCESS("已退款"),
/** /**
* 退款异常 * 退款异常
*/ */
REFUND_ABNORMAL("退款异常"), REFUND_ABNORMAL("退款异常"),
/** /**
* paypal订单状态为 APPROVED * paypal订单状态为 APPROVED
*/ */

View File

@@ -0,0 +1,25 @@
package com.ai.da.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ProductEnum {
// 积分购买
CreditsProduct("AiDA credits purchase", 6L),
// 年度订阅
AnnualSubscription("AiDA Annual Subscription", 5000L),
// 月度订阅
MonthlySubscription("AiDA Monthly Subscription", 500L),
// 测试
DailySubscription("AiDA Daily Subscription", 10L),
;
/**
* 类型
*/
private final String name;
private final Long price;
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.common.response;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@NoArgsConstructor
@ApiModel("交易记录分页响应结果")
public class TransactionPageResponse<T> extends PageBaseResponse<T> {
private BigDecimal totalAmount;
}

View File

@@ -1,6 +1,7 @@
package com.ai.da.common.security.filter; package com.ai.da.common.security.filter;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.ai.da.common.config.exception.TokenMissingOrExpiredException;
import com.ai.da.common.context.UserContext; import com.ai.da.common.context.UserContext;
import com.ai.da.common.security.config.SecurityProperties; import com.ai.da.common.security.config.SecurityProperties;
import com.ai.da.common.security.jwt.JWTTokenHelper; import com.ai.da.common.security.jwt.JWTTokenHelper;
@@ -101,7 +102,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
if (StrUtil.isBlank(jwtToken)) { if (StrUtil.isBlank(jwtToken)) {
String ipAddress = RequestInfoUtil.getIpAddress(request); String ipAddress = RequestInfoUtil.getIpAddress(request);
log.info("本次请求的ip为 " + ipAddress); log.info("本次请求的ip为 " + ipAddress);
throw new RuntimeException("请传入token"); // throw new RuntimeException("请传入token");
throw new TokenMissingOrExpiredException("请传入token");
} }
if(jwtToken.equals("Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA")){ if(jwtToken.equals("Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA")){
//写死 暂时放行 //写死 暂时放行
@@ -112,7 +114,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
if (validate) { if (validate) {
AuthPrincipalVo principal = jwtTokenHelper.parserToUser(jwtToken); AuthPrincipalVo principal = jwtTokenHelper.parserToUser(jwtToken);
if (principal == null) { if (principal == null) {
throw new RuntimeException("TOKEN已过期请重新登录"); // throw new RuntimeException("TOKEN已过期请重新登录");
throw new TokenMissingOrExpiredException("TOKEN已过期请重新登录(token without userInfo)");
} }
//先清空当前线程变量,防止上一个线程遗留 //先清空当前线程变量,防止上一个线程遗留
UserContext.delete(); UserContext.delete();
@@ -122,10 +125,12 @@ public class AuthenticationFilter extends OncePerRequestFilter {
String cacheToken = LocalCacheUtils.getTokenCache(String.valueOf(principal.getId())); String cacheToken = LocalCacheUtils.getTokenCache(String.valueOf(principal.getId()));
if(StringUtils.isEmpty(cacheToken)){ if(StringUtils.isEmpty(cacheToken)){
throw new RuntimeException("TOKEN已过期请重新登录"); // throw new RuntimeException("TOKEN已过期请重新登录");
throw new TokenMissingOrExpiredException("TOKEN已过期请重新登录(local cache empty)");
} }
if(!cacheToken.equals(jwtToken) ){ if(!cacheToken.equals(jwtToken) ){
throw new RuntimeException("TOKEN已过期请重新登录"); // throw new RuntimeException("TOKEN已过期请重新登录");
throw new TokenMissingOrExpiredException("TOKEN已过期请重新登录(token not match local cache)");
} }
// UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(null, null); // UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(null, null);
// SecurityContextHolder.getContext().setAuthentication(authentication); // SecurityContextHolder.getContext().setAuthentication(authentication);

View File

@@ -1,5 +1,6 @@
package com.ai.da.common.task; package com.ai.da.common.task;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.service.AccountService; import com.ai.da.service.AccountService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -15,25 +16,29 @@ public class AccountTask {
@Resource @Resource
private AccountService accountService; private AccountService accountService;
@Resource
private RedisUtil redisUtil;
/** /**
* 每周日晚上刷新 年付用户、月付用户的积分 * 每周日晚上刷新 年付用户、月付用户的积分
* 替换为
* 每个月月初只刷新年付用户的积分
*/ */
@Scheduled(cron = "59 59 23 ? * SUN")
// @Scheduled(cron = "59 59 23 * * ?") // @Scheduled(cron = "59 59 23 * * ?")
@Scheduled(cron = "0 0 0 1 * ?")
public void refreshCreditsMonthly() { public void refreshCreditsMonthly() {
log.info("周日晚115959刷新付费用户积分为 6000"); log.info("月1号0点 将年费用户积分重置为 6000");
accountService.refreshCreditsWeekly(); accountService.refreshCreditsWeekly();
} }
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void getPaidUser() { public void getPaidUser() {
// 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单 // 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单
accountService.extendValidityForCC(); accountService.extendValidityForCC();
} }
// 每天凌晨0点执行一次 // 每天凌晨0点执行一次
// @Scheduled(cron = "0 0 0 * * ?") @Scheduled(cron = "0 0 0 * * ?")
public void cancelActivityBenefits() { public void cancelActivityBenefits() {
// 1、查询当前所有参与了活动且过期的用户 // 1、查询当前所有参与了活动且过期的用户
List<Account> accountList = accountService.getExpiredUserBySystemUser(4); List<Account> accountList = accountService.getExpiredUserBySystemUser(4);
@@ -46,7 +51,7 @@ public class AccountTask {
} }
// 每天检测正式用户到期情况每天凌晨0点执行 // 每天检测正式用户到期情况每天凌晨0点执行
// @Scheduled(cron = "0 0 0 * * ?") @Scheduled(cron = "0 0 0 * * ?")
public void paidUserToVisitor() { public void paidUserToVisitor() {
// 1、查询当前已过期正式用户或试用用户 // 1、查询当前已过期正式用户或试用用户
List<Account> accountList = accountService.getExpiredUserBySystemUser(1); List<Account> accountList = accountService.getExpiredUserBySystemUser(1);
@@ -61,10 +66,18 @@ public class AccountTask {
} }
/** /**
* 关闭此定时器不再从Code-Create上默认创建AiDA游客
* 将Code-Create上注册的用户添加为AiDA的游客 * 将Code-Create上注册的用户添加为AiDA的游客
*/ */
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes // @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void registerUserToVisitor() { public void registerUserToVisitor() {
accountService.registerUserToVisitor(); accountService.registerUserToVisitor();
} }
@Scheduled(cron = "0 0 0 1 * ?")
// 每月初刷新所有用户用户名剩余修改次数
public void resetUsernameModifyTimes(){
log.info("重置所有用户的用户名修改次数");
redisUtil.batchDeleteKeysWithSamePrefix(RedisUtil.NICKNAME_MODIFY_TIMES);
}
} }

View File

@@ -1,42 +0,0 @@
package com.ai.da.common.task;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.common.enums.PayTypeEnum;
import com.ai.da.service.AliPayService;
import com.ai.da.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Component
public class AliPayTask {
@Resource
private OrderInfoService orderInfoService;
@Resource
private AliPayService aliPayService;
/**
* 从第0秒开始每隔30秒执行1次查询创建超过5分钟并且未支付的订单
*/
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirm(){
// log.info("Alipay orderConfirm 被执行......");
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(5, PayTypeEnum.ALIPAY.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
aliPayService.checkOrderStatus(orderNo);
}
}
}

View File

@@ -1,21 +0,0 @@
package com.ai.da.common.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class GenerateTask {
// @Scheduled(cron = "0 0 */1 * * ?")
public void generateScheduled(){
log.info("测试定时器generate");
try{
}catch(Exception e){
}
}
}

View File

@@ -0,0 +1,123 @@
package com.ai.da.common.task;
import com.ai.da.common.enums.PayTypeEnum;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.service.*;
import com.paypal.http.exceptions.SerializeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
@Slf4j
@Component
public class PaymentTask {
@Resource
private OrderInfoService orderInfoService;
@Resource
private StripeService stripeService;
@Resource
private AffiliateService affiliateService;
// 考虑删除该定时任务(原因:之后的订单列允许用户查看发票,发票未过期时仍可以支付,所以不需要手动使订单过期)
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForStripe() throws SerializeException {
// 查看超过30分钟以上仍未支付的订单 置为超时订单
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.STRIPE.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
stripeService.checkOrderStatus(orderNo);
}
}
@Resource
private PayPalCheckoutService payPalCheckoutService;
@Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForPaypal() throws SerializeException {
// log.info("PayPal orderConfirm 被执行......");
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.PAYPAL.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
payPalCheckoutService.checkOrderStatus(orderNo);
}
}
@Resource
private AliPayService aliPayService;
/**
* 从第0秒开始每隔30秒执行1次查询创建超过5分钟并且未支付的订单
*/
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForAlipay(){
/*
log.info("Alipay orderConfirm 被执行......");
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(5, PayTypeEnum.ALIPAY.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
aliPayService.checkOrderStatus(orderNo);
}*/
}
// !!关闭此定时器,改为提前三天站内信提醒!!
// 提前7天向用户发送提醒邮件,每天早上8点执行
// @Scheduled(cron = "0 0 8 * * ?")
public void subscriptionReminder(){
stripeService.subscriptionReminder();
}
// 如果有订阅已创建,但是没有发邮件通知的,需要主动获取回调信息并向用户发送邮件
public void checkSubscriptionPayment(){
//
}
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void updateAffiliateInfoWithPayment(){
// log.info("佣金计算定时器");
affiliateService.updateAffiliateInfoWithPayment();
}
@Scheduled(cron = "0 0 8 28-31 * ?")
public void commissionSummaryReminder(){
// 每个月末的最后一天的早上八点执行
LocalDate today = LocalDate.now();
// 判断是否为月底
if (today.plusDays(1).getDayOfMonth() == 1) {
log.info("今天是月底,执行佣金结算提醒任务!");
affiliateService.commissionCalculation(null, null);
}
}
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void calcCouponsCommission(){
// log.info("优惠券佣金计算定时器");
affiliateService.calcCouponsCommission();
}
}

View File

@@ -1,42 +0,0 @@
package com.ai.da.common.task;
import com.ai.da.common.enums.PayTypeEnum;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.service.OrderInfoService;
import com.ai.da.service.PayPalCheckoutService;
import com.paypal.http.exceptions.SerializeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Component
public class PaypalTask {
@Resource
private OrderInfoService orderInfoService;
@Resource
private PayPalCheckoutService payPalCheckoutService;
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirm() throws SerializeException {
// log.info("PayPal orderConfirm 被执行......");
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.PAYPAL.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
payPalCheckoutService.checkOrderStatus(orderNo);
}
}
}

View File

@@ -1,40 +0,0 @@
package com.ai.da.common.task;
import com.ai.da.common.enums.PayTypeEnum;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.service.OrderInfoService;
import com.ai.da.service.StripeService;
import com.paypal.http.exceptions.SerializeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Component
public class StripeTask {
@Resource
private OrderInfoService orderInfoService;
@Resource
private StripeService stripeService;
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirm() throws SerializeException {
// 查看超过30分钟以上仍未支付的订单 置为超时订单
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.STRIPE.getType());
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用支付宝查单接口
stripeService.checkOrderStatus(orderNo);
}
}
}

View File

@@ -0,0 +1,88 @@
package com.ai.da.common.utils;
import java.util.HashMap;
import java.util.Map;
public class ComprehensivePunctuationConverter {
private static final Map<Character, Character> FULL_TO_HALF_MAP = new HashMap<>();
static {
// 中文标点到英文标点的映射(扩展版)
FULL_TO_HALF_MAP.put('', ',');
FULL_TO_HALF_MAP.put('。', '.');
FULL_TO_HALF_MAP.put('', ';');
FULL_TO_HALF_MAP.put('', ':');
FULL_TO_HALF_MAP.put('', '?');
FULL_TO_HALF_MAP.put('', '!');
FULL_TO_HALF_MAP.put('', '(');
FULL_TO_HALF_MAP.put('', ')');
FULL_TO_HALF_MAP.put('【', '[');
FULL_TO_HALF_MAP.put('】', ']');
FULL_TO_HALF_MAP.put('「', '\'');
FULL_TO_HALF_MAP.put('」', '\'');
FULL_TO_HALF_MAP.put('『', '"');
FULL_TO_HALF_MAP.put('』', '"');
FULL_TO_HALF_MAP.put('、', '\\');
FULL_TO_HALF_MAP.put('', '~');
FULL_TO_HALF_MAP.put('—', '-');
FULL_TO_HALF_MAP.put('', '.');
FULL_TO_HALF_MAP.put('〈', '<');
FULL_TO_HALF_MAP.put('〉', '>');
FULL_TO_HALF_MAP.put('《', '«');
FULL_TO_HALF_MAP.put('》', '»');
FULL_TO_HALF_MAP.put('〝', '"');
FULL_TO_HALF_MAP.put('〞', '"');
FULL_TO_HALF_MAP.put('﹁', '"');
FULL_TO_HALF_MAP.put('﹂', '"');
FULL_TO_HALF_MAP.put('…', '.');
FULL_TO_HALF_MAP.put('', '_');
// 全角字母和数字
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + 'A'));
}
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + 'a'));
}
for (char c = ''; c <= ''; c++) {
FULL_TO_HALF_MAP.put(c, (char)(c - '' + '0'));
}
}
/**
* 将字符串中的全角字符(包括标点、字母、数字)转换为半角字符
*/
public static String convertToHalfWidth(String input) {
if (input == null || input.isEmpty()) {
return input;
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
// 检查映射表
if (FULL_TO_HALF_MAP.containsKey(c)) {
result.append(FULL_TO_HALF_MAP.get(c));
}
// 处理全角空格Unicode 12288
else if (c == ' ') {
result.append(' ');
}
// 其他字符保持不变
else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
// String text = "这是一个全角示例,包含:中文标点、全角字母(ABC)、全角数字(123) 还有全角空格!";
String text = "birdsyellow";
String converted = convertToHalfWidth(text);
System.out.println("原始文本: " + text);
System.out.println("转换后: " + converted);
}
}

View File

@@ -1,5 +1,6 @@
package com.ai.da.common.utils; package com.ai.da.common.utils;
import com.ai.da.common.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.text.ParseException; import java.text.ParseException;
@@ -9,8 +10,8 @@ import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
@Slf4j @Slf4j
@@ -18,6 +19,8 @@ public class DateUtil {
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYYMM = "yyyyMM"; public static final String YYYYMM = "yyyyMM";
public static final String YYYY_MM_DD = "yyyyMMdd"; public static final String YYYY_MM_DD = "yyyyMMdd";
public static final String YYYY_MM_DD_HH = "yyyyMMddHH";
public static final String YYYY_MM_DD_hh_mm_ss = "yyyyMMddHHMMss";
/** /**
* LocalDate -> Date * LocalDate -> Date
@@ -81,4 +84,21 @@ public class DateUtil {
return String.valueOf(epochSecond).substring(0, 10); return String.valueOf(epochSecond).substring(0, 10);
} }
public static String changeTimeStampFormat(Long timeStamp, String type, String format){
// 将秒级时间戳转换为毫秒级
if (type.equals("seconds")){
timeStamp = timeStamp * 1000;
}
// 输出格式
SimpleDateFormat outputFormat = new SimpleDateFormat(format, Locale.ENGLISH);
// 创建Date对象
Date date = new Date(timeStamp);
// 格式化输出
return outputFormat.format(date);
}
public static String changeTimeStampFormat(LocalDateTime localDate){
return localDate.format(DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE, Locale.US));
}
} }

View File

@@ -28,7 +28,7 @@ public final class LocalCacheUtils {
private static LoadingCache<String, String> loadTokenCache() { private static LoadingCache<String, String> loadTokenCache() {
LoadingCache<String, String> tokenCache = CacheBuilder.newBuilder() LoadingCache<String, String> tokenCache = CacheBuilder.newBuilder()
.concurrencyLevel(10) .concurrencyLevel(10)
.expireAfterWrite(24 * 100, TimeUnit.HOURS) .expireAfterWrite(24 * (7 - 1), TimeUnit.HOURS)
.initialCapacity(100) .initialCapacity(100)
.maximumSize(10000) .maximumSize(10000)
.recordStats() .recordStats()

View File

@@ -14,13 +14,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.*;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -441,6 +440,16 @@ public class MinioUtil {
return getPreSignedUrl(bucketName, String.valueOf(fileName), expiry); return getPreSignedUrl(bucketName, String.valueOf(fileName), expiry);
} }
public boolean doesObjectExist(String path) {
if (!path.contains("/")) {
throw new BusinessException("the.path.is.error");
}
int index = path.indexOf("/");
String bucketName = path.substring(0, index);
String objectName = path.substring(index + 1);
return doesObjectExist(bucketName, objectName);
}
public boolean doesObjectExist(String bucketName, String objectName) { public boolean doesObjectExist(String bucketName, String objectName) {
try { try {
minioClient.statObject( minioClient.statObject(
@@ -535,6 +544,32 @@ public class MinioUtil {
int index = path.indexOf("/"); int index = path.indexOf("/");
return path.substring(index + 1); // 获取路径的其余部分作为对象名称 return path.substring(index + 1); // 获取路径的其余部分作为对象名称
} }
public List<Integer> getImagesWidthAndHeight(String path){
int index = path.indexOf("/");
String bucketName = path.substring(0, index);
String objectName = path.substring(index + 1);
try {
// 从 MinIO 下载图片
GetObjectResponse response = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build()
);
BufferedImage image = ImageIO.read(response);
int width = image.getWidth();
int height = image.getHeight();
log.info("Image path {}, Width: {}, Height: {}", path, width, height);
response.close();
return Arrays.asList(width, height);
} catch (MinioException | IOException | NoSuchAlgorithmException | InvalidKeyException e) {
log.error("图片:{}, 获取宽高异常", path);
throw new BusinessException(e.getMessage());
}
}
} }

View File

@@ -28,4 +28,70 @@ public class PantoneUtils {
return new int[]{Math.round(hsv[0]), Math.round(hsv[1] * 100), Math.round(hsv[2] * 100)}; return new int[]{Math.round(hsv[0]), Math.round(hsv[1] * 100), Math.round(hsv[2] * 100)};
} }
public static int[] hsvToRgb(int h, int s, int v) {
// 确保 h 在 [0, 360) 范围内
h = h % 360;
if (h < 0) {
h += 360;
}
// 确保 s 和 v 在 [0, 100] 范围内
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
// 将 s 和 v 映射到 [0, 1] 范围
float sNorm = s / 100.0f;
float vNorm = v / 100.0f;
// 计算色相所在的区间
int hi = (h / 60) % 6;
float f = (h / 60.0f) - hi;
float p = vNorm * (1 - sNorm);
float q = vNorm * (1 - f * sNorm);
float t = vNorm * (1 - (1 - f) * sNorm);
float r, g, b;
switch (hi) {
case 0:
r = vNorm;
g = t;
b = p;
break;
case 1:
r = q;
g = vNorm;
b = p;
break;
case 2:
r = p;
g = vNorm;
b = t;
break;
case 3:
r = p;
g = q;
b = vNorm;
break;
case 4:
r = t;
g = p;
b = vNorm;
break;
case 5:
r = vNorm;
g = p;
b = q;
break;
default:
throw new RuntimeException("Invalid HSV values");
}
// 将 RGB 值从 [0, 1] 转换为 [0, 255]
int red = Math.round(r * 255);
int green = Math.round(g * 255);
int blue = Math.round(b * 255);
return new int[]{red, green, blue};
}
} }

View File

@@ -84,8 +84,10 @@ public class RedisUtil {
/** /**
* 将数据放入set缓存 * 将数据放入set缓存
*/ */
public void addToSet(String key, String value) { public void addToSet(String key, String value, Long expiresIn) {
redisTemplate.opsForSet().add(key, value); redisTemplate.opsForSet().add(key, value);
// 设置过期时间
redisTemplate.expire(key, expiresIn, TimeUnit.SECONDS);
} }
/** /**
@@ -278,4 +280,29 @@ public class RedisUtil {
// 设置过期时间为 5 分钟300 秒) // 设置过期时间为 5 分钟300 秒)
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES); redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
} }
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";
public void increaseAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
redisTemplate.opsForValue().increment(key);
}
public Long getAffiliateLinkViewCount(Long accountId) {
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
return redisTemplate.opsForValue().increment(key, 0);
}
public void batchDeleteKeysWithSamePrefix(String prefix){
Set<String> keys = redisTemplate.keys(prefix + "*");
assert keys != null;
if (!keys.isEmpty()){
redisTemplate.delete(keys);
}
}
public final static String STRIPE_EXCEPTION_LOG = "StripeException:";
public final static String SUBSCRIPTION_SENT_EMAIL_TYPE = "SubscriptionEmailSentType:";
} }

View File

@@ -1,7 +1,16 @@
package com.ai.da.common.utils; package com.ai.da.common.utils;
import javax.servlet.http.HttpServletRequest; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
@Slf4j
public class RequestInfoUtil { public class RequestInfoUtil {
/** /**
@@ -45,4 +54,58 @@ public class RequestInfoUtil {
return ip; return ip;
} }
/**
* 免费 API 服务可能有请求频率限制,如果你需要处理大量 IP 地址,可能需要考虑使用付费服务或购买 IP 地理位置数据库。此外,始终要遵守 API 提供商的使用条款和隐私政策
* @param ip https://ip-api.com/docs/api:json 使用的接口api
* @return
* {
* "query": "24.48.0.1",
* "status": "success",
* "country": "Canada",
* "countryCode": "CA",
* "region": "QC",
* "regionName": "Quebec",
* "city": "Montreal",
* "zip": "H1L",
* "lat": 45.6026,
* "lon": -73.5167,
* "timezone": "America/Toronto",
* "isp": "Le Groupe Videotron Ltee",
* "org": "Videotron Ltee",
* "as": "AS5769 Videotron Ltee"
* }
*/
public static Map getIPLocation(String ip) {
// String ip = "117.143.125.1"; // 替换为你想查询的 IP 地址
// String ip = "194.5.48.180"; // 替换为你想查询的 IP 地址
String apiURL = "http://ip-api.com/json/" + ip;
try {
URL url = new URL(apiURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String output;
StringBuilder outputBuilder = new StringBuilder();
// System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
outputBuilder.append(output);
System.out.println(output);
}
conn.disconnect();
Map map = JSONObject.parseObject(outputBuilder.toString(), Map.class);
log.info("map: {}", map);
return map;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
} }

View File

@@ -2,8 +2,11 @@ package com.ai.da.common.utils;
import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.AffiliateEmailParamsDTO;
import com.ai.da.model.dto.SubscriptionEmailParamsDTO;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.config.exception.BusinessException;
import com.alibaba.fastjson2.JSON;
import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.ClientProfile;
@@ -70,7 +73,8 @@ public class SendEmailUtil {
/** /**
* 绑定邮箱模板id * 绑定邮箱模板id
*/ */
public static Long BIND_MAILBOX_TEMPLATE_ID = 45619L; // public static Long BIND_MAILBOX_TEMPLATE_ID = 45619L;
public static Long BIND_MAILBOX_TEMPLATE_ID = 132754L;
public static Long CHANGE_MAILBOX_TEMPLATE_ID = 128210L; public static Long CHANGE_MAILBOX_TEMPLATE_ID = 128210L;
@@ -175,7 +179,7 @@ public class SendEmailUtil {
subject = "Approval Confirmation for AiDA System Trial Access"; subject = "Approval Confirmation for AiDA System Trial Access";
if (country.equals("China")) { if (country.equals("China")) {
template.setTemplateID(NOTIFICATION_CHINESE_TEMPLATE_ID); template.setTemplateID(NOTIFICATION_CHINESE_TEMPLATE_ID);
}else { } else {
template.setTemplateID(NOTIFICATION_TEMPLATE_ID); template.setTemplateID(NOTIFICATION_TEMPLATE_ID);
} }
template.setTemplateData(buildNotificationData(trialOrder, link)); template.setTemplateData(buildNotificationData(trialOrder, link));
@@ -225,7 +229,7 @@ public class SendEmailUtil {
attachment.setFileName(fileName); // 设置附件文件名 attachment.setFileName(fileName); // 设置附件文件名
// 设置附件内容 // 设置附件内容
attachment.setContent(Base64.getEncoder().encodeToString(fileContent)); attachment.setContent(Base64.getEncoder().encodeToString(fileContent));
req.setAttachments(new Attachment[] {attachment}); req.setAttachments(new Attachment[]{attachment});
// 发送邮件 // 发送邮件
SendEmailResponse resp = client.SendEmail(req); SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp)); log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
@@ -268,7 +272,9 @@ public class SendEmailUtil {
throw new BusinessException("failed.to.send.mail"); throw new BusinessException("failed.to.send.mail");
} }
} }
private final static Long WILLBEEXPIRED_TEMPLATE_ID = 118178L; private final static Long WILLBEEXPIRED_TEMPLATE_ID = 118178L;
public static void sendWillBeExpiredEmail(Account account, String senderAddress) { public static void sendWillBeExpiredEmail(Account account, String senderAddress) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
@@ -360,7 +366,7 @@ public class SendEmailUtil {
jsonObject.put("email", trialOrder.getEmail()); jsonObject.put("email", trialOrder.getEmail());
if (link) { if (link) {
jsonObject.put("days", 14); jsonObject.put("days", 14);
}else { } else {
jsonObject.put("days", 5); jsonObject.put("days", 5);
} }
return jsonObject.toJSONString(); return jsonObject.toJSONString();
@@ -370,6 +376,7 @@ public class SendEmailUtil {
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID = 118856L; private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID = 118856L;
private final static Long UPGRADE_NOTIFICATION_ID_CHINESE = 122898L; private final static Long UPGRADE_NOTIFICATION_ID_CHINESE = 122898L;
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE = 122899L; private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE = 122899L;
public static void sendUpgradeNotification(Account account, String senderAddress, Integer type) { public static void sendUpgradeNotification(Account account, String senderAddress, Integer type) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
@@ -397,10 +404,10 @@ public class SendEmailUtil {
// template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE); // template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE);
// } // }
if (type == 1) { if (type == 1) {
subject = "Successful System Upgrade and New Features in AiDA 3.1"; subject = "Successful System Upgrade and New Features in AiDA 3.0";
template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID); template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID);
}else { }else {
subject = "系统升级成功和AiDA 3.1新功能"; subject = "系统升级成功和AiDA 3.0新功能";
template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE); template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE);
} }
template.setTemplateData(buildAccountData(account)); template.setTemplateData(buildAccountData(account));
@@ -410,15 +417,18 @@ public class SendEmailUtil {
// 发送邮件 // 发送邮件
SendEmailResponse resp = client.SendEmail(req); SendEmailResponse resp = client.SendEmail(req);
log.info(senderAddress);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp)); log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) { } catch (TencentCloudSDKException e) {
log.info(senderAddress);
log.info("邮件发送失败###{}", e.toString()); log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail"); throw new BusinessException("failed.to.send.mail");
} }
} }
private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L; private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L;
public static void sendGenerateExceptionWarning(String message){
public static void sendGenerateExceptionWarning(String message) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
Credential cred = new Credential(SECRET_ID, SECRET_KEy); Credential cred = new Credential(SECRET_ID, SECRET_KEy);
@@ -457,7 +467,8 @@ public class SendEmailUtil {
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L; private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L; private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
public static void questionnaireRelatedNotify(String userName, String email, String language){
public static void questionnaireRelatedNotify(String userName, String email, String language) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
Credential cred = new Credential(SECRET_ID, SECRET_KEy); Credential cred = new Credential(SECRET_ID, SECRET_KEy);
@@ -502,7 +513,7 @@ public class SendEmailUtil {
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_EN = 124892L; private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_EN = 124892L;
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_CN = 124891L; private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_CN = 124891L;
public static void notificationForPaidUser(String receiverAddress, int emailType, String country, String userName, String date){ public static void notificationForPaidUser(String receiverAddress, int emailType, String country, String userName, String date) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
Credential cred = new Credential(SECRET_ID, SECRET_KEy); Credential cred = new Credential(SECRET_ID, SECRET_KEy);
@@ -525,7 +536,7 @@ public class SendEmailUtil {
subject = "Welcome to AiDA!"; subject = "Welcome to AiDA!";
if (country.equals("China")) { if (country.equals("China")) {
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_CN); template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_CN);
}else { } else {
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_EN); template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_EN);
} }
parameter.put("userName", userName); parameter.put("userName", userName);
@@ -536,7 +547,7 @@ public class SendEmailUtil {
subject = "Account renewal notification"; subject = "Account renewal notification";
if (country.equals("China")) { if (country.equals("China")) {
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_CN); template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_CN);
}else { } else {
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_EN); template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_EN);
} }
break; break;
@@ -597,8 +608,8 @@ public class SendEmailUtil {
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L; private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
public static void notificationForRegisterUser(String receiverAddress){ public static void notificationForRegisterUser(String receiverAddress) {
try{ try {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密 // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305 // 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
@@ -626,16 +637,18 @@ public class SendEmailUtil {
SendEmailResponse resp = client.SendEmail(req); SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp)); log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) { } catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString()); log.info("邮件发送至{} 发送失败###{}", receiverAddress, e.toString());
throw new BusinessException("failed.to.send.mail"); log.error(e.getMessage());
// 这里不再抛出异常 失败就不发,保证后续正常运行
// throw new BusinessException("failed.to.send.mail");
} }
} }
private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L; private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L;
private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L; private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L;
public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link){ public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link) {
try{ try {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密 // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305 // 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
@@ -653,10 +666,10 @@ public class SendEmailUtil {
req.setFromEmailAddress(SEND_ADDRESS); req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(new String[]{receiverAddress}); req.setDestination(new String[]{receiverAddress});
Template template = new Template(); Template template = new Template();
if (language.equals("ENGLISH")){ if (language.equals("ENGLISH")) {
req.setSubject("Change the email address bound to the AiDA account"); req.setSubject("Change the email address bound to the AiDA account");
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN); template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN);
}else { } else {
req.setSubject("更换AiDA账号绑定的邮箱地址"); req.setSubject("更换AiDA账号绑定的邮箱地址");
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN); template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN);
} }
@@ -678,12 +691,11 @@ public class SendEmailUtil {
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L; private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
public static void uploadTimeoutReminder(String userName, String time){ public static void uploadTimeoutReminder(String userName, String time) {
String xp = "xupei3360@163.com"; String xp = "xupei3360@163.com";
String shb = "shahaibodd99@gmail.com";
String wxd = "X1627315083@163.com"; String wxd = "X1627315083@163.com";
String pkc = "kaicpang.pang@connect.polyu.hk"; String pkc = "kaicpang.pang@connect.polyu.hk";
try{ try {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密 // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305 // 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
@@ -699,7 +711,7 @@ public class SendEmailUtil {
// 实例化一个请求对象,每个接口都会对应一个request对象 // 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest(); SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS); req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(new String[]{shb, xp, wxd, pkc}); req.setDestination(new String[]{xp, wxd, pkc});
Template template = new Template(); Template template = new Template();
req.setSubject("上传图片超时提醒"); req.setSubject("上传图片超时提醒");
template.setTemplateID(UPLOAD_TIMEOUT_REMINDER); template.setTemplateID(UPLOAD_TIMEOUT_REMINDER);
@@ -721,6 +733,7 @@ public class SendEmailUtil {
private final static Long HALFPRICEPROMOTION_CN_ID = 128582L; private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L; private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
public static void halfPricePromotion(Account account, String senderAddress, int type) { public static void halfPricePromotion(Account account, String senderAddress, int type) {
try { try {
// 实例化一个认证对象 // 实例化一个认证对象
@@ -750,7 +763,7 @@ public class SendEmailUtil {
if (type == 1) { if (type == 1) {
subject = "AiDA workshop - Win a trip to Hong Kong"; subject = "AiDA workshop - Win a trip to Hong Kong";
template.setTemplateID(HALFPRICEPROMOTION_EN_ID); template.setTemplateID(HALFPRICEPROMOTION_EN_ID);
}else { } else {
subject = "AiDA workshop - 赢取香港之旅"; subject = "AiDA workshop - 赢取香港之旅";
template.setTemplateID(HALFPRICEPROMOTION_CN_ID); template.setTemplateID(HALFPRICEPROMOTION_CN_ID);
} }
@@ -808,4 +821,259 @@ public class SendEmailUtil {
throw new BusinessException("failed.to.send.mail"); throw new BusinessException("failed.to.send.mail");
} }
} }
private final static Long CANCEL_MERCHANT_EN = 130720L;
// private final static Long NEW_MERCHANT_EN = 130721L;
// private final static Long NEW_USER_EN = 130722L;
// private final static Long NEW_USER_CN = 130723L;
private final static Long NEW_MERCHANT_EN = 140335L;
// private final static Long NEW_MERCHANT_EN = 135190L;
// private final static Long NEW_USER_EN = 135189L;
// private final static Long NEW_USER_CN = 135186L;
private final static Long NEW_USER_EN = 140316L;
private final static Long NEW_USER_CN = 140317L;
private final static Long RENEWAL_MERCHANT_EN = 130724L;
private final static Long RENEWAL_USER_EN = 130725L;
private final static Long RENEWAL_USER_CN = 130726L;
private final static Long RENEWAL_REMINDER_USER_EN = 130727L;
private final static Long RENEWAL_REMINDER_USER_CN = 130728L;
private final static Long PAYMENT_FAILED_NEW_MERCHANT_EN = 131230L;
private final static Long PAYMENT_FAILED_RENEWAL_MERCHANT_EN = 131225L;
private final static Long PAYMENT_FAILED_RENEWAL_USER_EN = 131563L;
private final static Long PAYMENT_FAILED_RENEWAL_USER_CN = 131564L;
public static boolean subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
try {
String merchantEmail = "kimwong@code-create.com.hk";
String developer = "xupei3360@163.com";
String[] receiverEmail = {merchantEmail, developer};
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest user = new SendEmailRequest();
user.setFromEmailAddress(SEND_ADDRESS);
user.setDestination(new String[]{receiverAddress});
SendEmailRequest merchant = new SendEmailRequest();
merchant.setFromEmailAddress(SEND_ADDRESS);
merchant.setDestination(receiverEmail);
Template templateUser = new Template();
Template templateMerchant = new Template();
switch (type) {
case "cancel":
merchant.setSubject("[Code-Create] Subscription Cancelled");
templateMerchant.setTemplateID(CANCEL_MERCHANT_EN);
break;
case "fail_new":
merchant.setSubject("[Code-Create] Payment Failed : New Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateMerchant.setTemplateID(PAYMENT_FAILED_NEW_MERCHANT_EN);
break;
case "fail_renewal":
merchant.setSubject("[Code-Create] Payment Failed : Renewal Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateMerchant.setTemplateID(PAYMENT_FAILED_RENEWAL_MERCHANT_EN);
// todo to user
if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] Payment Failed : Renewal Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateUser.setTemplateID(PAYMENT_FAILED_RENEWAL_USER_EN);
} else {
user.setSubject("[Code-Create] 自动续费失败 (" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateUser.setTemplateID(PAYMENT_FAILED_RENEWAL_USER_CN);
}
break;
case "new":
merchant.setSubject("[Code-Create] New Order(" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateMerchant.setTemplateID(NEW_MERCHANT_EN);
if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] You have successfully subscribed to AiDA");
templateUser.setTemplateID(NEW_USER_EN);
} else {
user.setSubject("[Code-Create] 您已成功订阅AiDA");
templateUser.setTemplateID(NEW_USER_CN);
}
break;
case "renewal":
merchant.setSubject("[Code-Create] New subscription renewal order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
templateMerchant.setTemplateID(RENEWAL_MERCHANT_EN);
if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] AiDA Renewal Successful");
templateUser.setTemplateID(RENEWAL_USER_EN);
} else {
user.setSubject("[Code-Create] AiDA续订成功");
templateUser.setTemplateID(RENEWAL_USER_CN);
}
break;
case "reminder":
if (language.equals("ENGLISH")) {
user.setSubject("[Code-Create] AiDA Subscription Renewal Reminder");
templateUser.setTemplateID(RENEWAL_REMINDER_USER_EN);
} else {
user.setSubject("[Code-Create] AiDA续订提醒");
templateUser.setTemplateID(RENEWAL_REMINDER_USER_CN);
}
break;
default:
log.error("unknown subscription email type");
return false;
// throw new BusinessException("unknown subscription email type");
}
templateUser.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
user.setTemplate(templateUser);
templateMerchant.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
merchant.setTemplate(templateMerchant);
if (!type.equals("cancel") && !type.equals("fail_new")) {
// 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse respUser = client.SendEmail(user);
log.info("邮件主题:{}发送结果toUser###{}", user.getSubject(), SendEmailResponse.toJsonString(respUser));
}
if (!type.equals("reminder")) {
SendEmailResponse respMerchant = client.SendEmail(merchant);
log.info("邮件主题:{}发送结果toMerchant###{}", merchant.getSubject(), SendEmailResponse.toJsonString(respMerchant));
}
return true;
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
return false;
// throw new BusinessException("failed.to.send.mail");
}
}
private final static Long NEW_REGISTRATION = 132123L;
private final static Long AFFILIATE_ACCEPTED = 132124L;
private final static Long AFFILIATE_REFUSED = 132125L;
private final static Long AFFILIATE_MONTHLY_SUMMARY = 132126L;
public static void affiliateEmailReminder(String[] receiverAddress, AffiliateEmailParamsDTO paramsDTO, String type) {
try {
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(receiverAddress);
Template template = new Template();
switch (type) {
case "new":
req.setSubject("New Affiliate Registration");
template.setTemplateID(NEW_REGISTRATION);
break;
case "accepted":
req.setSubject("Affiliate Application Accepted");
template.setTemplateID(AFFILIATE_ACCEPTED);
break;
case "refused":
req.setSubject("Affiliate Application Refused");
template.setTemplateID(AFFILIATE_REFUSED);
break;
case "summary":
req.setSubject("Your Monthly AffiliateWP Summary for AiDA");
template.setTemplateID(AFFILIATE_MONTHLY_SUMMARY);
break;
}
template.setTemplateData(JSON.toJSONString(paramsDTO));
req.setTemplate(template);
// 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}
private final static Long CREDITS_PURCHASE_MERCHANT = 133275L;
public static void creditsPurchaseReminder(String username, String quantity, String amount) {
try {
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS);
String merchantEmail = "kimwong@code-create.com.hk";
String developerEmail = "xupei@code-create.com.hk";
req.setDestination(new String[]{merchantEmail, developerEmail});
Template template = new Template();
req.setSubject("New Credit Purchase Order");
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);
JSONObject jsonObject = new JSONObject();
// 设置试用订单相关数据
jsonObject.put("username", username);
jsonObject.put("quantity", quantity);
jsonObject.put("totalFee", amount);
template.setTemplateData(JSON.toJSONString(jsonObject));
req.setTemplate(template);
// 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse resp = client.SendEmail(req);
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}
private final static Long COMMON_EXCEPTION_REMINDER = 135279L;
public static void commonExceptionReminder(String functionName, String[] destination) {
try {
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("ses.tencentcloudapi.com");
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendEmailRequest req = new SendEmailRequest();
req.setFromEmailAddress(SEND_ADDRESS);
req.setDestination(destination);
Template template = new Template();
req.setSubject("AiDA发生异常请及时处理");
template.setTemplateID(COMMON_EXCEPTION_REMINDER);
JSONObject param = new JSONObject();
param.put("function", functionName);
// 邮件内容 {{function}}处理异常,请及时查看
template.setTemplateData(param.toJSONString());
req.setTemplate(template);
// 返回的resp是一个SendEmailResponse的实例与请求对象对应
SendEmailResponse resp = client.SendEmail(req);
log.info("邮件发送结果res###{}", SendEmailResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
log.info("邮件发送失败###{}", e.toString());
throw new BusinessException("failed.to.send.mail");
}
}
} }

View File

@@ -4,10 +4,12 @@ import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.AccountExtend;
import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.*; import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountLoginVO;
import com.ai.da.model.vo.AccountPreLoginVO; import com.ai.da.model.vo.AccountPreLoginVO;
import com.ai.da.model.vo.BindEmailVO;
import com.ai.da.model.vo.PersonalHomepageVO; import com.ai.da.model.vo.PersonalHomepageVO;
import com.ai.da.service.AccountService; import com.ai.da.service.AccountService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@@ -49,8 +51,8 @@ public class AccountController {
@ApiOperation(value = "绑定邮箱") @ApiOperation(value = "绑定邮箱")
@PostMapping("/bindEmail") @PostMapping("/bindEmail")
public Response<Boolean> bindEmail(@Valid @RequestBody AccountBindEmailDTO accountBindEmailDTO) { public Response<BindEmailVO> bindEmail(@Valid @RequestBody AccountBindEmailDTO accountBindEmailDTO, HttpServletRequest request) {
return Response.success(accountService.bindEmail(accountBindEmailDTO)); return Response.success(accountService.bindEmail(accountBindEmailDTO, request));
} }
@ApiOperation(value = "忘记密码") @ApiOperation(value = "忘记密码")
@@ -223,7 +225,7 @@ public class AccountController {
@ApiOperation(value = "getUsernameModifyTimes") @ApiOperation(value = "getUsernameModifyTimes")
@GetMapping("/getNicknameModifyTimes") @GetMapping("/getNicknameModifyTimes")
public Response<Map<String, Long>> getNicknameModifyTimes(){ public Response<Long> getNicknameModifyTimes(){
return Response.success(accountService.getNicknameModifyTimes()); return Response.success(accountService.getNicknameModifyTimes());
} }
@@ -234,7 +236,7 @@ public class AccountController {
return Response.success("success"); return Response.success("success");
} }
@ApiOperation(value = "verifyUserEmail") /*@ApiOperation(value = "verifyUserEmail")
@GetMapping("/verifyUserEmail") @GetMapping("/verifyUserEmail")
public Response<String> verifyUserEmail(@RequestParam("verifyCode") String verifyCode){ public Response<String> verifyUserEmail(@RequestParam("verifyCode") String verifyCode){
accountService.verifyUserEmail(verifyCode); accountService.verifyUserEmail(verifyCode);
@@ -253,7 +255,7 @@ public class AccountController {
public Response<String> activateNewEmail(@RequestParam("token") String token){ public Response<String> activateNewEmail(@RequestParam("token") String token){
accountService.activateNewEmail(token); accountService.activateNewEmail(token);
return Response.success("success"); return Response.success("success");
} }*/
@PostMapping("halfPricePromotion") @PostMapping("halfPricePromotion")
@ApiOperation(value = "十月半价活动") @ApiOperation(value = "十月半价活动")
@@ -310,4 +312,40 @@ public class AccountController {
public Response<AccountLoginVO> getAccountDetail() { public Response<AccountLoginVO> getAccountDetail() {
return Response.success(accountService.getAccountDetail()); return Response.success(accountService.getAccountDetail());
} }
@GetMapping("/bindGoogle")
@ApiOperation(value = "绑定谷歌")
public Response<AccountExtend> bindGoogle(@RequestParam("credential") String credential) {
return Response.success(accountService.bindGoogle(credential));
}
@GetMapping("/bindWeChat")
@ApiOperation(value = "绑定微信")
public Response<AccountExtend> bindWeChat(@RequestParam("code") String code) {
return Response.success(accountService.bindWeChat(code));
}
@GetMapping("/bindEmail")
@ApiOperation(value = "绑定邮箱")
public Response<BindEmailVO> bindEmail(@RequestParam("email") String email) {
return Response.success(accountService.bindEmail(email));
}
@GetMapping("/unbindWeChat")
@ApiOperation(value = "解除绑定微信")
public Response<Boolean> unbindWeChat() {
return Response.success(accountService.unbindWeChat());
}
@GetMapping("/unbindGoogle")
@ApiOperation(value = "解除绑定谷歌")
public Response<Boolean> unbindGoogle() {
return Response.success(accountService.unbindGoogle());
}
@PostMapping("/updateUserInfo")
@ApiOperation(value = "更新用户国家、职业信息")
public Response<Boolean> updateUserInfo(@Valid @RequestBody UpdateUserInfoDTO updateUserInfoDTO) {
return Response.success(accountService.updateUserInfo(updateUserInfoDTO));
}
} }

View File

@@ -0,0 +1,94 @@
package com.ai.da.controller;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.model.dto.AffiliateQueryDTO;
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
import com.ai.da.model.vo.AffiliateVO;
import com.ai.da.service.AffiliateService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
@Slf4j
@RestController
@RequestMapping("/api/affiliate")
@Api(tags = "Affiliate模块")
public class AffiliateController {
@Resource
private AffiliateService affiliateService;
@ApiOperation(value = "注册成为affiliate")
@GetMapping("/registration")
public Response<Boolean> completeGuidance(@RequestParam(value = "promotionMethod", required = false) String promotionMethod) {
return Response.success(affiliateService.registerAsAnAffiliate(promotionMethod));
}
@ApiOperation(value = "获取affiliate列表")
@PostMapping("/list")
public Response<PageBaseResponse<AffiliateVO>> getAffiliateList(@Valid @RequestBody AffiliateQueryDTO affiliateQueryDTO) {
return Response.success(affiliateService.getAffiliateList(affiliateQueryDTO));
}
@ApiOperation(value = "获取affiliate个人中心")
@GetMapping("/personalCenter")
public Response<AffiliateVO> personalAffiliateCenter() {
return Response.success(affiliateService.personalAffiliateCenter());
}
@ApiOperation(value = "获取个人佣金图表数据")
@GetMapping("/getPersonalMonthlyIncome")
public Response<double[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
return Response.success(affiliateService.getPersonalMonthlyIncome(year));
}
@ApiOperation(value = "审批affiliate申请")
@GetMapping("/approval")
public Response<Boolean> applicationApproval(@RequestParam("id") Long id,
@RequestParam("isApproved")Boolean isApproved,
@RequestParam("commission") Float commission) {
return Response.success(affiliateService.applicationApproval(id, isApproved, commission));
}
@ApiOperation(value = "更新佣金比例")
@GetMapping("/updateCommission")
public Response<String> updateCommissionPercentage(@RequestParam("id") Long id, @RequestParam("commission") Float commission) {
affiliateService.updateCommissionPercentage(id, commission);
return Response.success("success");
}
/*@ApiOperation(value = "定时计算佣金")
@GetMapping("/testTask")
public Response<String> testTask() {
affiliateService.updateAffiliateInfoWithPayment();
return Response.success("success ");
}*/
/*@ApiOperation(value = "每月发送结算邮件")
@GetMapping("/commissionCalculation")
public Response<String> commissionCalculation(@RequestParam("year") Integer year, @RequestParam("month") Integer month) {
affiliateService.commissionCalculation(year, month);
return Response.success("success ");
}*/
@ApiOperation(value = "affiliate链接浏览量增加")
@GetMapping("/viewsIncrease")
public Response<Boolean> viewsGet(@RequestParam("id") Long id) {
return Response.success(affiliateService.affiliateLinkViewsIncrease(id));
}
@ApiOperation(value = "获取每个affiliate产生的收入")
@PostMapping("/getEachAffiliateGeneratedRevenue")
public Response<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) {
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO));
}
}

View File

@@ -1,6 +1,7 @@
package com.ai.da.controller; package com.ai.da.controller;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.model.dto.ProductPurchaseDTO;
import com.ai.da.service.AliPayService; import com.ai.da.service.AliPayService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -8,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map; import java.util.Map;
@CrossOrigin @CrossOrigin
@@ -21,12 +24,12 @@ public class AliPayController {
private AliPayService aliPayService; private AliPayService aliPayService;
@ApiOperation("统一收单下单并支付页面接口的调用") @ApiOperation("统一收单下单并支付页面接口的调用")
@PostMapping("/trade/page/pay/{amount}") @PostMapping("/trade/page/pay")
public Response<String> tradePagePay(@PathVariable Integer amount, @RequestParam String returnUrl){ public Response<String> tradePagePay(@Valid @RequestBody ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request){
log.info("统一收单下单并支付页面接口的调用"); log.info("统一收单下单并支付页面接口的调用");
//支付宝开放平台接受 request 请求对象后 //支付宝开放平台接受 request 请求对象后
// 会为开发者生成一个html 形式的 form表单包含自动提交的脚本 // 会为开发者生成一个html 形式的 form表单包含自动提交的脚本
String formStr = aliPayService.tradeCreate(amount, returnUrl); String formStr = aliPayService.tradeCreate(productPurchaseDTO, request);
//我们将form表单字符串返回给前端程序之后前端将会调用自动提交脚本进行表单的提交 //我们将form表单字符串返回给前端程序之后前端将会调用自动提交脚本进行表单的提交
//此时表单会自动提交到action属性所指向的支付宝开放平台中从而为用户展示一个支付页面 //此时表单会自动提交到action属性所指向的支付宝开放平台中从而为用户展示一个支付页面
return Response.success(formStr); return Response.success(formStr);

View File

@@ -1,6 +1,7 @@
package com.ai.da.controller; package com.ai.da.controller;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.model.dto.ProductPurchaseDTO;
import com.ai.da.service.AlipayHKService; import com.ai.da.service.AlipayHKService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -8,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
@CrossOrigin @CrossOrigin
@RestController @RestController
@@ -20,9 +23,9 @@ public class AlipayHKController {
private AlipayHKService alipayHKService; private AlipayHKService alipayHKService;
@ApiOperation(value = "创建订单") @ApiOperation(value = "创建订单")
@PostMapping(value = "/createOrder/{wallet}/{amount}") @PostMapping(value = "/createOrder")
public Response<String> createOrder(@PathVariable Integer amount, @PathVariable String wallet) { public Response<String> createOrder(@Valid @RequestBody ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request) {
String order = alipayHKService.createOrder(amount, wallet); String order = alipayHKService.createOrder(productPurchaseDTO, request);
return Response.success(order); return Response.success(order);
} }

View File

@@ -2,18 +2,21 @@ package com.ai.da.controller;
import com.ai.da.common.context.UserContext; import com.ai.da.common.context.UserContext;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.DesignMapper; import com.ai.da.mapper.primary.DesignMapper;
import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.AccountAddDTO; import com.ai.da.model.dto.AccountAddDTO;
import com.ai.da.model.dto.QueryPaymentInfoDTO;
import com.ai.da.model.dto.UserDesignStatisticDTO; import com.ai.da.model.dto.UserDesignStatisticDTO;
import com.ai.da.model.vo.PaymentInfoVO;
import com.ai.da.model.vo.QuestionnaireFeedbackVO; import com.ai.da.model.vo.QuestionnaireFeedbackVO;
import com.ai.da.model.vo.QuestionnaireVO; import com.ai.da.model.vo.QuestionnaireVO;
import com.ai.da.model.vo.QueryUserConditionsVO; import com.ai.da.model.vo.QueryUserConditionsVO;
import com.ai.da.service.AccountService;
import com.ai.da.service.ConvenientInquiryService; import com.ai.da.service.ConvenientInquiryService;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -23,6 +26,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
@@ -36,13 +40,21 @@ public class ConvenientInquiryController {
private DesignMapper designMapper; private DesignMapper designMapper;
@Resource @Resource
private ConvenientInquiryService convenientInquiryService; private ConvenientInquiryService convenientInquiryService;
@Resource
private AccountService accountService;
@ApiOperation("获取当前所有试用用户") @ApiOperation("获取当前所有试用用户")
@PostMapping("/getTrial") @PostMapping("/getTrial")
public Response<IPage<TrialOrder>> getTrial(@Valid @RequestBody QueryUserConditionsVO queryUserConditionsVO) { public Response<IPage<TrialOrder>> getTrial(@Valid @RequestBody QueryUserConditionsVO queryUserConditionsVO) {
Long accountId = UserContext.getUserHolder().getId(); Long accountId = UserContext.getUserHolder().getId();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L) || accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)) { String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
return Response.success(convenientInquiryService.getTrial(queryUserConditionsVO)); return Response.success(convenientInquiryService.getTrial(queryUserConditionsVO));
} else { } else {
return Response.fail("Sorry, you don't have permission"); return Response.fail("Sorry, you don't have permission");
@@ -51,10 +63,16 @@ public class ConvenientInquiryController {
@ApiOperation("获取指定时间区间内所有用户design的使用情况") @ApiOperation("获取指定时间区间内所有用户design的使用情况")
@GetMapping("/getDesignStatistic") @GetMapping("/getDesignStatistic")
public Response<List<UserDesignStatisticDTO>> getDesignStatistic(@RequestParam String startTime, @RequestParam String endTime, public Response<List<UserDesignStatisticDTO>> getDesignStatistic(@RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime,
@RequestParam(required = false) List<Long> ids, @RequestParam(required = false) String email) { @RequestParam(required = false) List<Long> ids, @RequestParam(required = false) String email) {
Long accountId = UserContext.getUserHolder().getId(); Long accountId = UserContext.getUserHolder().getId();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L) || accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)) { String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
if (StringUtil.isNullOrEmpty(startTime)) startTime = "2024-02-01 00:00:00"; if (StringUtil.isNullOrEmpty(startTime)) startTime = "2024-02-01 00:00:00";
if (StringUtil.isNullOrEmpty(endTime)) { if (StringUtil.isNullOrEmpty(endTime)) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@@ -137,7 +155,14 @@ public class ConvenientInquiryController {
@ApiOperation("添加用户") @ApiOperation("添加用户")
@PostMapping("/addUser") @PostMapping("/addUser")
public Response<Boolean> addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) { public Response<Boolean> addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) {
return Response.success(convenientInquiryService.addUser(accountAddDTO)); Long userAccountId = UserContext.getUserHolder().getId();
if (userAccountId.equals(31L) || userAccountId.equals(87L) || userAccountId.equals(83L)
|| userAccountId.equals(6L) || userAccountId.equals(4L) || userAccountId.equals(73L)
) {
return Response.success(convenientInquiryService.addUser(accountAddDTO));
} else {
return Response.fail("Sorry, you don't have permission");
}
} }
@ApiOperation("修改用户信息") @ApiOperation("修改用户信息")
@@ -146,14 +171,27 @@ public class ConvenientInquiryController {
@ApiParam(value = "有效期截止时间的毫秒级unix格式") @RequestParam @Nullable Long validEndTime, @ApiParam(value = "有效期截止时间的毫秒级unix格式") @RequestParam @Nullable Long validEndTime,
@ApiParam(value = "用户类型 1/2/3/0 -> yearly/monthly/trial/visitor") @RequestParam @Nullable Integer systemUser, @ApiParam(value = "用户类型 1/2/3/0 -> yearly/monthly/trial/visitor") @RequestParam @Nullable Integer systemUser,
@ApiParam("积分") @RequestParam @Nullable Long credits) { @ApiParam("积分") @RequestParam @Nullable Long credits) {
return Response.success(convenientInquiryService.modifyUser(accountId, validEndTime, systemUser, credits)); Long userAccountId = UserContext.getUserHolder().getId();
if (userAccountId.equals(31L) || userAccountId.equals(87L) || userAccountId.equals(83L)
|| userAccountId.equals(6L) || userAccountId.equals(4L) || userAccountId.equals(73L)
) {
return Response.success(convenientInquiryService.modifyUser(accountId, validEndTime, systemUser, credits));
} else {
return Response.fail("Sorry, you don't have permission");
}
} }
@ApiOperation("获取用户信息") @ApiOperation("获取用户信息")
@PostMapping("/getUserInfo") @PostMapping("/getUserInfo")
public Response<IPage<Account>> getUserInfo(@Valid @RequestBody QueryUserConditionsVO queryUserConditionsVO) { public Response<IPage<Account>> getUserInfo(@Valid @RequestBody QueryUserConditionsVO queryUserConditionsVO) {
Long accountId = UserContext.getUserHolder().getId(); Long accountId = UserContext.getUserHolder().getId();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L) || accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)) { String userEmail = accountService.getById(accountId).getUserEmail();
if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L)
|| accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)
|| userEmail.equals("joho8228@hotmail.com")
|| userEmail.equals("chelseayu@code-create.com.hk")
|| userEmail.equals("cheungzt007@gmail.com")
) {
return Response.success(convenientInquiryService.getUserInfo(queryUserConditionsVO)); return Response.success(convenientInquiryService.getUserInfo(queryUserConditionsVO));
} else { } else {
return Response.fail("Sorry, you don't have permission"); return Response.fail("Sorry, you don't have permission");
@@ -166,5 +204,21 @@ public class ConvenientInquiryController {
return Response.success(convenientInquiryService.getAllUserIdList()); return Response.success(convenientInquiryService.getAllUserIdList());
} }
@ApiOperation("获取所有交易信息")
@PostMapping("/queryTransaction")
public Response<PageBaseResponse<PaymentInfoVO>> queryTransactionRecords(@Valid @RequestBody QueryPaymentInfoDTO queryPaymentInfoDTO){
return Response.success(convenientInquiryService.queryTransactionRecords(queryPaymentInfoDTO));
}
@ApiOperation("获取所有国家、城市")
@GetMapping("/getCities")
public Response<Map<String, List<String>>> getCities(){
return Response.success(convenientInquiryService.getCities());
}
@ApiOperation("下载交易记录")
@PostMapping("/queryTransaction/download")
public Response<String> exportTransactionRecords(@Valid @RequestBody QueryPaymentInfoDTO queryPaymentInfoDTO, HttpServletResponse response){
return Response.success(convenientInquiryService.exportTransactionRecords(queryPaymentInfoDTO, response));
}
} }

View File

@@ -71,6 +71,12 @@ public class DesignController {
return Response.success(designService.dislike(disDesignLikeDTO)); return Response.success(designService.dislike(disDesignLikeDTO));
} }
@ApiOperation(value = "Design sort")
@PostMapping("/sort")
public Response<Boolean> sort(@Valid @RequestBody UserLikeSortDTO userLikeSortDTO) {
return Response.success(designService.sort(userLikeSortDTO));
}
@ApiOperation(value = "sketchBoard upload generate design前裁剪") @ApiOperation(value = "sketchBoard upload generate design前裁剪")
@PostMapping("/sketchBoardsBoundingBox") @PostMapping("/sketchBoardsBoundingBox")
public Response<List<CollectionSketchVO>> sketchesBoundingBox(@Valid @RequestBody ReDesignCollectionDTO reDesignCollectionDTO) { public Response<List<CollectionSketchVO>> sketchesBoundingBox(@Valid @RequestBody ReDesignCollectionDTO reDesignCollectionDTO) {

View File

@@ -5,7 +5,6 @@ import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*; import com.ai.da.model.vo.*;
import com.ai.da.service.DesignItemService; import com.ai.da.service.DesignItemService;
import com.ai.da.service.DesignService; import com.ai.da.service.DesignService;
import com.ai.da.service.UserLikeService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
@@ -15,8 +14,6 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.Map;
@Api(tags = "design Detail模块") @Api(tags = "design Detail模块")

View File

@@ -66,6 +66,8 @@ public class ElementController {
return Response.success(); return Response.success();
} }
/** 该功能已删除 */
@Deprecated
@ApiOperation(value = "生成印花") @ApiOperation(value = "生成印花")
@PostMapping("/generatePrint") @PostMapping("/generatePrint")
public Response<GenerateCollectionItemVO> generatePrint(@Valid @RequestBody CollectionGeneratePrintDTO generatePrintDTO) { public Response<GenerateCollectionItemVO> generatePrint(@Valid @RequestBody CollectionGeneratePrintDTO generatePrintDTO) {

View File

@@ -3,9 +3,10 @@ package com.ai.da.controller;
import com.ai.da.common.enums.OrderStatusEnum; import com.ai.da.common.enums.OrderStatusEnum;
import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.model.dto.QueryPageByTimeDTO; import com.ai.da.model.dto.QueryPageByTimeDTO;
import com.ai.da.model.vo.OrderListVO;
import com.ai.da.service.OrderInfoService; import com.ai.da.service.OrderInfoService;
import com.ai.da.service.PaymentInfoService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,10 +23,13 @@ public class OrderInfoController {
@Resource @Resource
private OrderInfoService orderInfoService; private OrderInfoService orderInfoService;
@Resource
private PaymentInfoService paymentInfoService;
@ApiOperation("订单列表") @ApiOperation("订单列表")
@PostMapping("/list") @PostMapping("/list")
public Response<PageBaseResponse<OrderInfo>> list(@Valid @RequestBody QueryPageByTimeDTO queryPageByTimeDTO){ public Response<PageBaseResponse<OrderListVO>> list(@Valid @RequestBody QueryPageByTimeDTO queryPageByTimeDTO){
PageBaseResponse<OrderInfo> orderByAccountId = orderInfoService.getOrderByPage(queryPageByTimeDTO); PageBaseResponse<OrderListVO> orderByAccountId = paymentInfoService.getPaymentInfo(queryPageByTimeDTO);
// List<OrderInfo> list = orderInfoService.listOrderByCreateTimeDesc(); // List<OrderInfo> list = orderInfoService.listOrderByCreateTimeDesc();
return Response.success(orderByAccountId); return Response.success(orderByAccountId);
} }

View File

@@ -1,6 +1,7 @@
package com.ai.da.controller; package com.ai.da.controller;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.model.dto.ProductPurchaseDTO;
import com.ai.da.service.PayPalCheckoutService; import com.ai.da.service.PayPalCheckoutService;
import com.paypal.http.HttpResponse; import com.paypal.http.HttpResponse;
import com.paypal.http.exceptions.SerializeException; import com.paypal.http.exceptions.SerializeException;
@@ -14,6 +15,7 @@ import javax.annotation.Resource;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -26,9 +28,9 @@ public class PayPalCheckoutController {
private PayPalCheckoutService payPalCheckoutService; private PayPalCheckoutService payPalCheckoutService;
@ApiOperation(value = "创建订单") @ApiOperation(value = "创建订单")
@PostMapping(value = "/trade/{amount}") @PostMapping(value = "/trade")
public Response<HashMap<String, String>> createOrder(@PathVariable Integer amount, @RequestParam String returnUrl) throws SerializeException { public Response<HashMap<String, String>> createOrder(@Valid @RequestBody ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request) throws SerializeException {
HashMap<String, String> approvalUrl = payPalCheckoutService.createOrder(amount,returnUrl); HashMap<String, String> approvalUrl = payPalCheckoutService.createOrder(productPurchaseDTO, request);
return Response.success(approvalUrl); return Response.success(approvalUrl);
} }

View File

@@ -1,47 +1,84 @@
package com.ai.da.controller; package com.ai.da.controller;
import com.ai.da.common.response.Response; import com.ai.da.common.response.Response;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.common.utils.SendEmailUtil;
import com.ai.da.mapper.primary.entity.ProductCoupons;
import com.ai.da.model.dto.CreateCouponDTO;
import com.ai.da.model.dto.ProductPurchaseDTO;
import com.ai.da.model.dto.QueryCouponsPageDTO;
import com.ai.da.model.vo.CheckCouponsVO;
import com.ai.da.service.StripeService; import com.ai.da.service.StripeService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.paypal.http.HttpResponse; import com.paypal.http.HttpResponse;
import com.paypal.payments.Refund; import com.paypal.payments.Refund;
import com.stripe.exception.StripeException;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.Date;
import java.util.List;
@Api(tags = "Stripe模块") @Api(tags = "Stripe模块")
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/api/stripe") @RequestMapping("/api/stripe")
@ApiIgnore
public class StripeController { public class StripeController {
@Resource @Resource
private StripeService stripeService; private StripeService stripeService;
@Resource
private RedisUtil redisUtil;
@ApiOperation("创建支付链接") @ApiOperation("创建支付链接")
@PostMapping("/createOrder/{amount}") @PostMapping("/createOrder")
public Response<String> pay(@PathVariable Integer amount, @RequestParam String returnUrl) { public Response<String> pay(@Valid @RequestBody ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request) {
return Response.success(stripeService.pay(amount, returnUrl)); return Response.success(stripeService.pay(productPurchaseDTO, request));
} }
@Value("${stripe.webhook.fail.reminder}")
private String webhookReminderFlag;
@ApiOperation("支付通知") @ApiOperation("支付通知")
@PostMapping("/trade/notify") @PostMapping("/trade/notify")
public Response<String> callback(HttpServletRequest request) throws ServletException, IOException { public void callback(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Boolean result = stripeService.notify(request); try{
if (result){ Boolean result = stripeService.notify(request);
return Response.success(200,"success"); if (result){
}else { response.setStatus(HttpServletResponse.SC_OK);
return Response.fail(400,"failure"); }else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}catch (Exception e){
log.error("Stripe Controller层异常捕捉, {}", e.getMessage());
e.printStackTrace();
String key_1 = RedisUtil.STRIPE_EXCEPTION_LOG + DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH);
String key_2 = key_1 + ":" + DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_hh_mm_ss);
String stackTrace = stripeService.getStackTrace(e, 10);
redisUtil.addToString(key_2, stackTrace);
Long size = redisUtil.getSize(key_1);
// 给我发送邮件
if (webhookReminderFlag.equals("1") && size == 3){
SendEmailUtil.commonExceptionReminder("Stripe Webhook 回调", new String[]{"xupei3360@163.com"});
}
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} }
} }
@ApiOperation("申请退款") @ApiOperation("申请退款")
@PostMapping("/trade/refund/{orderNo}/{reason}") @GetMapping("/trade/refund/{orderNo}/{reason}")
public Response<HttpResponse<Refund>> refund(@PathVariable String orderNo, @PathVariable String reason) throws IOException { public Response<HttpResponse<Refund>> refund(@PathVariable String orderNo, @PathVariable String reason) throws IOException {
String response = stripeService.refund(null,orderNo,reason); String response = stripeService.refund(null,orderNo,reason);
if (response.equals("退款成功")){ if (response.equals("退款成功")){
@@ -51,4 +88,105 @@ public class StripeController {
} }
} }
@ApiOperation("获取订阅")
@GetMapping("/getSubscription")
public Response<List<String>> getSubscription(@RequestParam String name, @RequestParam String email) {
try {
return Response.success(stripeService.getSubscriptionIds(name, email));
} catch (StripeException e) {
throw new RuntimeException(e);
}
}
@ApiOperation("取消订阅")
@GetMapping("/cancelSubscription")
public Response<String> cancelSubscription(@RequestParam String subscriptionId, @RequestParam(required = false) String reason) {
stripeService.cancelSubscription(subscriptionId, reason);
return Response.success("success");
}
@ApiOperation("创建推广码")
@PostMapping("/createCoupon")
public Response<String> createCoupon(@Valid @RequestBody CreateCouponDTO createCouponDTO){
return Response.success(stripeService.createCoupon(createCouponDTO));
}
@ApiOperation("检查推广码")
@GetMapping("/checkCoupon")
public Response<CheckCouponsVO> checkCoupon(@RequestParam String promotionCode, @RequestParam Long price){
return Response.success(stripeService.checkProductCoupon(promotionCode, price));
}
@ApiOperation("获取所有推广码")
@PostMapping("/getAllCoupons")
public Response<IPage<ProductCoupons>> getAllCoupons(@RequestBody QueryCouponsPageDTO queryCouponsPageDTO){
return Response.success(stripeService.getAllCoupons(queryCouponsPageDTO));
}
@ApiOperation("检索优惠券")
@GetMapping("/retrieveCoupon")
public Response<String> retrieveCoupon(@RequestParam String couponId){
return Response.success(stripeService.retrieveCoupon(couponId));
}
@ApiOperation("检索推广码")
@GetMapping("/retrievePromotionCode")
public Response<String> retrievePromotionCode(@RequestParam String retrievePromotionCode){
return Response.success(stripeService.retrievePromotionCode(retrievePromotionCode));
}
@ApiOperation("更新推广码信息")
@GetMapping("/updatePromCodeInfo")
public Response<ProductCoupons> updateCouponsInfo(@RequestParam Long id, @RequestParam(required = false) String paidCommission,
@RequestParam(required = false) String cooperator,
@RequestParam(required = false) String remark,
@RequestParam(required = false) Long startTime){
return Response.success(stripeService.updateCouponsInfo(id, paidCommission, cooperator, remark, startTime));
}
@ApiOperation("删除推广码")
@GetMapping("/deletePromCode")
public Response<String> deleteCoupon(@RequestParam Long id){
stripeService.deleteCoupon(id);
return Response.success("success");
}
/*@ApiOperation("临时 取消订阅")
@GetMapping("/cancelSubscriptionTemp")
public Response<String> cancelSubscriptionTemp(@RequestParam String subscriptionId) {
stripeService.cancelSubscriptionTemp(subscriptionId);
return Response.success("success");
}
@ApiOperation("创建订阅 临时")
@GetMapping("/createSubscriptionTemp")
public Response<String> createSubscriptionTemp(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.createSubscriptionTemp(name, email));
}
@ApiOperation("修改用户默认支付方式 临时")
@GetMapping("/changeCustomerPayment")
public Response<String> changeCustomerPayment(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.changeCustomerPayment(name, email));
}
@ApiOperation("临时 发送续订失败邮件")
@GetMapping("/sendRenewalFailEmail")
public Response<Boolean> sendRenewalFailEmail(@RequestParam String invoiceId, @RequestParam String subscriptionId, @RequestParam String orderNo) {
return Response.success(stripeService.sendRenewalFailEmail(invoiceId, subscriptionId,orderNo));
}
@ApiOperation("临时 查询指定用户绑定的付款方式")
@GetMapping("/getCustomerPaymentMethod")
public Response<List<Map<String,String>>> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.getCustomerPaymentMethod(name, email));
}
@ApiOperation("临时 解绑指定用户绑定的所有付款方式")
@GetMapping("/detachCustomerAllPaymentMethod")
public Response<String> detachCustomerAllPaymentMethod(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.detachCustomerAllPaymentMethod(name, email));
}*/
} }

View File

@@ -25,7 +25,7 @@ public class TagsController {
@ApiOperation("获取标签") @ApiOperation("获取标签")
@GetMapping("/getTags") @GetMapping("/getTags")
public Response<List<Tags>> getTags(@RequestParam("userInput") String userInput) { public Response<List<Tags>> getTags(@RequestParam(value = "userInput", required = false) String userInput) {
return Response.success(tagsService.getTags(userInput)); return Response.success(tagsService.getTags(userInput));
} }
} }

View File

@@ -130,14 +130,14 @@ public class ThirdPartyController {
} }
@CrossOrigin @CrossOrigin
@GetMapping("/parseGoogleCredential") @GetMapping("/parseGoogleCredential")
public Response<AccountLoginVO> parseGoogleCredential(@RequestParam("credential") String credential) { public Response<AccountLoginVO> parseGoogleCredential(@RequestParam("credential") String credential, @RequestParam("type") Integer type) {
return Response.success(accountService.parseGoogleCredential(credential)); return Response.success(accountService.parseGoogleCredential(credential, type));
} }
@CrossOrigin @CrossOrigin
@GetMapping("/parseWeChatCode") @GetMapping("/parseWeChatCode")
public Response<AccountLoginVO> parseWeChatCode(@RequestParam("code") String code) { public Response<AccountLoginVO> parseWeChatCode(@RequestParam("code") String code, @RequestParam("type") Integer type) {
return Response.success(accountService.parseWeChatCode(code)); return Response.success(accountService.parseWeChatCode(code, type));
} }
@ApiOperation(value = "接收Design结果") @ApiOperation(value = "接收Design结果")

View File

@@ -30,6 +30,6 @@ public interface AccountMapper extends CommonMapper<Account> {
*/ */
// Account findById(String id); // Account findById(String id);
void toVisitor(Long id, Date date); void toVisitor(Long id);
} }

View File

@@ -0,0 +1,14 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.AffiliateIncome;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Map;
public interface AffiliateIncomeMapper extends BaseMapper<AffiliateIncome> {
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
}

View File

@@ -0,0 +1,19 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.Affiliate;
import com.ai.da.model.vo.AffiliateVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Map;
public interface AffiliateMapper extends BaseMapper<Affiliate> {
Map<String, Long> getMonthlyApprovedAffiliate(int year, int month);
List<AffiliateVO> getAffiliateList(String status, String startTime, String endTime,
String order, Long affiliateId, int size, int offset);
int queryAffiliateTotalCount(String status, String startTime, String endTime, Long affiliateId);
}

View File

@@ -0,0 +1,16 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.AccountExtend;
import com.ai.da.mapper.primary.entity.DesignBatch;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface DesignBatchMapper extends CommonMapper<DesignBatch> {
}

View File

@@ -0,0 +1,7 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.MoodboardPosition;
public interface MoodboardPositionMapper extends CommonMapper<MoodboardPosition> {
}

View File

@@ -1,7 +1,39 @@
package com.ai.da.mapper.primary; package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.PaymentInfo; import com.ai.da.mapper.primary.entity.PaymentInfo;
import com.ai.da.model.vo.OrderListVO;
import com.ai.da.model.vo.PaymentInfoVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public interface PaymentInfoMapper extends BaseMapper<PaymentInfo> { public interface PaymentInfoMapper extends BaseMapper<PaymentInfo> {
List<OrderListVO> selectPageOrderList(Long accountId, String startTime, String endTime, int offset, int pageSize, Long id);
int queryOrderListTotalCount(Long accountId, String startTime, String endTime, Long id);
List<PaymentInfoVO> queryPaymentInfo(String paymentType,String payerTotal, String type, String status,
String country, String city, String startTime, String endTime,
int limit, int offset, String order, String payer
);
Long queryPaymentInfoCount(String paymentType,String payerTotal, String type, String status,
String country, String city, String startTime, String endTime, String payer
);
BigDecimal queryTotalPaymentAmount(String paymentType,String payerTotal, String type, String status,
String country, String city, String startTime, String endTime, String payer
);
List<Map<String, String>> getCities();
List<Map<String, String>> getCountries();
int insertIgnore(@Param("paymentInfo")PaymentInfo paymentInfo);
List<PaymentInfo> selectPaidPaymentsByAccountAndPromotion(Long accountId, String promotionCode);
} }

View File

@@ -0,0 +1,8 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.ProductCoupons;
public interface ProductCouponsMapper extends CommonMapper<ProductCoupons> {
}

View File

@@ -0,0 +1,9 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
public interface SubscriptionInfoMapper extends BaseMapper<SubscriptionInfo> {
int insertIgnore(@Param("subscriptionInfo") SubscriptionInfo subscriptionInfo);
}

View File

@@ -0,0 +1,7 @@
package com.ai.da.mapper.primary;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.primary.entity.UserLikeSort;
public interface UserLikeSortMapper extends CommonMapper<UserLikeSort> {
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -57,6 +58,11 @@ public class Account implements Serializable {
*/ */
private String country; private String country;
/**
* 职业
*/
private String occupation;
/** /**
* 账户有效期开始时间 * 账户有效期开始时间
*/ */
@@ -120,4 +126,13 @@ public class Account implements Serializable {
private Integer subAccountNum; private Integer subAccountNum;
private String invitationCode; private String invitationCode;
@ApiModelProperty("title")
private String title;
@ApiModelProperty("surname")
private String surname;
@ApiModelProperty("givenName")
private String givenName;
} }

View File

@@ -1,5 +1,6 @@
package com.ai.da.mapper.primary.entity; package com.ai.da.mapper.primary.entity;
import com.ai.da.common.response.PageResponse;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@@ -26,5 +27,9 @@ public class AccountExtend implements Serializable {
private String authType; private String authType;
private String headImgUrl;
private String name;
private String auth; private String auth;
} }

View File

@@ -0,0 +1,32 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_affiliate")
public class Affiliate extends BaseEntity{
private Long accountId;
// Active活跃 || Inactive过期 || Pending待审批 || Refused(拒绝)
private String status;
private Float commissionPercent;
private Float totalEarnings = 0.00F;
private Float monthlyEarnings = 0.00F;
private Float unpaidEarnings = 0.00F;
private Integer visits = 0;
private Boolean approved = false;
private String link;
private String promotionMethod;
}

View File

@@ -0,0 +1,28 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_affiliate_income")
public class AffiliateIncome extends BaseEntity {
private Long affiliateId;
private Long affiliateAccountId;
private Long inviteeAccountId;
private Float amount;
private Long paymentInfoId;
private LocalDateTime paymentTime;
private Float commission;
}

View File

@@ -0,0 +1,44 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.models.auth.In;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("design_batch")
public class DesignBatch implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long accountId; // account_id
private Long designId; // design_id
private Long collectionId; // collection_id
private Integer status; // status
private LocalDateTime createTime; // create_time
private LocalDateTime updateTime; // update_time
private String taskId; // task_id
private Integer totalNum; // total_num
private Integer completedNum; // completed_num
}

View File

@@ -41,7 +41,7 @@ public class DesignItemDetailPrint {
/** /**
* 印花缩放比例 * 印花缩放比例
*/ */
private Double scale; private String scale;
/** /**
* 印花旋转角度 * 印花旋转角度
*/ */

View File

@@ -80,4 +80,18 @@ public class Library implements Serializable {
private Date updateDate; private Date updateDate;
// private Integer isCopy; // private Integer isCopy;
public Library() {
}
public Library(Long accountId, String level1Type, String level2Type, String level3Type, String url, String md5, Date createDate) {
this.accountId = accountId;
this.level1Type = level1Type;
this.level2Type = level2Type;
this.level3Type = level3Type;
this.url = url;
this.md5 = md5;
this.createDate = createDate;
}
} }

View File

@@ -0,0 +1,29 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("moodboard_position")
public class MoodboardPosition implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long moodboardId;
private Long collectionId;
private String type;
private String styleData;
private Integer sequence;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@@ -21,5 +21,20 @@ public class OrderInfo extends BaseEntity{
private String orderStatus;//订单状态 private String orderStatus;//订单状态
private String note;
private byte autoRenewal;
private String paymentType;//支付方式 private String paymentType;//支付方式
// 可用于标记用户订单是否首次订阅
private byte isFirstSubscription = 0;
private byte isCommissionCalculated = 0;
private String ipAddress;
private String country;
private String city;
} }

View File

@@ -2,7 +2,9 @@ package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data @Data
@TableName("t_payment_info") @TableName("t_payment_info")
public class PaymentInfo extends BaseEntity{ public class PaymentInfo extends BaseEntity{
@@ -13,11 +15,38 @@ public class PaymentInfo extends BaseEntity{
private String paymentType;//支付类型 private String paymentType;//支付类型
private String tradeType;//交易类型 /**
* PayPal 订单状态CREATED/SAVED/APPROVED/VOIDED/COMPLETED/PAYER_ACTION_REQUIRED
* Stripe 订单状态: 原 session 状态open/completed/expired ; 现 invoice 状态draft/open/paid/uncollectible/void
* Alipay-HK 订单状态wait, paid, expired, liquidated
* paid and liquidated means the refund request has been executed.
* expired means the request has been rejected.
* wait means the request is still under processing.
*/
private String tradeState;//交易状态 private String tradeState;//交易状态
private Float payerTotal;//支付金额(元) private Float payerTotal;//支付金额(元)
private String content;//通知参数 private String content;//通知参数
// 支付类型 new || renewal || credits
private String type;
// 当前支付是否已邮件通知 0 || 1
private Integer notified;
private String paymentMethod;
private String last4;
// 发票托管页面
private String hostedInvoiceUrl;
private String ipAddress;
private String country;
private String city;
private String promotionCode;
} }

View File

@@ -0,0 +1,60 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_product_coupons")
@NoArgsConstructor
public class ProductCoupons extends BaseEntity{
// 优惠券id
private String couponId;
// 优惠券有效期的截止日期
private Long redeemBy;
// 绑定的推广码id
private String promotionCodeId;
// 对应的推广码
private String promotionCode;
// 优惠券有效期开始时间
private Long startTime;
// 最大兑换次数
private Long maxRedemptions;
// 优惠券的折扣
private float percentOff;
// 佣金比例
private float commissionRate;
// 合作者
private String cooperator;
// 使用了该优惠券支付的总金额
private BigDecimal totalEarnings = BigDecimal.ZERO;
// 佣金
private BigDecimal commission = BigDecimal.ZERO;
// 已付佣金
private BigDecimal paidCommission = BigDecimal.ZERO;
// 未付佣金
private BigDecimal unpaidCommission = BigDecimal.ZERO;
// 备注
private String remark;
@TableLogic
private Integer isDeleted;
public ProductCoupons(String couponId, Long redeemBy, String promotionCodeId, String promotionCode, Long maxRedemptions, float percentOff, float commissionRate, String cooperator, String remark) {
this.couponId = couponId;
this.redeemBy = redeemBy;
this.promotionCodeId = promotionCodeId;
this.promotionCode = promotionCode;
this.maxRedemptions = maxRedemptions;
this.percentOff = percentOff;
this.cooperator = cooperator;
this.remark = remark;
this.commissionRate = commissionRate;
}
}

View File

@@ -0,0 +1,39 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_subscription_info")
public class SubscriptionInfo extends BaseEntity{
private Long accountId;
private String orderNo;
// stripe || paypal 平台生成的id
private String subscriptionId;
// month || year
private String type;
// active || canceled
private String status = "active";
private byte cancelNotified = (byte)0;
// 续订的下一个付款日
private String nextPayDate;
// 当前订阅订单有效期开始时间
private Long currentPeriodStart;
// 当前订阅订单有效期结束时间
private Long currentPeriodEnd;
// 取消订阅原因
private String cancelReason;
}

View File

@@ -10,4 +10,7 @@ import lombok.EqualsAndHashCode;
public class Tags extends BaseEntity{ public class Tags extends BaseEntity{
private String tagName; private String tagName;
// 表示标签是否正在活动中 0->不在活动中 1->在活动中
private byte active = (byte)0;
} }

View File

@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Data @Data
@@ -44,4 +45,8 @@ public class ToProductImageResult implements Serializable {
private String resultType; private String resultType;
private Double brightenValue; private Double brightenValue;
private BigDecimal imageStrength;
private String direction;
} }

View File

@@ -0,0 +1,24 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user_like_sort")
public class UserLikeSort implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long userLikeGroupId;
private Long userLikeId;
private Integer sort;
}

View File

@@ -5,15 +5,14 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data @Data
@ApiModel("绑定邮箱") @ApiModel("绑定邮箱")
public class AccountBindEmailDTO { public class AccountBindEmailDTO {
@NotNull(message = "userId.cannot.be.empty") // @NotNull(message = "userId.cannot.be.empty")
@ApiModelProperty("用户id") // @ApiModelProperty("用户id")
private Long userId; // private Long userId;
@NotBlank(message = "email.cannot.be.empty") @NotBlank(message = "email.cannot.be.empty")
@ApiModelProperty("邮箱") @ApiModelProperty("邮箱")
@@ -22,4 +21,19 @@ public class AccountBindEmailDTO {
@NotBlank(message = "emailVerifyCode.cannot.be.empty") @NotBlank(message = "emailVerifyCode.cannot.be.empty")
@ApiModelProperty("邮箱验证码") @ApiModelProperty("邮箱验证码")
private String emailVerifyCode; private String emailVerifyCode;
// @ApiModelProperty("国家")
// private String country;
//
// @ApiModelProperty("职业")
// private String occupation;
//
// @ApiModelProperty("title")
// private String title;
//
// @ApiModelProperty("surname")
// private String surname;
//
// @ApiModelProperty("givenName")
// private String givenName;
} }

View File

@@ -6,4 +6,6 @@ import lombok.Data;
@Data @Data
public class AccountDesignWorksRegisterDTO extends Account { public class AccountDesignWorksRegisterDTO extends Account {
private String emailVerifyCode; private String emailVerifyCode;
// private String invitationCode;
} }

View File

@@ -0,0 +1,31 @@
package com.ai.da.model.dto;
import lombok.Data;
@Data
public class AffiliateEmailParamsDTO {
private String username;
private String promotionMethod;
private String totalProgramRevenue;
private String newApprovedAffiliates;
private String unpaidEarnings;
private String paidEarnings;
public AffiliateEmailParamsDTO() {
}
public AffiliateEmailParamsDTO(String username) {
this.username = username;
}
public AffiliateEmailParamsDTO(String username, String promotionMethod) {
this.username = username;
this.promotionMethod = promotionMethod;
}
}

View File

@@ -0,0 +1,31 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("查询affiliate列表")
public class AffiliateQueryDTO extends TimeQueryBaseDTO{
@ApiModelProperty("Active活跃 || Inactive过期 || Pending待审批 || Refused(拒绝)")
private String status;
@ApiModelProperty("推广者id")
private Long affiliateId;
@ApiModelProperty("按时间 DESC 降序 || ASC 升序")
private String order = "ASC";
@Override
public String toString() {
return "AffiliateQueryDTO{" +
"status='" + status + '\'' + ' ' +
"startTime='" + super.getStartTime() + '\'' + ' ' +
"endTime='" + super.getEndTime() + '\'' + ' ' +
"page='" + super.getPage() + '\'' + ' ' +
"size='" + super.getSize() + '\'' + ' ' +
'}';
}
}

View File

@@ -0,0 +1,26 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class CreateCouponDTO {
@ApiModelProperty("折扣率")
@NotNull(message = "Please set the percentOff")
private Float percentOff;
@ApiModelProperty("佣金比例")
@NotNull(message = "Please set the commissionRate.")
private Float commissionRate;
@ApiModelProperty("推广码到期时间 秒级时间戳")
private Long endTime;
@ApiModelProperty("推广码开始时间 秒级时间戳")
private Long startTime;
@ApiModelProperty("推广码最大使用次数")
private Long maxRedemptions;
@ApiModelProperty("合作者/机构名")
private String cooperator;
@ApiModelProperty("备注")
private String remark;
}

View File

@@ -61,7 +61,7 @@ public class DesignCollectionDTO {
@ApiModelProperty("python端design进程ID") @ApiModelProperty("python端design进程ID")
private String processId; private String processId;
private String moodboardPostion; private String moodboardPosition;
private List<String> requestIdList; private List<String> requestIdList;

View File

@@ -32,7 +32,6 @@ public class DesignSingleItemDTO implements Serializable {
@ApiModelProperty("对应的图片的minIO路径") @ApiModelProperty("对应的图片的minIO路径")
private String path; private String path;
@NotBlank(message = "color.cannot.be.empty")
@ApiModelProperty("颜色 存 RGB值 中间空格分隔 比如 \"58 58 169\"") @ApiModelProperty("颜色 存 RGB值 中间空格分隔 比如 \"58 58 169\"")
private String color; private String color;

View File

@@ -15,10 +15,22 @@ public class EmailSendDTO {
private String email; private String email;
@NotBlank(message = "operationType.cannot.be.empty") @NotBlank(message = "operationType.cannot.be.empty")
@ApiModelProperty("操作类型 LOGIN 注册 FORGET_PWD 忘记密码 BIND_MAILBOX 绑定邮箱 CHANGE_MAILBOX 更改邮箱") @ApiModelProperty("操作类型 LOGIN 登录 FORGET_PWD 忘记密码 BIND_MAILBOX 绑定邮箱 " +
"CHANGE_MAILBOX 更改邮箱 UPDATE_USERINFO 仅填写国家、职业(不发送邮件) REGISTER 注册")
private String operationType; private String operationType;
@ApiModelProperty("异常ip") @ApiModelProperty("异常ip")
private String ip; private String ip;
@ApiModelProperty("国家")
private String country;
@ApiModelProperty("职业")
private String occupation;
private String title;
private String surname;
private String givenName;
} }

View File

@@ -21,9 +21,12 @@ public class GenerateModifyDTO {
@ApiModelProperty(value = "sketch所属分类", required = true) @ApiModelProperty(value = "sketch所属分类", required = true)
private String category; private String category;
@ApiModelProperty(value = "originalId的来源 Library || Generate(默认为空)", required = true)
private String originalIdSource;
@NotNull(message = "id cannot be empty") @NotNull(message = "id cannot be empty")
@ApiModelProperty(value = "原图id", required = true) @ApiModelProperty(value = "原图id", required = true)
private String originalId; private Long originalId;
@ApiModelProperty("是否覆盖原图") @ApiModelProperty("是否覆盖原图")
private Boolean isOverride; private Boolean isOverride;

View File

@@ -12,49 +12,50 @@ import javax.validation.constraints.NotNull;
public class GenerateThroughImageTextDTO { public class GenerateThroughImageTextDTO {
@NotNull(message = "userId cannot be empty") @NotNull(message = "userId cannot be empty")
@ApiModelProperty("用户id") @ApiModelProperty("用户id")
Long userId; private Long userId;
@ApiModelProperty("caption | prompt") @ApiModelProperty("caption | prompt")
String text; private String text;
@ApiModelProperty("图片在t_collection_element表中的id") @ApiModelProperty("图片在t_collection_element表中的id")
Long collectionElementId; private Long collectionElementId;
// todo 后续取消这个字段的传输,由后端自行判断相关参数是否有值 // todo 后续取消这个字段的传输,由后端自行判断相关参数是否有值
// @NotBlank(message = "you have to choose the generate type") // @NotBlank(message = "you have to choose the generate type")
@ApiModelProperty("text image text-image") @ApiModelProperty("text image text-image")
String generateType; private String generateType;
@ApiModelProperty("图片来源update从library中选择,从toProductImage结果中选择 collection || library || productImage") @ApiModelProperty("图片来源update从library中选择,从toProductImage结果中选择 collection || library || productImage")
String designType; private String designType;
@NotBlank(message = "level1Type cannot be empty!") @NotBlank(message = "level1Type cannot be empty!")
@ApiModelProperty("Moodboard Printboard Sketchboard MarketingSketch") @ApiModelProperty("Moodboard Printboard Sketchboard MarketingSketch")
String level1Type; private String level1Type;
@ApiModelProperty("Outwear Dress Blouse Skirt Trousers || Logo Slogan Pattern") @ApiModelProperty("Outwear Dress Blouse Skirt Trousers || Logo Slogan Pattern")
String level2Type; private String level2Type;
@ApiModelProperty("性别") @ApiModelProperty("性别")
String gender; private String gender;
@ApiModelProperty("选择的模型名")
String version; @ApiModelProperty("选择的模型名 high || fast")
private String version;
@NotBlank(message = "timeZone cannot be empty!") @NotBlank(message = "timeZone cannot be empty!")
@ApiModelProperty("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取") @ApiModelProperty("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
String timeZone; private String timeZone;
@ApiModelProperty("唯一id用于保持消息唯一性") @ApiModelProperty("唯一id用于保持消息唯一性")
String uniqueId; private String uniqueId;
@NotNull(message = "Please check if the required fields are empty.(isTestUser)") @NotNull(message = "Please check if the required fields are empty.(isTestUser)")
@ApiModelProperty("是否是测试用户") @ApiModelProperty("是否是测试用户")
Boolean isTestUser; private Boolean isTestUser;
@ApiModelProperty("页面上用户设计的slogan所截的图片") @ApiModelProperty("页面上用户设计的slogan所截的图片")
String sloganBase64; private String sloganBase64;
@ApiModelProperty("种子 取值范围 0~500") @ApiModelProperty("种子 取值范围 0~500")
String seed; private String seed;
} }

View File

@@ -0,0 +1,36 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel("购买产品DTO")
public class ProductPurchaseDTO {
@ApiModelProperty("购买数量")
private int quantity;
// http://example.com
@NotBlank(message = "return url cannot be empty")
@ApiModelProperty("购买完成后返回页面地址")
private String returnUrl;
@NotBlank(message = "product name cannot be empty")
@ApiModelProperty("产品名 CreditsPurchase || Subscription")
private String productName;
@ApiModelProperty("Month || Year")
private String subscribeType;
@ApiModelProperty("是否自动续订 one_time || recurring")
private Boolean autoRenewal;
@ApiModelProperty("使用Alipay-HK时需要选择 ALIPAYHK || ALIPAYCN")
private String wallet;
@ApiModelProperty("优惠码")
private String promotionCode;
}

View File

@@ -0,0 +1,22 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel
public class QueryCouponsPageDTO extends QueryPageByTimeDTO {
@ApiModelProperty("DESC(按id降序) || ASC(按id升序)")
private String orderById;
@ApiModelProperty("推广码")
private String promotionCode;
@ApiModelProperty("查询过期 || 未过期的优惠券")
private Boolean isExpired;
@ApiModelProperty("按合作者名字查询")
private String cooperator;
}

View File

@@ -16,4 +16,7 @@ public class QueryPageByTimeDTO extends PageQueryBaseVo {
@ApiModelProperty("结束时间 yyyy-mm-dd hh:mm:ss 可以不要时分秒") @ApiModelProperty("结束时间 yyyy-mm-dd hh:mm:ss 可以不要时分秒")
private String endTime; private String endTime;
@ApiModelProperty("指定id")
private Long id;
} }

View File

@@ -0,0 +1,30 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Data
@ApiModel("交易记录详情")
public class QueryPaymentInfoDTO extends QueryPageByTimeDTO {
@ApiModelProperty("选择的支付平台 PayPal || Stripe || Alipay-HK")
private String platform;
@ApiModelProperty("支付的金额 单位:HKD")
private String payerTotal;
@ApiModelProperty("商品种类 new || renewal || credits")
private String type;
@ApiModelProperty("交易状态 Success || Fail || Pending")
private String status;
@ApiModelProperty("付款人所在国家")
private String country;
@ApiModelProperty("付款人所在城市")
private String city;
@ApiModelProperty("按id排序 DESC || ASC")
private String order = "DESC";
@ApiModelProperty("付款用户名")
private String payer;
}

View File

@@ -67,4 +67,8 @@ public class ReDesignCollectionDTO {
private String moodboardPosition; private String moodboardPosition;
private String moodTemplateId; private String moodTemplateId;
private List<String> requestIdList;
private Integer designNum;
} }

View File

@@ -0,0 +1,59 @@
package com.ai.da.model.dto;
import lombok.Data;
@Data
public class SubscriptionEmailParamsDTO {
// 用户名
private String username;
// t_payment_info id每次支付对于用户来说是一笔新订单
private String orderId;
// 链接到订单列表的某个订单
private String orderRef;
// 订单支付创建日期
private String createDate;
// 购买数量
private String quantity;
// 费用
private String totalFee;
private String renewalFee;
// 当前订阅开始时间
private String lastOrderDate;
// 当前订阅结束时间
private String endOfPrepaidTerm;
// 付款方式
private String paymentMethod;
private String last4;
// 订阅Id
private String subscriptionId;
// 订阅方式
private String subscriptionType;
// 订阅开始时间
private String startDate;
private String endDate;
// 下一个支付日期
private String nextPayDate;
// 下次付款时间reminder
private String renewalTime;
// 付款失败原因
private String failMessage;
}

View File

@@ -0,0 +1,19 @@
package com.ai.da.model.dto;
import com.ai.da.model.vo.PageQueryBaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("按时间查询")
public class TimeQueryBaseDTO extends PageQueryBaseVo {
@ApiModelProperty("按时间区间查询 区间起点")
private String startTime;
@ApiModelProperty("按时间区间查询 区间终点")
private String endTime;
}

View File

@@ -0,0 +1,13 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class UpdateUserInfoDTO {
private String country;
private String occupation;
private String title;
private String surname;
private String givenName;
}

View File

@@ -0,0 +1,13 @@
package com.ai.da.model.dto;
import com.ai.da.mapper.primary.entity.UserLikeSort;
import lombok.Data;
import java.util.List;
@Data
public class UserLikeSortDTO{
private Long userLikeGroupId;
List<UserLikeSort> userLikeSortList;
}

View File

@@ -1,13 +1,14 @@
package com.ai.da.model.vo; package com.ai.da.model.vo;
import com.ai.da.mapper.primary.entity.AccountExtend;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import java.util.List;
import java.util.Map;
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@@ -40,4 +41,42 @@ public class AccountLoginVO {
private Long followerCount; private Long followerCount;
private List<AccountExtend> accountExtendList;
private Long validStartTime;
private Long validEndTime;
private String Language;
// 订阅id(stripe提供)
private String subscriptionId;
// 订阅状态
private String status;
// 订阅过期时间
private String expireTime;
// 订阅类型 month || year
private String subscriptionType;
// 是否自动续订
private boolean isAutoRenewal;
// 是否是affiliate
private boolean isAffiliate = false;
private String country;
private String occupation;
private Long usernameModify;
private String title;
private String surname;
private String givenName;
} }

View File

@@ -0,0 +1,25 @@
package com.ai.da.model.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AffiliateInvitationDetailsVO {
private Long accountId;
private String username;
private Float firstSubscriptionPaymentAmount;
private Float commission;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private LocalDateTime time;
}

View File

@@ -0,0 +1,17 @@
package com.ai.da.model.vo;
import com.ai.da.mapper.primary.entity.Affiliate;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AffiliateVO extends Affiliate {
private Long linkViewCount;
private String username;
}

View File

@@ -0,0 +1,9 @@
package com.ai.da.model.vo;
import lombok.Data;
@Data
public class BindEmailVO {
private String token;
}

View File

@@ -0,0 +1,18 @@
package com.ai.da.model.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class CheckCouponsVO {
@ApiModelProperty("expired 过期 || invalid 无效 || valid 有效 || pending 尚未生效")
private String status;
private String message;
private Float discountedPrice;
}

View File

@@ -40,4 +40,6 @@ public class CollectionElementVO {
private String urlWithWhiteSide; private String urlWithWhiteSide;
private String originalUrl;
} }

View File

@@ -12,6 +12,8 @@ import java.util.List;
@ApiModel("design like-响应") @ApiModel("design like-响应")
public class DesignLikeVO { public class DesignLikeVO {
private Long userLikeSortId;
@ApiModelProperty("分组id") @ApiModelProperty("分组id")
private Long userGroupId; private Long userGroupId;
@ApiModelProperty("分组详情id") @ApiModelProperty("分组详情id")
@@ -19,6 +21,10 @@ public class DesignLikeVO {
private String pictureName; private String pictureName;
private Long userLikeId;
private Integer sort;
public DesignLikeVO() { public DesignLikeVO() {
} }
} }

View File

@@ -29,11 +29,11 @@ public class DesignSinglePrint implements Serializable {
private String minIOPath; private String minIOPath;
@ApiModelProperty("印花位置") @ApiModelProperty("印花位置")
private List<Double> location; private List<Float> location;
@ApiModelProperty("印花大小") @ApiModelProperty("印花大小")
@Range(max = 1, message = "印花缩放值需用大于等于0小于等于1的数表示") @Range(max = 1, message = "印花缩放值需用大于等于0小于等于1的数表示")
private Double scale; private List<Float> scale;
@Range(min = -360, max = 360, message = "印花旋转角度范围为-360° ~ 360°") @Range(min = -360, max = 360, message = "印花旋转角度范围为-360° ~ 360°")
@ApiModelProperty("印花角度") @ApiModelProperty("印花角度")
@@ -46,12 +46,12 @@ public class DesignSinglePrint implements Serializable {
public DesignSinglePrint() { public DesignSinglePrint() {
} }
public DesignSinglePrint(String path, Double scale) { public DesignSinglePrint(String path, List<Float> scale) {
this.path = path; this.path = path;
this.scale = scale; this.scale = scale;
} }
public DesignSinglePrint(String level2Type, String path, String minIOPath, List<Double> location, Double scale, Double angle, Integer priority, Boolean ifSingle) { public DesignSinglePrint(String level2Type, String path, String minIOPath, List<Float> location, List<Float> scale, Double angle, Integer priority, Boolean ifSingle) {
this.level2Type = level2Type; this.level2Type = level2Type;
this.path = path; this.path = path;
this.minIOPath = minIOPath; this.minIOPath = minIOPath;

View File

@@ -0,0 +1,29 @@
package com.ai.da.model.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用于订单列表展示(展示的是所有支付信息)
*/
@Data
public class OrderListVO {
private Long id;
private Float amount;
private String paymentMethod;
private String state;
private String orderType;
private String invoiceLink;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private LocalDateTime createTime;
}

View File

@@ -5,7 +5,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
@NoArgsConstructor @NoArgsConstructor
@Data @Data
@@ -43,4 +42,15 @@ public class PantoneVO {
this.name = name; this.name = name;
this.tcx = tcx; this.tcx = tcx;
} }
public PantoneVO(Integer r, Integer g, Integer b, Integer h, Integer s, Integer v) {
this.r = r;
this.g = g;
this.b = b;
this.h = h;
this.s = s;
this.v = v;
this.name = "--";
this.tcx = "--";
}
} }

View File

@@ -0,0 +1,36 @@
package com.ai.da.model.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
@ApiModel("交易记录详情")
public class PaymentInfoVO {
private Long id;
@ApiModelProperty("付款用户名")
private String payer;
@ApiModelProperty("付款者邮箱")
private String email;
@ApiModelProperty("选择的支付平台 PayPal || Stripe || Alipay-HK")
private String platform;
@ApiModelProperty("支付的金额 单位:HKD")
private String payerTotal;
@ApiModelProperty("商品种类 new || renewal || credits")
private String type;
@ApiModelProperty("交易状态 Success || Fail || Pending")
private String status;
@ApiModelProperty("付款人所在国家")
private String country;
@ApiModelProperty("付款人所在城市")
private String city;
@ApiModelProperty("使用Stripe具体的支付方式")
private String paymentMethod;
@ApiModelProperty("信用卡支付的卡号后四位")
private String last4;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private String createTime;
}

View File

@@ -23,4 +23,7 @@ public class UserLikeVO {
@ApiModelProperty("图片路径") @ApiModelProperty("图片路径")
private String designOutfitUrl; private String designOutfitUrl;
private String pictureName; private String pictureName;
private Integer sort;
private Long userLikeSortId;
} }

View File

@@ -41,6 +41,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@@ -237,6 +238,9 @@ public class PythonService {
int[] sketchNumbers = new int[3]; int[] sketchNumbers = new int[3];
int designNum = elementVO.getDesignNum(); int designNum = elementVO.getDesignNum();
Set<DesignPythonObject> assembledObjects = new HashSet<>(); // 用于存储已组装的 DesignPythonObject
DesignPythonObject lastAssembledObject = null; // 上一次组装的对象
for (int i = 0; i < designNum; i++) { for (int i = 0; i < designNum; i++) {
CurrentDesignPictureTypeEnum designPictureType = calculateCurrentDesignPictureTypeNew(elementVO, sketchNumbers, systemScale); CurrentDesignPictureTypeEnum designPictureType = calculateCurrentDesignPictureTypeNew(elementVO, sketchNumbers, systemScale);
if (designPictureType == null) break; if (designPictureType == null) break;
@@ -256,19 +260,70 @@ public class PythonService {
noPrintNum--; noPrintNum--;
break; break;
} }
// updatePrintNumbers(designPrintPictureType, pinPrintNum, noPinPrintNum, noPrintNum);
DesignPythonItemPrint designPythonItemPrint = getRandomPrint(elementVO, designPrintPictureType); DesignPythonItemPrint designPythonItemPrint = getRandomPrint(elementVO, designPrintPictureType);
elementVO.setDesignPythonItemPrint(designPythonItemPrint); elementVO.setDesignPythonItemPrint(designPythonItemPrint);
elementVO.setDesignPrintPictureTypeLayoutList(calculateCurrentDesignPintPictureTypeLayout(elementVO.getModelSex())); elementVO.setDesignPrintPictureTypeLayoutList(calculateCurrentDesignPintPictureTypeLayout(elementVO.getModelSex()));
List<String> beforeAssemblyHasUseMd5List = new ArrayList<>(elementVO.getHasUseMd5List());
DesignPythonObject pythonObject = createDesignPythonObject(elementVO, designPictureType, systemScale, singleOverall, switchCategory, i); DesignPythonObject pythonObject = createDesignPythonObject(elementVO, designPictureType, systemScale, singleOverall, switchCategory, i);
// 如果当前对象与已组装的对象重复,则跳过当前组装
DesignPythonObject designPythonObjectCopy = getCopy(pythonObject);
boolean isDuplicate = assembledObjects.contains(designPythonObjectCopy);
if (isDuplicate) {
// if (lastAssembledObject != null && assembledObjects.contains(lastAssembledObject)) {
// // 如果当前组装与前一个组装的对象重复,且前一个组装也重复,结束组装
// System.out.println("当前组装的对象与前两个组装的对象重复,结束组装。");
// break;
// }
elementVO.setHasUseMd5List(beforeAssemblyHasUseMd5List);
i --;
switch (designPrintPictureType) {
case PIN:
pinPrintNum++;
break;
case NO_PIN:
noPinPrintNum++;
break;
case NO:
noPrintNum++;
break;
}
continue;
}
// 将当前对象添加到已组装的集合中,并记录
assembledObjects.add(designPythonObjectCopy);
// lastAssembledObject = designPythonObjectCopy; // 更新上一次组装的对象
objects.add(pythonObject); objects.add(pythonObject);
redisUtil.addProcessId(processId, i + 1); redisUtil.addProcessId(processId, i + 1);
} }
return designPythonObjects; return designPythonObjects;
} }
private DesignPythonObject getCopy(DesignPythonObject pythonObject) {
DesignPythonObject designPythonObjectCopy = CopyUtil.copyObject(pythonObject, DesignPythonObject.class);
designPythonObjectCopy.setObjectSign(null);
DesignPythonBasic basic = designPythonObjectCopy.getBasic();
basic.setSave_name(null);
designPythonObjectCopy.setBasic(basic);
List<DesignPythonItem> items = designPythonObjectCopy.getItems();
List<DesignPythonItem> itemsCopy = new ArrayList<>();
for (DesignPythonItem item : items) {
item.setElementId(null);
item.setIcon(null);
item.setBusinessId(null);
item.setImage_id(null);
item.setImageId(null);
itemsCopy.add(item);
}
designPythonObjectCopy.setItems(itemsCopy);
return designPythonObjectCopy;
}
private void updateSketchNumbers(CurrentDesignPictureTypeEnum designPictureType, int[] sketchNumbers) { private void updateSketchNumbers(CurrentDesignPictureTypeEnum designPictureType, int[] sketchNumbers) {
switch (designPictureType) { switch (designPictureType) {
case PIN: case PIN:
@@ -301,7 +356,9 @@ public class PythonService {
DesignPythonObject pythonObject = new DesignPythonObject(); DesignPythonObject pythonObject = new DesignPythonObject();
pythonObject.setItems(coverToDesignPythonItemNew(elementVO, designPictureType, systemScale)); pythonObject.setItems(coverToDesignPythonItemNew(elementVO, designPictureType, systemScale));
pythonObject.setBasic(coverToBasic(pythonObject.getItems().get(0), singleOverall, switchCategory, elementVO.getDesignLibraryModelPoint())); pythonObject.setBasic(coverToBasic(pythonObject.getItems().get(0), singleOverall, switchCategory, elementVO.getDesignLibraryModelPoint()));
pythonObject.setObjectSign(elementVO.getRequestIdList().get(i)); if (CollectionUtil.isNotEmpty(elementVO.getRequestIdList())) {
pythonObject.setObjectSign(elementVO.getRequestIdList().get(i));
}
return pythonObject; return pythonObject;
} }
@@ -2710,13 +2767,13 @@ public class PythonService {
int size = printObject.size(); int size = printObject.size();
// 占位符填充数组 // 占位符填充数组
List<List<Double>> locationS = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> locationS = new ArrayList<>(Collections.nCopies(size, null));
List<Double> scaleS = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> scaleS = new ArrayList<>(Collections.nCopies(size, null));
List<Double> angleS = new ArrayList<>(Collections.nCopies(size, null)); List<Double> angleS = new ArrayList<>(Collections.nCopies(size, null));
ArrayList<String> pathsS = new ArrayList<>(Collections.nCopies(size, null)); ArrayList<String> pathsS = new ArrayList<>(Collections.nCopies(size, null));
List<List<Double>> locationO = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> locationO = new ArrayList<>(Collections.nCopies(size, null));
List<Double> scaleO = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> scaleO = new ArrayList<>(Collections.nCopies(size, null));
List<Double> angleO = new ArrayList<>(Collections.nCopies(size, null)); List<Double> angleO = new ArrayList<>(Collections.nCopies(size, null));
ArrayList<String> pathsO = new ArrayList<>(Collections.nCopies(size, null)); ArrayList<String> pathsO = new ArrayList<>(Collections.nCopies(size, null));
@@ -2773,8 +2830,8 @@ public class PythonService {
int size = trims.getPrints().size(); int size = trims.getPrints().size();
// 占位符填充数组 // 占位符填充数组
List<List<Double>> location = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> location = new ArrayList<>(Collections.nCopies(size, null));
List<Double> scale = new ArrayList<>(Collections.nCopies(size, null)); List<List<Float>> scale = new ArrayList<>(Collections.nCopies(size, null));
List<Double> angle = new ArrayList<>(Collections.nCopies(size, null)); List<Double> angle = new ArrayList<>(Collections.nCopies(size, null));
ArrayList<String> paths = new ArrayList<>(Collections.nCopies(size, null)); ArrayList<String> paths = new ArrayList<>(Collections.nCopies(size, null));
@@ -2784,6 +2841,8 @@ public class PythonService {
prints.forEach(p -> { prints.forEach(p -> {
p.getLocation().set(0, p.getLocation().get(0)); p.getLocation().set(0, p.getLocation().get(0));
p.getLocation().set(1, p.getLocation().get(1)); p.getLocation().set(1, p.getLocation().get(1));
p.getScale().set(0, p.getScale().get(0));
p.getScale().set(1, p.getScale().get(1));
Integer priority = p.getPriority(); Integer priority = p.getPriority();
location.set(priority - 1, p.getLocation()); location.set(priority - 1, p.getLocation());
scale.set(priority - 1, p.getScale()); scale.set(priority - 1, p.getScale());
@@ -3671,4 +3730,71 @@ public class PythonService {
//生成失败 //生成失败
throw new BusinessException("Atribute recognition exception!"); throw new BusinessException("Atribute recognition exception!");
} }
public String designBatch(DesignPythonObjects designPythonObjects, Long accountId, int designNum, String taskId) {
// todo 限流校验
// AccessLimitUtils.validate("design",5);
// 将 designPythonObjects 写入文件
File file = new File("design_batch_test.txt");
try (FileWriter writer = new FileWriter(file)) {
String param = JSON.toJSONString(designPythonObjects, SerializerFeature.DisableCircularReferenceDetect);
writer.write(param);
log.info("设计请求参数已写入文件:####{}", file.getAbsolutePath());
} catch (IOException e) {
log.error("写入文件异常:{}", e.getMessage());
throw new BusinessException("file.write.exception");
}
OkHttpClient client = new OkHttpClient().newBuilder()
.connectTimeout(30, TimeUnit.SECONDS)
.pingInterval(5, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
// 构建 multipart 表单
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", "design_batch_test.txt",
RequestBody.create(MediaType.parse("text/plain"), file))
.addFormDataPart("tasks_id", taskId)
.addFormDataPart("user_id", String.valueOf(accountId))
.addFormDataPart("file_name", "design_batch_test" + taskId + ".json")
.addFormDataPart("total", String.valueOf(designNum))
.build();
Request request = new Request.Builder()
.url("http://18.167.251.121:9994/api/design_batch_generate")
.method("POST", body)
.addHeader("Content-Type", "multipart/form-data")
.build();
Response response;
String responseBody;
try {
response = client.newCall(request).execute();
} catch (IOException ioException) {
AccessLimitUtils.validateOut("design");
log.error("PythonService##design异常###{}", ExceptionUtil.getThrowableList(ioException));
throw new BusinessException("design.interface.exception");
}
if (response.isSuccessful()) {
try {
if (Objects.nonNull(response.body())) {
responseBody = response.body().string();
JSONObject responseObject = JSON.parseObject(responseBody);
log.info("PythonService##responseObject###{}", responseObject);
return taskId;
}
throw new BusinessException("design.interface.exception");
} catch (IOException | JSONException e) {
log.error("PythonService##design异常###{}", e.getMessage());
throw new BusinessException("design.interface.exception");
}
}
log.error("PythonService##design异常response###{}", response);
throw new BusinessException("design.interface.exception");
}
} }

View File

@@ -10,12 +10,12 @@ import java.util.List;
public class DesignPythonItemElement { public class DesignPythonItemElement {
@ApiModelProperty("print的位置 传 [[0.2, 0.2]]") @ApiModelProperty("print的位置 传 [[0.2, 0.2]]")
private List<List<Double>> location = new ArrayList<>(); private List<List<Float>> location = new ArrayList<>();
private List<String> element_path_list = new ArrayList<>(); private List<String> element_path_list = new ArrayList<>();
@ApiModelProperty("print的缩放比例 传 [0.2, 0.2]") @ApiModelProperty("print的缩放比例 传 [0.2, 0.2]")
private List<Double> element_scale_list = new ArrayList<>(); private List<List<Float>> element_scale_list = new ArrayList<>();
@ApiModelProperty("print的旋转角度 传 [0.2, 0.2]") @ApiModelProperty("print的旋转角度 传 [0.2, 0.2]")
private List<Double> element_angle_list = new ArrayList<>(); private List<Double> element_angle_list = new ArrayList<>();

View File

@@ -36,10 +36,10 @@ public class DesignPythonItemPrint {
@ApiModelProperty("print的位置 传 [[0.2, 0.2]]") @ApiModelProperty("print的位置 传 [[0.2, 0.2]]")
private List<List<Double>> location = new ArrayList<>(); private List<List<Float>> location = new ArrayList<>();
@ApiModelProperty("print的缩放比例 传 [0.2, 0.2]") @ApiModelProperty("print的缩放比例 传 [0.2, 0.2]")
private List<Double> print_scale_list = new ArrayList<>(); private List<List<Float>> print_scale_list = new ArrayList<>();
@ApiModelProperty("print的旋转角度 传 [0.2, 0.2]") @ApiModelProperty("print的旋转角度 传 [0.2, 0.2]")
private List<Double> print_angle_list = new ArrayList<>(); private List<Double> print_angle_list = new ArrayList<>();
@@ -52,8 +52,8 @@ public class DesignPythonItemPrint {
public DesignPythonItemPrint(List<String> print_path_list, Boolean ifDesign) { public DesignPythonItemPrint(List<String> print_path_list, Boolean ifDesign) {
if (ifDesign){ if (ifDesign){
this.print_path_list = print_path_list; this.print_path_list = print_path_list;
this.location = Collections.singletonList(Arrays.asList(0.0, 0.0)); this.location = Collections.singletonList(Arrays.asList(0.0f, 0.0f));
this.print_scale_list = Arrays.asList(0.0, 0.0); this.print_scale_list = Collections.singletonList(Arrays.asList(0.0f, 0.0f));
this.print_angle_list = Arrays.asList(0.0, 0.0); this.print_angle_list = Arrays.asList(0.0, 0.0);
} }

View File

@@ -2,11 +2,12 @@ package com.ai.da.service;
import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Account;
import com.ai.da.mapper.primary.entity.GoogleUser; import com.ai.da.mapper.primary.entity.AccountExtend;
import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.mapper.primary.entity.TrialOrder;
import com.ai.da.model.dto.*; import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountLoginVO;
import com.ai.da.model.vo.AccountPreLoginVO; import com.ai.da.model.vo.AccountPreLoginVO;
import com.ai.da.model.vo.BindEmailVO;
import com.ai.da.model.vo.PersonalHomepageVO; import com.ai.da.model.vo.PersonalHomepageVO;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
@@ -47,7 +48,9 @@ public interface AccountService extends IService<Account> {
* @param accountBindEmailDTO * @param accountBindEmailDTO
* @return * @return
*/ */
Boolean bindEmail(AccountBindEmailDTO accountBindEmailDTO); BindEmailVO bindEmail(AccountBindEmailDTO accountBindEmailDTO, HttpServletRequest request);
BindEmailVO bindEmail(String email);
/** /**
* 忘记密码 * 忘记密码
@@ -171,15 +174,15 @@ public interface AccountService extends IService<Account> {
void registerUserToVisitor(); void registerUserToVisitor();
Map<String, Long> getNicknameModifyTimes(); Long getNicknameModifyTimes();
void editUserName(String newUserName); void editUserName(String newUserName);
void verifyUserEmail(String verifyCode); /*void verifyUserEmail(String verifyCode);
void changeUserEmail(String newMailbox); void changeUserEmail(String newMailbox);
void activateNewEmail(String token); void activateNewEmail(String token);*/
String updateNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request); String updateNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request);
@@ -203,9 +206,23 @@ public interface AccountService extends IService<Account> {
Account accountDetail(Long id); Account accountDetail(Long id);
AccountLoginVO parseGoogleCredential(String credential); AccountLoginVO parseGoogleCredential(String credential, Integer type);
AccountLoginVO parseWeChatCode(String code); AccountLoginVO parseWeChatCode(String code, Integer type);
AccountLoginVO getAccountDetail(); AccountLoginVO getAccountDetail();
AccountExtend bindGoogle(String credential);
AccountExtend bindWeChat(String code);
Boolean unbindWeChat();
Boolean unbindGoogle();
boolean updateAccountValidity(Long accountId, Long currentPeriodEnd);
void updateUserRoleAndCredits(Long accountId, String type);
Boolean updateUserInfo(UpdateUserInfoDTO updateUserInfoDTO);
} }

View File

@@ -0,0 +1,36 @@
package com.ai.da.service;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.mapper.primary.entity.Affiliate;
import com.ai.da.model.dto.AffiliateQueryDTO;
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
import com.ai.da.model.vo.AffiliateVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface AffiliateService extends IService<Affiliate> {
Boolean registerAsAnAffiliate(String promotionMethod);
PageBaseResponse<AffiliateVO> getAffiliateList(AffiliateQueryDTO affiliateQueryDTO);
AffiliateVO personalAffiliateCenter();
double[] getPersonalMonthlyIncome(int year);
Boolean applicationApproval(Long id, Boolean isApproved, Float commission);
void updateCommissionPercentage(Long id, Float commission);
void updateAffiliateInfoWithPayment();
Boolean affiliateLinkViewsIncrease(Long id);
IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO);
Affiliate getByAccountId(Long accountId);
void commissionCalculation(Integer year, Integer month);
void calcCouponsCommission();
}

View File

@@ -1,9 +1,12 @@
package com.ai.da.service; package com.ai.da.service;
import com.ai.da.model.dto.ProductPurchaseDTO;
import javax.servlet.http.HttpServletRequest;
import java.util.Map; import java.util.Map;
public interface AliPayService { public interface AliPayService {
String tradeCreate(Integer amount,String returnUrl); String tradeCreate(ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request);
String tradeNotify(Map<String, String> params); String tradeNotify(Map<String, String> params);

View File

@@ -1,10 +1,13 @@
package com.ai.da.service; package com.ai.da.service;
import com.ai.da.model.dto.AlipayHKCallbackDTO; import com.ai.da.model.dto.AlipayHKCallbackDTO;
import com.ai.da.model.dto.ProductPurchaseDTO;
import javax.servlet.http.HttpServletRequest;
public interface AlipayHKService { public interface AlipayHKService {
String createOrder(Integer amount, String wallet); String createOrder(ProductPurchaseDTO productPurchaseDTO, HttpServletRequest request);
String callback(String paramString); String callback(String paramString);

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