Compare commits

..

112 Commits

Author SHA1 Message Date
tianyongbao
ea4e6b5ea7 fix: 设备即将过期,功能优化完善。 2026-05-30 19:33:00 +08:00
tianyongbao
fbda67ed62 fix: 设备24小时内到期,电话通知修改。 2026-05-29 22:09:48 +08:00
tianyongbao
657df0a8be fix:设备过期,离线报警和溶解氧报警应不报警,sensorErrorCode逻辑问题修复。 2026-05-29 12:10:39 +08:00
tianyongbao
598f34eae2 fix: 设备添加,默认告警码为0,告警消息排序修改,sensorErrorCode处理修改。 2026-05-12 06:56:16 +08:00
tianyongbao
02cf52aed4 fix: 设备解绑后,新生成一个无用户无塘口的设备信息。 2026-05-12 05:49:27 +08:00
tianyongbao
b643662856 fix: 新绑定设备,偶尔出现设备名称重复情况,问题修复。 2026-05-06 23:04:03 +08:00
tianyongbao
5d5beff9a2 fix: 告警电话记录和报警记录,新增告警标题查询条件。 2026-05-06 22:50:00 +08:00
tianyongbao
b97194c5b5 fix: 设备绑定记录,设备管理,联动控制等,设备编号支持模糊查询。 2026-05-02 22:49:21 +08:00
tianyongbao
1a66982586 fix: 溶解氧探头离线告警修复。 2026-05-02 22:18:46 +08:00
tianyongbao
69bc7bf020 fix: 太阳能网控,设备休眠状态修改。 2026-04-27 16:48:21 +08:00
tianyongbao
c15cbc8c86 fix: 太阳能网控,离线报警问题修复。 2026-04-26 23:01:16 +08:00
tianyongbao
237a322b7b fix: 电话报警,回执超时问题修复。 2026-04-26 21:19:09 +08:00
tianyongbao
e98460af07 fix: 控制器定时控制删除时,实际未删除。 2026-04-26 11:18:59 +08:00
tianyongbao
d34e47dbf7 fix:太阳能网控,离线报警优化配置。 2026-04-26 07:24:50 +08:00
tianyongbao
51aae2b2b9 fix:太阳能网控,溶解氧下限未保存。 2026-04-26 06:26:44 +08:00
tianyongbao
03c8bfb276 fix:太阳能网控,后台代码修改完善。 2026-04-25 06:49:58 +08:00
tianyongbao
9217efc155 fix:子账号不充值后,回调后,更新设备有效期,问题修复。 2026-04-21 13:11:33 +08:00
tianyongbao
160b28e441 fix:子账号不存在,提示信息修改。 2026-04-20 12:56:04 +08:00
tianyongbao
7bb036c52c fix:设备电话通知和告警,以及设备历史数据,增加设备有效期判断。 2026-04-20 09:44:25 +08:00
tianyongbao
c7b74f6293 fix:给设备充值,去掉设备归属用户限制,允许给子账号充值。 2026-04-18 16:06:49 +08:00
tianyongbao
5cc04a2f0d fix:校准记录,去掉权限校验,登录用户都可以调用。 2026-04-15 16:33:21 +08:00
tianyongbao
34d9e2f8a5 fix:告警类型错误,问题修复。 2026-04-14 22:44:31 +08:00
tianyongbao
563449bd63 fix:三相输入缺相,缺相无告警,bug修复。 2026-04-14 22:31:02 +08:00
tianyongbao
33521b17c9 fix: 电话通知逻辑,功能修改,完善机制。 2026-04-14 22:02:13 +08:00
tianyongbao
6bb02480dd fix: 日志字符转义修复。 2026-04-12 20:49:44 +08:00
tianyongbao
82fe313b19 fix: 控制器不报警,问题解决。 2026-04-12 20:42:49 +08:00
tianyongbao
c604c84a08 fix: 用户普通登录,接口新增几个字段。 2026-04-12 12:07:54 +08:00
tianyongbao
ff07f77694 fix: 修改微信用户和验证码登录,改为永不因不活跃过期,token时间1年有效。 2026-04-11 21:50:33 +08:00
tianyongbao
41fc3ccc9d fix: 修改微信用户登录默认token时间,改为不活跃7天,超时30天。 2026-04-11 20:22:39 +08:00
tianyongbao
3755d01ea9 fix: 回执时间过长,问题修复。 2026-04-10 22:10:21 +08:00
tianyongbao
0011245a32 fix: 盐度取值错误,问题彻底解决。 2026-04-10 14:03:17 +08:00
tianyongbao
93fcd79f0b fix: 盐度取值错误,问题再次解决。 2026-04-10 12:24:53 +08:00
tianyongbao
16bd95ea30 fix: 盐度取值错误,问题解决。 2026-04-10 12:06:02 +08:00
tianyongbao
9a6c8b963d fix: 相位差不上数,修复。 2026-04-10 11:21:36 +08:00
tianyongbao
294b7c4e37 fix: 水温,饱和度等不上数,问题解决。 2026-04-10 10:58:00 +08:00
tianyongbao
70ac046e3e fix: 离线报警逻辑问题修复。 2026-04-09 09:17:41 +08:00
tianyongbao
3f27fc7541 fix:测试问题修复,ph值。 2026-04-09 00:03:15 +08:00
tianyongbao
2aec012fc2 fix: 塘口、设备按创建时间进行正序排列。 2026-04-05 13:28:47 +08:00
tianyongbao
98f91eb9de fix: 微信支付回调接口加入白名单。 2026-04-05 13:03:03 +08:00
tianyongbao
3d4ee0f33a fix: 用户登录逻辑判断修改。 2026-04-05 12:13:34 +08:00
tianyongbao
a425f1339d fix: 配置文件加上电话通知报警是否开启。 2026-04-05 00:09:06 +08:00
tianyongbao
6b2817393a fix: 新增电话告警统一配置,是否开启。 2026-04-05 00:05:33 +08:00
tianyongbao
8e7cccc537 fix: 微信支付,支付选项配置文件修改。 2026-04-04 08:29:36 +08:00
tianyongbao
8267b410a5 fix: 微信支付,改为http。 2026-04-04 01:01:39 +08:00
tianyongbao
bb2e0f1987 fix: 微信支付,创建失败,问题修复。 2026-04-04 00:44:12 +08:00
tianyongbao
0b006725bd fix: 子账号报警: ....您的xxx塘口, 设备设备 , xxx异常...。bug修复。 2026-04-04 00:29:03 +08:00
tianyongbao
3490aaa7a5 fix: 微信小程序登录,自测bug修复。 2026-04-04 00:07:33 +08:00
tianyongbao
b70e81266e fix: 微信小程序登录,传手机号,修改手机号接口修改完善。 2026-04-03 23:37:25 +08:00
tianyongbao
f252b94832 fix: 联动控制:溶氧低于阈值时,自动打开增氧机测试bug修复。 2026-04-03 22:51:40 +08:00
tianyongbao
7bf5813b35 fix: 同设备离线成功通知后抑制时间,改为2小时。 2026-04-03 16:00:27 +08:00
tianyongbao
75fa70184c fix: 编辑设备输入端接线方式接口bug修复。 2026-03-31 13:36:31 +08:00
tianyongbao
62b305855b fix: 电流上报值为0的时候,没有更新,bug修复。 2026-03-30 15:31:05 +08:00
tianyongbao
611f3d0542 fix: 新增太阳能网控添加接口,设置太阳能网控电量告警下限值。 2026-03-29 22:44:51 +08:00
tianyongbao
faa507f4bd fix: 新增太阳能网控添加接口。 2026-03-29 21:37:12 +08:00
tianyongbao
c6a5148ac6 fix: 控制开关,去掉三相电计算逻辑。 2026-03-29 19:26:43 +08:00
tianyongbao
cde35aee96 fix: 塘口控制器列表和溶解氧列表,自测问题修复。 2026-03-27 22:28:06 +08:00
tianyongbao
d3312db206 fix: 塘口控制器列表,只有开关关联,无溶解氧探头时,显示问题,bug修复。 2026-03-27 21:30:23 +08:00
tianyongbao
7eb07611a6 fix: 塘口设备列表,bug修复。 2026-03-27 20:50:19 +08:00
tianyongbao
035e9f78c0 fix: 定时任务逻辑修改,回查不管是否成功,都返回true。 2026-03-27 17:55:29 +08:00
tianyongbao
1aee70b492 fix: 删除定时控制不好用,逻辑修复。 2026-03-25 22:03:14 +08:00
tianyongbao
4944895622 fix: 获取开关电压和电流逻辑修改。 2026-03-23 23:49:57 +08:00
tianyongbao
0526aefb01 fix: 定时任务,新增回查逻辑。 2026-03-23 23:33:54 +08:00
tianyongbao
18a16dce35 fix: 控制器新增时候,开关原始状态修复。 2026-03-23 23:06:37 +08:00
tianyongbao
80b8e9da51 fix: 控制器新增时候,电压设置bug修复。 2026-03-23 22:52:52 +08:00
tianyongbao
ff3c3079ae fix: 修改设备故障码记录相关逻辑。 2026-03-22 22:21:38 +08:00
tianyongbao
5d9510f934 fix: 开关数据状态变化,bug修复。 2026-03-22 19:27:22 +08:00
tianyongbao
ada48d0d77 fix: 饱和度报警错别字修改。 2026-03-19 08:01:31 +08:00
tianyongbao
266087973f fix: 新增定时任务,饱和度。 2026-03-19 07:51:20 +08:00
tianyongbao
35901f667d fix: 饱和度浓度超过200,连续8小时,报警新增。 2026-03-18 23:17:37 +08:00
tianyongbao
975eb308a3 fix: 应该每次电话报警,就新增条消息,不能每次超过阈值就生成一条报警。 2026-03-18 22:36:13 +08:00
tianyongbao
cd1e8249ce fix: 告警通知,电话次数问题修复。 2026-03-10 08:34:12 +08:00
tianyongbao
fe85fb2b75 fix: 电话通知判断逻辑问题修复。 2026-03-10 00:02:37 +08:00
tianyongbao
c33ecd0ab4 fix: 电话通知报警,逻辑完善,改为报警电话列表获取电话号码,通知成功后24小时不再打电话等等。 2026-03-09 23:37:33 +08:00
tianyongbao
0f968d5e9f fix: 微信支付问题修复,代码提交。 2026-03-09 07:43:39 +08:00
tianyongbao
aa213e4d8d fix: 微信支付问题修复,bug。 2026-03-08 23:30:06 +08:00
tianyongbao
7e708c1286 fix: 设备在离线,类型修改。 2026-03-08 19:37:16 +08:00
tianyongbao
456d1af39a fix: 设备在离线,溶解氧和温度报警逻辑修改。 2026-03-08 19:28:30 +08:00
tianyongbao
85949ab4a0 fix: 测控一体机开关,VO备注新增。 2026-03-08 16:19:34 +08:00
tianyongbao
ab73d00299 fix: 逻辑修复完善。 2026-03-08 13:54:28 +08:00
tianyongbao
ec148bd203 fix: 电话报警通知逻辑修改。 2026-03-07 22:13:40 +08:00
tianyongbao
b5963e0948 fix: 数据接入,控制器需要判断开关数据和溶解氧数据。 2026-01-21 18:21:21 +08:00
tianyongbao
ceafe5646c fix: 绑定解绑数据时,没有添加操作记录,bug修复。 2026-01-21 16:10:30 +08:00
tianyongbao
adb291312d fix: 绑定解绑记录,新增接口。 2026-01-21 15:25:18 +08:00
tianyongbao
bb38f4d285 fix: 塘口绑定设备bug修复。 2026-01-21 13:12:39 +08:00
tianyongbao
a7bf9e6f6f fix: 短信验证码登录,逻辑修改。 2026-01-20 22:30:32 +08:00
tianyongbao
ae20a13add fix: 扫描设备二维码,bug修复。 2026-01-20 18:21:28 +08:00
tianyongbao
0a9e808b6f fix: 主子账号登录,数据隔离问题修复。 2026-01-20 16:10:01 +08:00
tianyongbao
22726ca92b fix: 微信登录,注册账户修改。 2026-01-20 11:12:53 +08:00
tianyongbao
7dce3a27d5 fix: 手机验证码和微信手机号登录,如果用户不存在,自动创建系统用户和鱼测云用户信息。 2026-01-20 09:31:41 +08:00
tianyongbao
770e615d80 fix: 自测问题修复。 2026-01-20 07:51:32 +08:00
tianyongbao
5a5ae53d09 fix: 微信支付,支付订单创建失败,修改。 2026-01-19 14:57:30 +08:00
tianyongbao
4e5c94b427 fix: 微信支付,接口测试问题修复。 2026-01-19 14:29:42 +08:00
tianyongbao
3fc42ac5b9 fix: 微信支付,接口bug修复。 2026-01-19 14:16:33 +08:00
tianyongbao
063579f8e3 fix: 微信登录,接口修改。 2026-01-18 20:23:15 +08:00
tianyongbao
d7702ee991 fix: 微信支付,登录接口。 2026-01-16 14:33:21 +08:00
tianyongbao
7efbad95aa fix: 微信小程序接口对接修改,联调测试问题修复。 2026-01-15 11:35:13 +08:00
tianyongbao
54bcaf3c2c fix: 微信小程序接口对接修改,联调测试问题修复。 2026-01-14 08:31:55 +08:00
tianyongbao
ecdaf5d4f8 fix: 微信小程序接口对接,测试问题修复。 2026-01-12 18:47:11 +08:00
tianyongbao
0387cc2f31 fix: 微信小程序接口对接修改。 2026-01-12 00:33:59 +08:00
tianyongbao
2f740b74cd fix: bug修复。 2026-01-10 01:43:49 +08:00
tianyongbao
5bd63f83df fix: 物联网平台,amqp数据接入并插入TD数据库相关逻辑编码。 2026-01-10 01:20:51 +08:00
tianyongbao
d1c829d410 fix: 微信登录验证码及配置修改。 2025-12-14 22:22:49 +08:00
tianyongbao
d9ae196daf fix: 微信登录验证码及配置修改。 2025-11-19 18:45:10 +08:00
tianyongbao
05fb822744 feat: 新功能开发,监测历史记录。微信和物联网平台,模块搭建。 2025-11-05 00:35:23 +08:00
tianyongbao
1d2e2e2513 feat: 新功能开发,设备告警信息、设备实时数据查看等。 2025-10-30 11:19:50 +08:00
tianyongbao
a9187da813 feat:功能优化,设备报警信息、微信缓存用户,操作记录信息,代码提交。 2025-10-24 20:44:36 +08:00
tianyongbao
d135c85ec0 feat:联动控制,定时控制,通知推送功能代码提交。 2025-10-23 14:24:02 +08:00
tianyongbao
f50ee440ef feat: 重构代码。 2025-10-21 10:00:26 +08:00
tianyongbao
7f40a94819 feat: 设备故障码、设备校验记录、测控一体机开关、设备充值记录、充值订单,代码提交。 2025-10-19 22:54:34 +08:00
tianyongbao
af1b0e5441 feat: 新需求功能代码提交,新增MPJLambdaWrapper查询。 2025-10-16 00:27:47 +08:00
tianyongbao
ab3508d6c4 feat: 新需求功能代码提交,新增MPJLambdaWrapper查询。 2025-10-16 00:27:38 +08:00
tianyongbao
f54859f62d feat: 新需求功能代码提交。 2025-10-15 14:14:22 +08:00
1124 changed files with 38908 additions and 5592 deletions

