Compare commits

...

93 Commits

Author SHA1 Message Date
yyb
6250442c77 update 租赁系统1.1.0 bug 测试修改 2025-12-16 11:33:38 +08:00
yyb
6983e8657b update 租赁系统1.1.0新版本业务完成 2025-12-12 15:13:53 +08:00
yyb
cdc0cc8212 update 租赁系统订单相关接口,tcp客户端相关业务 2025-12-05 17:46:29 +08:00
yyb
7cd19a2338 update 租赁系统业务完成,其他矿池挖矿机器租赁业务开始 2025-11-20 11:01:34 +08:00
yyb
a7a2b73d00 update 租赁系统业务完成,其他矿池挖矿机器租赁业务开始 2025-11-19 16:39:25 +08:00
yyb
9c0cc31a64 update 租赁系统业务完成(待测试) 2025-11-18 11:13:19 +08:00
yyb
20fcfa778e update 租赁系统11-14 一订单对应多个卖家需求完成 2025-11-14 11:41:39 +08:00
yyb
0fff57492e update 邮箱样式微调 2025-11-07 16:35:02 +08:00
yyb
0dfc209485 update 邮箱 2025-11-04 14:59:06 +08:00
yyb
2fedb72480 update 邮箱 2025-11-04 14:58:30 +08:00
yyb
f4566777d7 update 新增eth 币价定时任务 2025-11-04 14:57:03 +08:00
yyb
10d85fe508 update 新增eth 币价定时任务 2025-11-03 11:21:07 +08:00
yyb
066c3b48f6 update 在离线和验证码邮件发送改为html 2025-11-03 09:45:17 +08:00
yyb
4462ba7e7e update mona,grs,nexa,rxd 矿机收益定时任务修改 2025-10-15 14:33:10 +08:00
yyb
3bf81f5749 update 矿机离线邮箱发送定时任务修改 2025-10-15 09:58:05 +08:00
yyb
da64a7a517 update 矿机离线邮箱发送定时任务修改 2025-10-14 15:49:23 +08:00
yyb
4929188dd7 update 矿机离线邮箱发送定时任务修改 2025-10-13 16:17:35 +08:00
yyb
db21058db1 update 矿机离线邮箱发送定时任务修改 2025-10-13 13:49:23 +08:00
yyb
6ed6c2fc70 update 矿机离线邮箱发送定时任务修改 2025-10-13 13:33:04 +08:00
yyb
4e9d55aab6 update 新增算法sha3x xtm币种,后台管理系统优化钱包出入账信息 2025-10-09 14:19:38 +08:00
yyb
2efa65222d update 新增算法sha3x xtm币种,后台管理系统优化钱包出入账信息 2025-09-28 13:48:27 +08:00
yyb
ef395c5253 update 新增数据补全,删除接口 2025-09-12 16:27:48 +08:00
yyb
7161e6fe57 update 新增数据补全,删除接口 2025-09-12 16:27:20 +08:00
yyb
6bd204dc4b update 新增数据补全,删除接口 2025-09-12 15:30:50 +08:00
yyb
f0a2309b42 update 后台管理新增定时任务开关,收益入库定时任务修改。新增用户待支付汇总 接口 2025-09-05 14:18:23 +08:00
yyb
ec8faeb41d update 后台管理新增定时任务开关,收益入库定时任务修改。新增用户待支付汇总 接口 2025-09-05 11:18:52 +08:00
yyb
a9ddc0b9d3 update 门罗币上线m2pool矿池 2025-09-01 11:19:49 +08:00
yyb
182a2d6c43 update 后台管理系统出入账接口问题修复 2025-08-27 15:58:57 +08:00
yyb
981838726c update 后台管理系统出入账接口问题修复 2025-08-27 15:03:11 +08:00
yyb
f8264b2df1 update 聊天模块新增异常 2025-08-25 13:39:55 +08:00
yyb
80b15dcf5b update 聊天室误删客服bug修改 2025-08-20 11:16:58 +08:00
yyb
7258909381 update 全网报块定时任务修复 2025-08-13 13:36:41 +08:00
yyb
94899a4baa update 文档管理html 文本翻译改为腾讯云机器翻译服务器api,优化翻译逻辑,减少翻译量 2025-08-12 17:09:06 +08:00
yyb
95573662ff update 文档管理 翻译bug修改 2025-08-04 11:27:08 +08:00
yyb
c73dc4db7b update 文档管理系统新增子类型 2025-07-23 09:57:16 +08:00
yyb
00c490d28f update 解决定时任务cpu飙升问题 2025-07-21 09:41:33 +08:00
yyb
b43e8f9965 update 新增后台管理系统文档管理模块,以及业务系统帮助中心文档接口。修改首页折线图补零逻辑bug,及管理系统挖矿账户详情页,收支详情修改 2025-07-16 15:40:49 +08:00
yyb
0857913e54 update 工单系统,客服回复空格丢失问题 。挖矿账户钱包总余额展示 2025-07-09 13:58:42 +08:00
yyb
a51771db2e update 广播模块,新增广播按钮和跳转路径。定时任务新增开关功能 2025-07-08 14:22:25 +08:00
yyb
c698a8244c update 广播信息中英翻译功能,用户个人中心apikey失效修改问题 2025-07-02 16:18:06 +08:00
yyb
5a8e59336a update 管理系统用户算力曲线,在离线柱状图 2025-06-30 14:50:45 +08:00
yyb
0b2decafc9 update 工单,通知相关接口调试修改 2025-06-25 16:31:34 +08:00
yyb
315079e5d1 update nexa 收益计算器问题 2025-06-17 11:28:22 +08:00
yyb
4fad507896 update v1.1.0 新增用户详情挖矿账户所有收益金额、时间、状态、转账地址查询。用户列表接口新增返回挖矿账户状态 2025-06-16 14:26:50 +08:00
yyb
1ea709d1a8 update v1.1.0 新增用户详情挖矿账户所有收益金额、时间、状态、转账地址查询。用户列表接口新增返回挖矿账户状态 2025-06-16 11:42:21 +08:00
yyb
eeee428a94 update 聊天室功能完成 2025-06-13 15:11:45 +08:00
yyb
9ae9a88a46 update 新增mp3,aif,aiff,wav,wma 文件上传功能 2025-06-09 17:56:27 +08:00
yyb
3e2178e161 update 修改websocket 心跳间隔,nexa地址检查bug 2025-06-05 16:46:29 +08:00
yyb
ca86a560dc update 修改个人中心重置密码redis key 问题 2025-05-30 17:36:15 +08:00
yyb
ffff88bacf update ip限制改为,同一ip可多个登录用户连接,游客只能存在一个。新增一个因为服务器宕机原因未删除游客聊天室和消息的定时任务 2025-05-30 17:35:37 +08:00
yyb
9904fbeb24 update 幸运值90天限定为7天bug修改 2025-05-28 16:26:52 +08:00
yyb
d098702af7 update v1.1.0 版本接口提交 2025-05-27 17:51:18 +08:00
yyb
f65f08d1a6 update 聊天室功能,图片改url 2025-05-27 17:50:50 +08:00
yyb
65bd4c90c1 update dgb系列全网报块入库---修改测试完成 2025-05-27 17:50:20 +08:00
yyb
6b72064d5c update 新增一个查询所有矿工账号对应币种,的一段时间内的算力总和 2025-05-26 16:05:02 +08:00
yyb
b6b26e591f update 聊天室遗漏队列添加,dgb系列幸运值全网报块数问题 2025-05-26 14:04:28 +08:00
yyb
779aaca109 update nexa 全网算力调用三方api修改 2025-05-23 09:33:45 +08:00
yyb
5d7e3e6401 update dgb系列幸运值计算 2025-05-21 15:06:04 +08:00
yyb
86bb162b16 update 幸运值计算bug修改 2025-05-19 16:56:02 +08:00
yyb
88ea456424 update 幸运值计算bug修改 2025-05-19 15:12:39 +08:00
yyb
e3e7993134 Merge branch 'main' of http://47.129.22.53:22345/lizixuan/m2pool_web_backend 2025-05-14 15:08:16 +08:00
yyb
b1d1a3a93e 消息已讀 2025-05-14 15:08:09 +08:00
yyb
31e0f400d9 Merge remote-tracking branch 'origin/main' 2025-05-14 15:03:43 +08:00
yyb
40f4cd0007 update 放行部分接口,方便游客使用。区分游客和客服的对象。 2025-05-14 15:02:13 +08:00
jxy_duyi
a0750e1246 update 测试提交 2025-05-12 15:20:06 +08:00
yyb
cd57115454 update 幸运值修改 2025-05-12 09:37:33 +08:00
yyb
87a6e09c14 update 幸运值修改 2025-05-08 11:25:14 +08:00
yyb
14c8e731f2 update 全网算力优化,幸运值算法优化 2025-05-07 17:29:27 +08:00
yyb
589470260c update 全网算力优化,幸运值算法优化 2025-05-07 17:07:10 +08:00
yyb
3565396252 update 全网算力优化,幸运值算法优化 2025-05-07 16:33:27 +08:00
yyb
bea674e93c update 客户端:根据当前用户邮箱查询聊天室 和查询七天内的记录 接口修改,新增用户邮箱参数 2025-04-30 17:36:43 +08:00
yyb
934be40c8b update 废弃历史消息查询接口,自定义ws链接和ip限制数监听器 2025-04-30 14:02:32 +08:00
yyb
340f81a513 update 游客和用户未读数新增 2025-04-28 16:19:54 +08:00
yyb
099e973f64 update chat_room表新增client_read_num 和service_read_num,chat_message 表删除is_read字段。 websocket 返回消息新增一个isCreate 字段。 2025-04-28 16:05:08 +08:00
yyb
d941b161f9 update 聊天室列表新增返回对象,新增部分swagger注解 2025-04-27 14:27:09 +08:00
yyb
4dc7964ef4 update knife4j 配置 2025-04-25 14:33:20 +08:00
yyb
889189e726 update websocket 链接限制变为同ip可以多个用户登录,单用户只能登录一个 2025-04-24 16:10:39 +08:00
jxy_duyi
c596d9ab30 update swagger集成knife4j配置 2025-04-23 12:28:33 +08:00
yyb
e34a630e9e update bug 修改 2025-04-23 12:26:21 +08:00
yyb
c0fea6a787 update bug 修改 2025-04-23 12:24:50 +08:00
jxy_duyi
798bec4812 update 获取当前登录用户身份信息代码修正 2025-04-22 15:25:14 +08:00
yyb
b95eb1c1b2 update 登录用户消息获取为空修改,查找聊天室和随机匹配客服功能合并。 2025-04-22 12:04:17 +08:00
jxy_duyi
e077f5f296 update 获取客户列表方法修改 2025-04-22 10:54:30 +08:00
yyb
dc44379c5e update 修改消息存储规则 2025-04-21 15:18:57 +08:00
yyb
128078acaa Merge remote-tracking branch 'origin/main' 2025-04-21 10:15:47 +08:00
yyb
1d6fc57d27 update 修改消息存储规则 2025-04-21 10:15:16 +08:00
jxy_duyi
7f1175e9bd update alph收益相关数据更新 2025-04-18 18:27:53 +08:00
yyb
de4788319b update 文件上传服务完成 2025-04-17 17:47:03 +08:00
yyb
bcdbb2b538 update websocket 异常状态码新增 2025-04-17 16:45:02 +08:00
yyb
6db9f1a7b4 update websocket 异常状态码新增 2025-04-17 11:20:53 +08:00
yyb
e51364f20d update nacos 端口修改 2025-04-16 16:33:44 +08:00
yyb
7898750934 update 删除.iml 文件 2025-04-16 16:21:37 +08:00
yyb
3773c466ae update 删除.iml 文件 2025-04-16 16:19:03 +08:00
562 changed files with 39342 additions and 4170 deletions

438
lease_v1.0.0.sql Normal file
View File

