From 7565fec9bdeea3e3e9d2577c0df3491f7a497e5a Mon Sep 17 00:00:00 2001 From: vincent Date: Wed, 16 Sep 2026 11:56:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E6=BC=8F?= =?UTF-8?q?=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 - zdxt-extend/zdxt-monitor-admin/Dockerfile | 7 + .../src/main/resources/application.yml | 9 - .../common/util/IdCardCryptoUtil.java | 9 - .../common/util/ServiceInvocation.java | 2 +- .../common/util/UserConstants.java | 4 - .../AppEnterpriseLoginController.java | 1 - .../controller/app/utils/HttpUtil.java | 2 +- .../enforcementcode/helper/QrCodeHelper.java | 36 -- .../impl/AppEnfLoginServiceImpl.java | 4 - .../impl/AppEnterpriseLoginServiceImpl.java | 15 +- .../service/impl/MssqApiServiceImpl.java | 10 +- .../zdxt-admin-web-server/Dockerfile | 8 + .../src/main/resources/application-dev.yml | 8 +- .../src/main/resources/application-prod.yml | 13 - .../AppEnterpriseLoginControllerTest.java | 301 ---------------- .../test/cp/AppEnfCpPlanControllerTest.java | 329 ------------------ .../service/test/ResetUserPasswordTest.java | 225 ------------ 18 files changed, 26 insertions(+), 965 deletions(-) delete mode 100644 zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/AppEnterpriseLoginControllerTest.java delete mode 100644 zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java delete mode 100644 zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java diff --git a/pom.xml b/pom.xml index 8701ff9e..45e77609 100644 --- a/pom.xml +++ b/pom.xml @@ -74,21 +74,15 @@ local - local info - ruoyi - 123456 dev - dev info - ruoyi - 123456 @@ -100,8 +94,6 @@ prod warn - ruoyi - 123456 diff --git a/zdxt-extend/zdxt-monitor-admin/Dockerfile b/zdxt-extend/zdxt-monitor-admin/Dockerfile index 458eeade..88c463e0 100644 --- a/zdxt-extend/zdxt-monitor-admin/Dockerfile +++ b/zdxt-extend/zdxt-monitor-admin/Dockerfile @@ -7,6 +7,9 @@ LABEL maintainer="Lion Li" RUN mkdir -p /ruoyi/monitor/logs +RUN groupadd -r appuser && useradd -r -g appuser -d /ruoyi/monitor -s /sbin/nologin appuser \ + && chown -R appuser:appuser /ruoyi/monitor + WORKDIR /ruoyi/monitor ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" @@ -15,6 +18,10 @@ EXPOSE 9090 ADD ./target/zdxt-monitor-admin.jar ./app.jar +RUN chown appuser:appuser /ruoyi/monitor/app.jar + +USER appuser + SHELL ["/bin/bash", "-c"] ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \ diff --git a/zdxt-extend/zdxt-monitor-admin/src/main/resources/application.yml b/zdxt-extend/zdxt-monitor-admin/src/main/resources/application.yml index b6f987dd..e5eb4c73 100644 --- a/zdxt-extend/zdxt-monitor-admin/src/main/resources/application.yml +++ b/zdxt-extend/zdxt-monitor-admin/src/main/resources/application.yml @@ -11,10 +11,6 @@ logging: --- # 监控中心服务端配置 spring: - security: - user: - name: @monitor.username@ - password: @monitor.password@ boot: admin: ui: @@ -44,8 +40,3 @@ spring.boot.admin.client: url: http://localhost:9090/admin instance: service-host-type: IP - metadata: - username: ${spring.boot.admin.client.username} - userpassword: ${spring.boot.admin.client.password} - username: @monitor.username@ - password: @monitor.password@ diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/IdCardCryptoUtil.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/IdCardCryptoUtil.java index 7826b943..fb716e27 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/IdCardCryptoUtil.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/IdCardCryptoUtil.java @@ -22,15 +22,6 @@ public class IdCardCryptoUtil { * 以下字符串为密钥,可以通过配置来传递 * @deprecated 请使用 SiqConfig 配置类获取密钥 */ - @Deprecated - public static final String OUTER_AES_KEY = "u3BPiZWALItH27e34oO6bw=="; - @Deprecated - public static final String INNER_AES_KEY = "ol1hV81iCruo+thxtZGnCg=="; - @Deprecated - public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADIVdRXNyT5pmGxSUfwEup2Y1YCz7VfibMyyQhkpVP3ByKsoFDjZ30yW5gv70sQbqn/MCthTFqwh3/I/YLfthM3vU7TdlmNfnlKcQ6prxYofLkX8akrhgQVFerb/4DhcbAk5xvx12Dkeh/nzDf5Qw2K3CymRPnr4zN6ZjAL79HwIDAQAB"; - @Deprecated - public static final String PRIVATE_KEY = "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAMAMhV1Fc3JPmmYbFJR/AS6nZjVgLPtV+JszLJCGSlU/cHIqygUONnfTJbmC/vSxBuqf8wK2FMWrCHf8j9gt+2Eze9TtN2WY1+eUpxDqmvFih8uRfxqSuGBBUV6tv/gOFxsCTnG/HXYOR6H+fMN/lDDYrcLKZE+evjM3pmMAvv0fAgMBAAECf2rTWPVVrHuC/ywzFz+CmSXAxLNSZbMCH0doYvs0hIrmvtjCjgN1F6P1z2yUpHBEbsetZEwdyQnEf74+WCuBaFIYjmQm/05grIxam/QrGibnV5qNiA0VeCkj6bUy+z5mt3/ithgzjmOiYIgMenjf6ut6RmgRDodgJiFbvSvfskECQQDoqGMNaUV+Y/O9h+l9eOCkSUOjOsL9WDRL34ei/jf7VFFYBZLs2GMzLunDkDz1dHvufDiMPeHUTTN8zIEEpNMVAkEA01Ehf9Np2zUqFQp3SW/fHVsaGM97JsbsTQrsDdUWwZLJTSQ7Yf+yg21GkNa8Mmlsp1OLyS607HV7lPlKO0LsYwJBAN1LTOv0taUCbVRZcj1mPEYHac5Ylh9jRlrkwp7GL3lfOf//TUD6kWCdvrvE9jaCFV9ByIecVLEavV53JkDEhgECQHgR40z0XXOWs8Cc38a0cDwH5b4vNjSEVwQ3roT1jSaUNxlD+xHl7hLLZosp2Gl0ia5RxF2d0mOBJaUyOMGPdy0CQCLBU3995JMoUyLgt2+Riw0PFbdxFEnKGyshAt5Q957/hC6L/V5tQNnh/AM9q23DIUQGb1whhxdIzV12qFSSS34="; - public static void main(String[] args) { String key = "VRJHzFqJpsSZhwnsKTWNspv_GZMxTWl-bgH6DyE9Ty0"; System.out.println("====================== 示例 ======================"); diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ServiceInvocation.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ServiceInvocation.java index 9707c61c..e9bbbf53 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ServiceInvocation.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/ServiceInvocation.java @@ -261,7 +261,7 @@ public class ServiceInvocation { paramList.add(pair); } - SSLContext sc = SSLContext.getInstance("SSL"); + SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, new TrustManager[] { new HttpUtil.TrustAnyTrustManager() }, new SecureRandom()); Registry registry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/UserConstants.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/UserConstants.java index 00d74cdc..d4955ff9 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/UserConstants.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/common/util/UserConstants.java @@ -111,10 +111,6 @@ public class UserConstants */ public static final Long DEFAULT_ROLE = 178L; - /** - * 默认密码 - */ - public static final String DEFAULT_PASSWORD = "szsf@zfjd"; /** * 默认部门 diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enterprise/AppEnterpriseLoginController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enterprise/AppEnterpriseLoginController.java index a6467afa..7caa4d1b 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enterprise/AppEnterpriseLoginController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enterprise/AppEnterpriseLoginController.java @@ -83,7 +83,6 @@ public class AppEnterpriseLoginController { log.info("---> 深i企登录用户 code:{}",siqLogin.getCode()); String secret = IdCardCryptoUtil.symmetricEncryptIdCard(secretKey, siqLogin.getCode()); params.put("accessKeySign",secret); - log.info("accessKeySign{}",secret); params.put("appCode",code); String data = null; try { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/utils/HttpUtil.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/utils/HttpUtil.java index 0ddf0c9e..19cc9e66 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/utils/HttpUtil.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/utils/HttpUtil.java @@ -26,7 +26,7 @@ public class HttpUtil { public static String HttpSendGet(String url,String accessToken) throws Exception{ HttpGet httpGet = new HttpGet(url); CloseableHttpResponse response=null; - SSLContext sc = SSLContext.getInstance("SSL"); + SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); Registry registry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/helper/QrCodeHelper.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/helper/QrCodeHelper.java index 6d1bf91e..1f83c40d 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/helper/QrCodeHelper.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/helper/QrCodeHelper.java @@ -86,15 +86,12 @@ public class QrCodeHelper { // 2. 拼接明文并生成 vaCode(AES加密) - String vaCode = symmetricRQValidateCodeEncrypt(enterpriseNumber); - Map jsonMap = new HashMap<>(); jsonMap.put("salt", salt); jsonMap.put("codeId", codeId); jsonMap.put("type", "zfjd"); jsonMap.put("enterpriseId", enterpriseId); jsonMap.put("enterpriseNumber", enterpriseNumber); - jsonMap.put("vaCode", vaCode); jsonMap.put("formModule","EntPubQrcodeService"); jsonMap.put("createDate", DateUtils.getTime()); jsonMap.put("refExId", refExId); @@ -213,37 +210,4 @@ public class QrCodeHelper { } } - // ==================== 加密与辅助方法 ==================== - - /** - * AES/ECB/PKCS5Padding 对称加密 - */ - private static String symmetricRQValidateCodeEncrypt(String content) { - try { - javax.crypto.spec.SecretKeySpec secretKey = new javax.crypto.spec.SecretKeySpec(AES_KEY.getBytes(), "AES"); - javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/ECB/PKCS5Padding"); - cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey); - byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)); - return java.util.Base64.getEncoder().encodeToString(encrypted); - } catch (Exception e) { - throw new RuntimeException("AES加密失败", e); - } - } - - /** - * 构建二维码明文内容 - */ - private static String buildQrCodeContent(String salt, String codeId, String type, - String enterpriseId, String enterpriseNumber, - String formModule, Date createDate, String eprqId) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String dateStr = (createDate != null) ? sdf.format(createDate) : ""; - return String.join("|", salt, codeId, - nullToEmpty(type), nullToEmpty(enterpriseId), nullToEmpty(enterpriseNumber), - nullToEmpty(formModule), dateStr, nullToEmpty(eprqId)); - } - - private static String nullToEmpty(String s) { - return s != null ? s : ""; - } } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enforcement/impl/AppEnfLoginServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enforcement/impl/AppEnfLoginServiceImpl.java index 47464e45..03023090 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enforcement/impl/AppEnfLoginServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enforcement/impl/AppEnfLoginServiceImpl.java @@ -293,13 +293,9 @@ public class AppEnfLoginServiceImpl implements IAppEnfLoginService { // 证件号解密 String secretKey = srnwgConfig.getSecretKey(); String card = IdCardCryptoUtil.symmetricDecryptIdCard(secretKey, userIdCard); - log.debug("身份证解密用盐: {}", secretKey); - log.debug("解密后的身份证号: {}", card); // 查询执法人员信息 List zfryList = zfryjdm2405301Mapper.queryZFRYByIdCard(card); - log.debug("查询到的执法人员信息: {}", zfryList); - // 判断是否有执法证编号 if (zfryList != null && !zfryList.isEmpty()) { Zfryjdm2405301 zfry = zfryList.get(0); diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enterprise/impl/AppEnterpriseLoginServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enterprise/impl/AppEnterpriseLoginServiceImpl.java index 13c35509..5d59f4ae 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enterprise/impl/AppEnterpriseLoginServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/enterprise/impl/AppEnterpriseLoginServiceImpl.java @@ -4,6 +4,7 @@ package com.zdxt.enforcementcode.service.enterprise.impl; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; import com.alibaba.fastjson.JSON; @@ -118,7 +119,7 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService @Override public Map siqLogin(AppEnterpriseLoginBo bo) { JSONObject userInfo = siqLoginInfo(bo); - log.info("---> 深i企登录用户信息:{}", userInfo); +// log.info("---> 深i企登录用户信息:{}", userInfo); return doSiqLoginWithLock(userInfo); } @@ -134,22 +135,15 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService try { locked = lock.tryLock(5, 60*5, TimeUnit.SECONDS); if (!locked) { - log.info("用户正在登录中,用户信息:{}", userInfo.toJSONString()); throw new BaseException("用户正在登录中,请稍后再试"); } - log.info("---> 登入锁 key: {}", lockKey); - EnterpriseUser newUser = saveOrUpdateEnterpriseUser(userInfo); - log.info("---> newUser: {}", newUser); EnterpriseInformation enterpriseInformation = addSiqUserCompany(userInfo, newUser); - log.info("---> enterpriseInformation: {}", enterpriseInformation); - if (newUser != null && enterpriseInformation != null) { createUserEnterpriseRef(newUser.getUserId(), enterpriseInformation); } String token = generateToken(newUser, enterpriseInformation); - log.info("---> token: {}", token); return buildLoginResult(newUser, enterpriseInformation, token); } catch (BaseException e) { throw e; @@ -220,7 +214,6 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService EnterpriseUser existUser = enterpriseUserMapper.selectOne(queryWrapper); Long userId; - log.info("===> existUser: {}", existUser); if (existUser == null) { log.info("企业用户不存在,执行新增操作: userName={}, userType={}", loginName, userType); newUser = buildEnterpriseUser(userInfo, userType); @@ -259,7 +252,7 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService user.setDeptId(UserConstants.DEFAULT_DEPT); // 设置默认密码(MD5加盐加密) - String defaultPassword = UserConstants.DEFAULT_PASSWORD; + String defaultPassword = RandomUtil.randomNumbers(8); user.setPassword(DigestUtil.md5Hex(user.getLoginName() + defaultPassword + user.getSalt())); // 账号状态:正常 @@ -553,7 +546,7 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService // 调试:检查 Token 是否成功存储到 Redis long timeout = StpUtil.getTokenTimeout(); log.info("生成token成功: userId={}, token={}, timeout={}秒, platformType={}", user.getUserId(), token, timeout, loginUser.getPlatformType()); - log.info("Token session key: login:token:{}", token); +// log.info("Token session key: login:token:{}", token); return token; } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/MssqApiServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/MssqApiServiceImpl.java index b115cb41..a0ba5580 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/MssqApiServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/MssqApiServiceImpl.java @@ -52,7 +52,7 @@ public class MssqApiServiceImpl implements IMssqApiService { //请求类型 mssqAddOrder.setInvokingServiceRequestMethod("POST"); String s = JSONObject.toJSONString(mssqAddOrder); - log.info("民生诉求token:{}",JSONObject.toJSONString(mssqToken)); +// log.info("民生诉求token:{}",JSONObject.toJSONString(mssqToken)); log.info("民生诉求工单新增,上传参数:{}",s); JSONObject serviceJsonData = ServiceInvocation.httpRequestForInterface(mssqUrl + "/api/API_YX/handlerProcess/channelAddOrder", mssqAddOrder.getInvokingServiceRequestMethod(), s, appId, mssqToken.getGatewayRtime(), mssqToken.getGatewaySig()); @@ -79,14 +79,11 @@ public class MssqApiServiceImpl implements IMssqApiService { // log.info("民生诉求获取token接口:{}",jsonObject); if (jsonObjectBody != null) { String accessToken = jsonObjectBody.getString("access_token"); - log.info("民生诉求获取token:{}",accessToken); // 3.在获得服务调用秘钥access_token后,根据自己的appKey使用AES解密算法对返回值进行解密,最终获取签名密钥secretKey String secretKey = ServiceInvocation.gatewayAesDecode(appKey, accessToken); - log.info("民生诉求获取secretKey:{}",secretKey); // 4.获取本地签名 String sign = gatewaySignEncode(appId, secretKey, currTime); mssqBaseDomain.setAccessToken(accessToken); - log.info("民生诉求获取sign:{}",sign); //签名 mssqBaseDomain.setGatewaySig(sign); } @@ -206,19 +203,14 @@ public class MssqApiServiceImpl implements IMssqApiService { String tokenSign = gatewaySignEncode(appId, appKey, currTime); // 2.调用获取token接口 JSONObject jsonObject = httpRequest(mssqUrl + "/auth/token", "POST", "", hcpAppId, hcpTimestamp, hcpSign); - log.info("民生诉求获取auth:{}",jsonObject.toJSONString()); JSONObject jsonObjectBody = JSONObject.parseObject(jsonObject.getString("body")); -// log.info("民生诉求获取token接口:{}",jsonObject); if (jsonObjectBody != null) { String accessToken = jsonObjectBody.getString("access_token"); - log.info("民生诉求获取token:{}",accessToken); // 3.在获得服务调用秘钥access_token后,根据自己的appKey使用AES解密算法对返回值进行解密,最终获取签名密钥secretKey String secretKey = ServiceInvocation.gatewayAesDecode(appKey, accessToken); - log.info("民生诉求获取secretKey:{}",secretKey); // 4.获取本地签名 String sign = gatewaySignEncode(appId, secretKey, currTime); mssqBaseDomain.setAccessToken(accessToken); - log.info("民生诉求获取sign:{}",sign); //签名 mssqBaseDomain.setGatewaySig(sign); } diff --git a/zdxt-web-server/zdxt-admin-web-server/Dockerfile b/zdxt-web-server/zdxt-admin-web-server/Dockerfile index 4a043d40..4307a80a 100644 --- a/zdxt-web-server/zdxt-admin-web-server/Dockerfile +++ b/zdxt-web-server/zdxt-admin-web-server/Dockerfile @@ -9,6 +9,10 @@ RUN mkdir -p /ruoyi/server/logs \ /ruoyi/server/temp \ /ruoyi/skywalking/agent +RUN groupadd -r appuser && useradd -r -g appuser -d /ruoyi/server -s /sbin/nologin appuser \ + && chown -R appuser:appuser /ruoyi/server \ + && chown -R appuser:appuser /ruoyi/skywalking + WORKDIR /ruoyi/server ENV SERVER_PORT=8080 SNAIL_PORT=28080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" @@ -19,6 +23,10 @@ EXPOSE ${SNAIL_PORT} ADD ./target/zdxt-admin.jar ./app.jar +RUN chown appuser:appuser /ruoyi/server/app.jar + +USER appuser + SHELL ["/bin/bash", "-c"] ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \ diff --git a/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-dev.yml b/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-dev.yml index a3280f98..674a2f27 100644 --- a/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-dev.yml +++ b/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-dev.yml @@ -284,10 +284,6 @@ justauth: client-secret: 1f7d08**********5b7**********29e redirect-uri: ${justauth.address}/social-callback?source=gitea -#security: -# excludes: -# - /** - #深i企对接密钥 测试环境 siq: #正式 @@ -340,6 +336,10 @@ srnwg: paasToken: ENC(VfUgR5OXHJcKvBBfq/2ysuNPH6I7tCCeWHYSzXKicGChlMiw9mVPGD51naX9w42E) #市认证数据加密字符 secretKey: ENC(xWBA5VwT23j14A8+6I15HCerJvo3zaRxzVE2xc0i7wZ7wq/SCflOEkHCc8wwdi0KHkDGjKIoHhs=) + # RSA 公钥 + rsa-public-key: ENC(待用Jasypt加密后的公钥密文) + # RSA 私钥 + rsa-private-key: ENC(待用Jasypt加密后的私钥密文) # #测试 # url: ENC(jFwf6bYIMn+FOtbCkyPr0r+TBOPrp84tNotl912ilUZy2e9Y8cbH3uDQ5jtr6SAa) # systemCode: ENC(ECOnqNVVPmCmnqhde6tsS5JEQYPtlmCv) diff --git a/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-prod.yml b/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-prod.yml index a6bbd538..1002b60f 100644 --- a/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-prod.yml +++ b/zdxt-web-server/zdxt-admin-web-server/src/main/resources/application-prod.yml @@ -7,19 +7,6 @@ zdxt: url-prefix: /profile demo_enabled: false ---- # 监控中心配置 -spring.boot.admin.client: - # 增加客户端开关 - enabled: false - url: http://localhost:9090/admin - instance: - service-host-type: IP - metadata: - username: ${spring.boot.admin.client.username} - userpassword: ${spring.boot.admin.client.password} - username: @monitor.username@ - password: @monitor.password@ - --- # snail-job 配置 snail-job: enabled: false diff --git a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/AppEnterpriseLoginControllerTest.java b/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/AppEnterpriseLoginControllerTest.java deleted file mode 100644 index 6994f5fb..00000000 --- a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/AppEnterpriseLoginControllerTest.java +++ /dev/null @@ -1,301 +0,0 @@ -//package com.zdxt.rest.test; -// -//import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; -//import org.dromara.ZdxtAdminApplication; -//import org.junit.jupiter.api.*; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.http.MediaType; -//import org.springframework.test.web.servlet.MockMvc; -//import org.springframework.test.web.servlet.MvcResult; -// -//import java.nio.charset.StandardCharsets; -// -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -//import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -// -///** -// * AppEnterpriseLoginController 企业端-用户登录接口测试 -// *

-// * 覆盖以下接口: -// * 1. POST /app-ent/login/siqLogin - 深i企用户登录 -// *

-// *

-// * 注意:此测试需要配置真实的深i企接口地址,或在测试环境中 Mock 相关服务 -// *

-// * -// * @author zdxt -// */ -//@SpringBootTest(classes = ZdxtAdminApplication.class) -//@AutoConfigureMockMvc -//@DisplayName("AppEnterpriseLoginController 企业端-用户登录接口测试") -//@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -//public class AppEnterpriseLoginControllerTest { -// -// @Autowired -// private MockMvc mockMvc; -// -// private static final String BASE_URL = "/app-ent/login"; -// private static final String TEST_CLIENT_ID = "e5cd7e4891bf95d1d19206ce24a7b32e"; -// -// @BeforeEach -// public void setUp() { -// SaTokenContextMockUtil.setMockContext(); -// } -// -// @AfterEach -// public void tearDown() { -// SaTokenContextMockUtil.clearContext(); -// } -// -// // ==================== siqLogin 接口测试 ==================== -// -// @DisplayName("深i企登录 - 正常请求(需要有效的授权码)") -// @Test -// @Order(1) -// public void testSiqLoginSuccess() throws Exception { -// String requestBody = "{\"code\":\"test_authorization_code\"}"; -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// System.out.println("深i企登录接口响应: " + responseBody); -// -// if (responseBody.contains("\"code\":200")) { -// Assertions.assertTrue(responseBody.contains("token"), "返回数据应包含 token"); -// Assertions.assertTrue(responseBody.contains("userId"), "返回数据应包含 userId"); -// Assertions.assertTrue(responseBody.contains("userName"), "返回数据应包含 userName"); -// Assertions.assertTrue(responseBody.contains("enterpriseId"), "返回数据应包含 enterpriseId"); -// Assertions.assertTrue(responseBody.contains("enterpriseName"), "返回数据应包含 enterpriseName"); -// System.out.println("深i企登录成功,返回了完整的用户和企业信息"); -// } else { -// System.out.println("深i企登录失败(可能由于授权码无效或深i企接口未配置): " + responseBody); -// } -// } -// -// @DisplayName("深i企登录 - 缺少授权码参数应返回失败") -// @Test -// @Order(2) -// public void testSiqLoginMissingCode() throws Exception { -// String requestBody = "{}"; -// -// mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.code").value(500)); -// -// System.out.println("缺少授权码参数返回失败测试成功"); -// } -// -// @DisplayName("深i企登录 - 空授权码应返回失败") -// @Test -// @Order(3) -// public void testSiqLoginEmptyCode() throws Exception { -// String requestBody = "{\"code\":\"\"}"; -// -// mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.code").value(500)); -// -// System.out.println("空授权码返回失败测试成功"); -// } -// -// @DisplayName("深i企登录 - 无效授权码应返回失败") -// @Test -// @Order(4) -// public void testSiqLoginInvalidCode() throws Exception { -// String requestBody = "{\"code\":\"invalid_code_12345\"}"; -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// -// if (responseBody.contains("\"code\":500")) { -// System.out.println("无效授权码返回失败测试成功"); -// } else { -// System.out.println("注意:无效授权码未返回预期错误,响应: " + responseBody); -// } -// } -// -// @DisplayName("深i企登录 - 验证返回数据结构完整性") -// @Test -// @Order(5) -// public void testSiqLoginResponseStructure() throws Exception { -// String requestBody = "{\"code\":\"test_code\"}"; -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// System.out.println("验证返回数据结构响应: " + responseBody); -// -// if (responseBody.contains("\"code\":200")) { -// Assertions.assertTrue(responseBody.contains("\"data\""), "返回数据应包含 data 字段"); -// -// String data = extractDataJson(responseBody); -// if (data != null) { -// Assertions.assertTrue(data.contains("token"), "data 中应包含 token"); -// Assertions.assertTrue(data.contains("userId"), "data 中应包含 userId"); -// Assertions.assertTrue(data.contains("userName"), "data 中应包含 userName"); -// Assertions.assertTrue(data.contains("loginName"), "data 中应包含 loginName"); -// Assertions.assertTrue(data.contains("phonenumber"), "data 中应包含 phonenumber"); -// Assertions.assertTrue(data.contains("enterpriseId"), "data 中应包含 enterpriseId"); -// Assertions.assertTrue(data.contains("enterpriseName"), "data 中应包含 enterpriseName"); -// Assertions.assertTrue(data.contains("enterpriseNumber"), "data 中应包含 enterpriseNumber"); -// System.out.println("返回数据结构完整,包含所有必需字段"); -// } -// } else { -// System.out.println("登录失败,无法验证数据结构"); -// } -// } -// -// @DisplayName("深i企登录 - 重复登录应能正常处理(同一授权码多次调用)") -// @Test -// @Order(6) -// public void testSiqLoginDuplicateCall() throws Exception { -// String requestBody = "{\"code\":\"test_code\"}"; -// -// for (int i = 1; i <= 3; i++) { -// System.out.println("========== 第 " + i + " 次调用深i企登录 =========="); -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// System.out.println("第 " + i + " 次调用响应: " + responseBody); -// -// Thread.sleep(1000); -// } -// -// System.out.println("========== 重复登录测试完成 =========="); -// } -// -// @DisplayName("深i企登录 - 验证 Token 格式") -// @Test -// @Order(7) -// public void testSiqLoginTokenFormat() throws Exception { -// String requestBody = "{\"code\":\"test_code\"}"; -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// -// if (responseBody.contains("\"code\":200")) { -// String token = extractTokenFromResponse(responseBody); -// if (token != null && !token.isEmpty()) { -// Assertions.assertTrue(token.length() > 10, "Token 长度应大于10个字符"); -// System.out.println("Token 格式验证通过,Token: " + token); -// } else { -// System.out.println("未能提取到 Token"); -// } -// } else { -// System.out.println("登录失败,无法验证 Token 格式"); -// } -// } -// -// @DisplayName("深i企登录 - 验证企业信息关联") -// @Test -// @Order(8) -// public void testSiqLoginEnterpriseAssociation() throws Exception { -// String requestBody = "{\"code\":\"test_code\"}"; -// -// MvcResult result = mockMvc.perform(post(BASE_URL + "/siqLogin") -// .contentType(MediaType.APPLICATION_JSON) -// .content(requestBody)) -// .andDo(print()) -// .andExpect(status().isOk()) -// .andReturn(); -// -// String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); -// -// if (responseBody.contains("\"code\":200")) { -// String data = extractDataJson(responseBody); -// if (data != null) { -// String enterpriseId = extractJsonValue(data, "enterpriseId"); -// String enterpriseName = extractJsonValue(data, "enterpriseName"); -// String enterpriseNumber = extractJsonValue(data, "enterpriseNumber"); -// -// if (enterpriseId != null && enterpriseName != null && enterpriseNumber != null) { -// Assertions.assertFalse(enterpriseId.isEmpty(), "企业ID不应为空"); -// Assertions.assertFalse(enterpriseName.isEmpty(), "企业名称不应为空"); -// Assertions.assertFalse(enterpriseNumber.isEmpty(), "企业统一信用代码不应为空"); -// System.out.println("企业信息关联验证通过"); -// System.out.println("企业ID: " + enterpriseId); -// System.out.println("企业名称: " + enterpriseName); -// System.out.println("企业统一信用代码: " + enterpriseNumber); -// } -// } -// } else { -// System.out.println("登录失败,无法验证企业信息关联"); -// } -// } -// -// // ==================== 工具方法 ==================== -// -// /** -// * 从 JSON 响应中提取 data 字段 -// */ -// private String extractDataJson(String responseBody) { -// if (responseBody != null && responseBody.contains("\"data\":{")) { -// int start = responseBody.indexOf("\"data\":{") + 7; -// int end = responseBody.lastIndexOf("}"); -// if (start > 0 && end > start) { -// return responseBody.substring(start, end + 1); -// } -// } -// return null; -// } -// -// /** -// * 从响应中提取 Token -// */ -// private String extractTokenFromResponse(String responseBody) { -// return extractJsonValue(responseBody, "token"); -// } -// -// /** -// * 从 JSON 字符串中提取指定字段的值 -// */ -// private String extractJsonValue(String json, String key) { -// if (json != null && json.contains("\"" + key + "\"")) { -// int start = json.indexOf("\"" + key + "\":\"") + key.length() + 4; -// int end = json.indexOf("\"", start); -// if (start > 0 && end > start) { -// return json.substring(start, end); -// } -// } -// return null; -// } -//} -//{ -//} diff --git a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java b/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java deleted file mode 100644 index f5978294..00000000 --- a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java +++ /dev/null @@ -1,329 +0,0 @@ -package com.zdxt.rest.test.cp; - -import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; -import cn.dev33.satoken.stp.StpUtil; -import cn.dev33.satoken.stp.parameter.SaLoginParameter; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.zdxt.enforcementcode.domain.bo.EnterpriseInformationBo; -import com.zdxt.enforcementcode.domain.vo.EnterpriseInformationVo; -import com.zdxt.enforcementcode.service.IEnterpriseInformationService; -import org.dromara.ZdxtAdminApplication; -import org.dromara.common.core.domain.model.LoginUser; -import org.dromara.common.satoken.utils.LoginHelper; -import org.junit.jupiter.api.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.*; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * AppEnfCpPlanController 新增计划批量测试 - *

- * 为多个用户批量创建执法计划(每人100条) - *

- */ -@SpringBootTest(classes = ZdxtAdminApplication.class) -@AutoConfigureMockMvc -@ActiveProfiles({"dev", "dev-cust-zrb"}) -@DisplayName("AppEnfCpPlanController 批量新增计划测试") -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class AppEnfCpPlanControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private IEnterpriseInformationService enterpriseInformationService; - - private static final String BASE_URL = "/app-enf/cpPlan"; - private static final String LOGIN_URL = "/app-enf/login/do"; - private static final String AES_KEY = "1234567898745621"; - private static final String CLIENT_ID = "f0535c2a32ab4d0496ab9a699b2a7d36"; - private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"; - - /** 通用密码 */ - private static final String PASSWORD = "szsf@zfjd"; - - @BeforeEach - public void setUp() { - // 初始化 Sa-Token 上下文 - SaTokenContextMockUtil.setMockContext(); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - mockRequest.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); - RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(mockRequest)); - } - - @AfterEach - public void tearDown() { - try { - StpUtil.logout(); - } catch (Exception ignored) { - } - RequestContextHolder.resetRequestAttributes(); - SaTokenContextMockUtil.clearContext(); - } - - /** - * 登录指定账号,返回登录信息 - */ - private Map doLogin(String account) throws Exception { - String encryptedPassword = encryptByAes(PASSWORD); - Map loginParams = new HashMap<>(); - loginParams.put("secretName", account); - loginParams.put("secretKey", encryptedPassword); - - MvcResult loginResult = mockMvc.perform(post(LOGIN_URL) - .header("User-Agent", USER_AGENT) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(loginParams))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(200)) - .andReturn(); - - String loginBody = loginResult.getResponse().getContentAsString(StandardCharsets.UTF_8); - JsonNode loginJson = objectMapper.readTree(loginBody); - JsonNode data = loginJson.get("data"); - - Map info = new HashMap<>(); - info.put("token", data.get("token").asText()); - info.put("userId", data.get("userId").asText()); - // nickName 可能为空,回退到 userName(中文姓名) - String nickName = data.has("nickName") ? data.get("nickName").asText() : ""; - if (nickName == null || nickName.isBlank()) { - nickName = data.has("userName") ? data.get("userName").asText() : account; - } - info.put("nickName", nickName); - info.put("deptId", data.get("deptId").asText()); - info.put("deptName", data.get("deptName").asText()); - info.put("organId", data.get("organId").asText()); - info.put("organName", data.get("organName").asText()); - info.put("bureauUnitId", data.get("bureauUnitId").asText()); - info.put("bureauUnitName", data.get("bureauUnitName").asText()); - info.put("phonenumber", data.has("phonenumber") ? data.get("phonenumber").asText() : ""); - - System.out.println("[" + account + "] 登录成功: userId=" + info.get("userId")); - return info; - } - - // ==================== 各账号批量新增测试 ==================== - - @DisplayName("liuqianlin(刘倩琳)批量新增100条执法计划") - @Test - @Order(1) - public void testBatchCreate_liuqianlin() throws Exception { - batchCreatePlans("liuqianlin", 100); - } - - @DisplayName("baining(白宁)批量新增100条执法计划") - @Test - @Order(2) - public void testBatchCreate_baining() throws Exception { - batchCreatePlans("baining", 100); - } - - @DisplayName("caizifan(蔡梓帆)批量新增100条执法计划") - @Test - @Order(3) - public void testBatchCreate_caizifan() throws Exception { - batchCreatePlans("caizifan", 100); - } - - @DisplayName("chenchong4(陈冲)批量新增100条执法计划") - @Test - @Order(4) - public void testBatchCreate_chenchong4() throws Exception { - batchCreatePlans("chenchong4", 100); - } - - /** - * 为指定账号批量新增计划 - *

- * 唯一性约束:同一人 + 日期 + 时间段 + 企业 只能有一条计划。 - * 日期循环31天(7月1~31日),时间段2个(上午/下午),企业循环7家, - * 因 31、2、7 两两互素,由中国剩余定理(CRT)保证前 31×2×7=434 条组合均唯一, - * 故 count≤434 时所有计划不会重复。 - *

- */ - private void batchCreatePlans(String account, int count) throws Exception { - Map loginInfo = doLogin(account); - String token = loginInfo.get("token"); - String userId = loginInfo.get("userId"); - String nickName = loginInfo.get("nickName"); - - // 从数据库加载指定企业列表 - List enterprises = loadEnterprises(); - Assertions.assertFalse(enterprises.isEmpty(), "数据库中无可用企业数据"); - - // --- 唯一性预测验证 --- - int days = 31; // 7月有31天 - int timeSlots = 2; // 上午/下午 - int entCount = enterprises.size(); - // 由CRT保证的最大不重复组合数 = lcm(days, timeSlots, entCount) 当两两互素时 = days * timeSlots * entCount - int maxUnique = days * timeSlots * entCount; - int expectedSuccess = Math.min(count, maxUnique); - System.out.println("[" + account + "] 企业数=" + entCount - + ", 可用唯一组合(日期×时段×企业)=" + maxUnique - + ", 计划生成数=" + count - + ", 预计成功数=" + expectedSuccess); - Assertions.assertTrue(count <= maxUnique, - "计划数(" + count + ")超过最大唯一组合数(" + maxUnique + "),必然产生重复"); - - Random random = new Random(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - Calendar cal = Calendar.getInstance(); - - int successCount = 0; - int failCount = 0; - - for (int i = 0; i < count; i++) { - // 所有计划日期限定在2026年7月内,循环使用7月1日~31日 - int dayOfMonth = (i % days) + 1; - cal.set(2026, Calendar.JULY, dayOfMonth); - String planDate = sdf.format(cal.getTime()); - long planTime = (i % 2 == 0) ? 1L : 2L; // 交替上午/下午 - - // 确定性循环选取企业,保证 (日期, 时段, 企业) 三元组唯一 - EnterpriseInformationVo enterprise = enterprises.get(i % entCount); - Map planBo = buildPlanBo(planDate, planTime, i, nickName, userId, loginInfo, enterprise, random); - String requestBody = objectMapper.writeValueAsString(planBo); - - MvcResult result = mockMvc.perform(post(BASE_URL) - .header("Authorization", "Bearer " + token) - .header("clientid", CLIENT_ID) - .header("User-Agent", USER_AGENT) - .contentType(MediaType.APPLICATION_JSON) - .content(requestBody)) - .andReturn(); - - String responseBody = result.getResponse().getContentAsString(StandardCharsets.UTF_8); - JsonNode respJson = objectMapper.readTree(responseBody); - int code = respJson.get("code").asInt(); - - if (code == 200) { - successCount++; - } else { - failCount++; - System.out.println("[" + account + "] 第" + (i + 1) + "条失败: " + responseBody); - } - - if ((i + 1) % 10 == 0) { - System.out.println("[" + account + "] 已处理 " + (i + 1) + "/" + count - + ", 成功=" + successCount + ", 失败=" + failCount); - } - } - - System.out.println("========== [" + account + "] 批量新增完成 =========="); - System.out.println("总计: " + count + ", 成功: " + successCount + ", 失败: " + failCount); - Assertions.assertEquals(expectedSuccess, successCount, - "[" + account + "] 预期成功" + expectedSuccess + "条,实际成功" + successCount + "条"); - } - - /** 指定的企业统一社会信用代码列表 */ - private static final String[][] ENTERPRISE_DATA = { - {"吉田拉链(深圳)有限公司公明工厂", "91440300788302281W"}, - {"欧姆龙电子部件(深圳)有限公司", "914403007261811621"}, - {"深圳农牧美益肉业有限公司", "91440300662678582M"}, - {"深圳市深水龙岗污水处理有限公司", "914403006820066603"}, - {"深圳市强达电路股份有限公司", "91440300763461366N"}, - {"深圳康泰生物制品股份有限公司", "91440300618837873J"}, - {"深圳市里程食品有限公司", "91440300738848091F"}, - }; - - /** - * 从数据库加载指定的7家企业 - */ - private List loadEnterprises() { - List result = new ArrayList<>(); - for (String[] entry : ENTERPRISE_DATA) { - EnterpriseInformationBo queryBo = new EnterpriseInformationBo(); - queryBo.setEnterpriseNumber(entry[1]); - queryBo.setIsDelete(0L); - List list = enterpriseInformationService.queryList(queryBo); - if (!list.isEmpty()) { - result.add(list.get(0)); - } else { - System.out.println("[警告] 未找到企业: " + entry[0] + " (" + entry[1] + ")"); - } - } - return result; - } - - /** - * 构建计划BO的Map - */ - private Map buildPlanBo(String planDate, long planTime, int index, - String userName, String userId, Map loginInfo, - EnterpriseInformationVo enterprise, Random random) { - Map bo = new LinkedHashMap<>(); - bo.put("planType", 1L); // 日常计划 - bo.put("planDate", planDate); - bo.put("planTime", planTime); - bo.put("enforceContent", "批量测试执法事项-第" + (index + 1) + "条"); - bo.put("enterpriseName", enterprise.getEnterpriseName()); - bo.put("enterpriseNumber", enterprise.getEnterpriseNumber()); - bo.put("enterpriseId", enterprise.getId()); - bo.put("enforceUserNames", userName); - bo.put("enforceUserIds", userId); - bo.put("enforceUserTels", loginInfo.get("phonenumber")); - bo.put("enforceUserCodes", "-"); - bo.put("isPublic", random.nextInt(2) == 0 ? 0L : 1L); // 随机公开/不公开 - bo.put("isUnion", 1L); // 必须为联合执法,否则afterInsert会直接生成任务导致status变为3 - bo.put("reserveStatus", 1L); // 待预约 - bo.put("systemReserved", 0L); - bo.put("manualReserved", 0L); - bo.put("bureauDeptId", loginInfo.get("bureauUnitId")); - bo.put("bureauDeptName", loginInfo.get("bureauUnitName")); - bo.put("organId", loginInfo.get("organId")); - bo.put("organName", loginInfo.get("organName")); - bo.put("deptId", loginInfo.get("deptId")); - bo.put("deptName", loginInfo.get("deptName")); - bo.put("isDelete", 0L); - return bo; - } - - /** - * AES/CBC/ZeroPadding 加密(与前端 CryptoJS 对应) - */ - private String encryptByAes(String plainText) throws Exception { - byte[] keyBytes = AES_KEY.getBytes(StandardCharsets.UTF_8); - byte[] ivBytes = AES_KEY.getBytes(StandardCharsets.UTF_8); - - SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); - IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); - - // NoPadding 需要手动补零到16字节倍数 - byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8); - int blockSize = 16; - int paddedLen = ((plainBytes.length / blockSize) + 1) * blockSize; - byte[] padded = new byte[paddedLen]; - System.arraycopy(plainBytes, 0, padded, 0, plainBytes.length); - // 剩余字节默认为0(ZeroPadding) - - Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); - byte[] encrypted = cipher.doFinal(padded); - - return Base64.getEncoder().encodeToString(encrypted); - } -} diff --git a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java b/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java deleted file mode 100644 index d61a4e1c..00000000 --- a/zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/ResetUserPasswordTest.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.zdxt.service.test; - -import cn.hutool.crypto.digest.DigestUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.zdxt.enforcementcode.domain.EnterpriseUser; -import com.zdxt.enforcementcode.mapper.EnterpriseUserMapper; -import org.dromara.ZdxtAdminApplication; -import org.dromara.system.domain.SysUser; -import org.dromara.system.mapper.SysUserMapper; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; -import cn.dev33.satoken.stp.parameter.SaLoginParameter; -import cn.dev33.satoken.stp.StpUtil; -import org.dromara.common.core.domain.model.LoginUser; -import org.dromara.common.satoken.utils.LoginHelper; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -/** - * 批量重置 enterprise_user 表用户密码 - *

- * 密码加密规则: MD5(userName + password + salt) - *

- */ -@SpringBootTest(classes = ZdxtAdminApplication.class) -@AutoConfigureMockMvc -@ActiveProfiles({"dev", "dev-cust-zrb"}) -@DisplayName("批量重置企业用户密码") -public class ResetUserPasswordTest { - - @Autowired - private EnterpriseUserMapper enterpriseUserMapper; - - @Autowired - private SysUserMapper sysUserMapper; - - /** 重置后的明文密码 */ - private static final String NEW_PASSWORD = "szsf@zfjd"; - //private static final String NEW_PASSWORD = "Szsf@123"; - - private static final String TEST_CLIENT_ID = "e5cd7e4891bf95d1d19206ce24a7b32e"; - - @BeforeEach - public void setUp() { - // 初始化 Sa-Token 上下文(非 Web 环境下 StpUtil.login 需要) - SaTokenContextMockUtil.setMockContext(); - - // 设置模拟请求上下文(数据权限拦截器需要从 SaToken 上下文获取用户信息) - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - mockRequest.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"); - RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(mockRequest)); - - // 构造测试用登录用户 - LoginUser loginUser = new LoginUser(); - loginUser.setUserId(1L); - loginUser.setUserType("sys_user"); - loginUser.setTenantId("000000"); - loginUser.setUsername("test_admin"); - loginUser.setNickname("测试管理员"); - loginUser.setDeptId("103"); - loginUser.setDeptName("测试部门"); - loginUser.setRolePermission(new HashSet<>()); - loginUser.setMenuPermission(new HashSet<>()); - - // 模拟登录 - SaLoginParameter param = new SaLoginParameter(); - param.setExtra(LoginHelper.CLIENT_KEY, TEST_CLIENT_ID); - LoginHelper.login(loginUser, param); - } - - @AfterEach - public void tearDown() { - try { - StpUtil.logout(); - } catch (Exception ignored) { - } - RequestContextHolder.resetRequestAttributes(); - SaTokenContextMockUtil.clearContext(); - } - - @DisplayName("批量重置 enterprise_user 所有用户密码为 szsf@zfjd") - @Test - public void resetAllEnterpriseUserPassword() { - - /*-- 17608540150,weil45,"",15817307171,深圳农牧美益肉业有限公司,91440300662678582M,21 - -- 17608557492,DGD440881199506180622,"",15817381630,深圳市深水龙岗污水处理有限公司,914403006820066603,12 - -- 17608540121,smiledzb1982,"",13723454151,深圳康泰生物制品股份有限公司,91440300618837873J,10 - -- 17608594890,A7271888,"",13751661770,深圳市里程食品有限公司,91440300738848091F,9 - -- 17608565612,qintongzhen138,"",13823610579,欧姆龙电子部件(深圳)有限公司,914403007261811621,9 - -- 17608601734,XP073215,"",15012671807,深圳市强达电路股份有限公司,91440300763461366N,9 - -- 17608556724,33ef1970fd449676fa4bc197,"",13537602265,吉田拉链(深圳)有限公司公明工厂,91440300788302281W,8*/ - - // 1. 指定需要重置密码的用户ID列表 - List userIds = Arrays.asList( - // TODO: 在此填入需要重置的用户ID - "17608540150", "17608557492", "17608540121", "17608594890", "17608565612", "17608601734", "17608556724","2064275054386966530","2064274295779979265","17608629742" - ); - - // 2. 根据ID列表查询企业用户 - List userList = enterpriseUserMapper.selectList( - new LambdaQueryWrapper() - .select(EnterpriseUser::getUserId, EnterpriseUser::getLoginName, EnterpriseUser::getUserName, EnterpriseUser::getSalt) - .in(EnterpriseUser::getUserId, userIds) - ); - - System.out.println("查询到企业用户总数: " + userList.size()); - - int successCount = 0; - int skipCount = 0; - - for (EnterpriseUser user : userList) { - String loginName = user.getLoginName(); - String salt = user.getSalt(); - - if (loginName == null || loginName.isBlank()) { - System.out.println("跳过: userId=" + user.getUserId() + ", loginName为空"); - skipCount++; - continue; - } - if (salt == null || salt.isBlank()) { - System.out.println("跳过: userId=" + user.getUserId() + ", salt为空"); - skipCount++; - continue; - } - - // 3. 按规则生成新密码: MD5(loginName + newPassword + salt) - String newMd5Password = DigestUtil.md5Hex(loginName + NEW_PASSWORD + salt); - - // 4. 更新密码 - int rows = enterpriseUserMapper.update(null, - new LambdaUpdateWrapper() - .eq(EnterpriseUser::getUserId, user.getUserId()) - .set(EnterpriseUser::getPassword, newMd5Password) - ); - - if (rows > 0) { - successCount++; - } - } - - System.out.println("========== 重置完成 =========="); - System.out.println("成功: " + successCount + " 条"); - System.out.println("跳过: " + skipCount + " 条"); - System.out.println("新密码(明文): " + NEW_PASSWORD); - } - - - @DisplayName("批量重置 sys_user 指定用户密码为 szsf@zfjd") - @Test - public void resetSysUserPassword() { - // 1. 执法端的测试用户 - List userIds = Arrays.asList( - // TODO: 在此填入需要重置的用户ID - 7897L, 17608416858L,17608416876L, 17608416904L,17608416912L, 17608416926L,17608416927L, 17608416945L,17608417058L,17608642193L,17608502852L,17608515249L,17608497168L - ); - - // 监督端的报表测试用户 -// userIds = Arrays.asList( -// // TODO: 在此填入需要重置的用户ID -// 17608417340L, 17608417451L,17608417716L, 17608614169L,17608614499L,7897L,17608634290L -// ); - - // 2. 根据ID列表查询系统用户 - List userList = sysUserMapper.selectList( - new LambdaQueryWrapper() - .select(SysUser::getUserId, SysUser::getLoginName, SysUser::getSalt) - .in(SysUser::getUserId, userIds) - ); - - System.out.println("查询到系统用户总数: " + userList.size()); - - int successCount = 0; - int skipCount = 0; - - for (SysUser user : userList) { - String loginName = user.getLoginName(); - String salt = user.getSalt(); - - if (loginName == null || loginName.isBlank()) { - System.out.println("跳过: userId=" + user.getUserId() + ", loginName为空"); - skipCount++; - continue; - } - if (salt == null || salt.isBlank()) { - System.out.println("跳过: userId=" + user.getUserId() + ", salt为空"); - skipCount++; - continue; - } - - // 3. 按规则生成新密码: MD5( + newPassword + salt) - String newMd5Password = DigestUtil.md5Hex(loginName + NEW_PASSWORD + salt); - - // 4. 更新密码 - int rows = sysUserMapper.update(null, - new LambdaUpdateWrapper() - .eq(SysUser::getUserId, user.getUserId()) - .set(SysUser::getPassword, newMd5Password) - ); - - if (rows > 0) { - successCount++; - } - } - - System.out.println("========== sys_user 重置完成 =========="); - System.out.println("成功: " + successCount + " 条"); - System.out.println("跳过: " + skipCount + " 条"); - System.out.println("新密码(明文): " + NEW_PASSWORD); - } - -}