View File

@@ -5,11 +5,11 @@ FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
LABEL maintainer="Lion Li"
RUN mkdir -p /ruoyi/server/logs \
/ruoyi/server/temp \
/ruoyi/skywalking/agent
RUN mkdir -p /intc/server/logs \
/intc/server/temp \
/intc/skywalking/agent
WORKDIR /ruoyi/server
WORKDIR /intc/server
ENV SERVER_PORT=8080 SNAIL_PORT=28080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
@@ -17,7 +17,7 @@ EXPOSE ${SERVER_PORT}
# 暴露 snail job 客户端端口 用于定时任务调度中心通信
EXPOSE ${SNAIL_PORT}
ADD ./target/ruoyi-admin.jar ./app.jar
ADD ./target/intc-admin.jar ./app.jar
SHELL ["/bin/bash", "-c"]

View File

@@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi-vue-plus</artifactId>
<groupId>org.dromara</groupId>
<artifactId>intc-vue-ultra</artifactId>
<groupId>com.intc</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<artifactId>intc-admin</artifactId>
<description>
web服务入口
@@ -22,6 +22,11 @@
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.38</version>
</dependency>
<!-- &lt;!&ndash; mp支持的数据库均支持 只需要增加对应的jdbc依赖即可 &ndash;&gt;-->
<!-- &lt;!&ndash; Oracle &ndash;&gt;-->
@@ -46,56 +51,74 @@
<!-- </dependency>-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-doc</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-social</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-ratelimiter</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-ratelimiter</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mail</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-mail</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-system</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-system</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-job</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-job</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-generator</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-generator</artifactId>
</dependency>
<!-- demo模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-demo</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-demo</artifactId>
</dependency>
<!-- 鱼测云模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-fishery</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-fishery</artifactId>
<version>${revision}</version> <!-- 使用项目统一版本变量 -->
</dependency>
<!-- 时序数据 -->
<dependency>
<groupId>com.intc</groupId>
<artifactId>intc-tdengine</artifactId>
<version>${revision}</version> <!-- 使用项目统一版本变量 -->
</dependency>
<!-- 工作流模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-workflow</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-workflow</artifactId>
</dependency>
<!-- 物联网模块 -->
<dependency>
<groupId>com.intc</groupId>
<artifactId>intc-iot</artifactId>
<version>${revision}</version>
</dependency>
<!-- 微信对接模块 -->
<dependency>
<groupId>com.intc</groupId>
<artifactId>intc-weixin</artifactId>
<version>${revision}</version>
</dependency>
<dependency>

View File

@@ -1,8 +1,9 @@
package org.dromara;
package com.intc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 启动程序
@@ -11,13 +12,14 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt
*/
@SpringBootApplication
public class DromaraApplication {
@EnableScheduling
public class IntcUltraApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(DromaraApplication.class);
SpringApplication application = new SpringApplication(IntcUltraApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ RuoYi-Vue-Plus启动成功 ლ(´ڡ`ლ)゙");
System.out.println("(♥◠‿◠)ノ゙ Intc-Vue-Ultra启动成功 ლ(´ڡ`ლ)゙");
}
}

View File

@@ -1,4 +1,4 @@
package org.dromara;
package com.intc;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@@ -8,11 +8,11 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
*
* @author Lion Li
*/
public class DromaraServletInitializer extends SpringBootServletInitializer {
public class IntcUltraServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DromaraApplication.class);
return application.sources(IntcUltraApplication.class);
}
}

View File