@@ -0,0 +1,438 @@
-- 第一版租赁系统 只支持自营矿池挖矿
-- -- 创建用户表,存储用户基本信息
-- CREATE TABLE IF NOT EXISTS `lease_user` (
-- `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
-- `user_id` VARCHAR(50) NOT NULL UNIQUE COMMENT '用户id(邮箱)',
-- `password` VARCHAR(64) NOT NULL COMMENT '密码',
-- `address` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '钱包地址',
-- `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-- `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
--
--
-- 创建店铺表
CREATE TABLE IF NOT EXISTS `lease_shop` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '店铺ID',
`user_email` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '店铺拥有者邮箱',
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '店铺名称',
`image` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '店铺图片路径',
`state` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '商铺状态 0 待审核 1 审核通过(店铺开启) 2 店铺关闭',
`description` TEXT COMMENT '店铺描述',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段',
UNIQUE INDEX idx_email (user_email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺表';
-- 创建店铺--店铺支持收款地址配置表
CREATE TABLE IF NOT EXISTS `lease_shop_config` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '配置ID',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`product_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品 ID (商品id为0代表适用于店铺中所有商品) ------- 该字段删除',
`pay_coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'nexa rxd dgbo dgbq dgbs alph enx grs mona usdt usdc busd',
`chain` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖家地址链名称',
`pay_coin_image` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '支付币种图标',
`pay_type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '币种类型 0 虚拟币 1 稳定币',
`pay_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖方对应收款钱包',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`qrcode` LONGTEXT COMMENT '卖方对应收款钱包二维码',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺支持收款地址配置表';
-- 用于店铺收款钱包配置 时下拉选择链和币
CREATE TABLE IF NOT EXISTS `lease_chain_coin_config` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '配置ID',
`coin_full` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种全称',
`coin_image` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '支付币种图标',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'nexa rxd dgbo dgbq dgbs alph enx grs mona usdt usdc busd',
`chain` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '链名称'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺支持收款地址配置表(店铺钱包)';
-- 创建商品表,存储挖矿机器和算力套餐信息
CREATE TABLE IF NOT EXISTS `lease_product` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '商品 ID',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '商品名称',
`image` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '商品图片路径',
`algorithm` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '算法',
`sale_number` INT NOT NULL DEFAULT 0 COMMENT '销售机器数(租赁出一次算一个销售数)',
`total_machine_number` INT NOT NULL DEFAULT 0 COMMENT '当前总矿机数(包含已售出矿机数)',
`max_price` DECIMAL(30, 18) NOT NULL DEFAULT 0.000000 COMMENT '商品下机器最大价格',
`min_price` DECIMAL(30, 18) NOT NULL DEFAULT 0.000000 COMMENT '商品下机器最小价格',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT ' 矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona',
`coin_full_name` VARCHAR(32) NOT NULL DEFAULT '' COMMENT ' 矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona',
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '商品类型0 矿机 1 算力 ',
`state` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '上下架状态0 上架1 下架',
`description` TEXT COMMENT '商品描述',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
CREATE TABLE IF NOT EXISTS `lease_product_machine` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`product_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品 ID',
`user` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器 对应的矿工账号',
`type` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '矿机型号',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT ' 矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona',
`miner` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器编号',
`theory_power` DECIMAL(32, 6) NOT NULL DEFAULT 0.000000 COMMENT '商品机器单机算力(卖方手动填写)理论算力 (如果实时变化可不要这个字段)',
`computing_power` DECIMAL(32, 6) NOT NULL DEFAULT 0.000000 COMMENT '实际算力(计算得到,商家不能够自己添加和修改) (如果实时变化可不要这个字段)',
`theory_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.00 COMMENT '单机理论收益单位usdt每日:根据添加机器时,实时计算的收益值)',
-- `actual_income` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '单机预估实际收益(每日)',
`unit` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '算力单位 GH/s TH/s PH/s',
-- `electricity_bill` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '电费 单位 $/度 (该字段目前未使用,可删除)',
`max_lease_days` INT NOT NULL DEFAULT 7 COMMENT '矿机租售天数',
`power_dissipation` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '功耗 单位kw/h',
`income_rate` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 DEFAULT 0.00 COMMENT '收益率',
`cost` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '默认单价单位$ [ 功耗 * 电费 * 24 * (1 + 收益率) ]',
`price` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '实际单价',
`sale_state` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '售出状态 0未售出 1已售出 2售出中(已下单情况该状态已不存在)',
`state` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '上下架状态0 上架1 下架',
`del` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除字段',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
KEY `idx_user_coin_miner` (`user`, `coin`, `miner`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表对应的物品机器表';
CREATE TABLE IF NOT EXISTS `lease_product_machine_price` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
`product_machine_id` BIGINT NOT NULL DEFAULT 0 COMMENT '矿机id',
`price` DECIMAL(30, 18) NOT NULL DEFAULT 0.00 COMMENT '实际单价',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '价值单位',
`chain` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '',
`del` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表对应的物品机器表';
-- 创建已购机器表(租赁表)
CREATE TABLE IF NOT EXISTS `lease_user_owned_product` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`user_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户id(邮箱)',
`product_machine_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品对应的机器id',
`user` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器 对应的矿工账号',
`order_id` BIGINT NOT NULL DEFAULT 0 COMMENT '订单 ID',
`miner` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器编号',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona',
`estimated_end_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '预估商品结束时的总收益',
`estimated_end_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '预估商品结束时的总收益 单价usdt',
`current_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '当前收益(根据购买机器到现在的平均算力计算得到)单位 币种',
`current_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '当前收益(根据购买机器到现在的平均算力计算得到----非实时单位usdt',
`settle_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '待结算收益(用于存储某天还未支付情况下的收益)',
`settle_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '待结算收益 (用于存储某天还未支付情况下的收益----非实时)单位usdt',
`order_item_id` BIGINT NOT NULL DEFAULT 0 COMMENT '订单明细 ID关联订单中的购买记录',
`address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖方对应收款钱包',
`start_time` DATETIME NOT NULL COMMENT '商品开始使用时间(购买当天24点生效)',
`end_time` DATETIME NOT NULL COMMENT '商品使用结束时间',
`purchased_computing_power` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '购买算力时实时算力,当 type 为 1 时有效',
`status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '商品状态0 表示运行中1 表示已过期 ',
`type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '商品类型0 表示挖矿机器1 表示算力套餐',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '购买时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户拥有商品详情表';
-- 创建购物车表,存储用户添加到购物车的商品信息
CREATE TABLE IF NOT EXISTS `lease_shopping_cart` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '购物车 ID',
`user_id` varchar(64) NOT NULL DEFAULT '' COMMENT '用户 ID(邮箱)',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='购物车表';
-- 创建购物车详情表
CREATE TABLE IF NOT EXISTS `lease_shopping_cart_info` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`cart_id` BIGINT NOT NULL DEFAULT 0 COMMENT '购物车ID',
`product_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品 ID',
`product_machine_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品机器ID',
`lease_time` int NOT NULL DEFAULT 1 COMMENT '租赁天数',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='购物车详情表';
-- 创建订单表,存储订单基本信息
CREATE TABLE IF NOT EXISTS `lease_order_info` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单 ID',
`order_number` VARCHAR(50) NOT NULL DEFAULT '' UNIQUE COMMENT '订单号',
`user_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户id(邮箱)',
`total_price` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '订单总价',
`status` TINYINT(1) NOT NULL DEFAULT 7 COMMENT '订单状态0 表示待支付1 表示全部已支付2 表示已取消 3售后状态 4已退款 5 支付已超时 6 支付中 ( 目前只有这三种状态 7 订单进行中 8 订单已完成 9 余额不足,订单已取消) 10 部分已支付',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- 创建订单明细表,存储订单中的商品明细
CREATE TABLE IF NOT EXISTS `lease_order_item` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单明细 ID',
`order_id` BIGINT NOT NULL DEFAULT 0 COMMENT '订单 ID',
`user_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户id(邮箱)',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`product_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品 ID',
`product_machine_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商品对应的机器id',
`user` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器 对应的矿工账号',
`miner` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '挖矿机器编号',
`name` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '商品名称',
`theory_income` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '单机理论收益',
`lease_time` INT NOT NULL DEFAULT 0 COMMENT '租赁天数',
`status` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '0 租约已过期 1 租约生效中 2 等待租约生效 ',
`pay_coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'nexa rxd dgbo dgbq dgbs alph enx grs mona usdt usdc busd',
`coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '矿机挖矿币种 nexa rxd dgbo dgbq dgbs alph enx grs mona',
`address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖方对应收款钱包',
`chain` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖家地址链名称',
`symbol` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖家地址支付币种',
`from_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '买方对应收款钱包(删除,支付时用户必定存在和卖家收款地址相同币种和链的地址,代码中已做处理)',
`from_chain` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '买方地址链名称(删除)',
`from_symbol` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '买方地址支付币种(删除)',
`image` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '商品图片路径',
`quantity` INT NOT NULL DEFAULT 1 COMMENT '商品数量(弃用)',
`price` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '商品价格',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单明细表';
-- 创建支付记录表,模拟支付信息
CREATE TABLE IF NOT EXISTS `lease_payment_record` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '支付记录 ID',
`order_id` BIGINT NOT NULL DEFAULT 0 UNIQUE COMMENT '订单 ID',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`product_id` BIGINT COMMENT '商品 ID后续删除',
`pay_coin` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'nexa rxd dgbo dgbq dgbs alph enx grs mona usdt usdc busd',
`amount` DECIMAL(40, 6) NOT NULL DEFAULT 0.000000 COMMENT '需支付总金额',
`pay_amount` DECIMAL(40, 6) NOT NULL DEFAULT 0.000000 COMMENT '已支付金额',
`status` TINYINT(1) NOT NULL DEFAULT 7 COMMENT '支付状态0支付失败 1支付成功--全部货款已支付 2待支付 5支付已超时 6 支付中( 目前只有这三种状态 7 订单进行中 8 订单已完成 9 余额不足,订单已取消) 10支付成功--已支付部分货款 ',
`from` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '买家钱包',
`hash` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '交易id 交易成功后生成',
`pay_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖方对应收款钱包',
`qrcode` LONGTEXT COMMENT '支付地址二维码',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
KEY `orderid_shopid` (`order_id`,`shop_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付记录表';
-- -- 创建商品收益表,存储每个商品对应的收益信息
-- CREATE TABLE IF NOT EXISTS `lease_product_income` (
-- `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '收益记录 ID',
-- `user_owned_product_id` BIGINT NOT NULL DEFAULT 0 COMMENT '用户拥有商品详情 ID关联 lease_user_owned_product 表',
-- `estimated_end_income` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '预估商品结束时的总收益',
-- `current_actual_income` DECIMAL(18, 2) NOT NULL DEFAULT 0.00 COMMENT '当前实际总收益',
-- `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
-- `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间'
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品收益表';
--
--
-- -- 删除
-- CREATE TABLE IF NOT EXISTS `lease_shop_address_config` (
-- `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
-- `user_id` varchar(64) NOT NULL COMMENT '买方账号id邮箱',
-- `address` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '卖方收款钱包 每个买方对应一个地址(自动生成匹配)',
-- `shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
-- UNIQUE KEY `idx_user_address_shop` (`user_id`,`address`,shop_id)
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='矿池nexa机器实时平均算力';
-- 官方自动生成地址存储表
CREATE TABLE IF NOT EXISTS `lease_auto_address` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`address` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '钱包地址',
`from_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`from_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0 未使用 1 已使用 2 钱包已过期',
`bind_user` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '绑定者邮箱',
UNIQUE INDEX `idx_address_from_symbol_from_chain` (`address`, `from_symbol`, `from_chain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='官方自动生成地址表';
-- 个人钱包资料表
CREATE TABLE IF NOT EXISTS `lease_user_wallet_data` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`user_id` VARCHAR(50) NOT NULL UNIQUE COMMENT '用户id(邮箱)',
`queue_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '钱包唯一id(用于充值功能)',
`from_address` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '充值钱包地址(我们提供)',
`balance` DECIMAL(40, 6) NOT NULL DEFAULT 0.000000 COMMENT '余额',
`blocked_balance` DECIMAL(40, 6) NOT NULL DEFAULT 0.000000 COMMENT '冻结余额(用户购买机器完成租约所需金额)',
`to_address` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '收款钱包地址(用户自己填写)',
`from_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`from_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`to_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`to_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`qrcode` LONGTEXT COMMENT '支付地址二维码',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段' ,
UNIQUE INDEX `idx_user_from_info` (`user_id`, `from_address`,`from_symbol`, `from_chain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户钱包信息表(个人钱包)';
-- 支付记录表
CREATE TABLE IF NOT EXISTS lease_pay_record_message (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`queue_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '消息ID',
`from_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '买家充值地址',
`to_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖家充值地址',
`order_number` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '订单号(方便查询,基本未使用)',
`order_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '订单号',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`user_id` VARCHAR(50) NOT NULL COMMENT '买方邮箱',
`block_amount`DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '买方钱包冻结金额',
`amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '理论支付金额',
`real_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际支付金额',
`need_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际应支付金额(支付是一天一次,根据一天内预估算力和实际算力差值计算得来)',
`block_height` BIGINT NOT NULL DEFAULT 0 COMMENT '报块高度',
`from_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`from_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`to_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`to_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`tx_hash` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '交易id',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`status` tinyint(1) NOT NULL DEFAULT 2 COMMENT '0 支付失败 1 支付成功 2 支付中 3 校验失败 4 发送支付消息失败',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付记录表';
CREATE TABLE IF NOT EXISTS lease_pay_record_message_info (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`queue_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '消息ID',
`from_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '买家充值地址',
`to_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '卖家充值地址',
`order_number` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '订单号(方便查询,基本未使用)',
`order_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '订单号',
`shop_id` BIGINT NOT NULL DEFAULT 0 COMMENT '商铺ID',
`user_id` VARCHAR(50) NOT NULL COMMENT '买方邮箱',
`block_amount`DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '买方钱包冻结金额',
`amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '理论支付金额',
`real_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际支付金额',
`need_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际应支付金额(支付是一天一次,根据一天内预估算力和实际算力差值计算得来)',
`block_height` BIGINT NOT NULL DEFAULT 0 COMMENT '报块高度',
`from_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`from_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`to_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`to_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`tx_hash` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '交易id',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`status` tinyint(1) NOT NULL DEFAULT 2 COMMENT '0 支付失败 1 支付成功 2 支付中 3 校验失败 4 发送支付消息失败',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付记录详情表(订单对应每日应支付金额)';
-- 充值记录返回表
CREATE TABLE IF NOT EXISTS lease_pay_recharge_message (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`queue_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '消息ID',
`address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '充值地址',
`amount` DECIMAL(40, 6) NOT NULL DEFAULT 0.00000000 COMMENT '支付金额',
`chain` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '链名称',
`symbol` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '币种',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '充值时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '0 充值失败 1 充值成功 2 充值中',
`tx_hash` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '交易id',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段' ,
UNIQUE INDEX `tx_hash_key` (`tx_hash`);
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='充值记录表';
-- 提现记录表
CREATE TABLE IF NOT EXISTS lease_pay_withdraw_message (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID',
`queue_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '消息ID',
`from_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '用户充值地址',
`to_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '提现地址(用户自定义)',
`amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '提现金额',
`from_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`from_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`to_symbol` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '币种名称',
`service_charge` DECIMAL(40, 6) NOT NULL DEFAULT 0.000000 COMMENT '提现费用',
`to_chain` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链名称',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '充值时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`status` tinyint(1) NOT NULL DEFAULT 2 COMMENT '0 提现失败 1 提现成功 2 提现中',
`tx_hash` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '交易id',
`del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '逻辑删除字段'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='提现记录表';
CREATE TABLE IF NOT EXISTS `nexa_real_power` (
`id` int NOT NULL AUTO_INCREMENT,
`user` varchar(64) NOT NULL COMMENT "挖矿账户",
`miner` varchar(64) NOT NULL COMMENT "矿工编号",
`date` datetime NOT NULL,
`power` decimal(32,6) NOT NULL COMMENT "实时算力单位 MH/S",
PRIMARY KEY (`id`),
UNIQUE KEY `user_miner` (`user`,`miner`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='矿机实时算力';
CREATE TABLE IF NOT EXISTS `grs_real_power` (
`id` int NOT NULL AUTO_INCREMENT,
`user` varchar(64) NOT NULL COMMENT "挖矿账户",
`miner` varchar(64) NOT NULL COMMENT "矿工编号",
`date` datetime NOT NULL,
`power` decimal(32,6) NOT NULL COMMENT "实时算力单位 MH/S",
PRIMARY KEY (`id`),
UNIQUE KEY `user_miner` (`user`,`miner`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='矿机实时算力';
CREATE TABLE IF NOT EXISTS `mona_real_power` (
`id` int NOT NULL AUTO_INCREMENT,
`user` varchar(64) NOT NULL COMMENT "挖矿账户",
`miner` varchar(64) NOT NULL COMMENT "矿工编号",
`date` datetime NOT NULL,
`power` decimal(32,6) NOT NULL COMMENT "实时算力单位 MH/S",
PRIMARY KEY (`id`),
UNIQUE KEY `user_miner` (`user`,`miner`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='矿机实时算力';
CREATE TABLE IF NOT EXISTS `rxd_real_power` (
`id` int NOT NULL AUTO_INCREMENT,
`user` varchar(64) NOT NULL COMMENT "挖矿账户",
`miner` varchar(64) NOT NULL COMMENT "矿工编号",
`date` datetime NOT NULL,
`power` decimal(32,6) NOT NULL COMMENT "实时算力单位 MH/S",
PRIMARY KEY (`id`),
UNIQUE KEY `user_miner` (`user`,`miner`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='矿机实时算力';
ALTER TABLE lease_product MODIFY COLUMN `max_price` DECIMAL(30, 18) NOT NULL DEFAULT 0.000000 COMMENT '商品下机器最大价格';
ALTER TABLE lease_product MODIFY COLUMN `min_price` DECIMAL(30, 18) NOT NULL DEFAULT 0.000000 COMMENT '商品下机器最小价格';
ALTER TABLE lease_product_machine MODIFY COLUMN `theory_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '单机理论收益单位usdt每日:根据添加机器时,实时计算的收益值)';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `estimated_end_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '预估商品结束时的总收益';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `estimated_end_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '预估商品结束时的总收益 单价usdt';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `current_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '当前收益(根据购买机器到现在的平均算力计算得到)单位 币种';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `current_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '当前收益(根据购买机器到现在的平均算力计算得到----非实时单位usdt';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `settle_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '待结算收益(用于存储某天还未支付情况下的收益)';
ALTER TABLE lease_user_owned_product MODIFY COLUMN `settle_usdt_income` DECIMAL(32, 18) NOT NULL DEFAULT 0.000000 COMMENT '待结算收益 (用于存储某天还未支付情况下的收益----非实时)单位usdt';
ALTER TABLE lease_pay_record_message MODIFY COLUMN `block_amount`DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '买方钱包冻结金额';
ALTER TABLE lease_pay_record_message MODIFY COLUMN `amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '理论支付金额';
ALTER TABLE lease_pay_record_message MODIFY COLUMN `real_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际支付金额';
ALTER TABLE lease_pay_record_message MODIFY COLUMN `need_amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.000000 COMMENT '实际应支付金额(支付是一天一次,根据一天内预估算力和实际算力差值计算得来)';
ALTER TABLE lease_pay_withdraw_message MODIFY COLUMN `amount` DECIMAL(40, 18) NOT NULL DEFAULT 0.00000000 COMMENT '提现金额';
ALTER TABLE lease_pay_recharge_message ADD COLUMN `block_height` BIGINT NOT NULL DEFAULT 0 COMMENT '报块高度';
ALTER TABLE lease_pay_recharge_message ADD COLUMN `from_address` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '充值来源地址(用户自己的钱包)';
ALTER TABLE lease_pay_withdraw_message ADD COLUMN `block_height` BIGINT NOT NULL DEFAULT 0 COMMENT '报块高度';
ALTER TABLE lease_order_item ADD COLUMN `already_pay_amount` DECIMAL(32, 18) NOT NULL DEFAULT 0.00 COMMENT '已支付总金额(每天加一)';
ALTER TABLE lease_order_item ADD COLUMN `already_pay_real_amount` DECIMAL(32, 18) NOT NULL DEFAULT 0.00 COMMENT '已支付实际总金额';
ALTER TABLE lease_order_item ADD COLUMN `settle_pay_real_amount` DECIMAL(32, 18) NOT NULL DEFAULT 0.00 COMMENT '当日待确认支付金额';
ALTER TABLE lease_order_info ADD COLUMN `fee` DECIMAL(32, 8) NOT NULL DEFAULT 0.00 COMMENT '订单手续费';

View File

@@ -1,111 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -3,6 +3,7 @@ package com.m2pool.system.api;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.constant.ServiceNameConstants;
import com.m2pool.system.api.entity.EmailEntity;
import com.m2pool.system.api.entity.EmailTemplateEntity;
import com.m2pool.system.api.entity.GetEmailCodeEntity;
import com.m2pool.system.api.factory.RemoteMailFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
@@ -32,5 +33,14 @@ public interface RemoteMailService
*/
@PostMapping("/sendTextMail")
public R<?> sendTextMail(@RequestBody EmailEntity entity);
/**
* 发送html邮件
*
* @return 结果
*/
@PostMapping("/sendHtmlMailMessage")
public R<?> sendHtmlMailMessage(@RequestBody EmailTemplateEntity entity);
}

View File

@@ -89,7 +89,7 @@ public interface RemoteUserService {
*
* @return 结果
*/
@PostMapping("/user/getCSList")
@GetMapping("/user/getCSList")
public R<List<SysUser>> getCSList();
}

View File

@@ -3,6 +3,7 @@ package com.m2pool.system.api.factory;
import com.m2pool.common.core.Result.R;
import com.m2pool.system.api.RemoteMailService;
import com.m2pool.system.api.entity.EmailEntity;
import com.m2pool.system.api.entity.EmailTemplateEntity;
import com.m2pool.system.api.entity.GetEmailCodeEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,6 +36,11 @@ public class RemoteMailFallbackFactory implements FallbackFactory<RemoteMailServ
return R.fail("邮箱发送失败:" + cause.getMessage());
}
@Override
public R<?> sendHtmlMailMessage(@RequestBody EmailTemplateEntity entity) {
return R.fail("邮箱发送失败:" + cause.getMessage());
}
};
}
}

View File

@@ -1,6 +1,8 @@
package com.m2pool.system.api.model;
import com.m2pool.system.api.entity.SysUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -12,35 +14,45 @@ import java.util.Set;
* @Author dy
*/
@Data
@ApiModel(description = "登录用户信息")
public class LoginUser implements Serializable {
private static final long serialVersionUID = 1L;
/** 用户唯一标识 */
@ApiModelProperty(value = "用户唯一标识")
private String token;
/** 用户名id */
@ApiModelProperty(value = "用户名id")
private Long userid;
/** 用户名 */
@ApiModelProperty(value = "用户名")
private String username;
/** 登录时间 */
@ApiModelProperty(value = "登录时间")
private Long loginTime;
/** 过期时间 */
@ApiModelProperty(value = "过期时间")
private Long expireTime;
/** 登录IP地址 */
@ApiModelProperty(value = "登录IP地址")
private String ipaddr;
/** 权限列表 */
@ApiModelProperty(value = "权限列表")
private Set<String> permissions;
/** 角色列表 */
@ApiModelProperty(value = "角色列表")
private Set<String> roles;
/** 用户信息 */
@ApiModelProperty(value = "用户详情信息对象")
private SysUser sysUser;
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -1,178 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-commons:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:2.0.4" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_common:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel_agent:0.12.0" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.11" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-simple-http:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-common:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-datasource-extension:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-annotation-aspectj:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.8.3" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-circuitbreaker-sentinel:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webflux-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webmvc-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-parameter-flow-control:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-server-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-common-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-client-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.6.7" level="project" />
<orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.8.5" level="project" />
<orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
<orderEntry type="module" module-name="common-security" />
<orderEntry type="module" module-name="api-system" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -59,6 +59,18 @@
<artifactId>common-security</artifactId>
</dependency>
<!-- Thymeleaf 用于发送邮箱 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.0.RC1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View File

@@ -6,12 +6,11 @@ import com.m2pool.auth.service.impl.MaliServiceImpl;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.utils.JwtUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.common.security.annotation.RequiresLogin;
import com.m2pool.common.security.auth.AuthUtil;
import com.m2pool.common.security.service.TokenService;
import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.system.api.entity.SysUser;
import com.m2pool.system.api.entity.EmailTemplateEntity;
import com.m2pool.system.api.model.LoginUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -22,6 +21,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Map;
/**
@@ -49,6 +49,19 @@ public class TokenController {
}
/**
* 后台管理系统登录
* @param loginManageBody
* @return
*/
@PostMapping("managerLogin")
@ApiOperation(value = "后台管理系统登录")
public R<Map<String,Object>> managerLogin(@RequestBody @Valid LoginManageBody loginManageBody)
{
return sysLoginService.managerLogin(loginManageBody);
}
@PostMapping("registerCode")
public R<?> emailCode(@Validated @RequestBody GetEmailCodeEntity entity)
{
@@ -125,7 +138,7 @@ public class TokenController {
public R<?> resetPwd(@Valid @RequestBody ResetPwdBody resetPwdBody)
{
// 重置密码
sysLoginService.resetPwd(resetPwdBody);
sysLoginService.resetPwd(resetPwdBody,true);
return R.success("账号"+ resetPwdBody.getEmail()+"密码重置成功");
}
@@ -137,7 +150,7 @@ public class TokenController {
resetPwdBody.setEmail(email);
// 修改密码
sysLoginService.resetPwd(resetPwdBody);
sysLoginService.resetPwd(resetPwdBody,false);
return R.success("账号"+ resetPwdBody.getEmail()+"密码修改成功");
}
@@ -149,4 +162,13 @@ public class TokenController {
}
@PostMapping("sendHtmlMailMessage")
public R<?> sendHtmlMailMessage(@Valid @RequestBody EmailTemplateEntity entity)
{
maliService.sendHtmlMailMessage(entity);
return R.success("邮件已发送");
}
}

View File

@@ -0,0 +1,30 @@
package com.m2pool.auth.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.Email;
/**
* @Description 管理系统用户登录请求对象
* @Date 2025/5/22 16:13
* @Author yyb
*/
@Data
@ApiModel(description = "")
public class LoginManageBody {
/** 邮箱 */
@Email
@ApiModelProperty(value = "邮箱", required = true, example = "")
private String userName;
/** 密码 */
@ApiModelProperty(value = "密码", required = true, example = "")
private String password;
private String uuid;
//private boolean flag = false;
}

View File

@@ -19,6 +19,8 @@ public class ResetPwdBody {
private String resetPwdCode;
private String updatePwdCode;
/** 新密码 */
private String password;

View File

@@ -3,6 +3,7 @@ package com.m2pool.auth.service;
import com.m2pool.auth.entity.GetEmailCodeEntity;
import com.m2pool.auth.entity.GetLoginEmailCodeEntity;
import com.m2pool.common.core.Result.R;
import com.m2pool.system.api.entity.EmailTemplateEntity;
/**
* @Description TODO
@@ -19,12 +20,9 @@ public interface MailService {
public void sendTextMailMessage(String to,String subject,String text);
/**
* 发送html邮件
* @param to
* @param subject
* @param content
* 发送矿机离线数 html邮件
*/
public void sendHtmlMailMessage(String to,String subject,String content);
public void sendHtmlMailMessage(EmailTemplateEntity entity);
/**
* 发送带附件的邮件

View File

@@ -25,10 +25,15 @@ import com.m2pool.system.api.RemoteUserService;
import com.m2pool.system.api.entity.SysLogininfor;
import com.m2pool.system.api.entity.SysUser;
import com.m2pool.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -37,6 +42,7 @@ import java.util.concurrent.TimeUnit;
* @Date 2024/6/12 16:19
* @Author dy
*/
@Slf4j
@Component
public class SysLoginService {
@@ -232,6 +238,86 @@ public class SysLoginService {
return R.success(tokenService.createToken(userInfo));
}
public R<Map<String,Object>> managerLogin(LoginManageBody loginManageBody){
//邮箱
String email = loginManageBody.getUserName();
//String password= loginBody.getPassword();
String password="";
try {
password = RsaUtils.decryptByPrivateKey(loginManageBody.getPassword());
password = StringUtils.clean(password);
}catch (Exception e){
return R.fail(401,"加密密码传参有误");
}
// 用户名或密码为空 错误
if (StringUtils.isAnyBlank(email, password))
{
recordLogininfor(email, Constants.LOGIN_FAIL, "邮箱/密码必须填写");
throw new ServiceException("邮箱/密码必须填写");
}
if(!StringUtils.isBlank(email)){
if(!email.matches(EMAIL_REGEX)){
throw new ServiceException("邮箱格式错误");
}
}else {
throw new ServiceException("邮箱为必填项");
}
// 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
recordLogininfor(email, Constants.LOGIN_FAIL, "用户密码不在指定范围");
throw new ServiceException("用户密码不在指定范围");
}
// 查询用户信息
R<LoginUser> userResult = remoteUserService.getUserInfo(email, SecurityConstants.INNER);
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
if (StringUtils.isNull(userResult.getData()))
{
recordLogininfor(email, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + email + " 不存在");
}
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
Set<String> roles = userInfo.getRoles();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
recordLogininfor(email, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + email + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
recordLogininfor(email, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + email + " 已停用");
}
if(!SecurityUtils.matchesPassword(password, user.getPassword())){
throw new ServiceException("密码错误,请重新输入");
}
//必须是管理员才能登录
if(!roles.contains("3")){
recordLogininfor(email, Constants.LOGIN_FAIL, "对不起,您的账号没有权限不能登录后台管理");
throw new ServiceException("对不起,您的账号:" + email + " 没有权限不能登录后台管理");
}
recordLogininfor(email, Constants.LOGIN_SUCCESS, "后台管理系统用户登录成功");
return R.success(tokenService.createToken(userInfo));
}
public void logout(String loginName)
{
recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
@@ -320,11 +406,11 @@ public class SysLoginService {
/**
* 重置密码
*
*/
public void resetPwd(ResetPwdBody resetPwdBody)
public void resetPwd(ResetPwdBody resetPwdBody,boolean isUpdate)
{
log.info("验证码{},重置密码{},重置者邮箱{}",resetPwdBody.getResetPwdCode(),resetPwdBody.getPassword(),resetPwdBody.getEmail());
String password = resetPwdBody.getPassword();
try {
password = RsaUtils.decryptByPrivateKey(resetPwdBody.getPassword());
@@ -335,6 +421,7 @@ public class SysLoginService {
String email = resetPwdBody.getEmail();
String resetPwdCode = resetPwdBody.getResetPwdCode();
String updatePwdCode = resetPwdBody.getUpdatePwdCode();
// 邮箱或密码为空 错误
if (StringUtils.isAnyBlank(email, password))
{
@@ -382,8 +469,9 @@ public class SysLoginService {
//
//System.out.println(checkCodeResult);
if(redisService.hasKey(RedisTransKey.getResetPwdKey(email))){
log.info("重置密码{},修改验证码{},重置验证码{}",isUpdate,redisService.hasKey(RedisTransKey.getResetPwdKey(email)),redisService.hasKey(RedisTransKey.getUpdatePwdKey(email)));
// 如果是true代表就是忘记密码 false 就是个人中心重置密码
if(isUpdate && redisService.hasKey(RedisTransKey.getResetPwdKey(email))){
Object o = redisService.getCacheObject(RedisTransKey.getResetPwdKey(email));//user:emailCode:username
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
@@ -409,6 +497,32 @@ public class SysLoginService {
}else {
throw new ServiceException("请勿修改已输入的邮箱");
}
}else if(!isUpdate && redisService.hasKey(RedisTransKey.getUpdatePwdKey(email))){
Object o = redisService.getCacheObject(RedisTransKey.getUpdatePwdKey(email));//user:emailCode:username
EmailCodeEntity emailCodeEntity = JSON.parseObject(JSON.toJSONString(o), EmailCodeEntity.class);
if (email.equals(emailCodeEntity.getEmail())) {
//邮箱必须和刚刚传的一致
//验证验证码
if(updatePwdCode.equals(emailCodeEntity.getEmailCode())){
// 重置用户密码
SysUser sysUser = new SysUser();
sysUser.setEmail(email);
sysUser.setPassword(SecurityUtils.encryptPassword(password));
R<?> resetPwdResult = remoteUserService.resetPwdByEmail(sysUser);
if (R.FAIL == resetPwdResult.getCode())
{
throw new ServiceException(resetPwdResult.getMsg());
}
//recordLogininfor(username, Constants.REGISTER, "注册成功");
}else {
throw new ServiceException("邮箱验证码错误");
}
}else {
throw new ServiceException("请勿修改已输入的邮箱");
}
}else {
////判断是邮箱不存在还是操作超时
////通过邮箱获取用户
@@ -419,7 +533,6 @@ public class SysLoginService {
//}
throw new ServiceException("验证码校验失败:操作超时,请重新操作");
}
}

View File

@@ -8,12 +8,12 @@ import com.m2pool.auth.service.MailService;
import com.m2pool.common.core.RedisTransKey;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.constant.SecurityConstants;
import com.m2pool.common.core.exception.ServiceException;
import com.m2pool.common.core.utils.CodeUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.redis.service.RedisService;
import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.system.api.RemoteUserService;
import com.m2pool.system.api.entity.EmailTemplateEntity;
import com.m2pool.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -21,9 +21,15 @@ import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
@@ -42,12 +48,19 @@ public class MaliServiceImpl implements MailService {
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private TemplateEngine templateEngine;
@Autowired
private RedisService redisService;
@Value("${spring.mail.username}")
private String sendMailer;
@Value("${image.prefix}")
private String imagePrefix;
public static String EMAIL_REGEX="^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
/**
@@ -103,42 +116,52 @@ public class MaliServiceImpl implements MailService {
/**
* 发送html邮件
* 发送HTML邮件
* @param to
* @param subject
* @param content
* @param templateName 模版名
* @param variables 需要映射到html上的动态内容
* @throws MessagingException
*/
@Override
public void sendHtmlMailMessage(String to,String subject,String content){
public void sendHtmlEmail(String to, String subject, String templateName, Map<String, Object> variables) throws MessagingException {
// 创建 MimeMessage 对象
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
content="<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"<meta charset=\"utf-8\">\n" +
"<title>邮件</title>\n" +
"</head>\n" +
"<body>\n" +
"\t<h3>这是一封HTML邮件</h3>\n" +
"</body>\n" +
"</html>";
try {
//true 代表支持复杂的类型
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
//邮件发信人
mimeMessageHelper.setFrom(sendMailer);
//邮件收信人 1或多个
mimeMessageHelper.setTo(to.split(","));
//邮件主题
mimeMessageHelper.setSubject(subject);
//邮件内容 true 代表支持html
mimeMessageHelper.setText(content,true);
helper.setFrom(sendMailer);
// 收件人一个活多个
helper.setTo(to.split(","));
helper.setSubject(subject);
// 创建 Thymeleaf 上下文并添加变量
Context context = new Context();
//设置图片访问前缀
variables.put("imagePrefix", imagePrefix);
context.setVariables(variables);
// 处理 HTML 模板
String htmlContent = templateEngine.process(templateName, context);
// 设置邮件内容为 HTML
helper.setText(htmlContent, true);
//邮件发送时间
mimeMessageHelper.setSentDate(new Date());
helper.setSentDate(new Date());
//发送邮件
javaMailSender.send(mimeMessageHelper.getMimeMessage());
// 发送邮件
javaMailSender.send(message);
System.out.println("发送邮件成功:"+sendMailer+"->"+to);
}
@Override
public void sendHtmlMailMessage(EmailTemplateEntity entity){
try {
sendHtmlEmail(entity.getEmail(),entity.getSubject(),entity.getTemplateName(),entity.getData());
} catch (Exception e) {
e.printStackTrace();
System.out.println("发送邮件失败:"+e.getMessage());
@@ -189,9 +212,13 @@ public class MaliServiceImpl implements MailService {
*/
@Override
public void sendCodeMailMessage(String to, String code) {
String subject = "账号注册,邮箱验证码";
String text = "注册验证码10分钟内有效:\n\t"+code;
sendTextMailMessage(to,subject,text);
//String subject = "账号注册,邮箱验证码";
//String text = "注册验证码10分钟内有效:\n\t"+code;
Map<String, Object> content = new HashMap<>();
content.put("code",code);
content.put("text","The verification code for registration is valid for 10 minutes");
EmailTemplateEntity message = new EmailTemplateEntity(to,"Account registration, email verification code","emailCode-en",content);
sendHtmlMailMessage(message);
}
/**
@@ -201,25 +228,39 @@ public class MaliServiceImpl implements MailService {
*/
@Override
public void sendLoginCodeMailMessage(String to, String code) {
String subject = "用户登录,邮箱验证码";
String text = "登录验证码10分钟内有效:\n\t"+code;
sendTextMailMessage(to,subject,text);
//String subject = "用户登录,邮箱验证码";
//String text = "登录验证码10分钟内有效:\n\t"+code;
Map<String, Object> content = new HashMap<>();
content.put("code",code);
content.put("text","Login verification code is valid within 10 minutes");
EmailTemplateEntity entity = new EmailTemplateEntity(to,"User login, email verification code","emailCode-en",content);
sendHtmlMailMessage(entity);
}
@Override
public void sendResetPwdMailMessage(String to, String code) {
String subject = "账号重置密码,邮箱验证码";
String text = "您正在重置密码如果不是您本人操作请忽略。验证码10分钟内有效:\n\t"+code;
sendTextMailMessage(to,subject,text);
//String subject = "账号重置密码,邮箱验证码";
//String text = "您正在重置密码如果不是您本人操作请忽略。验证码10分钟内有效:\n\t"+code;
Map<String, Object> content = new HashMap<>();
content.put("code",code);
content.put("text","You are resetting your password. If this is not done by you, please ignore it. The verification code is valid for 10 minutes.");
EmailTemplateEntity entity = new EmailTemplateEntity(to,"Reset account password, email verification code","emailCode-en",content);
sendHtmlMailMessage(entity);
}
@Override
public void sendUpdatePwdMailMessage(String to, String code) {
String subject = "修改密码,邮箱验证码";
String text = "您正在修改密码如果不是您本人操作请忽略。验证码10分钟内有效:\n\t"+code;
sendTextMailMessage(to,subject,text);
//String subject = "修改密码,邮箱验证码";
//String text = "您正在修改密码如果不是您本人操作请忽略。验证码10分钟内有效:\n\t"+code;
Map<String, Object> content = new HashMap<>();
content.put("code",code);
content.put("text","You are currently modifying your password. If this is not done by you, please ignore it. The verification code is valid for 10 minutes.");
EmailTemplateEntity entity = new EmailTemplateEntity(to,"Change password, email verification code","emailCode-en",content);
sendHtmlMailMessage(entity);
}
@Override

View File

@@ -0,0 +1,89 @@
server:
port: 7777
# Spring
spring:
#邮箱基本配置
mail:
# 配置在limit_time内用户可以发送limit次验证码
limit: 2 这个是我额外的配置,结合邮箱服务用的
limitTime: 10 这个是我额外的配置
#配置smtp服务主机地址
# sina smtp.sina.cn
# aliyun smtp.aliyun.com
# 163 smtp.163.com 端口号465或994
host: mail.privateemail.com
#发送者邮箱
username: do.not.reply@m2pool.com
#配置密码,注意不是真正的密码,而是刚刚申请到的授权码
# password:
# password: M2202401!
# password: axvm-zfgx-cgcg-qhhu
password: M2202401!
#端口号
port: 587
# port: 465
#默认的邮件编码为UTF-8
default-encoding: UTF-8
#其他参数
properties:
mail:
#配置SSL 加密工厂
smtp:
ssl:
#本地测试先放开ssl
enable: false
required: false
#开启debug模式这样邮件发送过程的日志会在控制台打印出来方便排查错误
debug: false
socketFactory:
class: javax.net.ssl.SSLSocketFactory
#
# host: smtp.qq.com
# #发送者邮箱
# username: 1328642438@qq.com
# #配置密码,注意不是真正的密码,而是刚刚申请到的授权码
# # password:
# # password: M2pool2024@!
# # password: axvm-zfgx-cgcg-qhhu
# password: eqrzqxeqzlshhedh
#
# #端口号
# port: 465
# #默认的邮件编码为UTF-8
# default-encoding: UTF-8
# #其他参数
# properties:
# mail:
# #配置SSL 加密工厂
# smtp:
# ssl:
# #本地测试先放开ssl
# enable: true
# required: true
# #开启debug模式这样邮件发送过程的日志会在控制台打印出来方便排查错误
# debug: false
# socketFactory:
# class: javax.net.ssl.SSLSocketFactory
application:
# 应用名称
name: m2pool-auth
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
namespace: m2_dev
group: m2_dev_group
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: m2_dev
group: m2_dev_group

View File

@@ -62,3 +62,5 @@ spring:
namespace: m2_prod
group: m2_prod_group
image:
prefix: https://m2pool.com

View File

@@ -74,12 +74,12 @@ spring:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
namespace: m2_test
group: m2_test_group
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
# 配置文件格式
file-extension: yml
# 共享配置
@@ -87,3 +87,5 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: m2_test
group: m2_test_group
image:
prefix: https://test.m2pool.com

View File

@@ -1,3 +1,3 @@
spring:
profiles:
active: test
active: prod

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email code</title>
</head>
<body style="margin:0; padding:0;">
<!-- 合并 th:style 属性 -->
<div class="container" role="region" aria-label="M2POOL Email verification code page" tabindex="0"
th:style="'background-image: url(' + @{${imagePrefix} + '/img/email/bg1.png'} + '); width:100%; max-width:600px; height:auto; min-height:100vh; margin:0 auto; box-sizing:border-box; padding:5%; position:relative; overflow:hidden; background-color:#f5f5f5; background-size:cover; background-repeat:no-repeat; '">
<!-- 顶部品牌标识 -->
<div class="brand" aria-label="M2POOL brand logo" style="width:100%;">
<img th:src= "@{${imagePrefix} + '/img/email/logo.png'}" alt="logo" style="width: 8vw; height: auto; margin-left: 10%; margin-top: 6%;">
</div>
<!-- 中心验证码卡片 -->
<!-- 合并 th:style 属性 -->
<section class="card" aria-label="Verification code card"
th:style="'background-image: url(' + @{${imagePrefix} + '/img/email/daio.png'} + '); width:100%; max-width:320px; height:auto; min-height:250px; margin:0 auto; margin-top:10vh; box-shadow:0 8px 24px rgba(17, 24, 39, 0.10), 0 2px 6px rgba(17, 24, 39, 0.06); position:relative; overflow:hidden; display:block; text-align:center; background-color:#ffffff; background-size:120% auto; background-position:center; background-repeat:no-repeat; border-radius:12px; padding:5%;'">
<!-- 合并 th:style 属性 -->
<p class="notice" th:text="${text}" style="color:rgba(0,0,0,0.7); font-size:18px; margin-top:10%; text-align:center;"></p>
<!-- 合并 th:style 属性 -->
<div class="code-box" aria-live="polite" aria-label="CAPTCHA"
style="position:relative; display:inline-flex; align-items:center; justify-content:center; margin-top:2vh; width:80%; max-width:300px; height:50px; border-radius:12px; background:#ffffff; border:3px solid #651EFE;">
<!-- 合并 th:style 属性 -->
<span class="code-text js-code-text" data-default-code="4MKM6AX" th:text="${code}"
style="font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; font-weight:800; font-size:24px; letter-spacing:0.18em; color:#111827;margin:auto;"></span>
</div>
</section>
<!-- 底部帮助与联系入口 -->
<footer class="page-footer" style="margin-top:18vh; width:100%; height:auto; text-align:center;">
<!-- 合并 th:style 属性 -->
<div class="divider" aria-hidden="true"
style="width:100%; height:3px; background:#DDDDDD; margin:8px 0 20px;"></div>
<!-- 合并 th:style 属性 -->
<p style="margin:0; padding:0; font-size:14px; color:#777777;">
Thank you for choosing M2POOL. Need help?
<a class="contact-link" href="mailto:support@m2pool.com" aria-label="Contact customer service email"
style="color:#111827; font-weight:800; text-decoration:none; border-bottom:2px solid #111827; outline:none;">Please
contact customer service.</a>
</p>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>offline notification</title>
</head>
<body>
<div class="container" role="region" aria-label="M2POOL offline notification" tabindex="0"
th:style="'background-image: url(' + @{${imagePrefix} + '/img/email/bg1.png'} + '); width:100%; max-width:600px; height:auto; min-height:100vh; margin:0 auto; position:relative; overflow:hidden; padding:2%; background-color:#f5f5f5; background-size:cover; background-repeat:no-repeat;box-sizing:border-box;'">
<!-- 顶部品牌标识 -->
<div class="brand" aria-label="M2POOL brand logo">
<img th:src= "@{${imagePrefix} + '/img/email/logo.png'}" alt="logo" style="width:120px; height:auto; margin-left:10%; margin-top:6%;">
</div>
<!-- 中心验证码卡片 -->
<section class="card" aria-label="Offline Notification Card" th:style="'background-image: url(' + @{${imagePrefix} + '/img/email/daio.png'} + ');width:100%; max-width:310px; height:auto; min-height:240px; margin:0 auto; margin-top:10vh; box-shadow:0 8px 24px rgba(17, 24, 39, 0.10), 0 2px 6px rgba(17, 24, 39, 0.06); position:relative; overflow:hidden; padding:44px 40px 36px; text-align:center; background-color:#ffffff; background-size:105% 112%; background-position:center; background-repeat:no-repeat; border-radius:12px;'">
<p class="notice" style="color:rgba(0,0,0,0.8); font-size:18px; margin-bottom:15px;">Your <span class="account-name" th:text="${coin}" style="color:#F94D87; font-weight:900; font-size:20px;"></span> mining account: &nbsp; <span class="account-name" style="color:#F94D87; font-weight:900; font-size:20px;" th:text="${user}"></span> </p>
<p class="notice" style="color:rgba(0,0,0,0.8); font-size:18px; margin-bottom:15px;"> <span class="account-name" th:text="${offOnlineNumbers}" style="color:#F94D87; font-weight:900; font-size:20px;"></span> mining machines are offline!</p>
<p class="notice" style="color:rgba(0,0,0,0.8); font-size:18px;">If your mining rig has been abnormally disconnected, please address it promptly!</p>
</section>
<!-- 底部帮助与联系入口 -->
<footer class="page-footer" style="margin-top:18vh; width:100%; height:auto; text-align:center;">
<div class="divider" aria-hidden="true" style="width:100%; height:3px; background:#DDDDDD; margin:8px 0 20px;"></div>
<p style="margin:0; padding:0; font-size:14px; color:#777777;">
Thank you for choosing M2POOL. Need help?
<a class="contact-link" style="color:#111827; font-weight:800; text-decoration:none; border-bottom:2px solid #111827; outline:none;" href="mailto:support@m2pool.com" aria-label="Contact Customer Service Email">Please contact customer service.</a>
</p>
</footer>
</div>
<script>
</script>
</body>
</html>

View File

@@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
</component>
</module>

View File

@@ -126,8 +126,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -320,4 +320,46 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return DateUtils.parseDate(format);
}
/**
* 获取当前时间前一个包含 30 分或整点的 30 分钟时间段起始时间
* @param date 输入的日期
* @return 前一个 30 分或整点时间段起始的日期
*/
public static Date getPreviousHalfHourOrFullHour(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int minute = calendar.get(Calendar.MINUTE);
// 如果当前分钟数小于 30前一个时间段起始是上一个整点
if (minute < 30) {
calendar.set(Calendar.MINUTE, 0);
} else {
// 如果当前分钟数大于等于 30前一个时间段起始是 30 分
calendar.set(Calendar.MINUTE, 30);
}
// 将秒和毫秒置为 0
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 如果当前分钟已经是 0 分或者 30 分,需要再往前推 30 分钟
if (minute == 0 || minute == 30) {
calendar.add(Calendar.MINUTE, -30);
}
return calendar.getTime();
}
/**
* 获取指定日期一个月前的时间
* @param date 输入的日期
* @return 一个月前的日期
*/
public static Date getOneMonthAgo(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, -30);
return calendar.getTime();
}
}

View File

@@ -35,6 +35,8 @@ public class MimeTypeUtils
"rar", "zip", "gz", "bz2",
// 视频格式
"mp4", "avi", "rmvb",
//音频格式
"mp3","aif","aiff","wav","wma",
// pdf
"pdf" };

View File

@@ -1,5 +1,7 @@
package com.m2pool.common.core.web.page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -11,23 +13,29 @@ import java.util.List;
* @Author dy
*/
@Data
public class TableDataInfo implements Serializable
@ApiModel(description = "分页返回对象")
public class TableDataInfo<T> implements Serializable
{
private static final long serialVersionUID = 1L;
/** 总记录数 */
@ApiModelProperty(value = "总记录数", example = "1")
private long total;
/** 总页数 */
@ApiModelProperty(value = "总页数", example = "1")
private long totalPage;
/** 列表数据 */
private List<?> rows;
@ApiModelProperty(value = "查询结果集合")
private List<T> rows;
/** 消息状态码 */
@ApiModelProperty(value = "消息状态码", example = "200")
private int code;
/** 消息内容 */
@ApiModelProperty(value = "查询结果描述", example = "成功")
private String msg;
/**
@@ -43,7 +51,7 @@ public class TableDataInfo implements Serializable
* @param list 列表数据
* @param total 总记录数
*/
public TableDataInfo(List<?> list, int total)
public TableDataInfo(List<T> list, int total)
{
this.rows = list;
this.total = total;

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common-security" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="module" module-name="api-system" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:dynamic-datasource-spring-boot-starter:3.5.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common-security" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="module" module-name="api-system" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -7,6 +7,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
@@ -117,6 +118,31 @@ public class RedisService {
return operation.get(key);
}
/**
* 所有数字类型转换为BigDecimal
* @param key 缓存键值
* @return 缓存键值对应数据
*/
public BigDecimal getCacheBigDecimal(final String key) {
ValueOperations<String, Object> operation = redisTemplate.opsForValue();
Object value = operation.get(key);
if (value != null) {
if (value instanceof BigDecimal) {
return (BigDecimal) value;
} else if (value instanceof String) {
try {
return new BigDecimal((String) value);
} catch (NumberFormatException e) {
// 处理字符串无法转换为 BigDecimal 的情况
return null;
}
} else if (value instanceof Number) {
return new BigDecimal(value.toString());
}
}
return null;
}
/**
* 删除单个对象
*
@@ -150,7 +176,6 @@ public class RedisService {
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*

View File

@@ -1,122 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="module" module-name="api-system" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -215,6 +215,7 @@ public class AuthLogic {
{
if (requiresRoles.logical() == Logical.AND)
{
checkRoleAnd(requiresRoles.value());
}
else
@@ -248,6 +249,8 @@ public class AuthLogic {
public void checkRoleOr(String... roles)
{
Set<String> roleList = getRoleList();
System.out.println("从token获取的role"+roleList +"需要的权限"+roles);
for (String role : roles)
{
if (hasRole(roleList, role))

View File

@@ -1,5 +1,6 @@
package com.m2pool.common.security.config;
import com.m2pool.common.security.interceptor.CoinInterceptor;
import com.m2pool.common.security.interceptor.HeaderInterceptor;
import com.m2pool.common.security.interceptor.OpenApiHeaderInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -25,7 +26,6 @@ public class WebMvcConfig implements WebMvcConfigurer {
"/miner/hashrate_real","/miner/hashrate_history","/miner/hashrate_last24h",
"/pool/hashrate","/pool/hashrate_history","/pool/miners_list","/pool/watch","/oapi/**"};
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getHeaderInterceptor())
@@ -34,9 +34,14 @@ public class WebMvcConfig implements WebMvcConfigurer {
.order(-10);
registry.addInterceptor(getOpenApiHeaderInterceptor())
.addPathPatterns(matchUrls).
excludePathPatterns("/auth/**,/system/**,/pool/**")
.addPathPatterns(matchUrls)
.excludePathPatterns("/auth/**,/system/**,/pool/**")
.order(-15);
//registry.addInterceptor(getCoinInterceptor())
// .addPathPatterns("/**")
// .order(-20);
}
/**
* 自定义请求头拦截器
@@ -45,4 +50,5 @@ public class WebMvcConfig implements WebMvcConfigurer {
public OpenApiHeaderInterceptor getOpenApiHeaderInterceptor(){return new OpenApiHeaderInterceptor();}
public CoinInterceptor getCoinInterceptor(){return new CoinInterceptor();}
}

View File

@@ -78,6 +78,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(ServiceException.class)
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
{
log.error(e.getMessage(), e);
Integer code = e.getCode();
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
@@ -89,9 +90,10 @@ public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
{
System.out.println("异常抛出时间"+System.currentTimeMillis());
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
return AjaxResult.error(HttpStatus.BAD_REQUEST,e.getMessage());
}
/**

View File

@@ -0,0 +1,64 @@
package com.m2pool.common.security.interceptor;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public class AuthRequestWrapper extends HttpServletRequestWrapper {
private String body;
public AuthRequestWrapper(HttpServletRequest request) {
super(request);
try(BufferedReader reader = request.getReader()){
body= reader.lines().collect(Collectors.joining());
}catch (Exception e){
System.out.println("!!-- read request from requestbody error"+e.getMessage());
}
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletIns = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayIns.read();
}
};
return servletIns;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}

View File

@@ -0,0 +1,66 @@
package com.m2pool.common.security.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@Component
public class CoinInterceptor implements HandlerInterceptor {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("调用Coin拦截器1:" + request);
// 仅处理 POST、PUT 等有请求体的请求方法
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
try {
// 读取请求体内容
if (request instanceof AuthRequestWrapper){
//BufferedReader reader = request.getReader();
//System.out.println("调用Coin拦截器2:" + reader);
//
//if (!requestBody.isEmpty()) {
// // 反序列化请求体为 RequestObject 对象
// RequestObject requestObject = objectMapper.readValue(requestBody, RequestObject.class);
// System.out.println("调用Coin拦截器3:" + requestObject.toString());
// String coin = requestObject.getCoin();
// System.out.println("调用Coin拦截器4:" + coin);
// if ("enx".equals(coin)) {
// response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
// response.getWriter().write("enx币种已下架");
// return false;
// }
//}
}
} catch (Exception e) {
// 处理反序列化异常
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write("请求体解析失败");
return false;
}
}
return true;
}
/**
* 读取请求体内容
*/
private String readRequestBody(HttpServletRequest request) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
}
return stringBuilder.toString();
}
}

View File

@@ -2,6 +2,7 @@ package com.m2pool.common.security.interceptor;
import com.m2pool.common.core.constant.SecurityConstants;
import com.m2pool.common.core.context.SecurityContextHolder;
import com.m2pool.common.core.utils.JwtUtils;
import com.m2pool.common.core.utils.ServletUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.core.utils.ip.IpUtils;
@@ -37,6 +38,11 @@ public class HeaderInterceptor implements AsyncHandlerInterceptor {
SecurityContextHolder.setUserName(ServletUtils.getHeader(request,SecurityConstants.DETAILS_USERNAME));
SecurityContextHolder.setUserKey(ServletUtils.getHeader(request,SecurityConstants.USER_KEY));
//开发环境
String authorization = request.getHeader("Authorization");
String userName = JwtUtils.getUserName(authorization);
SecurityContextHolder.setUserName(userName);
String token = SecurityUtils.getToken();
if(StringUtils.isNotEmpty(token)){

View File

@@ -0,0 +1,27 @@
package com.m2pool.common.security.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
@Component
@WebFilter("/*")
public class RequestBodyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
request = new AuthRequestWrapper(request);
filterChain.doFilter(request,response);
}
}

View File

@@ -0,0 +1,16 @@
package com.m2pool.common.security.interceptor;
import com.fasterxml.jackson.annotation.JsonProperty;
public class RequestObject {
private String coin;
// 添加 getter 和 setter 方法
public String getCoin() {
return coin;
}
public void setCoin(String coin) {
this.coin = coin;
}
}

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.11.22" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.6.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.mapstruct:mapstruct:1.3.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -24,11 +24,17 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Swagger -->
<!-- Swagger -->
<!-- <dependency>-->
<!-- <groupId>io.springfox</groupId>-->
<!-- <artifactId>springfox-swagger2</artifactId>-->
<!-- <version>${swagger.fox.version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>

View File

@@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;

View File

@@ -18,6 +18,8 @@ public class SwaggerWebConfiguration implements WebMvcConfigurer {
/** swagger-ui 地址 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
</component>
</module>

View File

@@ -1,207 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-gateway:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.10.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.68" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-gateway-server:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-webflux:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-reactor-netty:2.6.7" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.netty:reactor-netty-http:1.0.18" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-http:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-http2:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-dns:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns-native-macos:osx-x86_64:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns-classes-macos:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport-native-epoll:linux-x86_64:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport-native-unix-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport-classes-epoll:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.netty:reactor-netty-core:1.0.18" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler-proxy:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec-socks:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webflux:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-commons:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:2.0.4" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_common:0.12.0" level="project" />
<orderEntry type="library" name="Maven: io.prometheus:simpleclient_tracer_otel_agent:0.12.0" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.29" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.11" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.6.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.1.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-simple-http:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-common:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-annotation-aspectj:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.8.3" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.7" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-circuitbreaker-sentinel:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webflux-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webmvc-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-parameter-flow-control:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-server-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-common-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.76.Final" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-client-default:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-gateway:2021.0.1.0" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-api-gateway-adapter-common:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-cloud-gateway-adapter:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-datasource-nacos:1.8.3" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-datasource-extension:1.8.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.7" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.11" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.36" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2" level="project" />
<orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.8.5" level="project" />
<orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.17" level="project" />
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
<orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.8" level="project" />
<orderEntry type="library" name="Maven: com.github.penggle:kaptcha:2.3.2" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: com.jhlabs:filters:2.0.235-1" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.11.22" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
<orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.6.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.mapstruct:mapstruct:1.3.1.Final" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok-maven-plugin:1.18.6.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
<orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.6.4" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.19" level="project" />
<orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.1.8.RELEASE" level="project" />
<orderEntry type="module" module-name="api-system" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.6.7" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-core:11.8" level="project" />
<orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:11.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.1.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:transmittable-thread-local:2.12.2" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.4.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.19" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.2.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.7" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.6" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.4.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.6.7" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.62" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.2.3.Final" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.2.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.80" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.mail:jakarta.mail:1.6.7" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.1" level="project" />
</component>
</module>

View File

@@ -71,15 +71,28 @@
<!-- Swagger -->
<!-- <dependency>-->
<!-- <groupId>io.springfox</groupId>-->
<!-- <artifactId>springfox-swagger-ui</artifactId>-->
<!-- <version>${swagger.fox.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>io.springfox</groupId>-->
<!-- <artifactId>springfox-swagger2</artifactId>-->
<!-- <version>${swagger.fox.version}</version>-->
<!-- </dependency>-->
<!-- knife4j -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>3.0.3</version>
</dependency>
<!-- Lombok -->
@@ -105,6 +118,7 @@
<artifactId>common-core</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@@ -19,6 +20,7 @@ import java.util.List;
* @author dy
*/
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer
{
/**

View File

@@ -0,0 +1,47 @@
server:
port: 8878
# Spring
spring:
application:
# 应用名称
name: m2pool-gateway
main:
allow-circular-references: true
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: m2_dev
group: m2_dev_group
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
namespace: m2_dev
group: m2_dev_group
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-m2pool-gateway
groupId: m2_dev_group
data-type: json
rule-type: flow
servlet:
multipart:
max-file-size: 2MB
max-request-size: 8MB

View File

@@ -1,3 +1,4 @@
server:
port: 8101
# Spring
@@ -12,12 +13,12 @@ spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
namespace: m2_test
group: m2_test_group
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
# 配置文件格式
file-extension: yml
# 共享配置
@@ -35,7 +36,7 @@ spring:
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
dataId: sentinel-m2pool-gateway
groupId: m2_test_group
data-type: json

View File

@@ -1,3 +1,3 @@
spring:
profiles:
active: test
active: prod

View File

@@ -2,10 +2,12 @@ package com.m2pool.chat.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "websocket.transport")
public class CustomWebSocketConfig {
private int messageSizeLimit;
@@ -13,4 +15,5 @@ public class CustomWebSocketConfig {
private int sendBufferSizeLimit;
private int timeToFirstMessage;
private int maxConnections;
private String defaultCustomerEmail;
}

View File

@@ -4,6 +4,8 @@ import com.m2pool.chat.constant.Destination;
import com.m2pool.chat.coverter.CommonMessageConvert;
import com.m2pool.chat.interceptor.WebsocketChannelInterceptor;
import com.m2pool.chat.interceptor.WebsocketHandshakeInterceptor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.simp.config.ChannelRegistration;
@@ -13,6 +15,8 @@ import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBr
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
import javax.annotation.Resource;
import java.util.List;
@@ -31,6 +35,9 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
@Resource
private CustomWebSocketConfig customWebSocketConfig;
@Resource
private ApplicationEventPublisher applicationEventPublisher;
/**
* 注册 Stomp的端点 可以注册多个端点
* addEndpoint添加STOMP协议的端点。客户端访问地址
@@ -51,6 +58,7 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
.setAllowedOrigins("*");
}
/**
* 配置消息代理
* 客户端订阅消息的请求前缀topic用于广播推送queue用于点对点推送
@@ -59,12 +67,13 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker(Destination.TOPIC, Destination.QUEUE)
.setHeartbeatValue(new long[] {10000, 10000})
config.enableSimpleBroker(Destination.TOPIC, Destination.QUEUE_USER,Destination.QUEUE_CUSTOMER,Destination.QUEUE_CLOSE_ROOM)
.setHeartbeatValue(new long[] {30000, 30000})
.setTaskScheduler(new DefaultManagedTaskScheduler());
//发送消息前缀
config.setApplicationDestinationPrefixes(Destination.SEND_PREFIX);
//服务端通知客户端前缀可以不设置默认为user
//客户端订阅前缀可以不设置默认为user
config.setUserDestinationPrefix(Destination.USER_PREFIX);
}
@@ -78,12 +87,23 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
registration
.setMessageSizeLimit(customWebSocketConfig.getMessageSizeLimit())
.setSendTimeLimit(customWebSocketConfig.getSendTimeLimit())
.setSendBufferSizeLimit(customWebSocketConfig.getSendBufferSizeLimit())
.setSendBufferSizeLimit(customWebSocketConfig.getSendBufferSizeLimit());
// 首次连接超时时间.正常情况下,前端订阅 和 心跳包的影响 不会超时断连
.setTimeToFirstMessage(customWebSocketConfig.getTimeToFirstMessage());
// .setTimeToFirstMessage(customWebSocketConfig.getTimeToFirstMessage());
}
// @Bean
// public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
// ServletServerContainerFactoryBean factoryBean = new ServletServerContainerFactoryBean();
// factoryBean.setMaxTextMessageBufferSize(customWebSocketConfig.getMessageSizeLimit());
// factoryBean.setMaxBinaryMessageBufferSize(customWebSocketConfig.getMessageSizeLimit());
// factoryBean.setMaxSessionIdleTimeout(2048L * 2048L);
// factoryBean.setAsyncSendTimeout(2048L * 2048L);
// return factoryBean;
// }
/**
* 配置客户端出站通道拦截器默认线程1
@@ -96,7 +116,7 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
.maxPoolSize(20)
.keepAliveSeconds(60);
// 拦截器配置
registration.interceptors(new WebsocketChannelInterceptor(customWebSocketConfig));
registration.interceptors(new WebsocketChannelInterceptor(customWebSocketConfig,applicationEventPublisher));
}
/**
@@ -110,4 +130,5 @@ public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
return true;
}
}

View File

@@ -7,20 +7,35 @@ package com.m2pool.chat.constant;
* @Date 2025/4/14 14:54
*/
public class Destination {
/**
* stomp 默认单对单 发送目的地
* stomp 默认单对单 发送目的地.单对单消息默认 /
*/
public static final String QUEUE = "/queue";
/**
* stomp 默认单对单 发送目的地.单对单消息默认 /
*/
public static final String QUEUE_USER = "/queue/user";
/**
* stomp 默认单对单 发送目的地.单对单消息默认 /
*/
public static final String QUEUE_CUSTOMER = "/queue/customer";
/**
* 聊天室关闭 路径
*/
public static final String QUEUE_CLOSE_ROOM = "/queue/close/room/";
/**
* stomp 默认群发 目的地
*/
public static final String TOPIC = "/topic";
/**
* 前端订阅消息所需前缀。 stomp 默认user前缀。
* 前端订阅消息所需前缀point。 stomp 默认user前缀。
*/
public static final String USER_PREFIX = "/user";
public static final String USER_PREFIX = "/sub";
/**
* stomp 默认发送消息前缀。

View File

@@ -0,0 +1,41 @@
package com.m2pool.chat.constant;
import lombok.Getter;
/**
* @Enums ExceptionEnum
* @Description 自定义websocket 异常码枚举类
* @Author yyb
* @Date 2025/4/17 10:18
*/
@Getter
public enum ExceptionEnum {
IP_LIMIT_CONNECT(1020, "本机连接数已达上限9,请先关闭已有链接,再重新链接"),
MAX_LIMIT_CONNECT(1021, "服务器websocket连接数已达上限,服务器拒绝链接"),
SET_PRINCIPAL_FAIL(1022, "websocket链接异常,用户身份设置失败"),
GET_PRINCIPAL_FAIL(1023, "websocket链接异常,用户信息邮箱获取失败"),
ACCOUNT_HAS_CONNECTED(1024, "当前登录用户在其他地方链接"),
ROOM_NOT_EXIST(1025, "聊天室不存在,发送消息失败");
private final int code;
private final String description;
ExceptionEnum(int code, String description) {
this.code = code;
this.description = description;
}
/**
* 根据枚举类,拼接一个返回给前端的状态信息
* @param exceptionEnum 枚举类
* @return 返回一个状态信息,供前端解析
*/
public static String fromCode(ExceptionEnum exceptionEnum) {
int code = exceptionEnum.getCode();
String description = exceptionEnum.getDescription();
return code+","+description;
}
}

View File

@@ -1,13 +1,18 @@
package com.m2pool.chat.controller;
import com.m2pool.chat.dto.ChatMessageDto;
import com.m2pool.chat.service.ChatMessageService;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.chat.vo.MessagePageVo;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.security.annotation.RequiresLogin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/message")
@Api(tags = "聊天消息相关接口")
@@ -20,35 +25,23 @@ public class ChatMessageController {
* 查询7天前的历史记录
* @return
*/
@GetMapping("/find/history/message")
@ApiOperation(value = "查询7天前的历史记录", notes = "根据ID查询7天前的历史记录")
public AjaxResult findHistoryMessage(
@ApiParam(value = "游标最后一条消息id", required = true, example = "1")
@RequestParam(defaultValue = "1") Long id,
@ApiParam(value = "分页页码默认为10条/页", example = "10")
@RequestParam(required = false,defaultValue = "10")Integer pageNum,
@ApiParam(value = "聊天室id", required = true, example = "1")
@RequestParam Long roomId
) {
return chatMessageService.findHistoryMessage(id,pageNum,roomId);
@PostMapping("/find/history/message")
@ApiOperation(value = "查询7天前的历史记录(废弃,请使用/find/recently/message", notes = "根据ID查询7天前的历史记录")
@RequiresLogin
public R<List<ChatMessageDto>> findHistoryMessage(@RequestBody MessagePageVo pageVo) {
return chatMessageService.findHistoryMessage(pageVo.getId(), pageVo.getPageNum(), pageVo.getRoomId());
}
@GetMapping("/find/recently/message")
@PostMapping("/find/recently/message")
@ApiOperation(value = "查询七天内的记录", notes = "根据ID查询七天内的记录")
public AjaxResult findRecentlyMessage(
@ApiParam(value = "游标最后一条消息id", required = true, example = "1")
@RequestParam(defaultValue = "1") Long id,
@ApiParam(value = "分页页码默认为10条/页", example = "10")
@RequestParam(required = false,defaultValue = "10")Integer pageNum,
@ApiParam(value = "聊天室id", required = true, example = "1")
@RequestParam Long roomId
) {
return chatMessageService.findRecentlyMessage(id,pageNum,roomId);
public R<List<ChatMessageDto>> findRecentlyMessage(@RequestBody MessagePageVo pageVo) {
return chatMessageService.findRecentlyMessage(pageVo.getEmail(),pageVo.getId(), pageVo.getPageNum(), pageVo.getRoomId());
}
@GetMapping("/delete/message")
@ApiOperation(value = "消息撤回或删除")
public AjaxResult deleteMessage(
@ApiOperation(value = "消息撤回或删除(废弃)")
@RequiresLogin
public R<String> deleteMessage(
@ApiParam(value = "消息id", required = true, example = "1")
@RequestParam(defaultValue = "1") Long id,
@ApiParam(value = "消息类型 0 文本 1 图片", example = "0")
@@ -59,13 +52,7 @@ public class ChatMessageController {
@PostMapping("/read/message")
@ApiOperation(value = "聊天室消息改已读")
public AjaxResult readMessage(
@ApiParam(value = "聊天室id", required = true, example = "1")
@RequestParam Long roomId) {
return chatMessageService.readMessage(roomId);
public R<String> readMessage(@RequestBody MessagePageVo pageVo) {
return chatMessageService.readMessage(pageVo.getRoomId(),pageVo.getUserType());
}
}

View File

@@ -1,15 +1,20 @@
package com.m2pool.chat.controller;
import com.m2pool.chat.dto.ChatRoomDto;
import com.m2pool.chat.service.ChatRoomService;
import com.m2pool.chat.vo.CharRoomVo;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.chat.vo.RoomPageVo;
import com.m2pool.chat.vo.RoomVo;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.web.page.TableDataInfo;
import com.m2pool.common.security.annotation.RequiresLogin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
@Api(tags = "聊天室相关接口")
@RestController
@RequestMapping("/rooms")
@@ -19,23 +24,29 @@ public class ChatRoomController {
private ChatRoomService chatRoomService;
@GetMapping("/find/room/list")
@ApiOperation(value = "查询客服人员的聊天室列表")
public TableDataInfo findRoomList() {
return chatRoomService.findRoomList();
@PostMapping("/find/room/list")
@ApiOperation(value = "客服端:查询客服人员的聊天室列表")
@RequiresLogin
public TableDataInfo<ChatRoomDto> findRoomList(@RequestBody(required = false) RoomPageVo roomPageVo) {
// 如果请求体为空,初始化一个默认的 RoomPageVo 对象
if (roomPageVo == null) {
roomPageVo = new RoomPageVo();
roomPageVo.setSendDateTime(LocalDateTime.now());
}
return chatRoomService.findRoomList(roomPageVo);
}
@GetMapping("/find/room/by/userid")
@ApiOperation(value = "根据当前用户邮箱查询聊天室")
public AjaxResult findRoomByUserid(@ApiParam(value = "当前用户聊天对象的userId", example = "1")
@RequestParam(required = false) String email) {
return chatRoomService.findRoomByUserid(email);
@PostMapping("/find/room/by/userid")
@ApiOperation(value = "客户端:根据当前用户邮箱查询聊天室")
public R<ChatRoomDto> findRoomByUserid(@RequestBody RoomVo roomVo) {
return chatRoomService.findRoomByUserid(roomVo);
}
@PostMapping("/update/room")
@ApiOperation(value = "修改room相关信息")
public AjaxResult updateRoom(@RequestBody CharRoomVo charRoomVo) {
@ApiOperation(value = "修改聊天室重要标记")
@RequiresLogin
public R<String> updateRoom(@RequestBody CharRoomVo charRoomVo) {
return chatRoomService.updateRoom(charRoomVo);
}
}

View File

@@ -1,5 +1,6 @@
package com.m2pool.chat.controller;
import com.m2pool.chat.entity.StompPrincipal;
import com.m2pool.chat.service.StompService;
import com.m2pool.chat.vo.UserMessageVo;
import com.m2pool.common.core.web.Result.AjaxResult;
@@ -26,13 +27,25 @@ public class StompController extends BaseController {
private StompService stompService;
/**
* 发送消息到对应的用户
* 发送消息给普通用户和游客
* @param userMessageVo 消息体
* @return 返回值通过CommonMessageConvert消息转换器转换
*/
@MessageMapping("/send/message")
@SendToUser("/queue")
public AjaxResult sendMessageToUser(@Payload UserMessageVo userMessageVo) {
return stompService.sendMessageToUser(userMessageVo);
@MessageMapping("/send/message/to/user")
@SendToUser("/queue/user")
public AjaxResult sendMessageToUser(StompPrincipal principal, @Payload UserMessageVo userMessageVo) {
return stompService.sendMessageToUser(principal,userMessageVo);
}
/**
* 发送消息到对应的客服
* @param userMessageVo 消息体
* @return 返回值通过CommonMessageConvert消息转换器转换
*/
@MessageMapping("/send/message/to/customer")
@SendToUser("/queue/customer/")
public AjaxResult sendMessageToCustomer(StompPrincipal principal, @Payload UserMessageVo userMessageVo) {
return stompService.sendMessageToCustomer(principal,userMessageVo);
}
}

View File

@@ -1,8 +1,8 @@
package com.m2pool.chat.coverter;
import com.m2pool.chat.exception.WebSocketException;
import com.m2pool.common.core.utils.JsonUtil;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.support.GenericMessage;
@@ -19,7 +19,7 @@ public class CommonMessageConvert implements MessageConverter {
/**
* 将客户端发送过来的消息转换为指定的对象
* @param message 客户端发送过来的消息
* @param targetClass 目标数据类型
* @param targetClass 目标数据类型 注意这里的targetClass是消息对象对应接口的@Payload 注解的类型,且里面序列化的字段必须一模一样。否则序列化报错
* @return 转换后的对象
*/
@Override
@@ -27,9 +27,11 @@ public class CommonMessageConvert implements MessageConverter {
if (message.getPayload() instanceof byte[]) {
try {
String textPayload = new String((byte[]) message.getPayload(), StandardCharsets.UTF_8);
System.out.println("发送者发送到服务器的消息:"+textPayload);
return JsonUtil.convertString2Object(textPayload,targetClass);
} catch (Exception e) {
throw new WebSocketException( "消息格式错误");
System.out.println("错误详情"+e);
throw new MessageDeliveryException( "消息格式错误");
}
}
return null;
@@ -46,6 +48,7 @@ public class CommonMessageConvert implements MessageConverter {
@Override
public Message<?> toMessage(Object payload, MessageHeaders headers) {
String str = JsonUtil.toJson(payload);
System.out.println("发送给接受者的消息:"+payload);
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
return new GenericMessage<>(bytes, headers);
}

View File

@@ -2,7 +2,9 @@ package com.m2pool.chat.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@@ -15,6 +17,8 @@ import java.time.LocalDateTime;
@ApiModel(description = "聊天消息返回对象")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessageDto {
@ApiModelProperty(value = "消息ID", example = "1")
@@ -31,4 +35,12 @@ public class ChatMessageDto {
@ApiModelProperty(value = "发送时间", example = "")
private LocalDateTime createTime;
@ApiModelProperty(value = "聊天室id", example = "")
private Long roomId;
@ApiModelProperty(value = "是否是自己发送的消息", example = "")
private Integer isSelf;
}

View File

@@ -1,6 +1,11 @@
package com.m2pool.chat.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@@ -10,35 +15,54 @@ import java.time.LocalDateTime;
* @Author yyb
* @Date 2025/4/14 14:28
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "客服 聊天室列表返回对象")
public class ChatRoomDto {
/**
* 聊天室id
*/
@ApiModelProperty(value = "聊天室id", example = "1")
private Long id;
/**
* 聊天对象id
* 聊天对象id:一般为客服
*/
@ApiModelProperty(value = "聊天对象id一般为客服", example = "1")
private String userEmail;
/**
* 聊天室重要程度
*/
@ApiModelProperty(value = "聊天室重要程度 0不重要 1重要", example = "1")
private Integer flag;
/**
* 未读消息条数
* 客户未读消息条数
*/
private Integer unReadNumber;
@ApiModelProperty(value = "客户未读消息条数", example = "1")
private Integer clientReadNum;
/**
* 用户回复时间
*/
@ApiModelProperty(value = "用户回复时间", example = "2025-10-01 12:32:01")
private LocalDateTime lastUserSendTime;
/**
* 客服回复时间
*/
@ApiModelProperty(value = "客服回复时间", example = "2025-10-01 12:32:01")
private LocalDateTime lastCustomerSendTime;
/**
* 聊天发起者id :一般为游客或登录用户
*/
@ApiModelProperty(value = "聊天发起者id :一般为游客或登录用户", example = "1")
private String selfEmail;
@ApiModelProperty(value = "客服是否在线", example = "true")
private boolean customerIsOnline;
}

View File

@@ -1,6 +1,11 @@
package com.m2pool.chat.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @ClassName WebsocketMessageDto
@@ -8,11 +13,14 @@ import lombok.Data;
* @Author yyb
* @Date 2025/4/10 16:27
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WebsocketMessageDto {
/**
* 消息id
* 消息id 目前没用,不做消息撤回功能了
*/
private Long id;
@@ -26,7 +34,39 @@ public class WebsocketMessageDto {
*/
private String content;
/**
* 是否是登录用户
* 发送者类型 0 游客 1 登录用户 2 客服人员
*/
private boolean isLoginUser;
private Integer sendUserType;
/**
* 发送者邮箱
*/
private String sendEmail;
/**
* 发送时间
*/
private Date sendTime;
/**
* 聊天室id
*/
private Long roomId;
/**
* 是否创建新聊天室
*/
private Boolean isCreate;
/**
* 未读消息数
*/
private Integer clientReadNum;
//
// /**
// * 消息状态码
// */
// private Integer code;
}

View File

@@ -1,16 +1,22 @@
package com.m2pool.chat.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessage {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Integer type;
private Integer read;
private String sendEmail;
private String content;
private Long roomId;

View File

@@ -1,11 +1,20 @@
package com.m2pool.chat.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessageHistory {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Integer type;
private String sendEmail;

View File

@@ -1,20 +1,29 @@
package com.m2pool.chat.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChatRoom {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String userOneEmail;
private String userTwoEmail;
private LocalDateTime lastUserSendTime;
private LocalDateTime lastCustomerSendTime;
private Boolean flag;
private Integer flag;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Integer serviceReadNum;
private Integer clientReadNum;
private Boolean del;
}

View File

@@ -13,13 +13,18 @@ public class StompPrincipal implements Principal {
Integer type;
public StompPrincipal(String name,Integer type) {
Boolean isCreate;
public StompPrincipal(String name,Integer type,Boolean create) {
this.name = name;
this.type = type;
this.isCreate = create;
}
@Override
public String getName() {
return name;
}
}

View File

@@ -1,27 +0,0 @@
package com.m2pool.chat.exception;
import com.m2pool.common.core.exception.base.BaseException;
public class WebSocketException extends BaseException {
public WebSocketException(String module, String code, Object[] args, String defaultMessage) {
super(module, code, args, defaultMessage);
}
public WebSocketException(String module, String code, Object[] args) {
super(module, code, args);
}
public WebSocketException(String module, String defaultMessage) {
super(module, defaultMessage);
}
public WebSocketException(String code, Object[] args) {
super(code, args);
}
public WebSocketException(String defaultMessage) {
super(defaultMessage);
}
}

View File

@@ -2,10 +2,14 @@ package com.m2pool.chat.interceptor;
import com.m2pool.chat.config.CustomWebSocketConfig;
import com.m2pool.chat.constant.ExceptionEnum;
import com.m2pool.chat.entity.StompPrincipal;
import com.m2pool.chat.listener.IpLimitEvent;
import io.lettuce.core.ScriptOutputType;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@@ -16,13 +20,17 @@ import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import static com.m2pool.chat.constant.CustomHeader.*;
import static com.m2pool.chat.constant.UserType.CUSTOMER;
import static com.m2pool.chat.constant.UserType.LOGIN_USER;
import static com.m2pool.chat.constant.UserType.TOURIST;
import static com.m2pool.chat.utils.StompUtils.getConnectCustomHeaders;
/**
@@ -36,10 +44,9 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketChannelInterceptor.class);
/**
* 当前加入链接的ip
* 当前加入链接的ip ,key 为 ip+邮箱 ,VALUE 邮箱
*/
private static final ConcurrentHashMap<String, Boolean> ipConnectionCountMap = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, EmailLimit> ipConnectionCountMap = new ConcurrentHashMap<>();
/**
* 当前链接数
@@ -51,8 +58,13 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
*/
private CustomWebSocketConfig customWebSocketConfig;
public WebsocketChannelInterceptor(CustomWebSocketConfig customWebSocketConfig) {
private ApplicationEventPublisher applicationEventPublisher;
public WebsocketChannelInterceptor(CustomWebSocketConfig customWebSocketConfig,
ApplicationEventPublisher applicationEventPublisher) {
this.customWebSocketConfig = customWebSocketConfig;
this.applicationEventPublisher = applicationEventPublisher;
}
/**
@@ -66,26 +78,22 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
//获取链接建立时的请求头信息
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if (accessor.getCommand() == StompCommand.CONNECT ) {
System.out.println("yyb-开始链接"+new Date());
StompHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if(mha == null){
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.SET_PRINCIPAL_FAIL));
}
Object raw = message.getHeaders().get(SimpMessageHeaderAccessor.NATIVE_HEADERS);
int type = Integer.parseInt(getConnectCustomHeaders(raw, TYPE));
String email = getConnectCustomHeaders(raw, EMAIL);
//最大链接数限制
maxConnectionsLimit();
//根据客服端ip + 用户类型限制连接数
ipLimit(accessor,type);
if(mha == null){
throw new MessageDeliveryException("get MessageHeaderAccessor failed,can not set Principal,connect failed");
}
ipLimit(accessor,type,email);
//链接请求头中用户信息存入stomp中
mha.setUser(new StompPrincipal(email,type));
mha.setUser(new StompPrincipal(email,type,true));
System.out.println("yyb-链接成功"+new Date());
}
if (accessor.getCommand() == StompCommand.SEND) {
LOGGER.info("------------websocket send message");
}
if (accessor.getCommand() == StompCommand.SUBSCRIBE) {
LOGGER.info("------------websocket subscribe message");
}
@@ -95,7 +103,21 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
}
if (accessor.getCommand() == StompCommand.DISCONNECT){
disconnectHandler(accessor);
StompHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if(mha == null){
try {
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.SET_PRINCIPAL_FAIL));
}catch (MessageDeliveryException e){
System.out.println("错误消息"+e.getMessage());
accessor.setHeader("error", e.getMessage());
}
}
if (mha.getUser() != null){
String email = mha.getUser().getName();
LOGGER.info("断开连接的邮箱为:{}",email);
disconnectHandler(accessor,email);
}
LOGGER.info("------------websocket disconnect");
}
return message;
@@ -107,7 +129,7 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
private void maxConnectionsLimit(){
if(connectionCount.incrementAndGet() >= customWebSocketConfig.getMaxConnections()){
LOGGER.info("reach max connections,refuse connect");
throw new MessageDeliveryException("reach max connections,refuse connect");
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.MAX_LIMIT_CONNECT));
}
}
@@ -115,79 +137,98 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
* ip 链接个数限制
* @param accessor
*/
private void ipLimit(StompHeaderAccessor accessor,int type){
private void ipLimit(StompHeaderAccessor accessor,int type,String email){
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
if (sessionAttributes != null) {
String ipAddr = (String) sessionAttributes.get(IPADDR);
if(type != CUSTOMER && ipConnectionCountMap.get(ipAddr) != null){
throw new MessageDeliveryException("this ip maximum number of connections is reached");
String key = ipAddr + email;
EmailLimit emailAndCount = ipConnectionCountMap.get(key);
//两种ip限制情况
//本次链接为游客 且ip上已经有人链接直接拒绝本次链接
if(type == TOURIST && emailAndCount != null){
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
}
ipConnectionCountMap.put(ipAddr,true);
// 登录用户现在ip限制不用做了前端在同一ip情况下不同用户会断开连接
//本次链接为登录用户,并且已经链接.直接拒绝本次链接
if ( type != TOURIST && emailAndCount != null) {
emailAndCount.setCount(emailAndCount.getCount() + 1);
if (emailAndCount.getCount() >= 10){
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
}
//if(ipConnectionCountMap.containsValue(emailAndCount)){
// ipConnectionCountMap.put(ipAddr, emailAndCount);
// throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.ACCOUNT_HAS_CONNECTED));
//}
}else{
throw new MessageDeliveryException("not find email and type headers");
EmailLimit emailLimit = new EmailLimit();
emailLimit.setEmail(email);
emailLimit.setCount(1);
ipConnectionCountMap.put(key,emailLimit );
}
}else{
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
}
}
/**
* 获取stomp自定义请求头
* @param raw
* @param headerKey
* @return
*/
private String getConnectCustomHeaders(Object raw,String headerKey){
String headerValue = "";
if (raw instanceof Map) {
Object value = ((Map<?, ?>) raw).get(headerKey);
if(value instanceof ArrayList){
headerValue = ((ArrayList<?>) value).get(0).toString();
}
}
return headerValue;
}
/**
* 断开链接处理
*/
private void disconnectHandler(StompHeaderAccessor accessor){
private void disconnectHandler(StompHeaderAccessor accessor,String email){
//连接数减一
connectionCount.decrementAndGet();
//断开链接的ip
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
if (sessionAttributes != null) {
if (sessionAttributes != null ) {
String ipAddr = (String) sessionAttributes.get(IPADDR);
if(ipConnectionCountMap.get(ipAddr) != null){
ipConnectionCountMap.remove(ipAddr);
}
String key = ipAddr + email;
EmailLimit emailAndCount = ipConnectionCountMap.get(key);
if (emailAndCount != null ){
if (emailAndCount.getCount() > 1){
emailAndCount.setCount(emailAndCount.getCount() - 1);
}else{
throw new MessageDeliveryException("not find email and type headers");
ipConnectionCountMap.remove(key);
}
}
}else{
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
}
}
@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
LOGGER.info("------------WebsocketChannelInterceptor-postSend");
}
@Override
public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, @Nullable Exception ex) {
LOGGER.info("-----------WebsocketChannelInterceptor-afterSendCompletion");
}
@Override
public boolean preReceive(MessageChannel channel) {
LOGGER.info("----------WebsocketChannelInterceptor-preReceive");
return true;
}
@Override
public Message<?> postReceive(Message<?> message, MessageChannel channel) {
LOGGER.info("----------WebsocketChannelInterceptor-postReceive");
return message;
}
@Override
public void afterReceiveCompletion(@Nullable Message<?> message, MessageChannel channel, @Nullable Exception ex) {
LOGGER.info("----------WebsocketChannelInterceptor-afterReceiveCompletion");
}
/**
* ip限制存储对象
*/
@Data
private class EmailLimit{
private String email;
private int count = 1;
}
}

View File

@@ -0,0 +1,21 @@
package com.m2pool.chat.listener;
import com.m2pool.chat.entity.StompPrincipal;
import org.springframework.context.ApplicationEvent;
/**
* 登录限制事件
*/
public class IpLimitEvent extends ApplicationEvent {
private final StompPrincipal principal;
public IpLimitEvent(Object source, StompPrincipal principal) {
super(source);
this.principal = principal;
}
public StompPrincipal getPrincipal() {
return principal;
}
}

View File

@@ -0,0 +1,28 @@
package com.m2pool.chat.listener;
import com.m2pool.chat.constant.ExceptionEnum;
import com.m2pool.chat.entity.StompPrincipal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
@Component
public class IpLimitListener implements ApplicationListener<IpLimitEvent> {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Override
public void onApplicationEvent(IpLimitEvent event) {
StompPrincipal principal =event.getPrincipal();
// messagingTemplate.convertAndSendToUser(principal.getName(),
// Destination.QUEUE + "/" + principal.getName()
// , "ip链接数限制");
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
}
}

View File

@@ -0,0 +1,61 @@
package com.m2pool.chat.listener;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.m2pool.chat.entity.ChatMessage;
import com.m2pool.chat.entity.ChatRoom;
import com.m2pool.chat.entity.StompPrincipal;
import com.m2pool.chat.mapper.ChatMessageMapper;
import com.m2pool.chat.mapper.ChatRoomMapper;
import com.m2pool.chat.service.impl.StompServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
import javax.annotation.Resource;
import static com.m2pool.chat.constant.UserType.TOURIST;
/**
* websocket通道关闭监听器
*/
@Component
public class WebSocketEventListener implements ApplicationListener<SessionDisconnectEvent>{
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketEventListener.class);
@Resource
private StompServiceImpl stompService;
@Resource
private ChatRoomMapper chatRoomMapper;
@Resource
private ChatMessageMapper chatMessageMapper;
@Override
public void onApplicationEvent(SessionDisconnectEvent event) {
StompPrincipal user = (StompPrincipal) event.getUser();
Message<byte[]> message = event.getMessage();
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if (user != null) {
LOGGER.info("用户{}断开链接:用户类型{},消息类型{}",user.getName(), user.getType(), accessor.getCommand());
if (accessor.getCommand() == StompCommand.DISCONNECT && TOURIST.equals(user.getType())) {
//游客断开链接,通知客服删除游客聊天室
stompService.customerCloseRoom(user.getName());
// 删除数据库中游客数据
int delete = chatRoomMapper.delete(new LambdaUpdateWrapper<ChatRoom>()
.eq(ChatRoom::getUserOneEmail, user.getName()).like(ChatRoom::getUserOneEmail, "guest_"));
int delete1 = chatMessageMapper.delete(new LambdaUpdateWrapper<ChatMessage>()
.eq(ChatMessage::getSendEmail, user.getName()).like(ChatMessage::getSendEmail, "guest_"));
LOGGER.info("删除游客聊天室个数:{},消息个数{}", delete,delete1);
}
}
}
}

View File

@@ -1,14 +1,16 @@
package com.m2pool.chat.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.m2pool.chat.dto.ChatMessageDto;
import com.m2pool.chat.entity.ChatMessageHistory;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ChatMessageHistoryMapper {
public interface ChatMessageHistoryMapper extends BaseMapper<ChatMessageHistory> {
/**
* 根据游标查询十条数据
@@ -17,6 +19,6 @@ public interface ChatMessageHistoryMapper {
* @param roomId
* @return
*/
List<ChatMessageDto> findHistoryMessage(@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId);
List<ChatMessageDto> findHistoryMessage(@Param("email") String email,@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId);
}

View File

@@ -20,7 +20,7 @@ public interface ChatMessageMapper extends BaseMapper<ChatMessage> {
* @param roomId
* @return
*/
List<ChatMessageDto> findRecentlyMessage(@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId);
List<ChatMessageDto> findRecentlyMessage(@Param("email")String email,@Param("id") Long id,@Param("pageNum") Integer pageNum,@Param("roomId") Long roomId);
/**
@@ -29,6 +29,13 @@ public interface ChatMessageMapper extends BaseMapper<ChatMessage> {
* @return Map<String, Integer>,键为用户邮箱,值为未读消息条数
*/
@MapKey("userEmail")
Map<String, Integer> findUnReadNums(@Param("userEmails") List<String> userEmails);
Map<String, Map<String,Integer>> findUnReadNums(@Param("userEmails") List<String> userEmails);
/**
* 查询当前客服参与过的所有聊天室
* @param userEmail
* @return
*/
List<Long> findRoomIdsByCustomerEmail(@Param("userEmail") String userEmail);
}

View File

@@ -7,6 +7,7 @@ import com.m2pool.chat.entity.ChatRoom;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
@Mapper
@@ -15,21 +16,24 @@ public interface ChatRoomMapper extends BaseMapper<ChatRoom> {
/**
* 查询客服的聊天室列表
* @param userEmail 客服邮箱
* @param ids 要查询的聊天室集合
* @return
*/
List<ChatRoomDto> findRoomList(@Param("userEmail") String userEmail);
List<ChatRoomDto> findRoomList(@Param("ids") List<Long> ids, @Param("sendDateTime") LocalDateTime sendDateTime);
/**
* 查找当前用户与对应用户是否已存在创建的聊天室
* @param userEmail 用户邮箱
* @param email 客服邮箱
* @return
*/
Long findRoomByUserEmail(@Param("userEmail") String userEmail,@Param("email") String email);
ChatRoomDto findRoomByUserEmail(@Param("userEmail") String userEmail);
/**
* 新增或修改聊天室
* @param room
* @return
*/
int insetOrUpdateRoom(@Param("room") ChatRoom room);
}

View File

@@ -0,0 +1,8 @@
package com.m2pool.chat.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.m2pool.chat.entity.ChatMessageHistory;
public interface ChatMessageHistoryService extends IService<ChatMessageHistory> {
}

View File

@@ -1,6 +1,9 @@
package com.m2pool.chat.service;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.chat.dto.ChatMessageDto;
import com.m2pool.common.core.Result.R;
import java.util.List;
public interface ChatMessageService{
@@ -12,16 +15,17 @@ public interface ChatMessageService{
* @param roomId 聊天室id
* @return
*/
AjaxResult findHistoryMessage(Long id, Integer pageNum,Long roomId);
R<List<ChatMessageDto>> findHistoryMessage(Long id, Integer pageNum, Long roomId);
/**
* 游标分页 查询7天内数据
* @param email 用户邮箱
* @param id 游标
* @param pageNum 每页条数
* @param roomId 聊天室id
* @return
*/
AjaxResult findRecentlyMessage(Long id,Integer pageNum,Long roomId);
R<List<ChatMessageDto>> findRecentlyMessage(String email,Long id,Integer pageNum,Long roomId);
/**
@@ -30,13 +34,14 @@ public interface ChatMessageService{
* @param type 消息类型 0 文本 1 图片
* @return
*/
AjaxResult deleteMessage(Long id,Integer type);
R<String> deleteMessage(Long id,Integer type);
/**
* 根据聊天室修改用户未读信息
* @param roomId
* @param type 用户类型
* @return
*/
AjaxResult readMessage(Long roomId);
R<String> readMessage(Long roomId,Integer type);
}

View File

@@ -1,30 +1,34 @@
package com.m2pool.chat.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.m2pool.chat.dto.ChatRoomDto;
import com.m2pool.chat.entity.ChatRoom;
import com.m2pool.chat.vo.CharRoomVo;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.chat.vo.RoomPageVo;
import com.m2pool.chat.vo.RoomVo;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.web.page.TableDataInfo;
public interface ChatRoomService extends IService<ChatRoom> {
/**
* 查询客服的聊天室列表
* @param roomPageVo
* @return
*/
TableDataInfo findRoomList();
TableDataInfo<ChatRoomDto> findRoomList(RoomPageVo roomPageVo);
/**
* 根据当前用户邮箱查询聊天室
* @return
*/
AjaxResult findRoomByUserid(String email);
R<ChatRoomDto> findRoomByUserid(RoomVo roomVo);
/**
* 修改聊天室信息
* @param charRoomVo
* @return
*/
AjaxResult updateRoom( CharRoomVo charRoomVo);
R<String> updateRoom( CharRoomVo charRoomVo);
}

View File

@@ -1,5 +1,6 @@
package com.m2pool.chat.service;
import com.m2pool.chat.entity.StompPrincipal;
import com.m2pool.chat.vo.UserMessageVo;
import com.m2pool.common.core.web.Result.AjaxResult;
@@ -10,6 +11,13 @@ public interface StompService {
* @param userMessageVo
* @return
*/
AjaxResult sendMessageToUser(UserMessageVo userMessageVo);
AjaxResult sendMessageToUser(StompPrincipal principal, UserMessageVo userMessageVo);
/**
* 发送消息给客服
* @param userMessageVo
* @return
*/
AjaxResult sendMessageToCustomer(StompPrincipal principal, UserMessageVo userMessageVo);
}

View File

@@ -0,0 +1,11 @@
package com.m2pool.chat.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.m2pool.chat.entity.ChatMessageHistory;
import com.m2pool.chat.mapper.ChatMessageHistoryMapper;
import com.m2pool.chat.service.ChatMessageHistoryService;
import org.springframework.stereotype.Service;
@Service
public class ChatMessageHistoryServiceImpl extends ServiceImpl<ChatMessageHistoryMapper, ChatMessageHistory> implements ChatMessageHistoryService {
}

View File

@@ -1,6 +1,6 @@
package com.m2pool.chat.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.m2pool.chat.dto.ChatMessageDto;
import com.m2pool.chat.entity.ChatMessage;
import com.m2pool.chat.entity.ChatRoom;
@@ -8,13 +8,17 @@ import com.m2pool.chat.mapper.ChatMessageHistoryMapper;
import com.m2pool.chat.mapper.ChatMessageMapper;
import com.m2pool.chat.mapper.ChatRoomMapper;
import com.m2pool.chat.service.ChatMessageService;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.security.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static com.m2pool.chat.constant.UserType.*;
@Service
public class ChatMessageServiceImpl implements ChatMessageService {
@@ -29,44 +33,70 @@ public class ChatMessageServiceImpl implements ChatMessageService {
private ChatRoomMapper chatRoomMapper;
@Override
public AjaxResult findHistoryMessage(Long id,Integer pageNum,Long roomId) {
List<ChatMessageDto> historyMessage = chatMessageHistoryMapper.findHistoryMessage(id, pageNum, roomId);
return AjaxResult.success(historyMessage);
public R<List<ChatMessageDto>>
findHistoryMessage(Long id,Integer pageNum,Long roomId) {
String email = SecurityUtils.getUsername();
List<ChatMessageDto> messages;
messages = chatMessageMapper.findRecentlyMessage(email,id, pageNum, roomId);
return R.success(messages);
}
@Override
public AjaxResult findRecentlyMessage(Long id,Integer pageNum,Long roomId) {
List<ChatMessageDto> recentlyMessage = chatMessageMapper.findRecentlyMessage(id, pageNum, roomId);
return AjaxResult.success(recentlyMessage);
public R<List<ChatMessageDto>> findRecentlyMessage(String email,Long id,Integer pageNum,Long roomId) {
ChatMessage chatMessage;
if(StringUtils.isEmpty(email)){
return R.fail("查询失败,用户标识或邮箱不能为空");
}
if(roomId == null){
return R.fail("查询聊天消息失败,聊天室ID不能为空");
}
//判断当前消息是否是七天内消息
if(id != null && id != 0){
chatMessage = chatMessageMapper.selectById(id);
}else{
chatMessage = chatMessageMapper.selectOne(new LambdaQueryWrapper<ChatMessage>()
.eq(ChatMessage::getRoomId, roomId).orderByDesc(ChatMessage::getId).last("LIMIT 1"));
}
List<ChatMessageDto> recentlyMessage;
if(chatMessage != null){
recentlyMessage = chatMessageMapper.findRecentlyMessage(email,id, pageNum, roomId);
if(recentlyMessage.size() != pageNum){
recentlyMessage.addAll(chatMessageHistoryMapper.findHistoryMessage(email, id, pageNum - recentlyMessage.size(), roomId));
}
}else{
recentlyMessage = chatMessageHistoryMapper.findHistoryMessage(email, id, pageNum, roomId);
}
return R.success(recentlyMessage);
}
@Override
public AjaxResult deleteMessage(Long id,Integer type) {
public R<String> deleteMessage(Long id,Integer type) {
if(chatMessageMapper.deleteById(id) > 0){
//TODO 对象图片存储删除
return AjaxResult.success("删除成功");
return R.success("删除成功");
}
return AjaxResult.error("删除失败");
return R.fail("删除失败");
}
@Override
@Transactional
public AjaxResult readMessage(Long roomId) {
public R<String> readMessage(Long roomId, Integer type) {
ChatRoom chatRoom = chatRoomMapper.selectById(roomId);
String username = SecurityUtils.getUsername();
ChatRoom build = ChatRoom.builder()
.id(roomId)
.build();
if (chatRoom != null){
String updateUserEmail = "";
if( username.equals(chatRoom.getUserOneEmail())){
updateUserEmail = chatRoom.getUserTwoEmail();
}else if (username.equals(chatRoom.getUserTwoEmail())) {
updateUserEmail = chatRoom.getUserOneEmail();
if (Objects.equals(type, LOGIN_USER) || Objects.equals(type, TOURIST) ) {
build.setClientReadNum(0);
}
int update = chatMessageMapper.update(ChatMessage.builder().read(1).build(),
new LambdaUpdateWrapper<ChatMessage>().eq(ChatMessage::getSendEmail, updateUserEmail).eq(ChatMessage::getRoomId, roomId));
return update > 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败");
if(Objects.equals(type, CUSTOMER)){
build.setServiceReadNum(0);
}
return AjaxResult.error("聊天室不存在");
int i = chatRoomMapper.updateById(build);
return i >= 0 ? R.success("已读") : R.fail("消息读取失败");
}
return R.fail("聊天室不存在");
}
}

View File

@@ -1,25 +1,38 @@
package com.m2pool.chat.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.m2pool.chat.config.CustomWebSocketConfig;
import com.m2pool.chat.dto.ChatRoomDto;
import com.m2pool.chat.entity.ChatRoom;
import com.m2pool.chat.mapper.ChatMessageMapper;
import com.m2pool.chat.mapper.ChatRoomMapper;
import com.m2pool.chat.service.ChatRoomService;
import com.m2pool.chat.vo.CharRoomVo;
import com.m2pool.chat.vo.RoomPageVo;
import com.m2pool.chat.vo.RoomVo;
import com.m2pool.chat.vo.UserMessageVo;
import com.m2pool.common.core.Result.R;
import com.m2pool.common.core.constant.HttpStatus;
import com.m2pool.common.core.utils.PageUtils;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.common.core.web.page.TableDataInfo;
import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.system.api.RemoteUserService;
import com.m2pool.system.api.entity.SysUser;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.user.SimpUser;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
@Service
@@ -31,62 +44,145 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
@Resource
private ChatMessageMapper chatMessageMapper;
@Override
public TableDataInfo findRoomList() {
PageUtils.startPage();
//1.查找当前客服对应的聊天室
List<ChatRoomDto> roomList = chatRoomMapper.findRoomList(SecurityUtils.getUsername());
List<String> userEmails = roomList.stream().map(ChatRoomDto::getUserEmail).collect(Collectors.toList());
//2.查询未读数量
if (!userEmails.isEmpty()){
Map<String, Integer> unReadNums = chatMessageMapper.findUnReadNums(userEmails);
for (ChatRoomDto room : roomList) {
Integer i = unReadNums.get(room.getUserEmail());
room.setUnReadNumber(i == null ? 0 : i);
}
@Resource
private RemoteUserService remoteUserService;
@Autowired
private SimpUserRegistry userRegistry;
@Resource
private CustomWebSocketConfig webSocketConfig;
@Override
public TableDataInfo<ChatRoomDto> findRoomList(RoomPageVo roomPageVo) {
String userEmail = SecurityUtils.getUsername();
List<Long> ids = chatMessageMapper.findRoomIdsByCustomerEmail(userEmail);
List<ChatRoomDto> roomList = new ArrayList<>();
if (ids.isEmpty()){
return getDataTable(roomList);
}
//1.查找当前客服对应的聊天室
roomList = chatRoomMapper.findRoomList(ids,roomPageVo.getSendDateTime());
// if (roomList.isEmpty()){
// TableDataInfo tableDataInfo = new TableDataInfo();
// tableDataInfo.setCode(HttpStatus.ERROR);
// tableDataInfo.setMsg("当前客服暂无聊天室");
// return tableDataInfo;
// }
return getDataTable(roomList);
}
private TableDataInfo getDataTable(List<?> list)
private TableDataInfo<ChatRoomDto> getDataTable(List<ChatRoomDto> list)
{
TableDataInfo rspData = new TableDataInfo();
TableDataInfo<ChatRoomDto> rspData = new TableDataInfo<ChatRoomDto>();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(list);
rspData.setMsg("查询成功");
PageInfo pageInfo = new PageInfo(list);
PageInfo<ChatRoomDto> pageInfo = new PageInfo<ChatRoomDto>(list);
rspData.setTotal(pageInfo.getTotal());
rspData.setTotalPage(pageInfo.getPages());
return rspData;
}
@Override
@Transactional
public AjaxResult findRoomByUserid(String email) {
public R<ChatRoomDto> findRoomByUserid(RoomVo roomVo) {
Random random = new Random();
//1.查询当前用户与对应用户是否已存在创建的聊天室
String userEmail = SecurityUtils.getUsername();
Long roomId = chatRoomMapper.findRoomByUserEmail(userEmail, email);
if(roomId != null){
return AjaxResult.success(roomId);
String userEmail = roomVo.getEmail();
ChatRoomDto roomByUserEmail = chatRoomMapper.findRoomByUserEmail(userEmail);
System.out.println("bby-用户邮箱"+roomByUserEmail);
//获取nacos中配置的客服邮箱列表,这个列表中的邮箱实际可能不是客服角色,但能够行驶客服角色功能
List<String> customerEmails = new ArrayList<>(Arrays.asList(webSocketConfig.getDefaultCustomerEmail().split(",")));
int i = random.nextInt(customerEmails.size());
String email = customerEmails.get(i);
customerEmails.removeIf(email1 -> !checkOnline(email1));
if(roomByUserEmail != null){
System.out.println("bby-在线的客服"+customerEmails + "初始化分配的客服"+email+"聊天室信息"+roomByUserEmail);
//1.1 客服在线,并且在客服列表
if (checkOnline(roomByUserEmail.getUserEmail()) && customerEmails.contains(roomByUserEmail.getUserEmail())) {
roomByUserEmail.setCustomerIsOnline(true);
}
ChatRoom build = ChatRoom.builder().userOneEmail(userEmail).userTwoEmail(email).build();
//2.不存在创建一个聊天室
int insert = chatRoomMapper.insert(build);
if (insert > 0){
roomId = build.getId();
return AjaxResult.success(roomId);
// 1.2客服账号不在担任客服角色选择使用nacos默认配置中的客服角色并修改数据库中的聊天室信息为新的客服角色。
if(!customerEmails.contains(roomByUserEmail.getUserEmail())){
roomByUserEmail.setCustomerIsOnline(false);
if (!customerEmails.isEmpty()){
email = customerEmails.get(random.nextInt(customerEmails.size()));
roomByUserEmail.setUserEmail(email);
roomByUserEmail.setCustomerIsOnline(true);
}
return AjaxResult.error("聊天室不存在,并且创建聊天室失败");
chatRoomMapper.updateById(ChatRoom.builder().id(roomByUserEmail.getId()).userTwoEmail(email).build());
}
// 1.3客服不在线不在线情况如果从nacos配置中获取到多个客服,选择一个在线的客服发送。
if (!checkOnline(roomByUserEmail.getUserEmail())){
roomByUserEmail.setCustomerIsOnline(false);
if (!customerEmails.isEmpty()){
roomByUserEmail.setCustomerIsOnline(true);
email = customerEmails.get(random.nextInt(customerEmails.size()));
roomByUserEmail.setUserEmail(email);
}
}
return R.success(roomByUserEmail);
}
//2.不存在创建一个聊天室
List<SysUser> data = remoteUserService.getCSList().getData();
List<String> emails = data.stream().map(SysUser::getEmail).collect(Collectors.toList());
emails.removeIf(email1 -> !checkOnline(email1));
//如果当前没有客服角色账号使用nacos 默认配置中的客服角色
if(Collections.isEmpty(emails)){
emails = customerEmails;
// 自己不能创建
if(emails.contains( userEmail)){
return R.fail("您作为管理员无法创建与自己的连接");
}
}
System.out.println("bby-在线的客服-创建聊天室emails"+emails);
boolean customerIsOnline = false;
//有在线客服,再次分配给在线的客服
if (!emails.isEmpty()){
customerIsOnline = true;
email = emails.get(random.nextInt(emails.size()));
System.out.println("bby-最终分配的在线客服"+email);
}
ChatRoom build = ChatRoom.builder()
.userOneEmail(userEmail)
.userTwoEmail(email)
.build();
try{
int insert = chatRoomMapper.insetOrUpdateRoom(build);
if (insert > 0){
return R.success(ChatRoomDto.builder()
.id(build.getId())
.selfEmail(userEmail)
.customerIsOnline(customerIsOnline)
.userEmail(build.getUserTwoEmail()).build());
}
}catch (Exception e){
return R.fail("聊天室已存在,创建聊天室失败");
}
return R.fail("聊天室不存在,并且创建聊天室失败");
}
/**
* 检查用户是否在线
* @return
*/
private boolean checkOnline(String email){
return userRegistry.getUsers().stream()
.anyMatch(user -> user.getName().equals(email));
}
@Override
public AjaxResult updateRoom(CharRoomVo charRoomVo) {
public R<String> updateRoom(CharRoomVo charRoomVo) {
int i = chatRoomMapper.updateById(ChatRoom.builder().id(charRoomVo.getId()).flag(charRoomVo.getFlag()).build());
if(i > 0){
return AjaxResult.success("修改成功");
return R.success("修改成功");
}
return AjaxResult.error("修改失败,不存在该聊天室");
return R.fail("修改失败,不存在该聊天室");
}
}

View File

@@ -1,25 +1,36 @@
package com.m2pool.chat.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.m2pool.chat.config.CustomWebSocketConfig;
import com.m2pool.chat.constant.Destination;
import com.m2pool.chat.constant.ExceptionEnum;
import com.m2pool.chat.dto.WebsocketMessageDto;
import com.m2pool.chat.entity.ChatMessage;
import com.m2pool.chat.entity.ChatRoom;
import com.m2pool.chat.entity.StompPrincipal;
import com.m2pool.chat.mapper.ChatMessageMapper;
import com.m2pool.chat.mapper.ChatRoomMapper;
import com.m2pool.chat.service.StompService;
import com.m2pool.chat.vo.UserMessageVo;
import com.m2pool.common.core.web.Result.AjaxResult;
import com.m2pool.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static com.alibaba.nacos.client.utils.EnvUtil.LOGGER;
import static com.m2pool.chat.constant.UserType.CUSTOMER;
import static com.m2pool.chat.constant.UserType.TOURIST;
@Service
public class StompServiceImpl implements StompService {
@@ -36,24 +47,108 @@ public class StompServiceImpl implements StompService {
@Resource
private ChatRoomMapper chatRoomMapper;
@Resource
private TransactionTemplate transactionTemplate;
@Resource
private CustomWebSocketConfig webSocketConfig;
/**
* key 为发送者+接受者 value 为 图片内容
*/
//private final ConcurrentHashMap<String, String> imageContent = new ConcurrentHashMap<>();
@Override
public AjaxResult sendMessageToUser(UserMessageVo userMessageVo) {
WebsocketMessageDto websocketMessageDto = new WebsocketMessageDto();
websocketMessageDto.setType(userMessageVo.getType());
websocketMessageDto.setContent(userMessageVo.getContent());
// 检查目标用户是否在线
if (!checkOnline(userMessageVo)) {
return AjaxResult.error("目标用户不在线");
public AjaxResult sendMessageToUser(StompPrincipal principal, UserMessageVo userMessageVo) {
WebsocketMessageDto build = buildDto(principal, userMessageVo);
//获取当前聊天室对象
ChatRoom chatRoom = chatRoomMapper.selectOne(new LambdaQueryWrapper<ChatRoom>()
.eq(ChatRoom::getUserOneEmail,userMessageVo.getEmail())
.eq(ChatRoom::getUserTwoEmail,principal.getName()));
build(chatRoom,userMessageVo,principal,build);
messagingTemplate.convertAndSendToUser(principal.getName(), Destination.QUEUE_CUSTOMER + "/" + principal.getName(),build);
messagingTemplate.convertAndSendToUser(userMessageVo.getEmail(), Destination.QUEUE_USER + "/" + userMessageVo.getEmail(),build);
return AjaxResult.success("成功");
}
//当前用户发送其他人, 发送给指定用户. 否则默认发送给当前发送者
messagingTemplate.convertAndSendToUser(userMessageVo.getEmail(), Destination.QUEUE + "/" + userMessageVo.getEmail(), userMessageVo.getContent());
// 接收者和发送者 都不是游客才能存储消息 和修改聊天室信息
if (!TOURIST.equals(userMessageVo.getReceiveUserType()) && TOURIST.equals(userMessageVo.getSendUserType())){
Long id = insertMessage(userMessageVo);
websocketMessageDto.setId(id);
updateRoom(userMessageVo);
@Override
public AjaxResult sendMessageToCustomer(StompPrincipal principal, UserMessageVo userMessageVo) {
WebsocketMessageDto build = buildDto(principal, userMessageVo);
ChatRoom chatRoom = chatRoomMapper.selectOne(new LambdaQueryWrapper<ChatRoom>()
.eq(ChatRoom::getUserOneEmail, principal.getName())
.eq(ChatRoom::getUserTwoEmail, userMessageVo.getEmail()));
build(chatRoom,userMessageVo,principal,build);
messagingTemplate.convertAndSendToUser(principal.getName(), Destination.QUEUE_USER + "/" + principal.getName(),build);
messagingTemplate.convertAndSendToUser(userMessageVo.getEmail(), Destination.QUEUE_CUSTOMER + "/" + userMessageVo.getEmail(),build);
return AjaxResult.success("成功");
}
return AjaxResult.success(websocketMessageDto);
public void build(ChatRoom chatRoom,UserMessageVo userMessageVo,StompPrincipal principal,WebsocketMessageDto build){
if (chatRoom == null && userMessageVo.getRoomId() == null){
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.ROOM_NOT_EXIST));
}
if(chatRoom != null && userMessageVo.getRoomId() == null){
userMessageVo.setRoomId(chatRoom.getId());
}
build.setRoomId(userMessageVo.getRoomId());
int serviceReadNum = chatRoom != null ? chatRoom.getServiceReadNum() : 0;
build.setClientReadNum(serviceReadNum + 1);
Long id = executeTran(principal, userMessageVo, chatRoom);
System.out.println("发送消息聊天室id"+userMessageVo.getRoomId()+"发送者邮箱"+principal.getName()+"接受者邮箱"+userMessageVo.getEmail()+"消息id"+id);
// 多端情况下,需要把消息发送给
build.setId(id);
}
/**
* 构建聊天实时返回信息
* @param principal
* @param userMessageVo
* @return
*/
private WebsocketMessageDto buildDto(StompPrincipal principal, UserMessageVo userMessageVo) {
Boolean isCreate = principal.getIsCreate();
WebsocketMessageDto build = WebsocketMessageDto.builder()
.type(userMessageVo.getType())
.content(userMessageVo.getContent())
.sendEmail(principal.getName())
.sendUserType(principal.getType())
.sendTime(new Date())
.isCreate(isCreate)
.clientReadNum(0)
.build();
if (isCreate){
principal.setIsCreate(false);
}
return build;
}
/**
* 执行消息表新增消息和聊天室已读未读消息数量更新事务
* @param principal
* @param userMessageVo
* @param chatRoom
*/
private Long executeTran(StompPrincipal principal, UserMessageVo userMessageVo, ChatRoom chatRoom){
final Long[] id = {0L};
// 消息存储
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
// 插入消息并获取 ID
id[0] = insertMessage(principal, userMessageVo);
//聊天室,已读未读数量,更新。
updateRoom(chatRoom,principal.getType());
} catch (Exception e) {
// 回滚事务
status.setRollbackOnly();
throw e;
}
}
});
return id[0];
}
/**
@@ -61,6 +156,7 @@ public class StompServiceImpl implements StompService {
* @return
*/
private boolean checkOnline(UserMessageVo userMessageVo){
return userRegistry.getUsers().stream()
.anyMatch(user -> user.getName().equals(userMessageVo.getEmail()));
}
@@ -70,9 +166,9 @@ public class StompServiceImpl implements StompService {
* @param userMessageVo
* @return
*/
private Long insertMessage(UserMessageVo userMessageVo){
private Long insertMessage(StompPrincipal principal,UserMessageVo userMessageVo){
ChatMessage message = ChatMessage.builder()
.sendEmail(SecurityUtils.getUsername())
.sendEmail(principal.getName())
.content(userMessageVo.getContent())
.type(userMessageVo.getType())
.roomId(userMessageVo.getRoomId())
@@ -83,15 +179,40 @@ public class StompServiceImpl implements StompService {
/**
* 修改聊天信息
* @param userMessageVo
* @param chatRoom 本次聊天聊天室信息
* @param sendUserType 发送者类型
* @param {bool 废弃 发送者是否在线,不在线,需要更新未读消息数量}
*/
private void updateRoom(UserMessageVo userMessageVo){
ChatRoom room = ChatRoom.builder().id(userMessageVo.getRoomId()).build();
if (CUSTOMER.equals(userMessageVo.getSendUserType())) {
private void updateRoom(ChatRoom chatRoom,Integer sendUserType){
System.out.println("聊天室信息"+chatRoom);
if(chatRoom != null){
ChatRoom room = ChatRoom.builder().id(chatRoom.getId()).build();
if (CUSTOMER.equals(sendUserType)) {
room.setClientReadNum(chatRoom.getClientReadNum() + 1);
room.setLastCustomerSendTime(LocalDateTime.now());
} else {
room.setServiceReadNum(chatRoom.getServiceReadNum() + 1);
room.setLastUserSendTime(LocalDateTime.now());
}
chatRoomMapper.insert(room);
chatRoomMapper.updateById(room);
}
}
/**
* 用于客服关闭断线客服端聊天室接口
* @param userName 游客邮箱
* @return
*/
public void customerCloseRoom(String userName){
//目前配置只配置了一个客服,如果多个关闭消息,需同时发送多个客服
System.out.println("当前配置的客服"+webSocketConfig.getDefaultCustomerEmail());
String[] split = webSocketConfig.getDefaultCustomerEmail().split(",");
for (String email : split) {
messagingTemplate.convertAndSendToUser(
email,
Destination.QUEUE_CLOSE_ROOM + email, userName);
}
}
}

View File

@@ -1,13 +1,105 @@
package com.m2pool.chat.task;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.m2pool.chat.entity.ChatMessage;
import com.m2pool.chat.entity.ChatMessageHistory;
import com.m2pool.chat.entity.ChatRoom;
import com.m2pool.chat.mapper.ChatMessageMapper;
import com.m2pool.chat.mapper.ChatRoomMapper;
import com.m2pool.chat.service.ChatMessageHistoryService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName ChatTask
* @Description chat 聊天室和消息定时任务
* @Author yyb
* @Date 2025/4/15 11:51
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "task")
@EnableScheduling
public class ChatTask {
@Resource
private ChatMessageMapper chatMessageMapper;
@Resource
private ChatMessageHistoryService chatMessageHistoryService;
@Autowired
private ChatRoomMapper chatRoomMapper;
private boolean enable;
// @Scheduled(cron = "0 0/1 * * * ?")
@Scheduled(cron = "0 15 1 * * ?")
public void chatMessageDataSeparatedForHotAndCold(){
if(!enable){
System.out.println("ChatTask 定时任务已关闭请在nacos修改配置");
return;
}
int pageNum = 1;
int pageSize = 1000; // 每批处理数量
List<ChatMessage> chatMessages;
do {
Page<ChatMessage> page = new Page<>(pageNum, pageSize);
chatMessageMapper.selectPage(page, new LambdaQueryWrapper<ChatMessage>()
.le(ChatMessage::getCreateTime, LocalDateTime.now().minusDays(7)));
chatMessages = page.getRecords();
if (!chatMessages.isEmpty()) {
List<ChatMessageHistory> collect = chatMessages.stream()
.map(chatMessage ->
ChatMessageHistory.builder()
.id(chatMessage.getId())
.type(chatMessage.getType())
.sendEmail(chatMessage.getSendEmail())
.content(chatMessage.getContent())
.roomId(chatMessage.getRoomId())
.createTime(chatMessage.getCreateTime())
.updateTime(chatMessage.getUpdateTime())
.build()
)
.collect(Collectors.toList());
// 批量插入
chatMessageHistoryService.saveBatch(collect);
chatMessageMapper.deleteBatchIds(chatMessages.stream().map(ChatMessage::getId).collect(Collectors.toList()));
}
pageNum++;
} while (!chatMessages.isEmpty());
}
/**
* 清理掉,因服务器异常,未发送到客服这边删除的游客聊天室和消息表数据
*
*/
@Scheduled(cron = "0 16 1 * * ?")
//@Scheduled(cron = "0 0/1 * * * ?")
public void clearTouristDatas(){
if(!enable){
return;
}
chatMessageMapper.delete(new LambdaUpdateWrapper<ChatMessage>()
.like(ChatMessage::getSendEmail, "guest_"));
chatRoomMapper.delete(new LambdaUpdateWrapper<ChatRoom>().like(ChatRoom::getUserOneEmail, "guest_"));
}
}

View File

@@ -0,0 +1,30 @@
package com.m2pool.chat.utils;
import java.util.ArrayList;
import java.util.Map;
/**
* @ClassName StompUtils
* @Description stomp工具类
* @Author yyb
* @Date 2025/4/29 11:35
*/
public class StompUtils {
/**
* 获取stomp自定义请求头
* @param raw
* @param headerKey
* @return
*/
public static String getConnectCustomHeaders(Object raw,String headerKey){
String headerValue = "";
if (raw instanceof Map) {
Object value = ((Map<?, ?>) raw).get(headerKey);
if(value instanceof ArrayList){
headerValue = ((ArrayList<?>) value).get(0).toString();
}
}
return headerValue;
}
}

View File

@@ -1,5 +1,7 @@
package com.m2pool.chat.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@@ -9,7 +11,10 @@ import lombok.Data;
* @Date 2025/4/15 10:42
*/
@Data
@ApiModel(description = "聊天室请求对象")
public class CharRoomVo {
@ApiModelProperty(value = "聊天室id", example = "1",required = true)
private Long id;
private Boolean flag;
@ApiModelProperty(value = "聊天室重要程度 0不重要 1重要", example = "1",required = true)
private Integer flag;
}

View File

@@ -0,0 +1,35 @@
package com.m2pool.chat.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @ClassName MessagePageVo
* @Description TODO
* @Author yyb
* @Date 2025/4/22 17:09
*/
@Data
@ApiModel(description = "消息分页对象")
public class MessagePageVo {
@ApiModelProperty(value = "消息id", example = "1")
private Long id;
@ApiModelProperty(value = "页数量", example = "1")
private Integer pageNum;
@ApiModelProperty(value = "聊天室id", example = "1",required = true)
private Long roomId;
@ApiModelProperty(value = "用户类型 0 游客 1 登录用户 2 客服", example = "1",required = true)
private Integer userType;
@ApiModelProperty(value = "当前登录用户邮箱;游客就是生成的唯一id", example = "54544@qq.com",required = true)
private String email;
public MessagePageVo() {
this.pageNum = 20;
}
}

View File

@@ -0,0 +1,24 @@
package com.m2pool.chat.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* @ClassName MessagePageVo
* @Description TODO
* @Author yyb
* @Date 2025/4/22 17:09
*/
@Data
@ApiModel(description = "请求对象")
public class RoomPageVo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "上一页最后一个聊天室发送时间", example = "2025-10-01 12:32:01")
private LocalDateTime sendDateTime;
}

View File

@@ -0,0 +1,18 @@
package com.m2pool.chat.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @ClassName RoomVo
* @Description TODO
* @Author yyb
* @Date 2025/4/30 16:27
*/
@Data
@ApiModel(description = "根据用户邮箱查询聊天室")
public class RoomVo {
@ApiModelProperty(value = "当前登录用户邮箱;游客就是生成的唯一id", example = "54544@qq.com",required = true)
private String email;
}

View File

@@ -1,7 +1,14 @@
package com.m2pool.chat.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @ClassName UserMessageVo
* @Description 用户发送消息对象
@@ -9,37 +16,56 @@ import lombok.Data;
* @Date 2025/4/10 16:28
*/
@Data
@ApiModel(description = "用户发送消息对象")
public class UserMessageVo {
/**
* 消息类型
*/
@ApiModelProperty(value = "消息类型", example = "0 文本 1 图片")
private Integer type;
/**
* 消息内容
*/
@ApiModelProperty(value = "消息内容", example = "消息内容")
private String content;
/**
* 接收者
*/
@ApiModelProperty(value = "接收者", example = "54544@qq.com")
private String email;
/**
* 接受用户类型 0 游客 1 登录用户 2 客服人员
*/
@ApiModelProperty(value = "接受用户类型 0 游客 1 登录用户 2 客服人员", example = "1")
private Integer receiveUserType;
/**
* 发送者类型 0 游客 1 登录用户 2 客服人员
*/
private Integer sendUserType;
/**
* 聊天室id
*/
@ApiModelProperty(value = "聊天室id", example = "1")
private Long roomId;
///**
// * 总的分片数
// */
//@ApiModelProperty(value = "总的分片数", example = "1",required = false)
//private Integer totalChunks;
///**
// * 当前分片数
// */
//@ApiModelProperty(value = "当前分片数", example = "1",required = false)
//private Integer currentChunk;
//
///**
// * 是否是第一个分片
// */
//@ApiModelProperty(value = "是否是第一个分片", example = "true",required = false)
//private Boolean isFirstChunk;
//
//@ApiModelProperty(value = "发送时间", example = "2025-05-27T15:39:29.221Z",required = false)
//private Date sendTime;
}

View File

@@ -6,6 +6,9 @@ server:
mime-types: application/json
spring:
mvc:
pathmatch:
matching-strategy: ant-path-matcher
application:
# 应用名称
name: m2pool-chat
@@ -16,13 +19,13 @@ spring:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
namespace: m2_test
group: m2_test_group
# server-addr: 127.0.0.1:8808
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
# server-addr: 127.0.0.1:8808
# 配置文件格式
file-extension: yml
@@ -36,10 +39,3 @@ spring:
max-file-size: 2MB
max-request-size: 8MB
websocket:
transport:
message-size-limit: 1500 # 消息大小限制 1.5k 约500汉字
send-time-limit: 5000 # 发送超时时间 5秒
send-buffer-size-limit: 65536 # 发送缓冲区大小 64K
time-to-first-message: 5000 # 首次消息超时时间 5秒
max-connections: 100 # 最大连接数

View File

@@ -1,3 +1,3 @@
spring:
profiles:
active: test
active: prod

View File

@@ -11,10 +11,19 @@
type,
send_email as sendEmail,
content,
create_time as createTime
create_time as createTime,
room_id as roomId,
case when send_email = #{email} then 1
else 0
end as isSelf
FROM chat_message_history
WHERE id <![CDATA[ <= ]]> #{id} AND room_id = #{roomId}
ORDER BY create_time DESC
<where>
room_id = #{roomId}
<if test="id != null">
AND id <![CDATA[ < ]]> #{id}
</if>
</where>
ORDER BY id DESC
LIMIT #{pageNum}
</select>
</mapper>

View File

@@ -8,22 +8,37 @@
type,
send_email as sendEmail,
content,
create_time as createTime
create_time as createTime,
room_id as roomId,
case when send_email = #{email} then 1
else 0
end as isSelf
FROM chat_message
WHERE id <![CDATA[ <= ]]> #{id} AND room_id = #{roomId}
ORDER BY create_time DESC
<where>
room_id = #{roomId}
<if test="id != null">
AND id <![CDATA[ < ]]> #{id}
</if>
</where>
ORDER BY id DESC
LIMIT #{pageNum}
</select>
<select id="findUnReadNums" resultType="java.util.Map">
SELECT send_email as userEmail,
count(*) as unReadNums
SELECT send_email as userEmail,count(*) as unReadNums
FROM chat_message
WHERE send_email IN
<foreach collection="userEmails" item="userEmail" open="(" separator="," close=")">
#{userEmail}
</foreach>
AND `read` = false
AND is_read = false
GROUP BY send_email
</select>
<select id="findRoomIdsByCustomerEmail" resultType="java.lang.Long">
select room_id from chat_message where send_email = #{userEmail} group by room_id
UNION
select room_id from chat_message_history where send_email = #{userEmail} group by room_id
UNION
select id as room_id from chat_room where user_two_email = #{userEmail}
</select>
</mapper>

View File

@@ -2,30 +2,53 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.m2pool.chat.mapper.ChatRoomMapper">
<select id="findRoomByUserEmail" resultType="java.lang.Long">
SELECT
id
FROM
chat_room
WHERE
user_one_email = #{userEmail} AND user_two_email = #{email} OR
(user_one_email = #{email} AND user_two_email = #{userEmail})
</select>
<select id="findRoomList" resultType="com.m2pool.chat.dto.ChatRoomDto">
SELECT
id,
user_one_email AS userEmail,
flag,
last_user_send_time as lastUserSendTime,
last_customer_send_time as lastCustomerSendTime
CASE WHEN last_user_send_time >= last_customer_send_time
THEN last_user_send_time ELSE last_customer_send_time END AS lastUserSendTime,
service_read_num AS clientReadNum
FROM
chat_room
<where>
del = false
<choose>
<when test="ids != null and ids.size() > 0">
AND id IN
<foreach item="id" index="index" collection="ids"
open="(" separator="," close=")">
#{id}
</foreach>
</when>
<when test="sendDateTime != null">
AND last_user_send_time <![CDATA[ <= ]]> #{sendDateTime}
</when>
<otherwise>
AND last_user_send_time <![CDATA[ <= ]]> NOW()
</otherwise>
</choose>
</where>
ORDER BY
flag DESC,
GREATEST( last_user_send_time, last_customer_send_time ) DESC
LIMIT 20
</select>
<select id="findRoomByUserEmail" resultType="com.m2pool.chat.dto.ChatRoomDto">
SELECT
id,client_read_num AS clientReadNum ,user_one_email AS selfEmail,user_two_email AS userEmail
FROM
chat_room
WHERE
user_two_email = #{userEmail}
AND del = FALSE
GROUP BY
flag DESC,
last_user_send_time DESC,
last_customer_send_time DESC
user_one_email = #{userEmail}
</select>
<insert id="insetOrUpdateRoom">
INSERT INTO chat_room(user_one_email,user_two_email)
VALUES (#{room.userOneEmail},#{room.userTwoEmail})
ON DUPLICATE KEY UPDATE
user_one_email = #{room.userOneEmail},
user_two_email = #{room.userTwoEmail}
</insert>
</mapper>

View File

@@ -38,7 +38,7 @@ public class SysFileController
/**
* 文件上传请求
*/
@PostMapping("upload")
@PostMapping("/upload")
public R<SysFile> upload(MultipartFile file)
{
try

View File

@@ -20,7 +20,7 @@ public class LocalSysFileServiceImpl implements ISysFileService
/**
* 资源映射路径 前缀
*/
@Value("${file.prefix")
@Value("${file.prefix}")
public String localFilePrefix;
/**

View File

@@ -1,11 +1,5 @@
package com.m2pool.file.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.m2pool.common.core.exception.file.FileNameLengthLimitExceededException;
import com.m2pool.common.core.exception.file.FileSizeLimitExceededException;
import com.m2pool.common.core.exception.file.InvalidExtensionException;
@@ -13,8 +7,13 @@ import com.m2pool.common.core.utils.DateUtils;
import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.core.utils.file.MimeTypeUtils;
import com.m2pool.common.core.utils.uuid.Seq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.sound.midi.Soundbank;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects;
/**
* 文件上传工具类
@@ -81,6 +80,7 @@ public class FileUploadUtils
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
file.transferTo(Paths.get(absPath));
return getPathFileName(fileName);
}

View File

@@ -1,28 +1,30 @@
# Tomcat
server:
port: 9300
port: 9504
# Spring
spring:
application:
# 应用名称
name: m2pool-file
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
namespace: m2_test
group: m2_test_group
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8808
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
file:
domain: https://www.m2pool.com
path: /var/www/html/web-test
domain: https://test.m2pool.com
path: /var/www/html/web_test
# img: /img
filepath: /home/ubuntu/web
prefix: /statics

View File

@@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>m2pool-modules</artifactId>
<groupId>com.m2pool</groupId>
<version>3.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>m2pool-lease</artifactId>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<scope>provided</scope>
</dependency>
<!-- &lt;!&ndash; Mybatis-Plus &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>mybatis-plus-boot-starter</artifactId>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>jsqlparser</artifactId>-->
<!-- <groupId>com.github.jsqlparser</groupId>-->
<!-- </exclusion>-->
<!--&lt;!&ndash; <exclusion>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>mybatis</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>org.mybatis</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; </exclusion>&ndash;&gt;-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- M2Pool Common DataSource -->
<dependency>
<groupId>com.m2pool</groupId>
<artifactId>common-datasource</artifactId>
</dependency>
<!-- M2Pool Common security -->
<dependency>
<groupId>com.m2pool</groupId>
<artifactId>common-security</artifactId>
</dependency>
<dependency>
<groupId>com.m2pool</groupId>
<artifactId>common-log</artifactId>
</dependency>
<dependency>
<groupId>com.m2pool</groupId>
<artifactId>common-swagger</artifactId>
</dependency>
<!-- WebSocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<!--google两步认证相关-->
<dependency>
<groupId>de.taimos</groupId>
<artifactId>totp</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.12.1</version>
</dependency>
<dependency>
<groupId>pt.kcry</groupId>
<artifactId>blake3_3</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
<profiles>
<profile>
<!-- 本地环境 -->
<id>dev</id>
<properties>
<spring.profile>dev</spring.profile>
<nacos.server.address>127.0.0.1:8808</nacos.server.address>
</properties>
<activation>
<!-- 是否默认激活 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties>
<spring.profile>test</spring.profile>
<nacos.server.address>127.0.0.1:8808</nacos.server.address>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<!-- 生产环境 -->
<id>prod</id>
<properties>
<spring.profile>prod</spring.profile>
<nacos.server.address>127.0.0.1:8808</nacos.server.address>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.6</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,38 @@
package com.m2pool.lease;
import com.m2pool.common.security.annotation.EnableCustomConfig;
import com.m2pool.common.security.annotation.EnableM2PoolFeignClients;
import com.m2pool.common.swagger.annotation.EnableCustomSwagger2;
import com.m2pool.lease.netty.server.NettyTcpServer;
import io.netty.channel.ChannelFuture;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
@EnableCustomConfig
@EnableCustomSwagger2
@EnableM2PoolFeignClients
@SpringBootApplication
@MapperScan({"com.m2pool.lease.mapper"})
public class M2poolLeaseApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(M2poolLeaseApplication.class, args);
}
@Resource
NettyTcpServer nettyTcpServer;
@Override
public void run(String... args) {
//启动服务端
ChannelFuture start = nettyTcpServer.start();
//服务端管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程
start.channel().closeFuture().syncUninterruptibly();
}
}

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