@@ -1,4 +1,4 @@
package org.dromara.web.controller;
package com.intc.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.NotLoginException;
@@ -6,6 +6,41 @@ import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.R;
import com.intc.common.core.domain.model.LoginBody;
import com.intc.common.core.domain.model.RegisterBody;
import com.intc.common.core.domain.model.SocialLoginBody;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.utils.*;
import com.intc.common.encrypt.annotation.ApiEncrypt;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.ratelimiter.annotation.RateLimiter;
import com.intc.common.ratelimiter.enums.LimitType;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.social.config.properties.SocialLoginConfigProperties;
import com.intc.common.social.config.properties.SocialProperties;
import com.intc.common.social.utils.SocialUtils;
import com.intc.common.sse.dto.SseMessageDto;
import com.intc.common.sse.utils.SseMessageUtils;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.fishery.domain.AquUser;
import com.intc.system.domain.bo.SysTenantBo;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysTenantVo;
import com.intc.system.service.ISysClientService;
import com.intc.system.service.ISysConfigService;
import com.intc.system.service.ISysSocialService;
import com.intc.system.service.ISysTenantService;
import com.intc.web.domain.vo.LoginTenantVo;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.domain.vo.TenantListVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import com.intc.web.service.SysRegisterService;
import com.intc.weixin.domain.bo.ReqWxLogin;
import com.intc.weixin.service.WxLoginService;
import com.intc.weixin.config.WxMaProperties;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -13,36 +48,7 @@ import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.RegisterBody;
import org.dromara.common.core.domain.model.SocialLoginBody;
import org.dromara.common.core.utils.*;
import org.dromara.common.encrypt.annotation.ApiEncrypt;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.ratelimiter.annotation.RateLimiter;
import org.dromara.common.ratelimiter.enums.LimitType;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.service.ISysClientService;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysTenantService;
import org.dromara.web.domain.vo.LoginTenantVo;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.domain.vo.TenantListVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.dromara.web.service.SysRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -75,6 +81,12 @@ public class AuthController {
private final ISysClientService clientService;
private final ScheduledExecutorService scheduledExecutorService;
@Autowired(required = false)
private WxLoginService wxLoginService;
@Autowired(required = false)
private WxMaProperties wxMaProperties;
/**
* 登录方法
@@ -106,7 +118,7 @@ public class AuthController {
Long userId = LoginHelper.getUserId();
scheduledExecutorService.schedule(() -> {
SseMessageDto dto = new SseMessageDto();
dto.setMessage("欢迎登录RuoYi-Vue-Plus后台管理系统");
dto.setMessage("欢迎登录水产养殖监测平台");
dto.setUserIds(List.of(userId));
SseMessageUtils.publishMessage(dto);
}, 5, TimeUnit.SECONDS);
@@ -239,4 +251,73 @@ public class AuthController {
return R.ok(result);
}
/**
* 微信小程序登录
*
* @param body 微信登录请求JSON字符串
* @return 结果
*/
@ApiEncrypt
@PostMapping("/wechat_login")
public R<LoginVo> wechatLogin(@RequestBody String body) {
try {
ReqWxLogin request = JsonUtils.parseObject(body, ReqWxLogin.class);
ValidatorUtils.validate(request);
// 如果未传递 clientId使用默认配置的 clientId
if (StringUtils.isBlank(request.getClientId()) && wxMaProperties != null) {
request.setClientId(wxMaProperties.getDefaultClientId());
// 更新 body 中的 clientId
body = JsonUtils.toJsonString(request);
}
String clientId = request.getClientId();
String grantType = "wechat"; // 微信登录的授权类型
log.info("收到微信登录请求: clientId={}, tenantId={}", clientId, request.getTenantId());
// 1. 检查服务是否可用
if (wxLoginService == null) {
log.error("微信登录服务未启用,请检查配置: wx.miniapp.app-id");
return R.fail("微信登录服务未启用,请联系管理员");
}
// 2. 校验客户端
SysClientVo client = clientService.queryByClientId(clientId);
if (ObjectUtil.isNull(client)) {
log.error("客户端不存在: clientId={}", clientId);
return R.fail(MessageUtils.message("auth.grant.type.error"));
}
// 校验 client 内是否包含 grantType
if (!StringUtils.contains(client.getGrantType(), grantType)) {
log.error("客户端不支持该授权类型: clientId={}, grantType={}", clientId, grantType);
return R.fail(MessageUtils.message("auth.grant.type.error"));
}
if (!SystemConstants.NORMAL.equals(client.getStatus())) {
log.error("客户端已被禁用: clientId={}, status={}", clientId, client.getStatus());
return R.fail(MessageUtils.message("auth.grant.type.blocked"));
}
// 3. 校验租户
if (StringUtils.isNotBlank(request.getTenantId())) {
loginService.checkTenant(request.getTenantId());
}
// 4. 使用标准的 IAuthStrategy 登录方法
LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
log.info("微信登录成功: userId={}, accessToken={}",
loginVo.getUserId(), loginVo.getAccessToken() != null ? "***" : "null");
return R.ok(loginVo);
} catch (ServiceException e) {
log.error("微信登录业务异常: {}", e.getMessage(), e);
return R.fail(e.getMessage());
} catch (Exception e) {
log.error("微信登录系统异常", e);
return R.fail("登录失败: " + e.getMessage());
}
}
}

View File

@@ -1,36 +1,40 @@
package org.dromara.web.controller;
package com.intc.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.GlobalConstants;
import com.intc.common.core.domain.R;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.utils.SpringUtils;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.core.utils.reflect.ReflectUtils;
import com.intc.common.mail.config.properties.MailProperties;
import com.intc.common.mail.utils.MailUtils;
import com.intc.common.ratelimiter.annotation.RateLimiter;
import com.intc.common.ratelimiter.enums.LimitType;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.sms.config.properties.SmsProperties;
import com.intc.common.web.config.properties.CaptchaProperties;
import com.intc.common.web.enums.CaptchaType;
import com.intc.web.domain.vo.CaptchaVo;
import com.intc.fishery.domain.bo.ReqVerifySmsCode;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.mail.config.properties.MailProperties;
import org.dromara.common.mail.utils.MailUtils;
import org.dromara.common.ratelimiter.annotation.RateLimiter;
import org.dromara.common.ratelimiter.enums.LimitType;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.common.web.enums.CaptchaType;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.dromara.web.domain.vo.CaptchaVo;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
@@ -50,6 +54,7 @@ public class CaptchaController {
private final CaptchaProperties captchaProperties;
private final MailProperties mailProperties;
private final SmsProperties smsProperties;
/**
* 短信验证码
@@ -60,21 +65,74 @@ public class CaptchaController {
@GetMapping("/resource/sms/code")
public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
String code = RandomUtil.randomNumbers(4);
String code = RandomUtil.randomNumbers(6);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
// 验证码模板id 自行处理 (查数据库或写死均可)
String templateId = "";
// 验证码模板id 从配置文件读取
String templateId = smsProperties.getCodeTemplateId();
if (StringUtils.isBlank(templateId)) {
log.error("短信验证码模板ID未配置请在配置文件中设置 sms.plus.code-template-id");
return R.fail("短信服务配置错误,请联系管理员");
}
LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
map.put("code", code);
SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
if (!smsResponse.isSuccess()) {
log.error("验证码短信发送异常 => {}", smsResponse);
return R.fail(smsResponse.getData().toString());
// 解析错误信息
String errorMsg = "短信发送失败";
if (smsResponse.getData() != null) {
String data = smsResponse.getData().toString();
if (data.contains("SMS_TEMPLATE_ILLEGAL")) {
errorMsg = "短信模板不存在请联系管理员配置正确的模板ID";
} else if (data.contains("SMS_SIGNATURE_ILLEGAL")) {
errorMsg = "短信签名不存在,请联系管理员配置正确的签名";
} else if (data.contains("Message")) {
// 尝试提取Message字段
try {
int msgStart = data.indexOf("Message\":\"") + 10;
int msgEnd = data.indexOf("\"", msgStart);
if (msgStart > 10 && msgEnd > msgStart) {
String message = data.substring(msgStart, msgEnd);
errorMsg = "短信发送失败:" + message;
}
} catch (Exception e) {
log.warn("解析短信错误信息失败", e);
}
} else if (data.contains("isv.")) {
errorMsg = "短信服务配置错误,请联系管理员";
}
}
return R.fail(errorMsg);
}
return R.ok();
}
/**
* 验证短信验证码
*
* @param request 手机号和验证码数据
* @return 验证结果
*/
@PostMapping("/resource/sms/verify")
public R<Void> verifySmsCode(@Validated @RequestBody ReqVerifySmsCode request) {
String key = GlobalConstants.CAPTCHA_CODE_KEY + request.getMobilePhone();
String cachedCode = RedisUtils.getCacheObject(key);
if (StringUtils.isBlank(cachedCode)) {
return R.fail("短信验证码已过期");
}
if (!cachedCode.equals(request.getSmsCode())) {
return R.fail("短信验证码错误");
}
// 验证成功后删除验证码根据 C# 代码中的 true 参数
RedisUtils.deleteObject(key);
return R.ok();
}
/**
* 邮箱验证码
*

View File

@@ -1,9 +1,9 @@
package org.dromara.web.controller;
package com.intc.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.intc.common.core.utils.SpringUtils;
import com.intc.common.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -1,4 +1,4 @@
package org.dromara.web.domain.vo;
package com.intc.web.domain.vo;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.web.domain.vo;
package com.intc.web.domain.vo;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.web.domain.vo;
package com.intc.web.domain.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@@ -51,4 +51,25 @@ public class LoginVo {
*/
private String openid;
/**
* 用户ID
*/
private Long userId;
/**
* 用户名
*/
private String userName;
/**
* 昵称
*/
private String nickName;
/**
* 手机号
*/
private String phonenumber;
}

View File

@@ -1,6 +1,6 @@
package org.dromara.web.domain.vo;
package com.intc.web.domain.vo;
import org.dromara.system.domain.vo.SysTenantVo;
import com.intc.system.domain.vo.SysTenantVo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.web.listener;
package com.intc.web.listener;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.StpUtil;
@@ -6,20 +6,20 @@ import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.intc.common.core.constant.CacheConstants;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.domain.dto.UserOnlineDTO;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.ServletUtils;
import com.intc.common.core.utils.SpringUtils;
import com.intc.common.core.utils.ip.AddressUtils;
import com.intc.common.log.event.LogininforEvent;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.domain.dto.UserOnlineDTO;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.ip.AddressUtils;
import org.dromara.common.log.event.LogininforEvent;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Component;
import java.time.Duration;

View File

@@ -1,11 +1,10 @@
package org.dromara.web.service;
package com.intc.web.service;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.web.domain.vo.LoginVo;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.utils.SpringUtils;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.web.domain.vo.LoginVo;
/**
* 授权策略

View File

@@ -1,4 +1,4 @@
package org.dromara.web.service;
package com.intc.web.service;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
@@ -7,31 +7,31 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.intc.common.core.constant.CacheConstants;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.constant.TenantConstants;
import com.intc.common.core.domain.dto.PostDTO;
import com.intc.common.core.domain.dto.RoleDTO;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.enums.LoginType;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.*;
import com.intc.common.log.event.LogininforEvent;
import com.intc.common.mybatis.helper.DataPermissionHelper;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.exception.TenantException;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.bo.SysSocialBo;
import com.intc.system.domain.vo.*;
import com.intc.system.mapper.SysUserMapper;
import com.intc.system.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.dto.PostDTO;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.*;
import org.dromara.common.log.event.LogininforEvent;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.exception.TenantException;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

View File

@@ -1,27 +1,27 @@
package org.dromara.web.service;
package com.intc.web.service;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.GlobalConstants;
import com.intc.common.core.domain.model.RegisterBody;
import com.intc.common.core.enums.UserType;
import com.intc.common.core.exception.user.CaptchaException;
import com.intc.common.core.exception.user.CaptchaExpireException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.ServletUtils;
import com.intc.common.core.utils.SpringUtils;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.log.event.LogininforEvent;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.common.web.config.properties.CaptchaProperties;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.bo.SysUserBo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.RegisterBody;
import org.dromara.common.core.enums.UserType;
import org.dromara.common.core.exception.user.CaptchaException;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.log.event.LogininforEvent;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysUserService;
import org.springframework.stereotype.Service;
/**

View File

@@ -1,33 +1,33 @@
package org.dromara.web.service.impl;
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.GlobalConstants;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.EmailLoginBody;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.enums.LoginType;
import com.intc.common.core.exception.user.CaptchaExpireException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.model.EmailLoginBody;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
@@ -50,8 +50,11 @@ public class EmailAuthStrategy implements IAuthStrategy {
String tenantId = loginBody.getTenantId();
String email = loginBody.getEmail();
String emailCode = loginBody.getEmailCode();
// 用于保存用户信息
SysUserVo[] userHolder = new SysUserVo[1];
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
SysUserVo user = loadUserByEmail(email);
userHolder[0] = user;
loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
return loginService.buildLoginUser(user);
@@ -72,6 +75,10 @@ public class EmailAuthStrategy implements IAuthStrategy {
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
loginVo.setUserId(loginUser.getUserId());
loginVo.setUserName(loginUser.getUsername());
loginVo.setNickName(loginUser.getNickname());
loginVo.setPhonenumber(userHolder[0].getPhonenumber());
return loginVo;
}

View File

@@ -1,36 +1,36 @@
package org.dromara.web.service.impl;
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.GlobalConstants;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.domain.model.PasswordLoginBody;
import com.intc.common.core.enums.LoginType;
import com.intc.common.core.exception.user.CaptchaException;
import com.intc.common.core.exception.user.CaptchaExpireException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.common.web.config.properties.CaptchaProperties;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.PasswordLoginBody;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.exception.user.CaptchaException;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
@@ -62,8 +62,11 @@ public class PasswordAuthStrategy implements IAuthStrategy {
if (captchaEnabled) {
validateCaptcha(tenantId, username, code, uuid);
}
// 用于保存用户信息包括手机号
SysUserVo[] userHolder = new SysUserVo[1];
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
SysUserVo user = loadUserByUsername(username);
userHolder[0] = user; // 保存用户信息
loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
// 此处可根据登录用户的数据不同 自行创建 loginUser
return loginService.buildLoginUser(user);
@@ -84,6 +87,10 @@ public class PasswordAuthStrategy implements IAuthStrategy {
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
loginVo.setUserId(loginUser.getUserId());
loginVo.setUserName(loginUser.getUsername());
loginVo.setNickName(loginUser.getNickname());
loginVo.setPhonenumber(userHolder[0].getPhonenumber());
return loginVo;
}

View File

@@ -0,0 +1,322 @@
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.intc.common.core.constant.Constants;
import com.intc.common.core.constant.GlobalConstants;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.domain.model.SmsLoginBody;
import com.intc.common.core.enums.LoginType;
import com.intc.common.core.exception.user.CaptchaExpireException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.redis.utils.RedisUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.fishery.domain.AquUser;
import com.intc.fishery.domain.bo.AquUserBo;
import com.intc.fishery.mapper.AquUserMapper;
import com.intc.fishery.service.IAquUserService;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.bo.SysUserBo;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.system.service.ISysUserService;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 短信认证策略
*
* @author Michelle.Chung
*/
@Slf4j
@Service("sms" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class SmsAuthStrategy implements IAuthStrategy {
private final SysLoginService loginService;
private final SysUserMapper userMapper;
private final ISysUserService userService;
private final AquUserMapper aquUserMapper;
private final IAquUserService aquUserService;
@Override
public LoginVo login(String body, SysClientVo client) {
SmsLoginBody loginBody = JsonUtils.parseObject(body, SmsLoginBody.class);
ValidatorUtils.validate(loginBody);
String tenantId = loginBody.getTenantId();
String phonenumber = loginBody.getPhonenumber();
String smsCode = loginBody.getSmsCode();
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
SysUserVo user = loadUserByPhonenumber(phonenumber);
loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
return loginService.buildLoginUser(user);
});
loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType());
// 短信登录用户token 有效期1年允许多设备同时在线与微信小程序一致
// - timeout: 1年 = 31536000秒
// - activeTimeout: -1 表示永不因不活跃而过期
// - isConcurrent: true 允许多设备同时在线
SaLoginParameter model = new SaLoginParameter();
model.setDeviceType(client.getDeviceType());
model.setTimeout(31536000L); // 1年 = 365天 * 24小时 * 60分钟 * 60秒
model.setActiveTimeout(-1); // 永不因不活跃过期
model.setIsConcurrent(true); // 允许多设备同时在线
model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
// 生成token
LoginHelper.login(loginUser, model);
LoginVo loginVo = new LoginVo();
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
loginVo.setUserId(loginUser.getUserId());
loginVo.setNickName(loginUser.getNickname());
loginVo.setUserName(loginUser.getUsername());
loginVo.setPhonenumber(phonenumber);
return loginVo;
}
/**
* 校验短信验证码
*/
private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
if (StringUtils.isBlank(code)) {
loginService.recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
}
return code.equals(smsCode);
}
/**
* 根据手机号加载系统用户,如果不存在则自动创建
* 逻辑先查AquUser再查系统用户
* 1. 如果AquUser不存在先创建AquUser再创建系统用户
* 2. 如果AquUser存在但系统用户不存在根据AquUser数据创建系统用户
* 3. 如果都存在,直接返回系统用户
*
* @param phonenumber 手机号
* @return 系统用户信息
*/
private SysUserVo loadUserByPhonenumber(String phonenumber) {
// 1. 先查询AquUser
AquUser aquUser = aquUserMapper.selectOne(
new LambdaQueryWrapper<AquUser>()
.eq(AquUser::getMobilePhone, phonenumber)
);
// 2. 查询系统用户
SysUserVo sysUser = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, phonenumber)
);
// 3. 根据不同情况处理
if (ObjectUtil.isNull(aquUser)) {
// 情况1AquUser不存在先创建AquUser再创建系统用户
log.info("AquUser不存在先创建AquUser再创建系统用户: phone={}", phonenumber);
aquUser = createAquUserFirst(phonenumber);
sysUser = createSysUserFromPhone(phonenumber, aquUser);
} else if (ObjectUtil.isNull(sysUser)) {
// 情况2AquUser存在但系统用户不存在根据AquUser创建系统用户
log.info("AquUser存在但系统用户不存在根据AquUser创建系统用户: phone={}, aquUserId={}",
phonenumber, aquUser.getId());
sysUser = createSysUserFromAquUser(aquUser);
}
// 检查用户状态
if (SystemConstants.DISABLE.equals(sysUser.getStatus())) {
log.info("登录用户:{} 已被停用.", phonenumber);
throw new UserException("user.blocked", phonenumber);
}
return sysUser;
}
/**
* 先创建AquUser当AquUser不存在时
*
* @param phone 手机号
* @return 新创建的AquUser
*/
private AquUser createAquUserFirst(String phone) {
try {
// 构建报警电话列表
List<String> warnPhoneList = new ArrayList<>();
warnPhoneList.add(phone);
String warnPhoneJson = JsonUtils.toJsonString(warnPhoneList);
// 创建鱼测云用户对象
AquUserBo aquUserBo = new AquUserBo();
aquUserBo.setUserName("用户" + phone.substring(phone.length() - 4));
aquUserBo.setMobilePhone(phone);
aquUserBo.setWarnPhoneJson(warnPhoneJson);
aquUserBo.setIsManager(0L);
aquUserBo.setHasScreen(0L);
aquUserBo.setRemark("短信登录自动创建");
// 调用服务创建鱼测云用户
boolean success = aquUserService.insertByBo(aquUserBo);
if (!success) {
log.error("创建AquUser失败: phone={}", phone);
throw new UserException("user.register.error");
}
// 查询刚创建的AquUser
AquUser createdAquUser = aquUserMapper.selectOne(
new LambdaQueryWrapper<AquUser>()
.eq(AquUser::getMobilePhone, phone)
);
if (ObjectUtil.isNull(createdAquUser)) {
log.error("创建AquUser后查询失败: phone={}", phone);
throw new UserException("user.register.error");
}
log.info("成功创建AquUser: phone={}, aquUserId={}, userName={}",
phone, createdAquUser.getId(), createdAquUser.getUserName());
return createdAquUser;
} catch (Exception e) {
log.error("创建AquUser异常: phone={}, error={}", phone, e.getMessage(), e);
throw new UserException("user.register.error");
}
}
/**
* 根据手机号创建系统用户当AquUser已创建但系统用户不存在时
*
* @param phone 手机号
* @param aquUser AquUser信息
* @return 新创建的系统用户
*/
private SysUserVo createSysUserFromPhone(String phone, AquUser aquUser) {
try {
// 构建新用户对象
SysUserBo newUser = new SysUserBo();
// 使用AquUser的ID作为系统用户ID保持一致
newUser.setUserId(aquUser.getId());
newUser.setUserName(phone);
newUser.setNickName(StringUtils.isNotBlank(aquUser.getUserName()) ?
aquUser.getUserName() : "用户" + phone.substring(phone.length() - 4));
newUser.setPhonenumber(phone);
newUser.setUserType("sys_user");
newUser.setDeptId(SystemConstants.DEFAULT_DEPT_ID);
newUser.setStatus(SystemConstants.NORMAL);
newUser.setSex("2");
newUser.setPassword(BCrypt.hashpw("yuceyun@123"));
newUser.setCreateBy(0L);
newUser.setUpdateBy(0L);
// 调用用户服务创建用户
boolean success = userService.registerUser(newUser, LoginHelper.getTenantId());
if (!success) {
log.error("创建系统用户失败: phone={}, aquUserId={}", phone, aquUser.getId());
throw new UserException("user.register.error");
}
// 查询刚创建的用户信息
SysUserVo createdUser = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, phone)
);
if (ObjectUtil.isNull(createdUser)) {
log.error("创建系统用户后查询失败: phone={}, aquUserId={}", phone, aquUser.getId());
throw new UserException("user.register.error");
}
log.info("成功创建系统用户(ID与AquUser一致): phone={}, userId={}, aquUserId={}, userName={}",
phone, createdUser.getUserId(), aquUser.getId(), createdUser.getUserName());
return createdUser;
} catch (Exception e) {
log.error("创建系统用户异常: phone={}, aquUserId={}, error={}", phone, aquUser.getId(), e.getMessage(), e);
throw new UserException("user.register.error");
}
}
/**
* 根据AquUser信息创建系统用户
*
* @param aquUser AquUser信息
* @return 新创建的系统用户
*/
private SysUserVo createSysUserFromAquUser(AquUser aquUser) {
try {
String phone = aquUser.getMobilePhone();
// 构建新用户对象
SysUserBo newUser = new SysUserBo();
// 使用AquUser的ID作为系统用户ID保持一致
newUser.setUserId(aquUser.getId());
newUser.setUserName(phone);
// 使用AquUser的用户名作为昵称
newUser.setNickName(StringUtils.isNotBlank(aquUser.getUserName()) ?
aquUser.getUserName() : "用户" + phone.substring(phone.length() - 4));
newUser.setPhonenumber(phone);
newUser.setUserType("sys_user");
newUser.setDeptId(SystemConstants.DEFAULT_DEPT_ID);
newUser.setStatus(SystemConstants.NORMAL);
newUser.setSex("2");
newUser.setPassword(BCrypt.hashpw("yuceyun@123"));
newUser.setCreateBy(0L);
newUser.setUpdateBy(0L);
// 调用用户服务创建用户
boolean success = userService.registerUser(newUser, LoginHelper.getTenantId());
if (!success) {
log.error("根据AquUser创建系统用户失败: phone={}, aquUserId={}", phone, aquUser.getId());
throw new UserException("user.register.error");
}
// 查询刚创建的用户信息
SysUserVo createdUser = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, phone)
);
if (ObjectUtil.isNull(createdUser)) {
log.error("根据AquUser创建系统用户后查询失败: phone={}, aquUserId={}", phone, aquUser.getId());
throw new UserException("user.register.error");
}
log.info("根据AquUser成功创建系统用户(ID一致): phone={}, userId={}, aquUserId={}, userName={}",
phone, createdUser.getUserId(), aquUser.getId(), createdUser.getUserName());
return createdUser;
} catch (Exception e) {
log.error("根据AquUser创建系统用户异常: aquUserId={}, error={}", aquUser.getId(), e.getMessage(), e);
throw new UserException("user.register.error");
}
}
}

View File

@@ -1,33 +1,33 @@
package org.dromara.web.service.impl;
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.domain.model.SocialLoginBody;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.StreamUtils;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.social.config.properties.SocialProperties;
import com.intc.common.social.utils.SocialUtils;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysSocialVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.system.service.ISysSocialService;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.SocialLoginBody;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysSocialService;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -80,8 +80,11 @@ public class SocialAuthStrategy implements IAuthStrategy {
} else {
social = list.get(0);
}
// 用于保存用户信息
SysUserVo[] userHolder = new SysUserVo[1];
LoginUser loginUser = TenantHelper.dynamic(social.getTenantId(), () -> {
SysUserVo user = loadUser(social.getUserId());
userHolder[0] = user;
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
return loginService.buildLoginUser(user);
});
@@ -101,6 +104,10 @@ public class SocialAuthStrategy implements IAuthStrategy {
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
loginVo.setUserId(loginUser.getUserId());
loginVo.setUserName(loginUser.getUsername());
loginVo.setNickName(loginUser.getNickname());
loginVo.setPhonenumber(userHolder[0].getPhonenumber());
return loginVo;
}

View File

@@ -0,0 +1,266 @@
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.LoginUser;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.exception.user.UserException;
import com.intc.common.core.utils.StringUtils;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.core.utils.MapstructUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.common.tenant.helper.TenantHelper;
import com.intc.fishery.domain.AquUser;
import com.intc.system.domain.SysUser;
import com.intc.system.domain.bo.SysUserBo;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.system.mapper.SysUserMapper;
import com.intc.system.service.ISysUserService;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import com.intc.weixin.domain.bo.ReqWxLogin;
import com.intc.weixin.service.WxLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 微信小程序认证策略
*
* @author intc
*/
@Slf4j
@Service("wechat" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class WechatAuthStrategy implements IAuthStrategy {
private final WxLoginService wxLoginService;
private final SysLoginService loginService;
private final SysUserMapper userMapper;
private final ISysUserService userService;
@Override
public LoginVo login(String body, SysClientVo client) {
ReqWxLogin loginBody = JsonUtils.parseObject(body, ReqWxLogin.class);
ValidatorUtils.validate(loginBody);
String tenantId = loginBody.getTenantId();
String code = loginBody.getCode();
String jsCode = loginBody.getJsCode();
// 在租户上下文中执行登录
AquUser[] aquUserHolder = new AquUser[1]; // 用于保存 AquUser
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
// 1. 调用微信登录服务获取或创建渔业用户用于获取手机号和openId
AquUser aquUser = wxLoginService.loginByWeChat(code, jsCode, tenantId);
if (aquUser == null) {
log.error("微信登录失败,未返回用户信息");
throw new ServiceException("登录失败,请重试");
}
aquUserHolder[0] = aquUser; // 保存以便后续使用
log.info("获取微信用户信息成功: aquUserId={}, mobilePhone={}",
aquUser.getId(), aquUser.getMobilePhone());
// 2. 根据手机号查询系统用户
String mobilePhone = aquUser.getMobilePhone();
if (StringUtils.isBlank(mobilePhone)) {
log.error("微信用户手机号为空: aquUserId={}", aquUser.getId());
throw new ServiceException("获取手机号失败,请重新授权");
}
// 3. 根据手机号加载或创建系统用户传入aquUser以保持ID一致
SysUserVo sysUser = loadUserByPhone(mobilePhone, aquUser);
log.info("找到对应的系统用户: sysUserId={}, userName={}",
sysUser.getUserId(), sysUser.getUserName());
// 4. 使用系统用户构建 LoginUser包含完整的权限信息
return loginService.buildLoginUser(sysUser);
});
// 3. 设置客户端信息
loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType());
// 4. 配置登录参数
// 微信小程序用户token 有效期1年允许多设备同时在线
// - timeout: 1年 = 31536000秒
// - activeTimeout: -1 表示永不因不活跃而过期用户1年内随时可用
// - isConcurrent: true 允许多设备同时在线
SaLoginParameter model = new SaLoginParameter();
model.setDeviceType(client.getDeviceType());
// 微信小程序token有效期1年永不因不活跃过期
model.setTimeout(31536000L); // 1年 = 365天 * 24小时 * 60分钟 * 60秒
model.setActiveTimeout(-1); // 永不因不活跃过期
// isConcurrent: 是否允许同一账号多地同时登录
// true = 允许多设备同时在线(手机+平板)
// false = 同一设备类型只能一个在线,新登录踢掉旧的(换手机场景)
model.setIsConcurrent(true); // 允许多设备同时在线
model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
log.info("微信登录token配置: clientId={}, timeout=1年, activeTimeout=永不过期, isConcurrent={}",
client.getClientId(), true);
// 5. 执行登录,生成 token
LoginHelper.login(loginUser, model);
// 6. 构建返回对象
LoginVo loginVo = new LoginVo();
loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(client.getClientId());
loginVo.setOpenid(aquUserHolder[0].getWxOpenId()); // 从 AquUser 中获取 openId
loginVo.setUserId(loginUser.getUserId());
loginVo.setUserName(loginUser.getUsername());
loginVo.setNickName(loginUser.getNickname());
loginVo.setPhonenumber(aquUserHolder[0].getMobilePhone()); // 返回用户手机号
return loginVo;
}
/**
* 根据手机号加载系统用户,如果不存在则自动创建
*
* @param phone 手机号
* @param aquUser 已存在的鱼测云用户用于保持ID一致
* @return 系统用户信息
*/
private SysUserVo loadUserByPhone(String phone, AquUser aquUser) {
// 1. 优先按 AquUser ID 查询 SysUser保证 ID 一致性
SysUserVo user = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUserId, aquUser.getId())
);
if (user != null) {
log.info("通过AquUser ID找到系统用户: aquUserId={}, sysUserId={}, phone={}",
aquUser.getId(), user.getUserId(), phone);
// 检查手机号是否一致
if (!phone.equals(user.getPhonenumber())) {
log.warn("系统用户手机号与AquUser不一致更新手机号: sysUserId={}, oldPhone={}, newPhone={}",
user.getUserId(), user.getPhonenumber(), phone);
// 更新手机号
SysUser updateUser = new SysUser();
updateUser.setUserId(user.getUserId());
updateUser.setPhonenumber(phone);
updateUser.setUserName(phone); // 用户名也更新为手机号
userMapper.updateById(updateUser);
// 重新查询获取更新后的数据
user = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getUserId, aquUser.getId())
);
}
} else {
// 2. 按手机号查询 SysUser
user = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, phone)
);
if (user != null) {
// 手机号匹配但 ID 不一致,说明是历史数据,需要更新 ID 以保持一致
log.info("通过手机号找到系统用户但ID不一致: sysUserId={}, aquUserId={}, phone={}",
user.getUserId(), aquUser.getId(), phone);
log.warn("将更新系统用户ID以与AquUser保持一致: oldSysUserId={}, newSysUserId={}",
user.getUserId(), aquUser.getId());
// 更新 SysUser 的 ID 以与 AquUser 一致
// 注意:需要先删除旧记录,再插入新记录(因为 ID 是主键)
Long oldUserId = user.getUserId();
userMapper.deleteById(oldUserId);
// 创建新的 SysUser 记录,使用 AquUser 的 ID
user = createNewUser(phone, aquUser);
log.info("已将系统用户ID从 {} 更新为 {}与AquUser保持一致", oldUserId, aquUser.getId());
} else {
// 3. 用户不存在,创建新用户
log.info("系统中不存在该手机号的用户,自动创建新用户: phone={}, aquUserId={}", phone, aquUser.getId());
user = createNewUser(phone, aquUser);
}
}
// 检查用户状态
if (SystemConstants.DISABLE.equals(user.getStatus())) {
log.error("用户已被停用: phone={}, userId={}", phone, user.getUserId());
throw new UserException("user.blocked", phone);
}
return user;
}
/**
* 创建新的系统用户
*
* @param phone 手机号
* @param aquUser 已存在的鱼测云用户用于保持ID一致
* @return 新创建的用户信息
*/
private SysUserVo createNewUser(String phone, AquUser aquUser) {
try {
// 构建新用户对象
SysUserBo newUser = new SysUserBo();
// 使用AquUser的ID作为系统用户ID保持一致
newUser.setUserId(aquUser.getId());
// 使用手机号作为用户名
newUser.setUserName(phone);
// 使用手机号作为昵称
newUser.setNickName("用户" + phone.substring(phone.length() - 4));
// 设置手机号
newUser.setPhonenumber(phone);
// 设置用户类型为系统用户
newUser.setUserType("sys_user");
// 设置默认部门ID
newUser.setDeptId(SystemConstants.DEFAULT_DEPT_ID);
// 设置状态为正常
newUser.setStatus(SystemConstants.NORMAL);
// 设置性别为未知
newUser.setSex("2");
// 设置默认密码
newUser.setPassword(BCrypt.hashpw("yuceyun@123"));
// 设置创建人和更新人为系统
newUser.setCreateBy(0L);
newUser.setUpdateBy(0L);
// 直接插入用户不使用registerUser因为ID已经指定
SysUser sysUser = MapstructUtils.convert(newUser, SysUser.class);
sysUser.setTenantId(LoginHelper.getTenantId());
int rows = userMapper.insert(sysUser);
if (rows <= 0) {
log.error("创建新用户失败: phone={}, aquUserId={}", phone, aquUser.getId());
throw new ServiceException("创建用户失败,请联系管理员");
}
// 查询刚创建的用户信息
SysUserVo createdUser = userMapper.selectVoOne(
new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getPhonenumber, phone)
);
if (ObjectUtil.isNull(createdUser)) {
log.error("创建用户后查询失败: phone={}", phone);
throw new ServiceException("创建用户失败,请联系管理员");
}
log.info("成功创建系统用户: phone={}, userId={}, userName={}, 与AquUser ID保持一致",
phone, createdUser.getUserId(), createdUser.getUserName());
return createdUser;
} catch (Exception e) {
log.error("创建新用户异常: phone={}, error={}", phone, e.getMessage(), e);
throw new ServiceException("创建用户失败: " + e.getMessage());
}
}
}

View File

@@ -1,8 +1,20 @@
package org.dromara.web.service.impl;
package com.intc.web.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.ObjectUtil;
import com.intc.common.core.constant.SystemConstants;
import com.intc.common.core.domain.model.XcxLoginBody;
import com.intc.common.core.domain.model.XcxLoginUser;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.utils.ValidatorUtils;
import com.intc.common.json.utils.JsonUtils;
import com.intc.common.satoken.utils.LoginHelper;
import com.intc.system.domain.vo.SysClientVo;
import com.intc.system.domain.vo.SysUserVo;
import com.intc.web.domain.vo.LoginVo;
import com.intc.web.service.IAuthStrategy;
import com.intc.web.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig;
@@ -12,18 +24,6 @@ import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWechatMiniProgramRequest;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.model.XcxLoginBody;
import org.dromara.common.core.domain.model.XcxLoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**

View File

@@ -13,7 +13,7 @@ spring.boot.admin.client:
--- # snail-job 配置
snail-job:
enabled: true
enabled: false
# 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务
group: "ruoyi_group"
# SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config` 表
@@ -35,7 +35,7 @@ spring:
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
dynamic:
# 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: true
p6spy: false
# 设置默认的数据源或者数据源组,默认值即为 master
primary: master
# 严格模式 匹配不到数据源则报错
@@ -51,17 +51,23 @@ spring:
# username: root
# password: root
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://117.72.197.29:15432/ruoyi-plus?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
url: jdbc:postgresql://81.70.89.108:15432/fishery_dev?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
username: postgres
password: intc@123987
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username:
# password:
# 从库数据源 - TDengine
taos:
lazy: false
type: ${spring.datasource.type}
driverClassName: com.taosdata.jdbc.rs.RestfulDriver
# 不指定数据库名,在 SQL 中使用完整路径 fishery.table_name
url: jdbc:TAOS-RS://81.70.89.108:6041?timezone=Shanghai&charset=UTF-8&locale=en_US.UTF-8
username: root
password: intc@123456
hikari:
connection-timeout: 60000
validation-timeout: 10000
max-pool-size: 5
min-idle: 2
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
@@ -100,13 +106,13 @@ spring:
spring.data:
redis:
# 地址
host: 117.72.197.29
host: 81.70.89.108
# 端口默认为6379
port: 6379
port: 26379
# 数据库索引
database: 6
database: 1
# redis 密码必须配置
password: intc@123987
password: bbd4b56e5d3f
# 连接超时时间
timeout: 10s
# 是否开启ssl
@@ -176,10 +182,12 @@ sms:
# 框架定义的厂商名称标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分
supplier: alibaba
# 有些称为accessKey有些称之为apiKey也有称为sdkKey或者appId。
access-key-id: 您的accessKey
access-key-id: LTAI5tRnPowmTLjH181nSbsR
# 称为accessSecret有些称之为apiSecret
access-key-secret: 您的accessKeySecret
signature: 您的短信签名
access-key-secret: Vh2LoAM1t3XuMUVy2wTWSACJ97kOUW
# 短信签名:需要在阿里云控制台创建并审核通过,格式如:鱼测云(不带【】符号)
# 请在阿里云短信服务控制台 -> 国内消息 -> 签名管理 中查看您的签名
signature: 鱼测云 # TODO: 请填写您的阿里云短信签名(不带【】符号)
sdk-app-id: 您的sdkAppId
config2:
# 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分
@@ -188,7 +196,81 @@ sms:
access-key-secret: 您的accessKeySecret
signature: 您的短信签名
sdk-app-id: 您的sdkAppId
# plus扩展配置
plus:
# 短信验证码模板ID(请根据实际短信服务商的模板ID配置)
# 请在阿里云短信服务控制台获取真实的模板CODE格式如SMS_460655548
# 模板内容需包含 ${code} 参数
code-template-id: 'SMS_465720430' # TODO: 请填写您的阿里云短信模板CODE
# 设备类型到 ProductKey 的映射配置
device-type:
# 1-水质检测仪 ProductKey请填写实际的 ProductKey
water-quality-monitor: a15hA3oBPmB # TODO: 请替换为实际的水质检测仪 ProductKey
# 2-控制一体机 ProductKey请填写实际的 ProductKey
control-integrated: a1Xj9dagTIx # TODO: 请替换为实际的控制一体机 ProductKey
# 3-太阳能网控 ProductKey
solar-controller: a1ZLJkYlSjs
--- # 阿里云生活物联网平台(飞燕平台)配置
aliyun:
living-iot:
# 阿里云 AccessKey ID必填
access-key-id: LTAI5tRnPowmTLjH181nSbsR
# 阿里云 AccessKey Secret必填
access-key-secret: Vh2LoAM1t3XuMUVy2wTWSACJ97kOUW
# 地域节点(必填)
region-id: cn-shanghai
# 飞燕平台项目IDProject ID
project-id: a123nMibvh0q4UnU
# App Key用于 API 调用)
app-key: 334224397
# App Secret
app-secret: 70de3018ec39423e9ca1e1b6a6a84ad6
# VMS 语音通知配置
vms:
# 是否启用 MNS 回扇消费true 时自动启动 MNS 消费线程接收 VMS 回扇)
mns-enabled: true
# VMS 语音服务对应的 AccessKey ID如果与上面 IoT 平台的 AK 相同可不填)
access-key-id: LTAI5tKh6fEKJJESaTdnChkh
# VMS 语音服务对应的 AccessKey Secret
access-key-secret: 6oa6t91ReT2YYSp3puuLA4FYtOyqDo
# MNS 账号 Endpoint格式https://{AccountId}.mns.cn-hangzhou.aliyuncs.com/
# 在阿里云控制台 > 语音服务 > 回扇配置 中查看对应的 MNS Endpoint
endpoint: https://1943695596114318.mns.cn-hangzhou.aliyuncs.com/
# MNS 队列名称(保持默认即可)
queue-name: Alicom-Queue-1572610294777992-VoiceReport
# 告警通知间隔时间(分钟),同一设备在此时间内不重复发电话通知
alarm-notification-interval-minutes: 30
# 电话回执成功后的抑制时间(小时),已成功解到就在此时间内不再重复发起电话通知
call-success-suppress-hours: 2
# 设备离线告警延迟触发时间(分钟),设备离线超过此时间后才发送告警
offline-warn-delay-minutes: 6
# 太阳能网控离线告警延迟触发时间分钟工作1分钟休眠同分钟为正常行为需要更长延迟
solar-offline-warn-delay-minutes: 30
# 是否启用报警电话通知(全局开关,关闭后所有类型的报警都不会触发电话通知)
call-notice-enabled: true
# AMQP 服务端订阅配置(使用数据同步的 AppKey + AppSecret
amqp:
# 是否启用
enabled: false
# 数据同步 AppKey与上面的 app-key 不同!)
data-sync-app-key: 334224409
# 数据同步 AppSecret请在阿里云控制台查看
data-sync-app-secret: 17fdd58f9a4c4c90be236897b1f8e8f7
# AMQP 接入点地址(使用生活物联网平台官方地址)
endpoint: amqps://ilop.iot-amqp.cn-shanghai.aliyuncs.com:5671
# 消费组 ID按照官方文档应该与数据同步 AppKey 相同)
consumer-group-id: 334224409
# 客户端 ID建议使用机器 UUID、MAC 地址等唯一标识)
client-id: fishery-backend-001
# 连接超时时间(毫秒)
connection-timeout: 80000
# 是否自动重连
auto-reconnect: true
# 最大重连次数
max-reconnect-attempts: 10
# 重连延迟(毫秒)
reconnect-delay: 30000
--- # 三方授权
justauth:
@@ -272,3 +354,74 @@ justauth:
client-id: 10**********6
client-secret: 1f7d08**********5b7**********29e
redirect-uri: ${justauth.address}/social-callback?source=gitea
--- # 微信支付选项配置
wx:
# 微信公众号配置
mp:
# 公众号appId必填
app-id: wx182a393d5c5e3479
# 公众号Secret必填
secret: 559d7bf12a781651c9772f525faa38e2
# 公众号token选填用于消息加解密
token: your_token_here
# 公众号EncodingAESKey选填用于消息加解密
aes-key: your_aes_key_here_43_characters_base64
# 微信小程序配置
miniapp:
# 小程序appId必填
app-id: wx9fb4034ebe52af77
# 小程序Secret必填
secret: 9b0eb221d9fa6bb46a463c24304f6d12
# 小程序token选填用于消息加解密
token: your_miniapp_token
# 小程序EncodingAESKey选填用于消息加解密
aes-key: your_miniapp_aes_key_43_characters_b64
# 消息格式XML或者JSON
msg-data-format: JSON
# 微信支付配置
pay:
# 商户号(必填)
mch-id: 1671289865
# 商户密钥V2版本必填
mch-key: your_mch_key_here_32_characters_md5
# 证书路径(退款等操作需要,选填)
key-path: classpath:cert/apiclient_cert.p12
# apiV3秘钥V3版本必填
api-v3-key: lms8a288e6694a429a2f15c718b1b17e
# 证书序列号V3版本必填
cert-serial-no: 6EFD85369A957FB27680825035E456065FD575D2
# 私钥路径V3版本选填与private-content二选一
# private-key-path: classpath:cert/apiclient_key.pem
# 私钥内容V3版本选填与private-key-path二选一推荐使用此方式
private-content: "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLEVxkdX6NJtDo\nzXOzkxn7kqR3MMc05/duLON4yjmLhTPQD8iiDoCOEuZEy8dLloi1OlXO3zu/F5jd\n9ynk8x++Px5A8gBQ16GZAMH18BQDzcFzy0EPe9ckiN3IXO8GT8Ht9oP430ugxF6t\nGM7Ixh93v48n7tUOZTISX5TzZCbXOiITH40b++/LB2LaMo9xAC4dEQs+2S4x5gO9\nPAh637ZAtVlbYxmJMYxzUM09KyXAoDlmO6YlO25EBkei7ZbyQob698s35+rSeq93\noFfUiegEL35SWeuuwp8ZFFvq24EUW7/n4U50/rS5hIFerEfcrFj2yPhP3sQtd4I+\nFjaEKzQLAgMBAAECggEBALxeUV9a4labUCT0GETWyr5j7C4oUFHSb+KCv0uYA0NZ\n/5McYRd67mNcQsBEa43BiPTbtSdeSnTbtdEI6pLXuHVo5W6HTiWvsNZWLpYt6tMQ\ndUgtnh932D2qvFiVZKBtMc7E4uzkbaonHk/heEgkCKKzTl9Tm81rr8P9aBVSrPjt\n6Xs7lORsD9bCoweYwfcrHELb+sLek/dOd9eCyabq7r5FV4EqOwJhw8btD7xgjw+o\nuVF3kWyhLSEwjpN/oo4w5r4yVPlMnSTn7MtTRFyJcU/w5YBk8MedGSTKRIvzPv4s\nRWU3ChTP5evGAh/FnpP6JGEhyvYGW0DqmuJUXK1n0fECgYEA/sSCT6Z+HSlwu/ui\nOSlDDFKZ/ci7vJcuksgf5Tw5Kj0fBVhgImO8hTS9nqCQx73JJTsUpTzyYOVxUd9b\nAqp42dgVbDYTmkfBi0xAZpnQD4Z4LUj6OkS2k3+2CPNN+jQpibGjGy11NDV/U8EQ\nP/9ioz+PoqwENG6wsaCT9LOC2DkCgYEAzAzUXJdH5T2LpSeO8e2NHtW6flemsJJ0\n+m0O03OWxQr6KNjFpNkTFoK6A2NYOiyqMZcQb+viHGFTFpFHkozo3QPaXpZsz3BC\ny9nQzqDbP3/MtfksE/MXOOw0qtdqT3csIxiXZqIjGYqAU08xcKyItZJGnIh/aKYn\nyobDnKkCRmMCgYB9mvbAPE6bJA4/r/03/17eGW9wjuH4RfUhSudmxn1MlNvRb9Pd\nwJx2dB00sucOg0RDRdCU8upw2U44Vk1xkAiLJpzRQAwEGXKTseFidFz++oYPlZZA\n2hXFvMZLvWDphYQhLeJDiPLq7aE78siHNOs1nyW6xuI/037r5EZt838ECQKBgQDC\n3+XY3+ob92Fsw5DzYIoMTtajXxalP9pUaN9l9tihKtCrPgvUWjSupP79yV0zggCx\nB7L9EOyLai+uN+WBAu5KVimxeDxHCNHiWg3fqSR7SpS5nlUIYHtnM79BAiZX6lrO\n0eeWb3bSJ8JSzilLkJunvSGO0ZXM3hLWi0o6TfcMPQKBgQDlmSC6/Ja4M+lGZEMx\nraCryScSi1kj3KkZFcGQEEejltpet2u06af/qA+tmMW7uxjLj5R80yqsYmUqS6Md\npHc1U7XsqU2MinqVJz47H8WZwYMDDLjNOI2f4coqbtBBOA6GKt+gYYqYxkpvVanT\noShAmWqOcPsioBVCFRVGvMlcNA==\n-----END PRIVATE KEY-----\n"
# 商户证书内容V3版本必填apiclient_cert.pem的内容
private-cert-content: "请将apiclient_cert.pem文件内容粘贴到此处"
# 支付选项列表配置
pay-item:
pay-items:
- id: 10001
amount: 1500 # 金额,单位:分
add-month: 1 # 增加月份
title: "月卡"
description: "增加1个月的使用时间"
- id: 10002
amount: 4000
add-month: 3
title: "季卡"
description: "增加3个月的使用时间"
- id: 10003
amount: 9900
add-month: 12
title: "年卡"
description: "增加12个月的使用时间"
# 支付回调通知配置
pay-notify:
# 支付回调通知URL需根据实际域名配置
notify-url: "https://api.yuceyun.cn/fishery-api/weixin/pay_notify"
# 微信商户号与上面wx.pay.mch-id保持一致
mch-id: "1671289865"

View File

@@ -187,6 +187,10 @@ sms:
access-key-secret: 您的accessKeySecret
signature: 您的短信签名
sdk-app-id: 您的sdkAppId
# plus扩展配置
plus:
# 短信验证码模板ID(请根据实际短信服务商的模板ID配置)
code-template-id: SMS_123456789
--- # 三方授权
justauth:

View File

@@ -35,7 +35,7 @@ captcha:
# 日志配置
logging:
level:
org.dromara: @logging.level@
org.dromara: info
org.springframework: warn
org.mybatis.spring.mapper: error
org.apache.fury: warn
@@ -69,7 +69,7 @@ spring:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: @profiles.active@
active: dev
# 文件上传
servlet:
multipart:
@@ -118,6 +118,10 @@ security:
- /*/api-docs
- /*/api-docs/**
- /warm-flow-ui/config
- /iot/test
- /iot/device/**
- /iot/amqp/**
- /weixin/pay_notify
# 多租户配置
tenant:
@@ -141,12 +145,12 @@ tenant:
mybatis-plus:
# 自定义配置 是否全局开启逻辑删除 关闭后 所有逻辑删除功能将失效
enableLogicDelete: true
# 多包名使用 例如 org.dromara.**.mapper,org.xxx.**.mapper
mapperPackage: org.dromara.**.mapper
# 多包名使用 例如 com.intc.**.mapper,org.xxx.**.mapper
mapperPackage: com.intc.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: org.dromara.**.domain
typeAliasesPackage: com.intc.**.domain
global-config:
dbConfig:
# 主键类型
@@ -171,7 +175,7 @@ mybatis-encryptor:
# api接口加密
api-decrypt:
# 是否开启全局接口加密
enabled: true
enabled: false
# AES 加密头标识
headerFlag: encrypt-key
# 响应加密公钥 非对称算法的公私钥 如SM2RSA 使用者请自行更换

View File

@@ -4,8 +4,8 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bom</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-bom</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
@@ -21,161 +21,161 @@
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-core</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-core</artifactId>
<version>${revision}</version>
</dependency>
<!-- 接口模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-doc</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-doc</artifactId>
<version>${revision}</version>
</dependency>
<!-- excel -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-excel</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-excel</artifactId>
<version>${revision}</version>
</dependency>
<!-- 幂等 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-idempotent</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-idempotent</artifactId>
<version>${revision}</version>
</dependency>
<!-- 调度模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-job</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-job</artifactId>
<version>${revision}</version>
</dependency>
<!-- 日志记录 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-log</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-log</artifactId>
<version>${revision}</version>
</dependency>
<!-- 邮件服务 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mail</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-mail</artifactId>
<version>${revision}</version>
</dependency>
<!-- 数据库服务 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mybatis</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-mybatis</artifactId>
<version>${revision}</version>
</dependency>
<!-- OSS -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-oss</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-oss</artifactId>
<version>${revision}</version>
</dependency>
<!-- 限流 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-ratelimiter</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-ratelimiter</artifactId>
<version>${revision}</version>
</dependency>
<!-- 缓存服务 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-redis</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-redis</artifactId>
<version>${revision}</version>
</dependency>
<!-- satoken -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-satoken</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-satoken</artifactId>
<version>${revision}</version>
</dependency>
<!-- 安全模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-security</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-security</artifactId>
<version>${revision}</version>
</dependency>
<!-- 短信模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-sms</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-sms</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-social</artifactId>
<version>${revision}</version>
</dependency>
<!-- web服务 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-web</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-web</artifactId>
<version>${revision}</version>
</dependency>
<!-- 翻译模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-translation</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-translation</artifactId>
<version>${revision}</version>
</dependency>
<!-- 脱敏模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-sensitive</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-sensitive</artifactId>
<version>${revision}</version>
</dependency>
<!-- 序列化模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-json</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-json</artifactId>
<version>${revision}</version>
</dependency>
<!-- 数据库加解密模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-encrypt</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-encrypt</artifactId>
<version>${revision}</version>
</dependency>
<!-- 租户模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-tenant</artifactId>
<version>${revision}</version>
</dependency>
<!-- WebSocket模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-websocket</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-websocket</artifactId>
<version>${revision}</version>
</dependency>
<!-- SSE模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-sse</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common-sse</artifactId>
<version>${revision}</version>
</dependency>

View File

@@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common</artifactId>
<groupId>com.intc</groupId>
<artifactId>intc-common</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-core</artifactId>
<artifactId>intc-common-core</artifactId>
<description>
ruoyi-common-core 核心模块

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.config;
package com.intc.common.core.config;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

View File

@@ -1,11 +1,11 @@
package org.dromara.common.core.config;
package com.intc.common.core.config;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.dromara.common.core.config.properties.ThreadPoolProperties;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.Threads;
import com.intc.common.core.config.properties.ThreadPoolProperties;
import com.intc.common.core.utils.SpringUtils;
import com.intc.common.core.utils.Threads;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.config;
package com.intc.common.core.config;
import jakarta.validation.Validator;
import org.hibernate.validator.HibernateValidator;

View File

@@ -0,0 +1,71 @@
package com.intc.common.core.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 设备类型配置
*
* @author intc
*/
@Data
@Component
@ConfigurationProperties(prefix = "device-type")
public class DeviceTypeProperties {
/**
* 水质检测仪 ProductKey
*/
private String waterQualityMonitor;
/**
* 控制一体机 ProductKey
*/
private String controlIntegrated;
/**
* 太阳能网控 ProductKey
*/
private String solarController;
/**
* 根据 ProductKey 判断设备类型
* @param productKey ProductKey
* @return 设备类型: 1-水质检测仪, 2-控制一体机, 3-太阳能网控, null-未知类型
*/
public Integer getDeviceTypeByProductKey(String productKey) {
if (productKey == null) {
return null;
}
if (productKey.equals(waterQualityMonitor)) {
return 1;
} else if (productKey.equals(controlIntegrated)) {
return 2;
} else if (productKey.equals(solarController)) {
return 3;
}
return null;
}
/**
* 根据设备类型获取 ProductKey
* @param deviceType 1-水质检测仪, 2-控制一体机, 3-太阳能网控
* @return ProductKey
*/
public String getProductKeyByType(Integer deviceType) {
if (deviceType == null) {
return null;
}
switch (deviceType) {
case 1:
return waterQualityMonitor;
case 2:
return controlIntegrated;
case 3:
return solarController;
default:
return null;
}
}
}

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.config.properties;
package com.intc.common.core.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 缓存的key 常量

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 缓存组名称常量

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 通用常量信息

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 全局的key常量 (业务无关的key)

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 返回状态码

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
import cn.hutool.core.lang.RegexPool;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 系统常量信息

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.constant;
package com.intc.common.core.constant;
/**
* 租户常量信息

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.domain;
package com.intc.common.core.domain;
import org.dromara.common.core.constant.HttpStatus;
import com.intc.common.core.constant.HttpStatus;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.dto;
package com.intc.common.core.domain.dto;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.event;
package com.intc.common.core.domain.event;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.event;
package com.intc.common.core.domain.event;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.event;
package com.intc.common.core.domain.event;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,9 +1,9 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.dromara.common.core.domain.dto.PostDTO;
import org.dromara.common.core.domain.dto.RoleDTO;
import com.intc.common.core.domain.dto.PostDTO;
import com.intc.common.core.domain.dto.RoleDTO;
import java.io.Serial;
import java.io.Serializable;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.domain.model;
package com.intc.common.core.domain.model;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@@ -1,10 +1,10 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import com.intc.common.core.exception.ServiceException;
import com.intc.common.core.utils.StringUtils;
import java.util.Arrays;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@@ -1,8 +1,8 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dromara.common.core.utils.StringUtils;
import com.intc.common.core.utils.StringUtils;
/*
* 日期格式

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;

View File

@@ -1,8 +1,8 @@
package org.dromara.common.core.enums;
package com.intc.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dromara.common.core.utils.StringUtils;
import com.intc.common.core.utils.StringUtils;
/**
* 用户类型

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.exception;
package com.intc.common.core.exception;
import cn.hutool.core.text.StrFormatter;
import lombok.AllArgsConstructor;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.exception;
package com.intc.common.core.exception;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@@ -1,8 +1,8 @@
package org.dromara.common.core.exception.base;
package com.intc.common.core.exception.base;
import lombok.AllArgsConstructor;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import com.intc.common.core.utils.MessageUtils;
import com.intc.common.core.utils.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.exception.file;
package com.intc.common.core.exception.file;
import org.dromara.common.core.exception.base.BaseException;
import com.intc.common.core.exception.base.BaseException;
import java.io.Serial;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.exception.user;
package com.intc.common.core.exception.user;
import java.io.Serial;

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.exception.user;
package com.intc.common.core.exception.user;
import org.dromara.common.core.exception.base.BaseException;
import com.intc.common.core.exception.base.BaseException;
import java.io.Serial;

View File

@@ -1,7 +1,7 @@
package org.dromara.common.core.factory;
package com.intc.common.core.factory;
import cn.hutool.core.lang.PatternPool;
import org.dromara.common.core.constant.RegexConstants;
import com.intc.common.core.constant.RegexConstants;
import java.util.regex.Pattern;

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.factory;
package com.intc.common.core.factory;
import org.dromara.common.core.utils.StringUtils;
import com.intc.common.core.utils.StringUtils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
/**
* 通用 参数配置服务

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.DeptDTO;
import com.intc.common.core.domain.dto.DeptDTO;
import java.util.List;
import java.util.Map;

View File

@@ -1,7 +1,7 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.DictDataDTO;
import org.dromara.common.core.domain.dto.DictTypeDTO;
import com.intc.common.core.domain.dto.DictDataDTO;
import com.intc.common.core.domain.dto.DictTypeDTO;
import java.util.List;
import java.util.Map;

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.OssDTO;
import com.intc.common.core.domain.dto.OssDTO;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import java.util.Set;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import java.util.List;
import java.util.Map;

View File

@@ -1,4 +1,4 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import java.util.List;
import java.util.Map;

View File

@@ -1,7 +1,7 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
import org.dromara.common.core.domain.model.TaskAssigneeBody;
import com.intc.common.core.domain.dto.TaskAssigneeDTO;
import com.intc.common.core.domain.model.TaskAssigneeBody;
/**
* 工作流设计器获取任务执行人

View File

@@ -1,6 +1,6 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.UserDTO;
import com.intc.common.core.domain.dto.UserDTO;
import java.util.List;
import java.util.Map;

View File

@@ -1,8 +1,8 @@
package org.dromara.common.core.service;
package com.intc.common.core.service;
import org.dromara.common.core.domain.dto.CompleteTaskDTO;
import org.dromara.common.core.domain.dto.StartProcessDTO;
import org.dromara.common.core.domain.dto.StartProcessReturnDTO;
import com.intc.common.core.domain.dto.CompleteTaskDTO;
import com.intc.common.core.domain.dto.StartProcessDTO;
import com.intc.common.core.domain.dto.StartProcessReturnDTO;
import java.util.List;
import java.util.Map;

View File

@@ -1,8 +1,8 @@
package org.dromara.common.core.utils;
package com.intc.common.core.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.exception.ServiceException;
import com.intc.common.core.enums.FormatsType;
import com.intc.common.core.exception.ServiceException;
import java.lang.management.ManagementFactory;
import java.text.ParseException;

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