Compare commits
	
		
			269 Commits
		
	
	
		
			7824803bf6
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b88a92b7e1 | |||
| fb72063369 | |||
| 9809213a12 | |||
| 87e1cb7473 | |||
| c456ae215f | |||
| 091d7bfc0e | |||
| c9f80fe498 | |||
| 7a3deba52a | |||
| eb015fcecc | |||
| d9fab2a4a2 | |||
| 7f125b4548 | |||
| 88dcecc88c | |||
| 5458329252 | |||
| c4e275f5a8 | |||
| f8f89fd96e | |||
| b8ffa41a30 | |||
| f99cd08d57 | |||
| 45cae080a0 | |||
| 84a8f49e95 | |||
| e725991ece | |||
| c2a06a729c | |||
| 4a5e50a7a2 | |||
| 9b30a7bcec | |||
| ec383e44db | |||
| d3909f131f | |||
| a444d4c953 | |||
| 3c01ec861b | |||
| 365cf00644 | |||
| 4faff3b0bc | |||
| 866f2336c3 | |||
| e4132ea540 | |||
| 53208c36cf | |||
| 8f2a3e6e50 | |||
| b67a7d5370 | |||
| 07509c8e15 | |||
| e6c58a64ac | |||
| abb6b8c13a | |||
| de492728bc | |||
| 82fa732db6 | |||
| 275d640263 | |||
| 7e47b8a74f | |||
| d4301da0ec | |||
| fe5b5473dd | |||
| 0126d44761 | |||
| dbefd88e41 | |||
| 9a3b7ebe54 | |||
| 81be4a862c | |||
| 43f2db9f7e | |||
| abefa90408 | |||
| 08f48b7817 | |||
| 6b8ace60d4 | |||
| b997dd5f00 | |||
| 6174743858 | |||
| 82d55d7188 | |||
| aec5eacd0b | |||
| a320b85965 | |||
| b61a7c153d | |||
| fb9b01cf34 | |||
| 32f134873a | |||
| f4220be9d6 | |||
| 8252fd7216 | |||
| 57855f4307 | |||
| 6784eafe6e | |||
| 0b42c1d6a6 | |||
| 4b37a7327f | |||
| 0287f1e4ce | |||
| 5d8af1cab8 | |||
| 123896f08b | |||
| a8a198b51f | |||
| f00b98714a | |||
| 4ff87f3996 | |||
| 5f3ae0f9f1 | |||
| 786c864a27 | |||
| c61e802b85 | |||
| 9a568799f4 | |||
| 8aa38063bf | |||
| c4a11ec245 | |||
| 169b76589c | |||
| 199f51ea21 | |||
| 23572dfc07 | |||
| 570b0ce316 | |||
| f953a96c36 | |||
| 25c4eee464 | |||
| b209ef1fab | |||
| 77e9f4d9a2 | |||
| e73c808bc3 | |||
| edf0d1a5db | |||
| cc23a308c1 | |||
| bc891327c9 | |||
| 39bedfeb92 | |||
| 56fc4ff83e | |||
| 524ed30728 | |||
| 584304e744 | |||
| 56418600c5 | |||
| 40e57b18cb | |||
| ced6cb219c | |||
| 218ec5ea95 | |||
| 1c601bd68e | |||
| 7d6eba719b | |||
| 8cfc34dbcb | |||
| 23a749973d | |||
| 4b96702dc9 | |||
| a1af8711ef | |||
| 9e8cff931b | |||
| 5bccd71bdc | |||
| 544f35a601 | |||
| f920d4976e | |||
| cdcd665d43 | |||
| 08de61e455 | |||
| 025c3115b7 | |||
| 9e366554b7 | |||
| d934abf0fe | |||
| e16e9133e2 | |||
| d7854a35d7 | |||
| 97e0dd467f | |||
| e58a99e696 | |||
| 0d5a9eb505 | |||
| 45ac1817e1 | |||
| f2d4ff4237 | |||
| a4cc5c14f3 | |||
| 5be571cc30 | |||
| ff656dd046 | |||
| 20574d0037 | |||
| 42cf396e93 | |||
| 2a30b05dd7 | |||
| 4ecee185bf | |||
| 48ab59c67d | |||
| 806e8f3391 | |||
| 61244321a7 | |||
| ff1e613316 | |||
| 03161751fc | |||
| 9ebf4a3e5f | |||
| 3ba13e3ef8 | |||
| 8d3853fe6b | |||
| dbc09a62ea | |||
| f3fa78475c | |||
| c565771283 | |||
| bac8488244 | |||
| a5f661b558 | |||
| ceecec97c7 | |||
| c6ae8a4c00 | |||
| 37d0c776c0 | |||
| f8eea0f63f | |||
| 59c749ab2a | |||
| eeeba2bf4b | |||
| a9ce42101f | |||
| 13de88265f | |||
| a464a1236d | |||
| fce5d0e7fc | |||
| 66ba43d030 | |||
| 1aa77e5eda | |||
| 037016fc13 | |||
| 99f0026552 | |||
| 535262d721 | |||
| fbcb9ca3f2 | |||
| 2a7a20b966 | |||
| 98fdab0dba | |||
| bd71335ae6 | |||
| 7f746fc250 | |||
| 901c8785fe | |||
| e4e9718acb | |||
| 738101f374 | |||
| a7befd7278 | |||
| 52e968c313 | |||
| de9d7d34d6 | |||
| 9f0105d88a | |||
| 80ec8ff86d | |||
| f3473fe5d5 | |||
| 856f3f334b | |||
| 0b216a4101 | |||
| c7338b45ad | |||
| c93b1b752e | |||
| e38074bb25 | |||
| be0f425e14 | |||
| f24e33b1c7 | |||
| 48ea20581c | |||
| e7fa22e573 | |||
| 83b7b32035 | |||
| 6a0be071b8 | |||
| 7bdf8f53b9 | |||
| 03b249afe7 | |||
| 2e5e42fd84 | |||
| f9d9785536 | |||
| a06511e0bf | |||
| 31aa56d34b | |||
| 2b4517760f | |||
| c318d0b10b | |||
| ec54b4ff52 | |||
| 965a0cc90e | |||
| ebddc5c51f | |||
| a323844440 | |||
| 6bcddf50da | |||
| c72275859f | |||
| 9561ee9323 | |||
| b7a52de2d2 | |||
| bfc3ea60fd | |||
| 1acc676b0f | |||
| d6a378f711 | |||
| b4f56b6c79 | |||
| b5d2b3df06 | |||
| 4042b4a441 | |||
| 1fd3da3e2a | |||
| 0d84c49ca4 | |||
| cecfb60e71 | |||
| aec8667edc | |||
| e930cd3b7c | |||
| 373906bde7 | |||
| bca9745e60 | |||
| 6808057111 | |||
| 9f1da9e6c0 | |||
| d8838f8e01 | |||
| d92d37c646 | |||
| 6398a28974 | |||
| cce9ef98d8 | |||
| 467a972a6d | |||
| 00e5f5ede6 | |||
| 1b590bbcbd | |||
| 40d53dffba | |||
| db3af72d5f | |||
| 9604cab4d6 | |||
| 536b25d773 | |||
| e87cbce77a | |||
| f34afd962d | |||
| 98f23e2c02 | |||
| b9507e1fd7 | |||
| 1ceef7f1d1 | |||
| 0fb3fd70a6 | |||
| aab0a5e0b8 | |||
| f9d1a7a489 | |||
| 87e58ca4af | |||
| d6263c6430 | |||
| 253ef81066 | |||
| 2f4bec42a3 | |||
| 3879ce28b6 | |||
| 691b5341c7 | |||
| 4a50dc6ff0 | |||
| d7e4c65afb | |||
| 61b39d89de | |||
| 2497527c77 | |||
| 79f74434f7 | |||
| bd0fe7228b | |||
| 66b45df3fb | |||
| 38d6832f2c | |||
| 8e51d67071 | |||
| 942ca4202a | |||
| 255a202c02 | |||
| 1033ee01fb | |||
| 201f7bd3a7 | |||
| 8a7726e216 | |||
| bc85fe64a4 | |||
| 549fbe92de | |||
| 270071a5f3 | |||
| 09cbb6a8c5 | |||
| f825b9f968 | |||
| f7b9d2f431 | |||
| 742df7279b | |||
| 684209aa36 | |||
| d033b505e2 | |||
| 59623f53a0 | |||
| b9cf8ea3de | |||
| 45761415fa | |||
| 4dca396d11 | |||
| 0efaf12849 | |||
| 51686c212e | |||
| 866c53c6cc | |||
| 809494ffca | |||
| c7dcddb58e | |||
| e7aec88abf | |||
| f820edebb5 | 
| @ -92,7 +92,7 @@ public class SysRegisterService { | ||||
| //        if (!isValid) { | ||||
| //            throw new UserException("注册失败,密码需满足8–18位,包含大小写字母、数字、特殊字符中的至少三种组合"); | ||||
| //        } | ||||
|         // 验证码开关 | ||||
|  | ||||
|         SysUserBo sysUser = new SysUserBo(); | ||||
|         sysUser.setUserName(username); | ||||
|         sysUser.setNickName(username); | ||||
| @ -101,16 +101,24 @@ public class SysRegisterService { | ||||
|         sysUser.setUserType(userType); | ||||
|         sysUser.setEmail(registerBody.getEmail()); | ||||
|  | ||||
|         boolean exist = TenantHelper.dynamic(tenantId, () -> { | ||||
|             return userMapper.exists(new LambdaQueryWrapper<SysUser>() | ||||
|                 .eq(SysUser::getPhonenumber, sysUser.getPhonenumber())); | ||||
|         }); | ||||
|         if (exist) { | ||||
|             throw new UserException("user.register.save.error", username); | ||||
|         } | ||||
|         boolean regFlag = userService.registerUser(sysUser, tenantId); | ||||
|         if (!regFlag) { | ||||
|             throw new UserException("user.register.error"); | ||||
|         SysUser sysUserByPhonenumber = userMapper.selectDefFlagUser(username); | ||||
|         if(sysUserByPhonenumber != null){ | ||||
|             sysUser.setUserId(sysUserByPhonenumber.getUserId()); | ||||
|             userMapper.updateDefFlag(sysUser); | ||||
|             userMapper.updateConstructionUser(sysUserByPhonenumber.getUserId()); | ||||
|         }else { | ||||
|  | ||||
|             boolean exist = TenantHelper.dynamic(tenantId, () -> { | ||||
|                 return userMapper.exists(new LambdaQueryWrapper<SysUser>() | ||||
|                     .eq(SysUser::getPhonenumber, sysUser.getPhonenumber())); | ||||
|             }); | ||||
|             if (exist) { | ||||
|                 throw new UserException("user.register.save.error", username); | ||||
|             } | ||||
|             boolean regFlag = userService.registerUser(sysUser, tenantId); | ||||
|             if (!regFlag) { | ||||
|                 throw new UserException("user.register.error"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success")); | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| # 开发环境配置 | ||||
| server: | ||||
|   # 服务器的HTTP端口,默认为8080 | ||||
|   port: 8899 | ||||
| --- # 监控中心配置 | ||||
| spring.boot.admin.client: | ||||
|   # 增加客户端开关 | ||||
| @ -32,6 +36,12 @@ snail-job: | ||||
|  | ||||
| --- # 数据源配置 | ||||
| spring: | ||||
|   ai: | ||||
|     dashscope: | ||||
|       api-key: sk-8d8df92fcbac4bd2922edba30b0bb8fa | ||||
|       chat: | ||||
|         options: | ||||
|           model: qwen-plus | ||||
|   datasource: | ||||
|     type: com.zaxxer.hikari.HikariDataSource | ||||
|     # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content | ||||
| @ -52,28 +62,38 @@ spring: | ||||
|           url: jdbc:mysql://192.168.110.2:13386/xinnengyuandev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 | ||||
|           username: xinnengyuandev | ||||
|           password: StRWCZdZirysNSs2 | ||||
|           #          url: jdbc:mysql://192.168.110.2:13386/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 | ||||
|           #          username: xinnengyuan | ||||
|           #          password: mEZPC5Sdf3r2HENi | ||||
|           # 从库数据源 | ||||
|         slave: | ||||
|           lazy: true | ||||
|           type: ${spring.datasource.type} | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           url: jdbc:mysql://192.168.110.2:13386/zmkgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: zmkgc | ||||
|           password: nWKDKRNRT48tFBdh | ||||
|         slave1: | ||||
|           lazy: true | ||||
|           type: ${spring.datasource.type} | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           url: jdbc:mysql://192.168.110.2:13386/zmkgprod?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: zmkgprod | ||||
|           password: MaY8nehwWkJriWPm | ||||
|         slave2: | ||||
|           lazy: true | ||||
|           type: ${spring.datasource.type} | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           url: jdbc:mysql://192.168.110.2:13386/zmkgdev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: zmkgdev | ||||
|           password: JhYxREf25AXdy3h8 | ||||
| #        slave: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgc | ||||
|       #          password: nWKDKRNRT48tFBdh | ||||
|       #        slave1: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgprod?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgprod | ||||
|       #          password: MaY8nehwWkJriWPm | ||||
|       #        slave2: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgc | ||||
|       #          password: nWKDKRNRT48tFBdh | ||||
|       #        slave: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgprod?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgprod | ||||
|       #          password: MaY8nehwWkJriWPm | ||||
|       #        oracle: | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: oracle.jdbc.OracleDriver | ||||
| @ -116,7 +136,7 @@ spring.data: | ||||
|     # 端口,默认为6379 | ||||
|     port: 9287 | ||||
|     # 数据库索引 | ||||
|     database: 10 | ||||
|     database: 16 | ||||
|     # redis 密码必须配置 | ||||
|     password: syar23rdsaagdrsa | ||||
|     # 连接超时时间 | ||||
| @ -175,7 +195,7 @@ sms: | ||||
|   # 配置源类型用于标定配置来源(interface,yaml) | ||||
|   config-type: yaml | ||||
|   # 用于标定yml中的配置是否开启短信拦截,接口配置不受此限制 | ||||
|   restricted: true | ||||
|   restricted: false | ||||
|   # 短信拦截限制单手机号每分钟最大发送,只对开启了拦截的配置有效 | ||||
|   minute-max: 1 | ||||
|   # 短信拦截限制单手机号每日最大发送量,只对开启了拦截的配置有效 | ||||
| @ -209,6 +229,30 @@ sms: | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2491776 | ||||
|     config4: | ||||
|       # 质量工单逾期 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534747 | ||||
|     config5: | ||||
|       # 设计图纸 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534750 | ||||
|     config6: | ||||
|       # 安全工单 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534848 | ||||
|  | ||||
|  | ||||
| --- # 三方授权 | ||||
| @ -300,6 +344,7 @@ ys7: | ||||
|   app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e | ||||
|   job: | ||||
|     capture-enabled: false   # 控制是否启用萤石抓拍任务 | ||||
|     device-sync-enabled: false # 控制是否同步萤石设备 | ||||
| #ys7: | ||||
| #  app-key: 081b0d6d5f7f4de8bc5c7fa350fb26ec | ||||
| #  app-secret: caa37b9f60ef02deb57e563bc190e6db | ||||
| @ -319,3 +364,7 @@ qrCode: | ||||
| # 无人机大图 | ||||
| drone: | ||||
|   url: http://192.168.110.2:9512 | ||||
| # 聊天服务 | ||||
| chat: | ||||
|   server: | ||||
|     port: 19099 | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| # 开发环境配置 | ||||
| server: | ||||
|   # 服务器的HTTP端口,默认为8080 | ||||
|   port: 9918 | ||||
| --- # 临时文件存储位置 避免临时文件被系统清理报错 | ||||
| spring.servlet.multipart.location: /ruoyi/server/temp | ||||
|  | ||||
| @ -35,6 +39,12 @@ snail-job: | ||||
|  | ||||
| --- # 数据源配置 | ||||
| spring: | ||||
|   ai: | ||||
|     dashscope: | ||||
|       api-key: xxx | ||||
|       chat: | ||||
|         options: | ||||
|           model: qwen-plus | ||||
|   datasource: | ||||
|     type: com.zaxxer.hikari.HikariDataSource | ||||
|     # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content | ||||
| @ -105,7 +115,7 @@ spring.data: | ||||
|     # 端口,默认为6379 | ||||
|     port: 9287 | ||||
|     # 数据库索引 | ||||
|     database: 6 | ||||
|     database: 17 | ||||
|     # redis 密码必须配置 | ||||
|     password: syar23rdsaagdrsa | ||||
|     # 连接超时时间 | ||||
| @ -164,7 +174,7 @@ sms: | ||||
|   # 配置源类型用于标定配置来源(interface,yaml) | ||||
|   config-type: yaml | ||||
|   # 用于标定yml中的配置是否开启短信拦截,接口配置不受此限制 | ||||
|   restricted: true | ||||
|   restricted: false | ||||
|   # 短信拦截限制单手机号每分钟最大发送,只对开启了拦截的配置有效 | ||||
|   minute-max: 1 | ||||
|   # 短信拦截限制单手机号每日最大发送量,只对开启了拦截的配置有效 | ||||
| @ -183,12 +193,45 @@ sms: | ||||
|       signature: 您的短信签名 | ||||
|       sdk-app-id: 您的sdkAppId | ||||
|     config2: | ||||
|       # 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 | ||||
|       # 登录 | ||||
|       supplier: tencent | ||||
|       access-key-id: 您的accessKey | ||||
|       access-key-secret: 您的accessKeySecret | ||||
|       signature: 您的短信签名 | ||||
|       sdk-app-id: 您的sdkAppId | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2491779 | ||||
|     config3: | ||||
|       # 注册 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2491776 | ||||
|     config4: | ||||
|       # 质量工单逾期 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534747 | ||||
|     config5: | ||||
|       # 设计图纸 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534750 | ||||
|     config6: | ||||
|       # 安全工单 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534848 | ||||
|  | ||||
| --- # 三方授权 | ||||
| justauth: | ||||
| @ -275,8 +318,11 @@ weather: | ||||
| dxf2GeoJson: | ||||
|   file-name: main | ||||
| ys7: | ||||
|   app-key: 3acf9f1a43dc4209841e0893003db0a2 | ||||
|   app-secret: 4bbf3e9394f55d3af6e3af27b2d3db36 | ||||
|   app-key: xxx | ||||
|   app-secret: xxx | ||||
|   job: | ||||
|     capture-enabled: false   # 控制是否启用萤石抓拍任务 | ||||
|     device-sync-enabled: false # 控制是否同步萤石设备 | ||||
| # 斯巴达算法 | ||||
| sparta: | ||||
|   url: http://119.3.204.120:8040 | ||||
| @ -286,10 +332,14 @@ sparta: | ||||
| id-card: | ||||
|   encrypt-key: 7ae260d150a14027d2238a1cf80a48ef | ||||
| recognizer: | ||||
|   url: http://192.168.110.5:50070 | ||||
|   url: http://192.168.110.5:50071 | ||||
|  | ||||
| qrCode: | ||||
|   url: http://xny.yj-3d.com:7171 | ||||
|   url: http://xny.yj-3d.com:7788 | ||||
| # 无人机大图 | ||||
| drone: | ||||
|   url: http://192.168.110.2:9512 | ||||
| # 聊天服务 | ||||
| chat: | ||||
|   server: | ||||
|     port: 18088 | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| # 开发环境配置 | ||||
| server: | ||||
|   # 服务器的HTTP端口,默认为8080 | ||||
|   port: 8899 | ||||
| --- # 临时文件存储位置 避免临时文件被系统清理报错 | ||||
| spring.servlet.multipart.location: /ruoyi/server/temp | ||||
|  | ||||
| @ -35,6 +39,12 @@ snail-job: | ||||
|  | ||||
| --- # 数据源配置 | ||||
| spring: | ||||
|   ai: | ||||
|     dashscope: | ||||
|       api-key: xxx | ||||
|       chat: | ||||
|         options: | ||||
|           model: qwen-plus | ||||
|   datasource: | ||||
|     type: com.zaxxer.hikari.HikariDataSource | ||||
|     # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content | ||||
| @ -55,21 +65,21 @@ spring: | ||||
|           url: jdbc:mysql://192.168.110.2:13386/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: xinnengyuan | ||||
|           password: mEZPC5Sdf3r2HENi | ||||
|         # 从库数据源 | ||||
|         slave: | ||||
|           lazy: true | ||||
|           type: ${spring.datasource.type} | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           url: jdbc:mysql://192.168.110.2:13386/zmkgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: zmkgc | ||||
|           password: nWKDKRNRT48tFBdh | ||||
|         slave1: | ||||
|           lazy: true | ||||
|           type: ${spring.datasource.type} | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           url: jdbc:mysql://192.168.110.2:13386/zmkgprod?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|           username: zmkgprod | ||||
|           password: MaY8nehwWkJriWPm | ||||
|       #        # 从库数据源 | ||||
|       #        slave: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgc | ||||
|       #          password: nWKDKRNRT48tFBdh | ||||
|       #        slave1: | ||||
|       #          lazy: true | ||||
|       #          type: ${spring.datasource.type} | ||||
|       #          driverClassName: com.mysql.cj.jdbc.Driver | ||||
|       #          url: jdbc:mysql://192.168.110.2:13386/zmkgprod?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true | ||||
|       #          username: zmkgprod | ||||
|       #          password: MaY8nehwWkJriWPm | ||||
|       #        # 从库数据源 | ||||
|       #        slave: | ||||
|       #          lazy: true | ||||
| @ -179,7 +189,7 @@ sms: | ||||
|   # 配置源类型用于标定配置来源(interface,yaml) | ||||
|   config-type: yaml | ||||
|   # 用于标定yml中的配置是否开启短信拦截,接口配置不受此限制 | ||||
|   restricted: true | ||||
|   restricted: false | ||||
|   # 短信拦截限制单手机号每分钟最大发送,只对开启了拦截的配置有效 | ||||
|   minute-max: 1 | ||||
|   # 短信拦截限制单手机号每日最大发送量,只对开启了拦截的配置有效 | ||||
| @ -213,6 +223,30 @@ sms: | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2491776 | ||||
|     config4: | ||||
|       # 质量工单逾期 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534747 | ||||
|     config5: | ||||
|       # 设计图纸 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534750 | ||||
|     config6: | ||||
|       # 安全工单 | ||||
|       supplier: tencent | ||||
|       access-key-id: AKIDb3JK5dx4wa0DCxWqvxlKejvysZ3ITVJv | ||||
|       access-key-secret: c5LPFsJI8k7GDxTkoeFj4A1ukQr66rPi | ||||
|       signature: 重庆远界大数据研究院 | ||||
|       sdk-app-id: 1401018866 | ||||
|       template-id: 2534848 | ||||
|  | ||||
| --- # 三方授权 | ||||
| justauth: | ||||
| @ -297,12 +331,13 @@ weather: | ||||
|   api-host: n35rk53njv.re.qweatherapi.com | ||||
| # dxf转 geojson 执行文件名 | ||||
| dxf2GeoJson: | ||||
|   file-name: main.exe | ||||
|   file-name: main | ||||
| ys7: | ||||
|   app-key: 3acf9f1a43dc4209841e0893003db0a2 | ||||
|   app-secret: 4bbf3e9394f55d3af6e3af27b2d3db36 | ||||
|   app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e | ||||
|   job: | ||||
|     capture-enabled: true   # 控制是否启用萤石抓拍任务 | ||||
|     device-sync-enabled: true # 控制是否同步萤石设备 | ||||
| # 斯巴达算法 | ||||
| sparta: | ||||
|   url: http://119.3.204.120:8040 | ||||
| @ -319,3 +354,7 @@ qrCode: | ||||
| # 无人机大图 | ||||
| drone: | ||||
|   url: http://192.168.110.2:9512 | ||||
| # 聊天服务 | ||||
| chat: | ||||
|   server: | ||||
|     port: 19099 | ||||
|  | ||||
| @ -22,7 +22,7 @@ captcha: | ||||
| # 开发环境配置 | ||||
| server: | ||||
|   # 服务器的HTTP端口,默认为8080 | ||||
|   port: 8899 | ||||
|   #  port: 8899 | ||||
|   servlet: | ||||
|     # 应用的访问路径 | ||||
|     context-path: / | ||||
| @ -106,6 +106,10 @@ sa-token: | ||||
|   is-share: false | ||||
|   # jwt秘钥 | ||||
|   jwt-secret-key: abcdefghijklmnopqrstuvwxyz | ||||
|   # token有效期,单位s 默认30天, -1代表永不过期 | ||||
|   timeout: 2592000 | ||||
|   # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 | ||||
|   active-timeout: 86400 | ||||
|  | ||||
| # security配置 | ||||
| security: | ||||
| @ -129,6 +133,8 @@ security: | ||||
|     - /resource/oss/upload | ||||
|     # todo 仅测试 | ||||
|     - /facility/matrix/** | ||||
|     - /hat/device/data | ||||
|     - /websocket/ue | ||||
|  | ||||
| # 多租户配置 | ||||
| tenant: | ||||
| @ -252,6 +258,8 @@ springdoc: | ||||
|       packages-to-scan: org.dromara.design | ||||
|     - group: 13.工作流模块 | ||||
|       packages-to-scan: org.dromara.workflow | ||||
|     - group: 14.合同模块 | ||||
|       packages-to-scan: org.dromara.ctr | ||||
|     - group: 15.无人机模块 | ||||
|       packages-to-scan: org.dromara.drone | ||||
|     - group: 20.代码生成模块 | ||||
| @ -274,12 +282,16 @@ springdoc: | ||||
|       packages-to-scan: org.dromara.gps | ||||
|     - group: 24.招标模块 | ||||
|       packages-to-scan: org.dromara.tender | ||||
|     - group: 25.app版本模块 | ||||
|     - group: 29.app版本模块 | ||||
|       packages-to-scan: org.dromara.app | ||||
|     - group: 25.数据迁移模块 | ||||
|       packages-to-scan: org.dromara.transferData | ||||
|     - group: 26.netty消息模块 | ||||
|       packages-to-scan: org.dromara.websocket | ||||
|     - group: 27.新中大模块 | ||||
|       packages-to-scan: org.dromara.xzd | ||||
|     - group: 28.车辆模块 | ||||
|       packages-to-scan: org.dromara.vehicle | ||||
| # knife4j的增强配置,不需要增强可以不配 | ||||
| knife4j: | ||||
|   enable: true | ||||
| @ -295,6 +307,15 @@ xss: | ||||
|     - /system/notice | ||||
|     - /warm-flow/save-xml | ||||
|     - /project/project | ||||
|     - /xzd/contractDetails/** | ||||
|     - /xzd/contractChange/** | ||||
|     - /xzd/comprehensive/csContractChange/** | ||||
|     - /xzd/comprehensive/csContractInformation/** | ||||
|     - /xzd/hetongbiangeng/** | ||||
|     - /xzd/fenbaohetongjungong/** | ||||
|     - /xzd/fenbaohetongbiangg/** | ||||
|     - /xzd/fenbaohetongxinxi/** | ||||
|     - /xzd/contractManagement/** | ||||
|  | ||||
| # 全局线程池相关配置 | ||||
| # 如使用JDK21请直接使用虚拟线程 不要开启此配置 | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								xinnengyuan/ruoyi-admin/src/main/resources/template/设计更改通知单.docx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								xinnengyuan/ruoyi-admin/src/main/resources/template/设计更改通知单.docx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								xinnengyuan/ruoyi-admin/src/main/resources/template/设计验证表.docx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								xinnengyuan/ruoyi-admin/src/main/resources/template/设计验证表.docx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -3,6 +3,9 @@ package org.dromara.test; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.io.FileUtil; | ||||
| import cn.hutool.core.util.IdcardUtil; | ||||
| import cn.hutool.http.HttpRequest; | ||||
| import cn.hutool.http.HttpResponse; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.IdWorker; | ||||
| @ -22,6 +25,13 @@ import org.dromara.facility.service.IFacMatrixService; | ||||
| import org.dromara.facility.service.IFacPhotovoltaicPanelPartsService; | ||||
| import org.dromara.facility.service.IFacPhotovoltaicPanelService; | ||||
| import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult; | ||||
| import org.dromara.manager.ys7manager.Ys7Constant; | ||||
| import org.dromara.manager.ys7manager.Ys7Manager; | ||||
| import org.dromara.manager.ys7manager.vo.Ys7ResponseVo; | ||||
| import org.dromara.other.domain.OthYs7Device; | ||||
| import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture; | ||||
| import org.dromara.other.service.IOthYs7DeviceImgService; | ||||
| import org.dromara.other.service.IOthYs7DeviceService; | ||||
| import org.dromara.out.domain.OutConstructionValue; | ||||
| import org.dromara.out.domain.OutConstructionValueRange; | ||||
| import org.dromara.out.service.IOutConstructionValueRangeService; | ||||
| @ -47,6 +57,8 @@ import java.time.LocalDate; | ||||
| import java.time.temporal.TemporalAdjusters; | ||||
| import java.util.*; | ||||
| import java.util.function.Function; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
| @ -101,6 +113,15 @@ public class DemoTest { | ||||
|     @Resource | ||||
|     private IOutConstructionValueService constructionValueService; | ||||
|  | ||||
|     @Resource | ||||
|     private IOthYs7DeviceService ys7DeviceService; | ||||
|  | ||||
|     @Resource | ||||
|     private IOthYs7DeviceImgService ys7DeviceImgService; | ||||
|  | ||||
|     @Resource | ||||
|     private Ys7Manager ys7Manager; | ||||
|  | ||||
|  | ||||
|     @Test | ||||
|     void testConstructionValue() { | ||||
| @ -114,7 +135,7 @@ public class DemoTest { | ||||
|         log.info("执行定时任务:同步 {}至{} 计划详情到施工产值", lastMonday, lastSunday); | ||||
|         Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(lastMonday, lastSunday, null);*/ | ||||
|         LocalDate start = LocalDate.of(2024, 1, 1); // 起始时间(2024-01-01) | ||||
|         LocalDate end = LocalDate.of(2025, 9, 15); // 截止时间(2025-09-15) | ||||
|         LocalDate end = LocalDate.of(2025, 10, 20); // 截止时间(2025-09-15) | ||||
|  | ||||
|         // 如果起始不是周一,调整到当周的周一 | ||||
|         if (start.getDayOfWeek() != DayOfWeek.MONDAY) { | ||||
| @ -134,7 +155,7 @@ public class DemoTest { | ||||
|                 .ge(PgsProgressPlanDetail::getDate, monday) | ||||
|                 .le(PgsProgressPlanDetail::getDate, sunday) | ||||
|                 .ne(PgsProgressPlanDetail::getFinishedNumber, BigDecimal.ZERO) | ||||
|                 .eq(PgsProgressPlanDetail::getStatus, "1") | ||||
| //                .eq(PgsProgressPlanDetail::getStatus, "1") | ||||
|                 .list(); | ||||
|             if (CollUtil.isEmpty(planDetailList)) { | ||||
|                 // 下一周 | ||||
| @ -229,8 +250,8 @@ public class DemoTest { | ||||
|                     value.setOutValue(constructionValue); | ||||
|                     value.setOwnerValue(ownerValue); | ||||
|                     // 统计总产值 | ||||
|                     allConstructionValue = allConstructionValue.add(constructionValue).setScale(4, RoundingMode.HALF_UP); | ||||
|                     allOwnerValue = allOwnerValue.add(ownerValue).setScale(4, RoundingMode.HALF_UP); | ||||
|                     allConstructionValue = allConstructionValue.add(constructionValue); | ||||
|                     allOwnerValue = allOwnerValue.add(ownerValue); | ||||
|                     // 添加需要修改状态的计划详情 | ||||
|                     PgsProgressPlanDetail update = new PgsProgressPlanDetail(); | ||||
|                     update.setId(planDetail.getId()); | ||||
| @ -238,8 +259,8 @@ public class DemoTest { | ||||
|                     updateList.add(update); | ||||
|                     saveList.add(value); | ||||
|                 } | ||||
|                 range.setOutValue(allConstructionValue); | ||||
|                 range.setOwnerValue(allOwnerValue); | ||||
|                 range.setOutValue(allConstructionValue.setScale(4, RoundingMode.HALF_UP)); | ||||
|                 range.setOwnerValue(allOwnerValue.setScale(4, RoundingMode.HALF_UP)); | ||||
|                 // 如果产值都为0,则不保存 | ||||
|                 if (allConstructionValue.compareTo(BigDecimal.ZERO) == 0 && allOwnerValue.compareTo(BigDecimal.ZERO) == 0) { | ||||
|                     return null; | ||||
| @ -505,4 +526,66 @@ public class DemoTest { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void openSxtLx() { | ||||
|         String token = ys7Manager.getToken(); | ||||
|         List<OthYs7Device> list = ys7DeviceService.list(); | ||||
|         for (OthYs7Device othYs7Device : list) { | ||||
|             HashMap<String, Object> paramMap = new HashMap<>(); | ||||
|             paramMap.put("accessToken", token); | ||||
|             paramMap.put("deviceSerial", othYs7Device.getDeviceSerial()); | ||||
|             paramMap.put("enable", 1); | ||||
|             String errorMsg = "Ys7 Token 请求失败"; | ||||
|             try (HttpResponse response = HttpRequest.post(Ys7Constant.setDeviceVideoUrlByPost) | ||||
|                 .form(paramMap) | ||||
|                 .execute()) { | ||||
|                 if (!response.isOk()) { | ||||
|                     log.error("{}:{}", errorMsg, response.getStatus()); | ||||
| //                    throw new ServiceException(errorMsg + response.getStatus()); | ||||
|                 } | ||||
|                 String body = response.body(); | ||||
|                 Ys7ResponseVo responseVo = JSONUtil.toBean(body, Ys7ResponseVo.class); | ||||
|                 if (!responseVo.getCode().equals("200")) { | ||||
|                     log.error("{},状态码:{},{}", errorMsg, responseVo.getCode(), responseVo.getMsg()); | ||||
| //                    throw new ServiceException(errorMsg + responseVo.getMsg()); | ||||
|                 } | ||||
|                 log.info("Ys7 Token 请求成功:{}", body); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Test | ||||
|     void capturePic() { | ||||
|         List<String> urlList = List.of( | ||||
|             "http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/23/db8a379b456142459852b654f20d5f97.png", | ||||
|             "http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/23/913dbcf0f7244c8b878e84b5525bec4b.png", | ||||
|             "http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/23/2b904765f03f40b2ad0ddbf6ddeadb45.png" | ||||
|         ); | ||||
|         for (String url : urlList) { | ||||
|             Pattern pattern = Pattern.compile(".*/device/img/([^/]+)/.*"); | ||||
|             Matcher matcher = pattern.matcher(url); | ||||
|             OthYs7Device ys7Device = ys7DeviceService.lambdaQuery() | ||||
|                 .eq(OthYs7Device::getDeviceSerial, "GA1730672") | ||||
|                 .last("limit 1") | ||||
|                 .one(); | ||||
|             if (ys7Device == null) { | ||||
|                 throw new ServiceException("设备不存在", HttpStatus.ERROR); | ||||
|             } | ||||
|             String deviceSerial = ys7Device.getDeviceSerial(); | ||||
|             // 如果没有预置位,则直接对默认通道抓图 | ||||
|             OthYs7DeviceImgCreateByCapture img = new OthYs7DeviceImgCreateByCapture(); | ||||
|             img.setProjectId(ys7Device.getProjectId()); | ||||
|             img.setDeviceSerial(deviceSerial); | ||||
|             img.setDeviceName(ys7Device.getDeviceName()); | ||||
| //        String url = "http://xny.yj-3d.com:9000/xinnengyuan/ys7/device/img/GA1044315/2025-10-13_859fdfb7dde540608356f29cb9e3d63e.jpg"; | ||||
| //            String url = "http://xny.yj-3d.com:9000/xinnengyuan/ys7/device/img/GA1044315/2025-10-12_2801707255b84004acb5fee2a75299b2.jpg"; | ||||
|             img.setCreateTime(new Date()); | ||||
|             img.setUrl(url); | ||||
|             log.info("图片:{},识别中", url); | ||||
|             ys7DeviceImgService.saveCapturePic(List.of(img)); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,99 @@ | ||||
| package org.dromara.test; | ||||
|  | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.materials.domain.MatMaterialIssue; | ||||
| import org.dromara.materials.domain.MatMaterialReceive; | ||||
| import org.dromara.materials.domain.MatMaterials; | ||||
| import org.dromara.materials.domain.MatMaterialsInventory; | ||||
| import org.dromara.materials.domain.enums.MatMaterialsInventoryOutPutEnum; | ||||
| import org.dromara.materials.service.IMatMaterialIssueService; | ||||
| import org.dromara.materials.service.IMatMaterialReceiveService; | ||||
| import org.dromara.materials.service.IMatMaterialsInventoryService; | ||||
| import org.dromara.materials.service.IMatMaterialsService; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-30 15:58 | ||||
|  */ | ||||
| @Slf4j | ||||
| @SpringBootTest | ||||
| public class MaterialsTest { | ||||
|  | ||||
|     /** | ||||
|      * 长顺项目id | ||||
|      */ | ||||
|     private static final Long PROJECT_ID = 1897161054676336641L; | ||||
|  | ||||
|     @Resource | ||||
|     private IMatMaterialsService materialsService; | ||||
|  | ||||
|     @Resource | ||||
|     private IMatMaterialsInventoryService materialsInventoryService; | ||||
|  | ||||
|     @Resource | ||||
|     private IMatMaterialReceiveService materialReceiveService; | ||||
|  | ||||
|     @Resource | ||||
|     private IMatMaterialIssueService materialIssueService; | ||||
|  | ||||
|     @Test | ||||
|     void test() { | ||||
|         List<MatMaterials> materials = materialsService.lambdaQuery() | ||||
|             .eq(MatMaterials::getProjectId, PROJECT_ID) | ||||
|             .list(); | ||||
|         Set<Long> materialIds = materials.stream().map(MatMaterials::getId).collect(Collectors.toSet()); | ||||
|         List<MatMaterialsInventory> inventoryList = materialsInventoryService.lambdaQuery() | ||||
|             .in(MatMaterialsInventory::getMaterialsId, materialIds) | ||||
|             .eq(MatMaterialsInventory::getOutPut, MatMaterialsInventoryOutPutEnum.OUT.getValue()) | ||||
|             .list(); | ||||
|         Map<String, List<MatMaterials>> map = materials.stream() | ||||
|             .collect(Collectors.groupingBy(MatMaterials::getFormCode)); | ||||
|  | ||||
|  | ||||
|         for (MatMaterials material : materials) { | ||||
|             String formCode = material.getFormCode(); | ||||
|             // 查看入库数据 | ||||
|             MatMaterialReceive receive = materialReceiveService.lambdaQuery() | ||||
|                 .eq(MatMaterialReceive::getFormCode, formCode) | ||||
|                 .one(); | ||||
|             // 查看出库数据 | ||||
| /*            List<MatMaterialsInventory> inventoryList = materialsInventoryService.lambdaQuery() | ||||
|                 .eq(MatMaterialsInventory::getMaterialsId, material.getId()) | ||||
|                 .eq(MatMaterialsInventory::getOutPut, MatMaterialsInventoryOutPutEnum.OUT.getValue()) | ||||
|                 .list(); | ||||
|             if (CollUtil.isEmpty(inventoryList)) { | ||||
|                 continue; | ||||
|             }*/ | ||||
|             // 创建领料出库数据 | ||||
|             List<MatMaterialIssue> issueList = inventoryList.stream().map(inventory -> { | ||||
|                 MatMaterialIssue issue = new MatMaterialIssue(); | ||||
|                 issue.setProjectId(PROJECT_ID); | ||||
|                 issue.setMaterialSource("2"); | ||||
|                 issue.setFormCode(receive.getFormCode()); | ||||
|                 issue.setProjectName(receive.getProjectName()); | ||||
|                 issue.setMaterialName(receive.getMaterialName()); | ||||
|                 issue.setOrderingUnit(receive.getOrderingUnit()); | ||||
|                 issue.setSupplierUnit(receive.getSupplierUnit()); | ||||
|                 issue.setIssueUnit(inventory.getRecipient()); | ||||
|                 issue.setIssueUnitId(inventory.getRecipientId()); | ||||
|                 issue.setShipper(inventory.getShipper()); | ||||
| //                issue.setStorageUnit(); | ||||
|                 issue.setCertCount(0); | ||||
|                 issue.setReportCount(0); | ||||
|                 issue.setTechDocCount(0); | ||||
|                 issue.setLicenseCount(0); | ||||
|                 log.info("领料出库数据:{}", issue); | ||||
|                 log.info("============================="); | ||||
|                 return issue; | ||||
|             }).toList(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -23,7 +23,7 @@ public class RecognizerTest { | ||||
|  | ||||
|     @Test | ||||
|     void test() { | ||||
|         RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PHO)); | ||||
|         RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PANEL)); | ||||
|         log.info("recognize: {}", recognize); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,17 @@ | ||||
| package org.dromara.test; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import jakarta.annotation.Resource; | ||||
| import org.dromara.common.core.utils.MapstructUtils; | ||||
| import org.dromara.safety.domain.dto.violationrecord.HseViolationRecordCreateDto; | ||||
| import org.dromara.safety.service.IHseViolationRecordService; | ||||
| import org.dromara.system.domain.SysMenu; | ||||
| import org.dromara.system.domain.vo.SysMenuVo; | ||||
| import org.dromara.system.mapper.SysMenuMapper; | ||||
| import org.dromara.system.service.ISysMenuService; | ||||
| import org.hamcrest.core.Is; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| @ -20,6 +28,9 @@ public class ViolationRecordTest { | ||||
|     @Resource | ||||
|     private IHseViolationRecordService violationRecordService; | ||||
|  | ||||
|     @Autowired | ||||
|     private SysMenuMapper sysMenuMapper; | ||||
|  | ||||
|     @Test | ||||
|     void test() { | ||||
|         List<HseViolationRecordCreateDto> list = new ArrayList<>(); | ||||
| @ -55,4 +66,26 @@ public class ViolationRecordTest { | ||||
|         list.add(dto5); | ||||
|         violationRecordService.insertByMonitor(list); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void contextLoads() { | ||||
|         SysMenuVo sysMenuVo = sysMenusByList(1972500768346673154L); | ||||
|         System.out.println(sysMenuVo.toString()); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     SysMenuVo sysMenusByList(Long id) { | ||||
|         SysMenuVo sysMenus = new SysMenuVo(); | ||||
|         List<SysMenu> res = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, id)); | ||||
|         if (res != null && res.size() > 0 ) { | ||||
|             sysMenus.setChildren(MapstructUtils.convert(res, SysMenuVo.class)); | ||||
|             res.forEach(sysMenu -> { | ||||
|                 sysMenusByList(sysMenu.getMenuId()); | ||||
|             }); | ||||
|         } | ||||
|         return sysMenus; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,32 @@ | ||||
| package org.dromara.common.core.domain.vo; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
|  | ||||
|  | ||||
| @Data | ||||
| public class XzdCustomerSupplierVos  implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|  | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1、供应商,2、客户) | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 供应商-客户id | ||||
|      */ | ||||
|     private Long cSId; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdCsContractInformationService { | ||||
|  | ||||
|     String selectNameByIds(String ids); | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| import org.dromara.common.core.domain.vo.XzdCustomerSupplierVos; | ||||
|  | ||||
| public interface XzdCustomerSupplierService { | ||||
|  | ||||
|     /** | ||||
|      * 查询供应商-客户中间 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      * @return 供应商-客户中间 | ||||
|      */ | ||||
|     XzdCustomerSupplierVos queryByIdone(Long id); | ||||
| } | ||||
| @ -0,0 +1,8 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdCustomerinformationService { | ||||
|  | ||||
|     String selectNmaeByIds(String id); | ||||
|  | ||||
|     String selectNmaeById(Long id); | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdJsCgJungonService { | ||||
|  | ||||
|     String selectNameByIds(String ids); | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdProjectService { | ||||
|  | ||||
|     String selectNmaeByIds(String ids); | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdPurchaseContractInformationService { | ||||
|     String selectNameByIds(String ids); | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdSupplierInfoService { | ||||
|  | ||||
|     String selectNmaeByIds(String ids); | ||||
|  | ||||
|     String selectNmaeById(Long id); | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| package org.dromara.common.core.service; | ||||
|  | ||||
| public interface XzdSupplierOpenBankService { | ||||
|  | ||||
|     String selectNameByIds(String ids); | ||||
| } | ||||
| @ -77,7 +77,7 @@ public class RedisUtils { | ||||
|     public static <T> void publish(String channelKey, T msg, Consumer<T> consumer) { | ||||
|         RTopic topic = CLIENT.getTopic(channelKey); | ||||
|         topic.publish(msg); | ||||
|         System.out.println("发布通道消息---------"+msg.toString()); | ||||
| //        System.out.println("发布通道消息---------"+msg.toString()); | ||||
|         consumer.accept(msg); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -37,4 +37,36 @@ public interface TransConstant { | ||||
|      */ | ||||
|     String PROJECT_ID_TO_NAME = "project_id_to_name"; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 客户id转名称 | ||||
|      */ | ||||
|     String XZD_KHXX_ID_TO_NAME = "khxx_id_to_name"; | ||||
|  | ||||
|  | ||||
| //    /** | ||||
| //     * 供应商id转名称 | ||||
| //     */ | ||||
| //    String XZD_KHXX_ID_TO_NAME = "gysxx_id_to_name"; | ||||
|  | ||||
|     /** | ||||
|      * 新中大项目id转名称 | ||||
|      */ | ||||
|     String XZD_PROJECT_ID_TO_NAME = "xzd_project_id_to_name"; | ||||
|     /** | ||||
|      * 采购合同id转名称 | ||||
|      */ | ||||
|     String XZD_PURCHASE_CONTRACT_ID_TO_NAME = "xzd_purchase_contract_id_to_name"; | ||||
|     /** | ||||
|      * 综合服务合同id转名称 | ||||
|      */ | ||||
|     String XZD_CS_CONTRACT_INFORMATION_ID_TO_NAME = "xzd_cs_contract_information_id_to_name"; | ||||
|     /** | ||||
|      * 结算-采购合同竣工结算id转名称 | ||||
|      */ | ||||
|     String XZD_JS_CG_JUNGON_ID_TO_NAME = "xzd_js_cg_jungon_id_to_name"; | ||||
|     /** | ||||
|      * 新中大供应商信息-开户银行id转银行名称 | ||||
|      */ | ||||
|     String XZD_SUPPLIER_OPEN_BANK_ID_TO_NAME = "xzd_supplier_open_bank_id_to_name"; | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,26 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdCsContractInformationService; | ||||
| import org.dromara.common.core.service.XzdPurchaseContractInformationService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_CS_CONTRACT_INFORMATION_ID_TO_NAME) | ||||
| public class XzdCsContractInformationImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdCsContractInformationService xzdCsContractInformationService; | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdCsContractInformationService.selectNameByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdCsContractInformationService.selectNameByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdCustomerinformationService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_KHXX_ID_TO_NAME) | ||||
| public class XzdCustomerinformationImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdCustomerinformationService xzdCustomerinformationService; | ||||
|  | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdCustomerinformationService.selectNmaeByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdCustomerinformationService.selectNmaeByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdJsCgJungonService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_JS_CG_JUNGON_ID_TO_NAME) | ||||
| public class XzdJsCgJungonImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdJsCgJungonService xzdJsCgJungonService; | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdJsCgJungonService.selectNameByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdJsCgJungonService.selectNameByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdProjectService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_PROJECT_ID_TO_NAME) | ||||
| public class XzdProjectImpl implements TranslationInterface<String> { | ||||
|     private final XzdProjectService xzdProjectService; | ||||
|  | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdProjectService.selectNmaeByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdProjectService.selectNmaeByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
|  | ||||
| import org.dromara.common.core.service.XzdPurchaseContractInformationService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_PURCHASE_CONTRACT_ID_TO_NAME) | ||||
| public class XzdPurchaseContractInformationImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdPurchaseContractInformationService xzdCustomerinformationService; | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdCustomerinformationService.selectNameByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdCustomerinformationService.selectNameByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdSupplierInfoService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| //@TranslationType(type = TransConstant.XZD_KHXX_ID_TO_NAME) | ||||
| public class XzdSupplierInfoImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdSupplierInfoService xzdSupplierInfoService; | ||||
|  | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdSupplierInfoService.selectNmaeByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdSupplierInfoService.selectNmaeByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.dromara.common.translation.core.impl; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import org.dromara.common.core.service.XzdSupplierOpenBankService; | ||||
| import org.dromara.common.translation.annotation.TranslationType; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.common.translation.core.TranslationInterface; | ||||
|  | ||||
| @AllArgsConstructor | ||||
| @TranslationType(type = TransConstant.XZD_SUPPLIER_OPEN_BANK_ID_TO_NAME) | ||||
| public class XzdSupplierOpenBankImpl implements TranslationInterface<String> { | ||||
|  | ||||
|     private final XzdSupplierOpenBankService xzdSupplierOpenBankService; | ||||
|     @Override | ||||
|     public String translation(Object key, String other) { | ||||
|         if (key instanceof String ids) { | ||||
|             return xzdSupplierOpenBankService.selectNameByIds(ids); | ||||
|         } else if (key instanceof Long id) { | ||||
|             return xzdSupplierOpenBankService.selectNameByIds(id.toString()); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -5,3 +5,10 @@ org.dromara.common.translation.core.impl.OssUrlTranslationImpl | ||||
| org.dromara.common.translation.core.impl.UserNameTranslationImpl | ||||
| org.dromara.common.translation.core.impl.NicknameTranslationImpl | ||||
| org.dromara.common.translation.core.impl.ProjectNameTranslationImpl | ||||
| org.dromara.common.translation.core.impl.XzdCustomerinformationImpl | ||||
| org.dromara.common.translation.core.impl.XzdProjectImpl | ||||
| org.dromara.common.translation.core.impl.XzdPurchaseContractInformationImpl | ||||
| org.dromara.common.translation.core.impl.XzdSupplierInfoImpl | ||||
| org.dromara.common.translation.core.impl.XzdJsCgJungonImpl | ||||
| org.dromara.common.translation.core.impl.XzdCsContractInformationImpl | ||||
| org.dromara.common.translation.core.impl.XzdSupplierOpenBankImpl | ||||
|  | ||||
| @ -13,6 +13,7 @@ import org.springframework.web.socket.WebSocketHandler; | ||||
| import org.springframework.web.socket.config.annotation.EnableWebSocket; | ||||
| import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | ||||
| import org.springframework.web.socket.server.HandshakeInterceptor; | ||||
| import org.springframework.web.socket.server.standard.ServerEndpointExporter; | ||||
|  | ||||
| /** | ||||
|  * WebSocket 配置 | ||||
|  | ||||
| @ -26,7 +26,7 @@ public class WebSocketTopicListener implements ApplicationRunner, Ordered { | ||||
|     public void run(ApplicationArguments args) throws Exception { | ||||
|         // 订阅WebSocket消息 | ||||
|         WebSocketUtils.subscribeMessage((message) -> { | ||||
|             log.info("WebSocket主题订阅收到消息session keys={} message={}", message.getSessionKeys(), message.getMessage()); | ||||
| //            log.info("WebSocket主题订阅收到消息session keys={} message={}", message.getSessionKeys(), message.getMessage()); | ||||
|             // 如果key不为空就按照key发消息 如果为空就群发 | ||||
|             if (CollUtil.isNotEmpty(message.getSessionKeys())) { | ||||
|                 message.getSessionKeys().forEach(key -> { | ||||
|  | ||||
| @ -69,8 +69,8 @@ public class WebSocketUtils { | ||||
|             broadcastMessage.setMessage(webSocketMessage.getMessage()); | ||||
|             broadcastMessage.setSessionKeys(unsentSessionKeys); | ||||
|             RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> { | ||||
|                 log.info(" WebSocket发送主题订阅消息topic:{} session keys:{} message:{}", | ||||
|                     WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage()); | ||||
| //                log.info(" WebSocket发送主题订阅消息topic:{} session keys:{} message:{}", | ||||
| //                    WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage()); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| @ -84,7 +84,7 @@ public class WebSocketUtils { | ||||
|         WebSocketMessageDto broadcastMessage = new WebSocketMessageDto(); | ||||
|         broadcastMessage.setMessage(message); | ||||
|         RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> { | ||||
|             log.info("WebSocket发送主题订阅消息topic:{} message:{}", WEB_SOCKET_TOPIC, message); | ||||
| //            log.info("WebSocket发送主题订阅消息topic:{} message:{}", WEB_SOCKET_TOPIC, message); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -15,21 +15,54 @@ | ||||
|         system系统模块 | ||||
|     </description> | ||||
|  | ||||
|     <dependencyManagement> | ||||
|         <dependencies> | ||||
|             <dependency> | ||||
|                 <groupId>com.alibaba.cloud.ai</groupId> | ||||
|                 <artifactId>spring-ai-alibaba-bom</artifactId> | ||||
|                 <version>1.0.0.2</version> | ||||
|                 <type>pom</type> | ||||
|                 <scope>import</scope> | ||||
|             </dependency> | ||||
|         </dependencies> | ||||
|     </dependencyManagement> | ||||
|  | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>com.alibaba.cloud.ai</groupId> | ||||
|             <artifactId>spring-ai-alibaba-starter-dashscope</artifactId> | ||||
|         </dependency> | ||||
|         <!-- Java WebSocket 标准API --> | ||||
|         <!--        <dependency>--> | ||||
|         <!--            <groupId>javax.websocket</groupId>--> | ||||
|         <!--            <artifactId>javax.websocket-api</artifactId>--> | ||||
|         <!--            <version>1.1</version>--> | ||||
|         <!--            <scope>provided</scope>--> | ||||
|         <!--        </dependency>--> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-websocket</artifactId> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <groupId>org.springframework.boot</groupId> | ||||
|                     <artifactId>spring-boot-starter-tomcat</artifactId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|  | ||||
| <!--        <dependency>--> | ||||
| <!--            <groupId>com.drewnoakes</groupId>--> | ||||
| <!--            <artifactId>metadata-extractor</artifactId>--> | ||||
| <!--            <version>2.18.0</version>--> | ||||
| <!--        </dependency>--> | ||||
|         <!--        <dependency>--> | ||||
|         <!--            <groupId>com.drewnoakes</groupId>--> | ||||
|         <!--            <artifactId>metadata-extractor</artifactId>--> | ||||
|         <!--            <version>2.18.0</version>--> | ||||
|         <!--        </dependency>--> | ||||
|  | ||||
|  | ||||
| <!--        <dependency>--> | ||||
| <!--            <groupId>technology.tabula</groupId>--> | ||||
| <!--            <artifactId>tabula</artifactId>--> | ||||
| <!--            <version>1.0.4</version>--> | ||||
| <!--        </dependency>--> | ||||
|         <!--        <dependency>--> | ||||
|         <!--            <groupId>technology.tabula</groupId>--> | ||||
|         <!--            <artifactId>tabula</artifactId>--> | ||||
|         <!--            <version>1.0.4</version>--> | ||||
|         <!--        </dependency>--> | ||||
|  | ||||
|  | ||||
|         <!-- JSON解析(FastJSON) --> | ||||
| @ -101,19 +134,18 @@ | ||||
|         </dependency> | ||||
|  | ||||
|  | ||||
|  | ||||
|         <!--  支持中文字体  --> | ||||
| <!--        <dependency>--> | ||||
| <!--            <groupId>com.itextpdf</groupId>--> | ||||
| <!--            <artifactId>itext-asian</artifactId>--> | ||||
| <!--            <version>5.2.0</version>--> | ||||
| <!--        </dependency>--> | ||||
| <!--        <!–  iText  –>--> | ||||
| <!--        <dependency>--> | ||||
| <!--            <groupId>com.itextpdf</groupId>--> | ||||
| <!--            <artifactId>itextpdf</artifactId>--> | ||||
| <!--            <version>5.5.13.3</version>--> | ||||
| <!--        </dependency>--> | ||||
|         <!--        <dependency>--> | ||||
|         <!--            <groupId>com.itextpdf</groupId>--> | ||||
|         <!--            <artifactId>itext-asian</artifactId>--> | ||||
|         <!--            <version>5.2.0</version>--> | ||||
|         <!--        </dependency>--> | ||||
|         <!--        <!–  iText  –>--> | ||||
|         <!--        <dependency>--> | ||||
|         <!--            <groupId>com.itextpdf</groupId>--> | ||||
|         <!--            <artifactId>itextpdf</artifactId>--> | ||||
|         <!--            <version>5.5.13.3</version>--> | ||||
|         <!--        </dependency>--> | ||||
|         <!--  ZXing  --> | ||||
|         <dependency> | ||||
|             <groupId>com.google.zxing</groupId> | ||||
| @ -262,6 +294,13 @@ | ||||
|             <artifactId>netty-all</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|  | ||||
|         <dependency> | ||||
|             <groupId>commons-codec</groupId> | ||||
|             <artifactId>commons-codec</artifactId> | ||||
|             <version>1.15</version> <!-- 最新版本可自行调整 --> | ||||
|         </dependency> | ||||
|  | ||||
|     </dependencies> | ||||
|  | ||||
| </project> | ||||
|  | ||||
| @ -0,0 +1,51 @@ | ||||
| package org.dromara.ai.controller; | ||||
|  | ||||
| import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.springframework.ai.chat.client.ChatClient; | ||||
| import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RequestParam; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| import reactor.core.publisher.Flux; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-23 11:32 | ||||
|  */ | ||||
| @Validated | ||||
| @RestController | ||||
| @RequestMapping("/ai") | ||||
| public class AIController { | ||||
|  | ||||
|     private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!"; | ||||
|  | ||||
|     private final ChatClient dashScopeChatClient; | ||||
|  | ||||
|     public AIController(ChatClient.Builder chatClientBuilder) { | ||||
|         this.dashScopeChatClient = chatClientBuilder | ||||
|             .defaultSystem(DEFAULT_PROMPT) | ||||
|             // 实现 Logger 的 Advisor | ||||
|             .defaultAdvisors( | ||||
|                 new SimpleLoggerAdvisor() | ||||
|             ) | ||||
|             // 设置 ChatClient 中 ChatModel 的 Options 参数 | ||||
|             .defaultOptions( | ||||
|                 DashScopeChatOptions.builder() | ||||
|                     .withTopP(0.7) | ||||
|                     .build() | ||||
|             ) | ||||
|             .build(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * ChatClient 流式调用 | ||||
|      */ | ||||
|     @GetMapping("/stream/chat") | ||||
|     public Flux<String> streamChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?") String query, HttpServletResponse response) { | ||||
|         response.setCharacterEncoding("UTF-8"); | ||||
|         return dashScopeChatClient.prompt(query).stream().content(); | ||||
|     } | ||||
| } | ||||
| @ -3,8 +3,12 @@ package org.dromara.app.controller; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.app.domain.SysPackage; | ||||
| import org.dromara.app.domain.bo.SysPackageBo; | ||||
| import org.dromara.app.domain.vo.SysPackageVo; | ||||
| import org.dromara.app.service.SysPackageServiceImpl; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.service.impl.SysOssServiceImpl; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| @ -26,6 +30,14 @@ public class SysPackageController { | ||||
|     @Autowired | ||||
|     private SysPackageServiceImpl sysPackageService; | ||||
|  | ||||
|     /** | ||||
|      * 获取列表 | ||||
|      */ | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<SysPackageVo> list(SysPackageBo bo, PageQuery pageQuery) { | ||||
|         return sysPackageService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取最新版本 | ||||
|      */ | ||||
| @ -42,7 +54,7 @@ public class SysPackageController { | ||||
|      * 上传最新安装包及版本 | ||||
|      */ | ||||
|     @GetMapping("/uploadNewVersion") | ||||
|     public R<SysPackage> uploadNewVersion(String version, String type, MultipartFile file) { | ||||
|     public R<SysPackage> uploadNewVersion(String version, String type, MultipartFile file, String context) { | ||||
|         String originalFileName = "apk/package/app-release.apk"; | ||||
|  | ||||
|         // 先查询最新记录 | ||||
| @ -57,11 +69,11 @@ public class SysPackageController { | ||||
|         } | ||||
|  | ||||
|         // 分离事务:再处理数据库操作 | ||||
|         return handleDatabaseOperations(version, type, upload, list); | ||||
|         return handleDatabaseOperations(version, type, upload, list, context); | ||||
|     } | ||||
|  | ||||
|     @Transactional | ||||
|     public R<SysPackage> handleDatabaseOperations(String version, String type, SysOssVo upload, List<SysPackage> existingPackages) { | ||||
|     public R<SysPackage> handleDatabaseOperations(String version, String type, SysOssVo upload, List<SysPackage> existingPackages, String context) { | ||||
|         try { | ||||
|             // 先删除旧文件记录 | ||||
|             if (existingPackages != null && !existingPackages.isEmpty()) { | ||||
| @ -78,6 +90,7 @@ public class SysPackageController { | ||||
|             sysPackage.setFileId(upload.getOssId()); | ||||
|             sysPackage.setFileUrl(upload.getUrl()); | ||||
|             sysPackage.setType(type); | ||||
|             sysPackage.setContext(context); | ||||
|  | ||||
|             boolean save = sysPackageService.save(sysPackage); | ||||
|             if (!save) { | ||||
|  | ||||
| @ -30,4 +30,9 @@ public class SysPackage extends BaseEntity { | ||||
|  | ||||
|     private String fileUrl; | ||||
|  | ||||
|     /** | ||||
|      * 更新内容 | ||||
|      */ | ||||
|     private String context; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,32 @@ | ||||
| package org.dromara.app.domain.bo; | ||||
|  | ||||
|  | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.xzd.domain.XzdContractDetails; | ||||
|  | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = XzdContractDetails.class, reverseConvertGenerate = false) | ||||
| public class SysPackageBo extends BaseEntity { | ||||
|  | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 0安卓1苹果2鸿蒙 | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     private String version; | ||||
|  | ||||
|     private Long fileId; | ||||
|  | ||||
|     private String fileUrl; | ||||
|  | ||||
|     /** | ||||
|      * 更新内容 | ||||
|      */ | ||||
|     private String context; | ||||
| } | ||||
| @ -27,4 +27,9 @@ public class SysPackageVo { | ||||
|  | ||||
|     @ExcelProperty("安装包地址") | ||||
|     private String fileUrl; | ||||
|  | ||||
|     /** | ||||
|      * 更新内容 | ||||
|      */ | ||||
|     private String context; | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,24 @@ | ||||
| package org.dromara.app.service; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import org.dromara.app.domain.SysPackage; | ||||
| import org.dromara.app.domain.bo.SysPackageBo; | ||||
| import org.dromara.app.domain.vo.SysPackageVo; | ||||
| import org.dromara.app.mapper.SysPackageMapper; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| @Service | ||||
| public class SysPackageServiceImpl extends ServiceImpl<SysPackageMapper, SysPackage> { | ||||
|  | ||||
|     public TableDataInfo<SysPackageVo> queryPageList(SysPackageBo bo, PageQuery pageQuery) { | ||||
| //        LambdaQueryWrapper<SysPackage> lqw = buildQueryWrapper(bo); | ||||
|         Page<SysPackageVo> result = baseMapper.selectVoPage(pageQuery.build(), new LambdaQueryWrapper<>()); | ||||
| //        setValue(result.getRecords()); | ||||
|         return TableDataInfo.build(result); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,43 @@ | ||||
| package org.dromara.bigscreen.config; | ||||
|  | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.scheduling.annotation.EnableAsync; | ||||
| import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||||
|  | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.concurrent.ThreadPoolExecutor; | ||||
|  | ||||
| /** | ||||
|  * 无人机消息redis订阅专用线程池 | ||||
|  */ | ||||
| @Configuration // 标记为配置类,让Spring扫描加载 | ||||
| @EnableAsync // 启用Spring异步功能(若项目已在启动类加过,此处可省略,但加上更稳妥) | ||||
| public class AsyncConfig { | ||||
|  | ||||
|     /** | ||||
|      * 定义名为 "messageAsyncExecutor" 的线程池 Bean(与 @Async("messageAsyncExecutor") 对应) | ||||
|      */ | ||||
|     @Bean(name = "messageAsyncExecutor") // Bean名称必须是 "messageAsyncExecutor",大小写敏感 | ||||
|     public Executor messageAsyncExecutor() { | ||||
|         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | ||||
|  | ||||
|         // 1. 核心线程数:根据CPU核心数或业务量调整(示例:5个) | ||||
|         executor.setCorePoolSize(5); | ||||
|         // 2. 最大线程数:避免线程过多导致资源耗尽(示例:10个) | ||||
|         executor.setMaxPoolSize(10); | ||||
|         // 3. 任务队列容量:缓冲待处理的异步任务(示例:50个) | ||||
|         executor.setQueueCapacity(50); | ||||
|         // 4. 线程名前缀:便于日志排查(格式:message-async-1, message-async-2...) | ||||
|         executor.setThreadNamePrefix("message-async-"); | ||||
|         // 5. 线程空闲时间:超过60秒空闲则销毁(释放资源) | ||||
|         executor.setKeepAliveSeconds(60); | ||||
|         // 6. 任务拒绝策略:队列满时,由提交任务的线程临时执行(避免消息丢失) | ||||
|         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); | ||||
|  | ||||
|         // 7. 初始化线程池(必须调用,否则线程池不会生效) | ||||
|         executor.initialize(); | ||||
|  | ||||
|         return executor; | ||||
|     } | ||||
| } | ||||
| @ -30,11 +30,11 @@ public class RedisConfig { | ||||
|  | ||||
|         RedisMessageListenerContainer container = new RedisMessageListenerContainer(); | ||||
|         container.setConnectionFactory(connectionFactory); | ||||
|         List<String> wrjKeys = droProjectDroneService.getTopicsByKeyPrefix(); | ||||
|         for (String key : wrjKeys) { | ||||
|             // 订阅 wrj:8UUXN4P00A06NK 频道 | ||||
|             container.addMessageListener(listenerAdapter, new PatternTopic("wrj:"+key)); | ||||
|         } | ||||
| //        List<String> wrjKeys = droProjectDroneService.getTopicsByKeyPrefix(); | ||||
| //        for (String key : wrjKeys) { | ||||
| //            // 订阅 wrj:8UUXN4P00A06NK 频道 | ||||
| //            container.addMessageListener(listenerAdapter, new PatternTopic("wrj:osd4"+key)); | ||||
| //        } | ||||
|         return container; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,20 @@ | ||||
| package org.dromara.bigscreen.config;// 路径:com.ruoyi.framework.config.WebSocketConfig | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.web.socket.server.standard.ServerEndpointExporter; | ||||
|  | ||||
| /** | ||||
|  * WebSocket 配置类:确保 @ServerEndpoint 端点随项目启动注册 | ||||
|  */ | ||||
| @Configuration | ||||
| public class WebSocketConfig { | ||||
|  | ||||
|     /** | ||||
|      * 注册 WebSocket 端点处理器 | ||||
|      * 作用:Spring 启动时自动扫描并初始化 @ServerEndpoint 注解的类 | ||||
|      */ | ||||
|     @Bean | ||||
|     public ServerEndpointExporter serverEndpointExporter() { | ||||
|         return new ServerEndpointExporter(); | ||||
|     } | ||||
| } | ||||
| @ -1,10 +1,8 @@ | ||||
| package org.dromara.bigscreen.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| import org.dromara.bigscreen.domain.dto.WeatherQueryReq; | ||||
| import org.dromara.bigscreen.domain.vo.*; | ||||
| import org.dromara.bigscreen.mapper.ProjectBigScreenMapper; | ||||
| @ -52,14 +50,10 @@ public class EnterpriseBigScreenController { | ||||
|     @Resource | ||||
|     private IBusProjectService projectService; | ||||
|  | ||||
|     @Resource | ||||
|     private ProjectBigScreenMapper projectBigScreenMapper; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 获取关键指标 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:keyIndex") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:keyIndex") | ||||
|     @GetMapping("/keyIndex") | ||||
|     public R<EnterpriseKeyIndexVo> getEnterpriseKeyIndex() { | ||||
|         return R.ok(enterpriseBigScreenService.getEnterpriseKeyIndex()); | ||||
| @ -68,7 +62,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 项目进度分析 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:projectProgress") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:projectProgress") | ||||
|     @GetMapping("/projectProgress") | ||||
|     public R<ProjectProgressAnalysisVo> getProjectProgress() { | ||||
|         return R.ok(enterpriseBigScreenService.getProjectProgressAnalysis()); | ||||
| @ -77,7 +71,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 项目产值对比 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:projectOutputValueComparison") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:projectOutputValueComparison") | ||||
|     @GetMapping("/projectOutputValueComparison") | ||||
|     public R<List<OutputValueComparisonVo>> getProjectOutputValueComparison() { | ||||
|         return R.ok(enterpriseBigScreenService.getProjectOutputValueComparison()); | ||||
| @ -86,7 +80,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 项目进度完成度和计划容量 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:projectProgressCapacity") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:projectProgressCapacity") | ||||
|     @GetMapping("/projectProgressCapacity") | ||||
|     public R<List<ProjectProgressCapacityVo>> getProjectProgressCapacity() { | ||||
|         return R.ok(enterpriseBigScreenService.getProjectProgressCapacity()); | ||||
| @ -95,7 +89,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 风险预警 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:riskEarlyWarning") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:riskEarlyWarning") | ||||
|     @GetMapping("/riskEarlyWarning") | ||||
|     public R<List<RiskEarlyWarningVo>> getRiskEarlyWarning() { | ||||
|         return R.ok(enterpriseBigScreenService.getRiskEarlyWarning()); | ||||
| @ -104,7 +98,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 查询天气 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:weather") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:weather") | ||||
|     @GetMapping("/weather") | ||||
|     public R<List<WeatherVo>> getProjectWeather(WeatherQueryReq req) { | ||||
|         return R.ok(enterpriseBigScreenService.getWeather3DaysList(req)); | ||||
| @ -113,7 +107,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 查询安全天数 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:safetyDay") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:safetyDay") | ||||
|     @GetMapping("/safetyDay") | ||||
|     public R<Long> getProjectSafetyDay() { | ||||
|         LocalDate date = LocalDate.of(2023, 1, 1); | ||||
| @ -125,7 +119,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 人数统计 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:peopleCount") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:peopleCount") | ||||
|     @GetMapping("/peopleCount") | ||||
|     public R<PeopleCountVo> getProjectPeopleCount() { | ||||
|         PeopleCountVo peopleCountVo = new PeopleCountVo(); | ||||
| @ -156,7 +150,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 出勤人数统计 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:allAttendanceCount") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:allAttendanceCount") | ||||
|     @GetMapping("/allAttendanceCount") | ||||
|     public R<TodayAttendanceCountVo> getAllAttendanceCount() { | ||||
|         TodayAttendanceCountVo todayAttendanceCountVo = new TodayAttendanceCountVo(); | ||||
| @ -195,7 +189,7 @@ public class EnterpriseBigScreenController { | ||||
|     /** | ||||
|      * 每个项目的出勤人数 | ||||
|      */ | ||||
|     @SaCheckPermission("enterprise:bigScreen:projectAttendanceCount") | ||||
| //    @SaCheckPermission("enterprise:bigScreen:projectAttendanceCount") | ||||
|     @GetMapping("/projectAttendanceCount") | ||||
|     public R<List<ProjectAttendanceCountVo>> getProjectAttendanceCount() { | ||||
|  | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| package org.dromara.bigscreen.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| @ -62,7 +61,7 @@ public class MoneyBigScreenController { | ||||
|     /** | ||||
|      * 查询项目位置列表 | ||||
|      */ | ||||
|     @SaCheckPermission("money:bigScreen:projectGis") | ||||
| //    @SaCheckPermission("money:bigScreen:projectGis") | ||||
|     @GetMapping("/project/gis") | ||||
|     public R<List<BusProjectGisVo>> getProjectGis() { | ||||
|         return R.ok(moneyBigScreenService.getProjectGis()); | ||||
| @ -545,7 +544,7 @@ public class MoneyBigScreenController { | ||||
|     /** | ||||
|      * 查询项目天气 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:weather") | ||||
| //    @SaCheckPermission("project:bigScreen:weather") | ||||
|     @GetMapping("/weather/{projectId}") | ||||
|     public R<List<WeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空") | ||||
|                                                 @PathVariable Long projectId) { | ||||
| @ -555,7 +554,7 @@ public class MoneyBigScreenController { | ||||
|     /** | ||||
|      * 查询项目安全天数 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:safetyDay") | ||||
| //    @SaCheckPermission("project:bigScreen:safetyDay") | ||||
|     @GetMapping("/safetyDay/{projectId}") | ||||
|     public R<BusProjectSafetyDayVo> getProjectSafetyDay(@NotNull(message = "主键不能为空") | ||||
|                                                         @PathVariable Long projectId) { | ||||
|  | ||||
| @ -1,20 +1,15 @@ | ||||
| package org.dromara.bigscreen.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import cn.hutool.core.collection.CollectionUtil; | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.bigscreen.domain.dto.WurenjiQueryReq; | ||||
| import org.dromara.bigscreen.domain.dto.ProjectUpdateDto; | ||||
| import org.dromara.bigscreen.domain.dto.TanchuangInfoReq; | ||||
| import org.dromara.bigscreen.domain.dto.Ys7DeviceUpdateReq; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectLandVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectPeopleVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo; | ||||
| import org.dromara.bigscreen.domain.vo.*; | ||||
| import org.dromara.bigscreen.service.ProjectBigScreenService; | ||||
| import org.dromara.common.core.constant.HttpStatus; | ||||
| import org.dromara.common.core.domain.R; | ||||
| @ -22,12 +17,13 @@ import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.redis.utils.RedisUtils; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.drone.service.IDroProjectDroneService; | ||||
| import org.dromara.facility.domain.bo.FacRedLineBo; | ||||
| import org.dromara.facility.domain.vo.redline.FacRedLineVo; | ||||
| import org.dromara.facility.service.IFacRedLineService; | ||||
| import org.dromara.gps.domain.bo.GpsEquipmentBo; | ||||
| import org.dromara.gps.domain.vo.GpsEquipmentSonVo; | ||||
| import org.dromara.gps.service.IGpsEquipmentService; | ||||
| import org.dromara.land.domain.BusLandBlock; | ||||
| import org.dromara.land.domain.BusLandTransferLedger; | ||||
| import org.dromara.land.domain.BusLandTransferLedgerSon; | ||||
| @ -39,6 +35,7 @@ import org.dromara.manager.ys7manager.Ys7Manager; | ||||
| import org.dromara.other.domain.OthYs7Device; | ||||
| import org.dromara.other.service.IOthYs7DeviceService; | ||||
| import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo; | ||||
| import org.dromara.project.domain.vo.project.BusProjectVo; | ||||
| import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo; | ||||
| import org.dromara.project.service.IBusProjectNewsService; | ||||
| import org.dromara.project.service.IBusProjectService; | ||||
| @ -54,10 +51,8 @@ import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.function.Consumer; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
| @ -94,23 +89,33 @@ public class ProjectBigScreenController extends BaseController { | ||||
|  | ||||
|     private final BusLandTransferLedgerSonServiceImpl busLandTransferLedgerSonService; | ||||
|  | ||||
|     private final IFacRedLineService facRedLineService; | ||||
|  | ||||
|     /** | ||||
|      * 查询项目土地统计 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/{projectId}") | ||||
|     public R<List<ProjectLandVo>> landCount(@NotNull(message = "主键不能为空") | ||||
|                                             @PathVariable Long projectId) { | ||||
|         List<BusLandTransferLedger> levelList = busLandTransferLedgerService.list(Wrappers.lambdaQuery(BusLandTransferLedger.class) | ||||
|             .eq(BusLandTransferLedger::getProjectId, projectId)); | ||||
|  | ||||
|         if(CollectionUtil.isNotEmpty(levelList)){ | ||||
|         if (CollectionUtil.isNotEmpty(levelList)) { | ||||
|             List<Long> list1 = levelList.stream().map(BusLandTransferLedger::getId).toList(); | ||||
|             LambdaQueryWrapper<BusLandTransferLedgerSon> lambdaQueryWrapper = new LambdaQueryWrapper<>(); | ||||
|             lambdaQueryWrapper.in(BusLandTransferLedgerSon::getParentId,list1); | ||||
|             lambdaQueryWrapper.in(BusLandTransferLedgerSon::getParentId, list1); | ||||
|             List<BusLandTransferLedgerSon> sonList = busLandTransferLedgerSonService.list(lambdaQueryWrapper); | ||||
|             Map<Long, BigDecimal> collect = sonList.stream().filter(vo -> "1".equals(vo.getTransferStatus())) | ||||
|                 .collect(Collectors.toMap(BusLandTransferLedgerSon::getParentId, BusLandTransferLedgerSon::getAreaValue)); | ||||
|  | ||||
|             Map<Long, BigDecimal> collect = sonList.stream() | ||||
|                 .filter(vo -> "1".equals(vo.getTransferStatus())) | ||||
|                 .collect(Collectors.groupingBy( | ||||
|                     BusLandTransferLedgerSon::getParentId, | ||||
|                     Collectors.reducing( | ||||
|                         BigDecimal.ZERO, | ||||
|                         BusLandTransferLedgerSon::getAreaValue, | ||||
|                         BigDecimal::add | ||||
|                     ) | ||||
|                 )); | ||||
|             for (BusLandTransferLedger busLandTransferLedger : levelList) { | ||||
|                 BigDecimal areaValue = collect.get(busLandTransferLedger.getId()); | ||||
|                 if (areaValue != null) { | ||||
| @ -161,7 +166,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询项目天气 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:weather") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/weather/{projectId}") | ||||
|     public R<List<WeatherVo>> getProjectWeather(@NotNull(message = "主键不能为空") | ||||
|                                                 @PathVariable Long projectId) { | ||||
| @ -171,7 +176,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询项目安全天数 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:safetyDay") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/safetyDay/{projectId}") | ||||
|     public R<BusProjectSafetyDayVo> getProjectSafetyDay(@NotNull(message = "主键不能为空") | ||||
|                                                         @PathVariable Long projectId) { | ||||
| @ -181,138 +186,57 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询项目公告 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:news") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/news/{projectId}") | ||||
|     public R<List<BusProjectNewsVo>> getProjectNews(@NotNull(message = "主键不能为空") | ||||
|                                                     @PathVariable Long projectId) { | ||||
| //        List<BusCorporateEvents> busCorporateEvents = projectBigScreenMapper.getBusCorporateEvents(); | ||||
| //        return R.ok(busCorporateEvents.stream().map(event -> { | ||||
| //            BusProjectNewsVo vo = new BusProjectNewsVo(); | ||||
| //            vo.setId(event.getId()); | ||||
| //            vo.setTitle(event.getHeadline()); | ||||
| //            vo.setContent(event.getContent()); | ||||
| //            return vo; | ||||
| //        }).toList()); | ||||
|         return R.ok(projectBigScreenService.getProjectNews(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询项目AI安全巡检 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:safetyInspection") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/safetyInspection/{projectId}") | ||||
|     public R<List<ProjectSafetyInspectionVo>> getProjectSafetyInspection(@NotNull(message = "主键不能为空") | ||||
|                                                                          @PathVariable Long projectId) { | ||||
| /*        BusProject project = projectService.getById(projectId); | ||||
|         projectId = project.getGoId(); | ||||
|         String pic; | ||||
|         if (projectId == 60) { | ||||
|             pic = "http://xny.yj-3d.com:7464"; | ||||
|         } else { | ||||
|             pic = "http://xny.yj-3d.com:7363"; | ||||
|         } | ||||
|         List<BusTour> busTours = projectBigScreenMapper.selectTourByProjectId(projectId); | ||||
|         return R.ok(busTours.stream().map(tour -> { | ||||
|             ProjectSafetyInspectionVo vo = new ProjectSafetyInspectionVo(); | ||||
|             vo.setId(tour.getId()); | ||||
|             vo.setViolationType(tour.getTourType()); | ||||
|             vo.setPicture(pic + tour.getPicture()); | ||||
|             vo.setCreateTime(tour.getCreatedAt()); | ||||
|             return vo; | ||||
|         }).toList());*/ | ||||
|         return R.ok(projectBigScreenService.getProjectSafetyInspection(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询项目人员情况 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:people") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/people/{projectId}") | ||||
|     public R<ProjectPeopleVo> getProjectPeople(@NotNull(message = "主键不能为空") | ||||
|                                                @PathVariable Long projectId) { | ||||
| //        BusProject project = projectService.getById(projectId); | ||||
| //        projectId = project.getGoId(); | ||||
| //        Integer projectUserCount = projectBigScreenMapper.getProjectUserCount(projectId); | ||||
| //        ProjectPeopleVo vo = new ProjectPeopleVo(); | ||||
| //        vo.setPeopleCount(BigDecimal.valueOf(projectUserCount)); | ||||
| //        Integer attendanceCount = projectBigScreenMapper.getAttendanceCount(projectId, DateUtils.getDate()); | ||||
| //        vo.setAttendanceCount(BigDecimal.valueOf(attendanceCount)); | ||||
| //        vo.setAttendanceRate(BigDecimalUtil.toPercentage(BigDecimal.valueOf(attendanceCount), BigDecimal.valueOf(projectUserCount))); | ||||
| //        List<BusConstructionUser> projectUserList = projectBigScreenMapper.getProjectUserList(projectId); | ||||
| //        List<BusProjectTeamByGo> teamList = projectBigScreenMapper.getTeamList(projectId); | ||||
| // | ||||
| //        List<ProjectTeamAttendanceVo> teamAttendanceList = new ArrayList<>(); | ||||
| //        String punchRange = project.getPunchRange(); | ||||
| //        String punchTime = ""; | ||||
| //        if (punchRange != null) { | ||||
| //            String start = punchRange.split(",")[0]; | ||||
| //            punchTime = LocalDate.now() + " " + start; | ||||
| //        } | ||||
| //        if (projectUserList != null && teamList != null) { | ||||
| //            projectUserList = projectUserList.stream().filter(user -> user.getTeamId() != null).toList(); | ||||
| //            Map<Long, List<BusConstructionUser>> userMap = projectUserList.stream() | ||||
| //                .collect(Collectors.groupingBy(BusConstructionUser::getTeamId)); | ||||
| //            for (BusProjectTeamByGo team : teamList) { | ||||
| //                ProjectTeamAttendanceVo vo1 = new ProjectTeamAttendanceVo(); | ||||
| //                vo1.setId(team.getId()); | ||||
| //                vo1.setTeamName(team.getName()); | ||||
| //                vo1.setAttendanceTime(punchTime); | ||||
| //                vo1.setAttendanceNumber(BigDecimal.ZERO); | ||||
| //                List<BusConstructionUser> userList = userMap.get(team.getId()); | ||||
| //                if (CollUtil.isNotEmpty(userList)) { | ||||
| //                    List<String> list = userList.stream().map(BusConstructionUser::getOpenid).distinct().toList(); | ||||
| //                    Integer aCount = projectBigScreenMapper.getAttendanceCountByOpenIds(list, LocalDate.now()); | ||||
| //                    vo1.setAttendanceNumber(BigDecimal.valueOf(aCount)); | ||||
| //                } | ||||
| //                vo1.setAllNumber(BigDecimal.valueOf(userMap.getOrDefault(team.getId(), List.of()).size())); | ||||
| //                if (vo1.getAttendanceNumber() != null && vo1.getAllNumber() != null && vo1.getAllNumber().compareTo(BigDecimal.ZERO) != 0) { | ||||
| //                    vo1.setAttendanceRate(BigDecimalUtil.toPercentage(vo1.getAttendanceNumber(), vo1.getAllNumber())); | ||||
| //                } else { | ||||
| //                    vo1.setAttendanceRate(BigDecimal.ZERO); | ||||
| //                } | ||||
| //                teamAttendanceList.add(vo1); | ||||
| //            } | ||||
| //        } | ||||
| //        vo.setTeamAttendanceList(teamAttendanceList); | ||||
| //        return R.ok(vo); | ||||
|         return R.ok(projectBigScreenService.getProjectPeople(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询项目形象进度 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:imageProgress") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/imageProgress/{projectId}") | ||||
|     public R<ProjectImageProgressVo> getProjectImageProgress(@NotNull(message = "主键不能为空") | ||||
|                                                              @PathVariable Long projectId) { | ||||
|     public R<List<ProjectImageProgressVo>> getProjectImageProgress(@NotNull(message = "主键不能为空") | ||||
|                                                                    @PathVariable Long projectId) { | ||||
|         return R.ok(projectBigScreenService.getProjectImageProgress(projectId)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询项目概括 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:generalize") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/generalize/{projectId}") | ||||
|     public R<String> getProjectGeneralize(@NotNull(message = "主键不能为空") | ||||
|                                           @PathVariable Long projectId) { | ||||
| //        BusProject project = projectService.getById(projectId); | ||||
| //        if (project != null) { | ||||
| //            Long goId = project.getGoId(); | ||||
| //            if (goId != null) { | ||||
| //                List<SysProjectIntroduce> sysProjectIntroduces = projectBigScreenMapper.selectByProjectId(goId); | ||||
| //                if (CollUtil.isNotEmpty(sysProjectIntroduces)) { | ||||
| //                    return R.ok(sysProjectIntroduces.getFirst().getRichText()); | ||||
| //                } | ||||
| //            } | ||||
| //        } | ||||
|         return R.ok(projectBigScreenService.getProjectGeneralize(projectId)); | ||||
| //        return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询设备列表 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:getClientList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getClientList/{projectId}") | ||||
|     public R<List<Map<String, Object>>> getClientList(@NotNull(message = "主键不能为空") | ||||
|                                                       @PathVariable Long projectId) { | ||||
| @ -322,6 +246,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 修改萤石摄像头 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping("/device") | ||||
|     public R<Void> edit(@Validated @RequestBody Ys7DeviceUpdateReq req) { | ||||
| @ -345,11 +270,15 @@ public class ProjectBigScreenController extends BaseController { | ||||
|             if (count > 0) { | ||||
|                 throw new ServiceException("已存在同名萤石摄像头", HttpStatus.CONFLICT); | ||||
|             } | ||||
|             // todo 更新云端名称 | ||||
| /*            Boolean result = ys7Manager.updateDeviceName(one.getDeviceSerial(), deviceName); | ||||
|             // 更新云端名称 | ||||
|             Boolean result = ys7Manager.updateDeviceName(one.getDeviceSerial(), deviceName); | ||||
|             if (!result) { | ||||
|                 throw new ServiceException("更新云端萤石摄像头名称异常", HttpStatus.ERROR); | ||||
|             }*/ | ||||
|             } | ||||
|         } | ||||
|         if (req.getLatitude() != null && req.getLongitude() != null) { | ||||
|             ys7Device.setLatitude(req.getLatitude()); | ||||
|             ys7Device.setLongitude(req.getLongitude()); | ||||
|         } | ||||
|         return toAjax(othYs7DeviceService.updateById(ys7Device)); | ||||
|     } | ||||
| @ -357,6 +286,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询质量信息 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getQualityList/gis") | ||||
|     public R<QltQualityInspectionListGisVo> queryGisList(QltQualityInspectionGisReq req) { | ||||
|         return R.ok(qualityInspectionService.queryGisList(req)); | ||||
| @ -365,6 +295,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询大屏安全信息 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getSafetyList/gis") | ||||
|     public R<HseSafetyInspectionListGisVo> queryGisList(HseSafetyInspectionGisReq req) { | ||||
|         return R.ok(safetyInspectionService.queryGisList(req)); | ||||
| @ -373,7 +304,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询GPS设备用户列表 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:getList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getList") | ||||
|     public R<List<String>> getList(Long projectId) { | ||||
|         return R.ok(projectBigScreenService.getList(projectId)); | ||||
| @ -382,7 +313,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 新增GPS设备详细 | ||||
|      */ | ||||
|     @SaCheckPermission("project:bigScreen:setList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @Log(title = "GPS设备详细", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping("/setList") | ||||
| @ -393,17 +324,42 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询地图项目分类 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:bigScreen:getProjectMapList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getProjectMapList") | ||||
|     public R<Map<String, Map<String, Map<String, String>>>> getProjectMapList() { | ||||
|         return R.ok(projectService.getProjectMapList()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询地图项目分类 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @PostMapping("/updatePosition") | ||||
|     public R<Void> updatePosition(@RequestBody ProjectUpdateDto dto) { | ||||
|         return toAjax(projectService.updatePosition(dto)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取项目信息 | ||||
|      */ | ||||
|     @GetMapping("/getProjectInfo/{projectId}") | ||||
|     public R<ProjectInfo> getProjectInfo(@NotNull(message = "主键不能为空") | ||||
|                                          @PathVariable Long projectId) { | ||||
|         BusProjectVo projectVo = projectService.queryById(projectId); | ||||
|         ProjectInfo info = new ProjectInfo(); | ||||
|         info.setLat(projectVo.getLat()); | ||||
|         info.setLng(projectVo.getLng()); | ||||
|         info.setPlan(projectVo.getPlan()); | ||||
|         info.setPosition(projectVo.getPosition()); | ||||
|         info.setProjectId(projectVo.getId().toString()); | ||||
|         return R.ok(info); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询项目地域分散图 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:bigScreen:getProjectMapList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getProjectDiYv") | ||||
|     public R<Map<String, Long>> getProjectDiYv() { | ||||
|         return R.ok(projectService.getProjectDiYv()); | ||||
| @ -412,11 +368,37 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 计划和实际容量对比 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:bigScreen:getProjectMapList") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getProjectCapacity") | ||||
|     public R<Map<String, Map<String, String>>> getProjectCapacity() { | ||||
|         return R.ok(projectService.getProjectCapacity()); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 更新无人机缓存 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/setWrjHc") | ||||
|     public void setWrjHc() { | ||||
|         projectBigScreenService.setWrjHc(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 更新无人机缓存 | ||||
|      */ | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getInfoData") | ||||
|     public R<Map<String, Map<String, Object>>> getInfoData(TanchuangInfoReq req) { | ||||
|         return R.ok(projectBigScreenService.getInfoData(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询设施-红线列表 | ||||
|      */ | ||||
|     @GetMapping("/redLine/list") | ||||
|     public TableDataInfo<FacRedLineVo> list(FacRedLineBo bo, PageQuery pageQuery) { | ||||
|         return facRedLineService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| package org.dromara.bigscreen.domain.dto; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| @Data | ||||
| public class ProjectUpdateDto implements Serializable { | ||||
|  | ||||
|  | ||||
|     private Long projectId;       // 项目id | ||||
|  | ||||
|     private String position;      // 图片 | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,11 @@ | ||||
| package org.dromara.bigscreen.domain.dto; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| @Data | ||||
| public class TanchuangInfoReq implements Serializable { | ||||
|  | ||||
|     private Long id; | ||||
| } | ||||
| @ -5,6 +5,7 @@ import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
| @ -37,4 +38,13 @@ public class Ys7DeviceUpdateReq implements Serializable { | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|     /** | ||||
|      * 纬度(精确到6位小数) | ||||
|      */ | ||||
|     private BigDecimal latitude; | ||||
|     /** | ||||
|      * 经度(精确到6位小数) | ||||
|      */ | ||||
|     private BigDecimal longitude; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -16,39 +16,49 @@ public class ProjectImageProgressVo implements Serializable { | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 7963637133004484891L; | ||||
|  | ||||
|     /** | ||||
|      * 类别名称 | ||||
|      */ | ||||
|     private String progressName; | ||||
|  | ||||
|     /** | ||||
|      * 进度百分比 | ||||
|      */ | ||||
|     private BigDecimal progressTotal; | ||||
|  | ||||
|     /** | ||||
|      * 场区百分比 | ||||
|      */ | ||||
|     private BigDecimal areaPercentage; | ||||
| //    private BigDecimal areaPercentage; | ||||
|  | ||||
|     /** | ||||
|      * 道路百分比 | ||||
|      */ | ||||
|     private BigDecimal roadPercentage; | ||||
| //    private BigDecimal roadPercentage; | ||||
|  | ||||
|     /** | ||||
|      * 集电线路百分比 | ||||
|      */ | ||||
|     private BigDecimal collectorLinePercentage; | ||||
| //    private BigDecimal collectorLinePercentage; | ||||
|  | ||||
|     /** | ||||
|      * 送出线路百分比 | ||||
|      */ | ||||
|     private BigDecimal exportLinePercentage; | ||||
| //    private BigDecimal exportLinePercentage; | ||||
|  | ||||
|     /** | ||||
|      * 升压站百分比 | ||||
|      */ | ||||
|     private BigDecimal substationPercentage; | ||||
| //    private BigDecimal substationPercentage; | ||||
|  | ||||
|     /** | ||||
|      * 箱变百分比 | ||||
|      */ | ||||
|     private BigDecimal boxTransformerPercentage; | ||||
| //    private BigDecimal boxTransformerPercentage; | ||||
|  | ||||
|     /** | ||||
|      * 总百分比 | ||||
|      */ | ||||
|     private BigDecimal totalPercentage; | ||||
| //    private BigDecimal totalPercentage; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,42 @@ | ||||
| package org.dromara.bigscreen.domain.vo; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-22 15:00 | ||||
|  */ | ||||
| @Data | ||||
| public class ProjectInfo implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = -8436930470114636496L; | ||||
|  | ||||
|     /** | ||||
|      * 纬度 | ||||
|      */ | ||||
|     private String lat; | ||||
|  | ||||
|     /** | ||||
|      * 经度 | ||||
|      */ | ||||
|     private String lng; | ||||
|  | ||||
|     /** | ||||
|      * 计划 | ||||
|      */ | ||||
|     private String plan; | ||||
|  | ||||
|     /** | ||||
|      * 位置 | ||||
|      */ | ||||
|     private String position; | ||||
|  | ||||
|     /** | ||||
|      * 项目id | ||||
|      */ | ||||
|     private String projectId; | ||||
| } | ||||
| @ -5,7 +5,11 @@ import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.bigscreen.service.IAsyncMessageHandlerService; | ||||
| import org.dromara.bigscreen.service.impl.InitOnStartWebSocketServer; | ||||
| import org.dromara.common.websocket.dto.WebSocketMessageDto; | ||||
| import org.dromara.common.websocket.holder.WebSocketSessionHolder; | ||||
| import org.dromara.common.websocket.utils.WebSocketUtils; | ||||
| import org.dromara.drone.domain.DroProjectDrone; | ||||
| import org.dromara.drone.service.IDroProjectDroneService; | ||||
| @ -17,25 +21,18 @@ import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.Objects; | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * Redis消息监听器,用于处理订阅频道收到的消息 | ||||
|  */ | ||||
| @Slf4j | ||||
| @Component | ||||
| public class RedisMessageListener implements MessageListener { | ||||
|  | ||||
|     @Lazy | ||||
|     private final StringRedisTemplate stringRedisTemplate; | ||||
|  | ||||
|     // 注入异步消息处理服务 | ||||
|     @Resource | ||||
|     @Lazy | ||||
|     private IDroProjectDroneService droProjectDroneService; | ||||
|  | ||||
|     // 构造函数注入StringRedisTemplate | ||||
|     public RedisMessageListener(StringRedisTemplate stringRedisTemplate) { | ||||
|         this.stringRedisTemplate = stringRedisTemplate; | ||||
|     } | ||||
|  | ||||
|     private IAsyncMessageHandlerService asyncMessageHandlerService; | ||||
|     /** | ||||
|      * 处理接收到的消息 | ||||
|      * @param message 消息对象 | ||||
| @ -43,32 +40,19 @@ public class RedisMessageListener implements MessageListener { | ||||
|      */ | ||||
|     @Override | ||||
|     public void onMessage(Message message, byte[] pattern) { | ||||
|         // 处理消息 | ||||
| //        System.out.println("返回:"+stringRedisTemplate.getStringSerializer().deserialize(message.getBody())); | ||||
|         String gateway = JSONUtil.parseObj(stringRedisTemplate.getStringSerializer().deserialize(message.getBody())).getStr("gateway"); | ||||
|         stringRedisTemplate | ||||
|             .opsForValue() | ||||
|             .set("wrj:"+gateway | ||||
|                 , Objects.requireNonNull(stringRedisTemplate.getStringSerializer().deserialize(message.getBody()))); | ||||
|         DroProjectDrone droProjectDrone = droProjectDroneService.getBaseMapper().selectOne(new LambdaQueryWrapper<DroProjectDrone>().eq(DroProjectDrone::getDroneSn, gateway)); | ||||
|         String pushContent = buildPushMessage(gateway,stringRedisTemplate.getStringSerializer().deserialize(message.getBody()),droProjectDrone.getProjectId()); | ||||
|         // 发送给指定用户(equipment.getUserId()) | ||||
|         WebSocketMessageDto messageDto = new WebSocketMessageDto(); | ||||
|         messageDto.setMessage(pushContent); | ||||
|         messageDto.setSessionKeys(Collections.singletonList(droProjectDrone.getProjectId())); | ||||
|         WebSocketUtils.publishMessage(messageDto); | ||||
|         try { | ||||
|             // 1. 快速日志记录(证明监听到消息) | ||||
|             log.info("【Redis消息监听】收到消息,长度:{}字节,提交异步处理", message.getBody().length); | ||||
|  | ||||
|             // 2. 提交给异步服务处理(核心:线程分离,监听线程立即返回) | ||||
|             asyncMessageHandlerService.handleRedisMessageAsync(message); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             // 捕获提交过程中的异常(如异步服务注入失败) | ||||
|             log.error("【Redis消息监听】提交异步处理失败", e); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     private String buildPushMessage(String key, String message, Long projectId) { | ||||
|         JSONObject messageObj = new JSONObject(); | ||||
|         messageObj.put("type", "wrj_DATA_UPDATE"); | ||||
|         messageObj.put("projectId",projectId); | ||||
|         messageObj.put("clientId",key); | ||||
|         // 位置信息 | ||||
|         JSONObject locationObj = new JSONObject(); | ||||
|         locationObj.put("latitude", JSONUtil.parseObj(message).getJSONObject("data").get("latitude")); // 纬度 | ||||
|         locationObj.put("longitude", JSONUtil.parseObj(message).getJSONObject("data").get("longitude")); // 经度 | ||||
|         messageObj.put("location", locationObj); | ||||
|         return messageObj.toString(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,255 @@ | ||||
| package org.dromara.bigscreen.manager; | ||||
|  | ||||
| import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import jakarta.annotation.PostConstruct; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.bigscreen.service.impl.InitOnStartWebSocketServer; | ||||
| import org.dromara.common.redis.utils.RedisUtils; | ||||
| import org.dromara.drone.domain.DroProjectDrone; | ||||
| import org.dromara.drone.service.IDroProjectDroneService; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.data.redis.listener.PatternTopic; | ||||
| import org.springframework.data.redis.listener.RedisMessageListenerContainer; | ||||
| import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; | ||||
| import org.springframework.scheduling.annotation.Scheduled; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
|  * Redis 订阅管理器(定时任务动态更新订阅关系) | ||||
|  */ | ||||
| @Component | ||||
| @Slf4j | ||||
| public class RedisSubscribeManager { | ||||
|  | ||||
|     // 1. 注入 Redis 核心组件 | ||||
|     @Resource | ||||
|     private RedisMessageListenerContainer redisMessageListenerContainer; | ||||
|     @Resource | ||||
|     private MessageListenerAdapter redisMessageListenerAdapter; | ||||
|  | ||||
|     // 2. 注入业务 Service(延迟加载,避免循环依赖) | ||||
|     @Resource | ||||
|     @Lazy | ||||
|     private IDroProjectDroneService droProjectDroneService; | ||||
|  | ||||
|     // 3. 维护已订阅的主题关系:key=完整主题(如wrj:8UUXN4P00A06NK),value=对应的PatternTopic | ||||
|     private final Map<String, PatternTopic> subscribedTopics = new ConcurrentHashMap<>(); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 项目启动后立即执行一次订阅(避免等待定时任务首次执行) | ||||
|      */ | ||||
|     @PostConstruct | ||||
|     public void initSubscribe() { | ||||
|         log.info("项目启动,初始化Redis订阅..."); | ||||
|         // 步骤1:从数据库获取最新的主题列表(原逻辑:getTopicsByKeyPrefix) | ||||
|         List<DroProjectDrone> latestKeys = droProjectDroneService.getBaseMapper().selectList(new LambdaQueryWrapper<DroProjectDrone>().groupBy(DroProjectDrone::getDroneSn)); | ||||
|         if (latestKeys == null || latestKeys.isEmpty()) { | ||||
|             log.warn("未获取到任何主题,将取消所有现有订阅"); | ||||
|             cancelAllSubscribes(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 步骤2:构建最新的完整主题(格式:wrj:key) | ||||
|         Set<String> latestFullTopics = new HashSet<>(); | ||||
|         for (DroProjectDrone key : latestKeys) { | ||||
|             latestFullTopics.add("wrj:osd1:" + key.getDroneSn()); | ||||
|             latestFullTopics.add("wrj:osd2:" + key.getDroneSn()); | ||||
|             latestFullTopics.add("wrj:osd3:" + key.getDroneSn()); | ||||
|             if (key.getAirplaneSn() != null && !key.getAirplaneSn().isEmpty()) { | ||||
|                 latestFullTopics.add("wrj:osd4:" + key.getAirplaneSn()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // 步骤3:对比现有订阅,删除过期主题 | ||||
|         cancelExpiredSubscribes(latestFullTopics); | ||||
|  | ||||
|         // 步骤4:对比现有订阅,新增未订阅的主题 | ||||
|         addNewSubscribes(latestFullTopics); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 4. 定时任务:定期更新订阅(每5分钟执行一次,可调整cron表达式) | ||||
|      * cron格式:秒 分 时 日 月 周 年(示例:0 0/5 * * * ? 表示每5分钟) | ||||
|      */ | ||||
| //    @Scheduled(cron = "0 0/6 * * * ?") | ||||
|     public void dynamicUpdateSubscribe() { | ||||
|         try { | ||||
|             Object object = RedisUtils.getCacheObject("xmjdap:ws"); | ||||
|             log.info("开始执行Redis订阅更新定时任务..."); | ||||
|             if (object == null) { | ||||
|                 cancelAllSubscribes(); | ||||
|                 return; | ||||
|             } | ||||
|             long oldTime = Long.parseLong(String.valueOf(object)); | ||||
|             long now = System.currentTimeMillis(); | ||||
|             if (now-oldTime > 300000) { | ||||
|                 RedisUtils.deleteObject("xmjdap:ws"); | ||||
|                 cancelAllSubscribes(); | ||||
|                 return; | ||||
|             } | ||||
|             // 步骤1:从数据库获取最新的主题列表(原逻辑:getTopicsByKeyPrefix) | ||||
|             List<DroProjectDrone> latestKeys = droProjectDroneService.getBaseMapper().selectList(new LambdaQueryWrapper<DroProjectDrone>().groupBy(DroProjectDrone::getDroneSn)); | ||||
|             if (latestKeys == null || latestKeys.isEmpty()) { | ||||
|                 log.warn("定时任务未获取到任何主题,将取消所有现有订阅"); | ||||
|                 cancelAllSubscribes(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // 步骤2:构建最新的完整主题(格式:wrj:key) | ||||
|             Set<String> latestFullTopics = new HashSet<>(); | ||||
|             for (DroProjectDrone key : latestKeys) { | ||||
|                 latestFullTopics.add("wrj:osd1:" + key.getDroneSn()); | ||||
|                 latestFullTopics.add("wrj:osd2:" + key.getDroneSn()); | ||||
|                 latestFullTopics.add("wrj:osd3:" + key.getDroneSn()); | ||||
|                 if (key.getAirplaneSn() != null && !key.getAirplaneSn().isEmpty()) { | ||||
|                     latestFullTopics.add("wrj:osd4:" + key.getAirplaneSn()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // 步骤3:对比现有订阅,删除过期主题 | ||||
|             cancelExpiredSubscribes(latestFullTopics); | ||||
|  | ||||
|             // 步骤4:对比现有订阅,新增未订阅的主题 | ||||
|             addNewSubscribes(latestFullTopics); | ||||
|  | ||||
|             log.info("Redis订阅更新完成,当前已订阅主题数:{}", subscribedTopics.size()); | ||||
|         } catch (Exception e) { | ||||
|             log.error("Redis订阅更新定时任务执行失败", e); | ||||
|             // 异常时不修改现有订阅,避免误删 | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| //    @Scheduled(cron = "0/10 * * * * ?") | ||||
|     @JobExecutor(name = "ueWsConnect") | ||||
|     public void ueWsConnect() { | ||||
|         try { | ||||
|             int onlineCount = InitOnStartWebSocketServer.getOnlineCount(); | ||||
|             Object object = RedisUtils.getCacheObject("xmjdap:ws"); | ||||
|             log.info("开始执行Redis订阅更新定时任务..."); | ||||
|             if (onlineCount == 0 && object == null) { | ||||
|                 cancelAllSubscribes(); | ||||
|                 return; | ||||
|             } | ||||
|             if (object != null) { | ||||
|                 long oldTime = Long.parseLong(String.valueOf(object)); | ||||
|                 long now = System.currentTimeMillis(); | ||||
|                 if (now-oldTime > 300000) { | ||||
|                     RedisUtils.deleteObject("xmjdap:ws"); | ||||
|                     cancelAllSubscribes(); | ||||
|                     return; | ||||
|                 } | ||||
|                 log.info("Redis时间缓存更新定时任务"); | ||||
|             } | ||||
|             // 步骤1:从数据库获取最新的主题列表(原逻辑:getTopicsByKeyPrefix) | ||||
|             List<DroProjectDrone> latestKeys = droProjectDroneService.getBaseMapper().selectList(new LambdaQueryWrapper<DroProjectDrone>().groupBy(DroProjectDrone::getDroneSn)); | ||||
|             if (latestKeys == null || latestKeys.isEmpty()) { | ||||
|                 log.warn("定时任务未获取到任何主题,将取消所有现有订阅"); | ||||
|                 cancelAllSubscribes(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // 步骤2:构建最新的完整主题(格式:wrj:key) | ||||
|             Set<String> latestFullTopics = new HashSet<>(); | ||||
|             for (DroProjectDrone key : latestKeys) { | ||||
|                 latestFullTopics.add("wrj:osd1:" + key.getDroneSn()); | ||||
|                 latestFullTopics.add("wrj:osd2:" + key.getDroneSn()); | ||||
|                 latestFullTopics.add("wrj:osd3:" + key.getDroneSn()); | ||||
|                 if (key.getAirplaneSn() != null && !key.getAirplaneSn().isEmpty()) { | ||||
|                     latestFullTopics.add("wrj:osd4:" + key.getAirplaneSn()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // 步骤3:对比现有订阅,删除过期主题 | ||||
|             cancelExpiredSubscribes(latestFullTopics); | ||||
|  | ||||
|             // 步骤4:对比现有订阅,新增未订阅的主题 | ||||
|             addNewSubscribes(latestFullTopics); | ||||
|  | ||||
|             log.info("Redis订阅更新完成,当前已订阅主题数:{}", subscribedTopics.size()); | ||||
|         } catch (Exception e) { | ||||
|             log.error("Redis订阅更新定时任务执行失败", e); | ||||
|             // 异常时不修改现有订阅,避免误删 | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 取消过期的订阅(现有订阅不在最新列表中的主题) | ||||
|      */ | ||||
|     public void cancelExpiredSubscribes(Set<String> latestFullTopics) { | ||||
|         // 遍历现有订阅,找出需要删除的主题 | ||||
|         Set<String> expiredTopics = subscribedTopics.keySet().stream() | ||||
|                 .filter(topic -> !latestFullTopics.contains(topic)) | ||||
|                 .collect(Collectors.toSet()); | ||||
|  | ||||
|         if (expiredTopics.isEmpty()) { | ||||
|             log.info("无过期订阅主题,无需删除"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 取消每个过期主题的订阅 | ||||
|         for (String expiredTopic : expiredTopics) { | ||||
|             PatternTopic topic = subscribedTopics.get(expiredTopic); | ||||
|             if (topic != null) { | ||||
|                 // 从容器中移除监听器(取消订阅) | ||||
|                 redisMessageListenerContainer.removeMessageListener(redisMessageListenerAdapter, topic); | ||||
|                 subscribedTopics.remove(expiredTopic); | ||||
|                 log.info("已取消过期订阅:{}", expiredTopic); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增未订阅的主题(最新列表中有但现有订阅没有的主题) | ||||
|      */ | ||||
|     public void addNewSubscribes(Set<String> latestFullTopics) { | ||||
|         // 遍历最新主题,找出需要新增的主题 | ||||
|         Set<String> newTopics = latestFullTopics.stream() | ||||
|                 .filter(topic -> !subscribedTopics.containsKey(topic)) | ||||
|                 .collect(Collectors.toSet()); | ||||
|  | ||||
|         if (newTopics.isEmpty()) { | ||||
|             log.info("无新增订阅主题,无需添加"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 为每个新主题添加订阅 | ||||
|         for (String newTopic : newTopics) { | ||||
|             PatternTopic topic = new PatternTopic(newTopic); | ||||
|             // 向容器中添加监听器(新增订阅) | ||||
|             redisMessageListenerContainer.addMessageListener(redisMessageListenerAdapter, topic); | ||||
|             subscribedTopics.put(newTopic, topic); | ||||
|             log.info("已新增订阅:{}", newTopic); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 取消所有现有订阅(兜底方法) | ||||
|      */ | ||||
|     public void cancelAllSubscribes() { | ||||
|         if (subscribedTopics.isEmpty()) { | ||||
|             return; | ||||
|         } | ||||
|         // 遍历所有已订阅主题,取消订阅 | ||||
|         for (Map.Entry<String, PatternTopic> entry : subscribedTopics.entrySet()) { | ||||
|             redisMessageListenerContainer.removeMessageListener(redisMessageListenerAdapter, entry.getValue()); | ||||
|             log.info("已取消订阅:{}", entry.getKey()); | ||||
|         } | ||||
|         subscribedTopics.clear(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| package org.dromara.bigscreen.service; | ||||
|  | ||||
| import org.springframework.data.redis.connection.Message; | ||||
|  | ||||
| /** | ||||
|  * 异步消息处理服务接口(扩展原有接口,增加Redis消息处理方法) | ||||
|  */ | ||||
| public interface IAsyncMessageHandlerService { | ||||
|     /** | ||||
|      * 异步处理Redis消息(核心:接收Message对象,处理业务逻辑) | ||||
|      * @param message Redis消息对象 | ||||
|      */ | ||||
|     void handleRedisMessageAsync(Message message); | ||||
| } | ||||
| @ -1,11 +1,11 @@ | ||||
| package org.dromara.bigscreen.service; | ||||
|  | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import org.dromara.bigscreen.domain.dto.TanchuangInfoReq; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectPeopleVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo; | ||||
| import org.dromara.manager.weathermanager.vo.WeatherVo; | ||||
| import org.dromara.gps.domain.bo.GpsEquipmentBo; | ||||
| import org.dromara.manager.weathermanager.vo.WeatherVo; | ||||
| import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo; | ||||
| import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo; | ||||
|  | ||||
| @ -64,7 +64,7 @@ public interface ProjectBigScreenService { | ||||
|      * @param projectId 项目id | ||||
|      * @return 项目形象进度 | ||||
|      */ | ||||
|     ProjectImageProgressVo getProjectImageProgress(Long projectId); | ||||
|     List<ProjectImageProgressVo> getProjectImageProgress(Long projectId); | ||||
|  | ||||
|     /** | ||||
|      * 获取项目概括 | ||||
| @ -79,4 +79,11 @@ public interface ProjectBigScreenService { | ||||
|     void setList(GpsEquipmentBo bo); | ||||
|  | ||||
|     List<Map<String, Object>> getClientList(Long projectId); | ||||
|  | ||||
|     /** | ||||
|      * 更新无人机缓存 | ||||
|      */ | ||||
|     void setWrjHc(); | ||||
|  | ||||
|     Map<String, Map<String, Object>> getInfoData(TanchuangInfoReq req); | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,180 @@ | ||||
| package org.dromara.bigscreen.service.impl; | ||||
|  | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.bigscreen.service.IAsyncMessageHandlerService; | ||||
| import org.dromara.common.websocket.dto.WebSocketMessageDto; | ||||
| import org.dromara.common.websocket.holder.WebSocketSessionHolder; | ||||
| import org.dromara.common.websocket.utils.WebSocketUtils; | ||||
| import org.dromara.drone.domain.DroProjectDrone; | ||||
| import org.dromara.drone.mapper.DroProjectDroneMapper; | ||||
| import org.springframework.data.redis.connection.Message; | ||||
| import org.springframework.data.redis.core.StringRedisTemplate; | ||||
| import org.springframework.scheduling.annotation.Async; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.Objects; | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * 异步消息处理实现(核心:原onMessage逻辑迁移至此) | ||||
|  */ | ||||
| @Slf4j | ||||
| @Service | ||||
| public class AsyncMessageHandlerServiceImpl implements IAsyncMessageHandlerService { | ||||
|  | ||||
|     @Resource | ||||
|     private StringRedisTemplate stringRedisTemplate; | ||||
|  | ||||
|     @Resource | ||||
|     private DroProjectDroneMapper droProjectDroneMapper; // 直接注入Mapper,减少Service层调用开销 | ||||
|  | ||||
|     /** | ||||
|      * 异步处理消息(指定线程池:messageAsyncExecutor) | ||||
|      */ | ||||
|     @Override | ||||
|     @Async("messageAsyncExecutor") | ||||
|     public void handleRedisMessageAsync(Message message) { | ||||
|         try { | ||||
|             // 1. 解析消息体(只解析一次,避免重复操作) | ||||
|             byte[] messageBody = message.getBody(); | ||||
|             if (messageBody == null || messageBody.length == 0) { | ||||
|                 log.warn("【异步消息处理】消息体为空,忽略处理"); | ||||
|                 return; | ||||
|             } | ||||
|             String messageContent = stringRedisTemplate.getStringSerializer().deserialize(messageBody); | ||||
|             if (messageContent == null) { | ||||
|                 log.warn("【异步消息处理】消息反序列化失败,内容:{}", new String(messageBody)); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // 2. 解析JSON(使用框架兼容的JSONUtil,处理可能的解析异常) | ||||
|             JSONObject messageJson; | ||||
|             try { | ||||
|                 messageJson = JSONUtil.parseObj(messageContent); | ||||
|             } catch (Exception e) { | ||||
|                 log.error("【异步消息处理】JSON解析失败,内容:{}", messageContent, e); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // 3. 获取gateway字段(核心业务参数) | ||||
|             String gateway = messageJson.getStr("gateway"); | ||||
|             if (gateway == null) { | ||||
|                 log.warn("【异步消息处理】消息缺少gateway字段,内容:{}", messageContent); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // 4. 解析data字段,判断key类型 | ||||
|             JSONObject dataJson = messageJson.getJSONObject("data"); | ||||
|             if (dataJson == null) { | ||||
|                 log.warn("【异步消息处理】消息缺少data字段,gateway:{}", gateway); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             String key = ""; | ||||
|             DroProjectDrone droProjectDrone = null; | ||||
|             boolean isOsd4 = false; | ||||
|  | ||||
|             // 5. 根据data字段内容判断key类型,并查询无人机信息 | ||||
|             if (dataJson.get("job_number") != null) { | ||||
|                 key = "wrj:osd1:" + gateway; | ||||
|             } else if (dataJson.get("wireless_link") != null) { | ||||
|                 key = "wrj:osd2:" + gateway; | ||||
|             } else if (dataJson.get("network_state") != null) { | ||||
|                 key = "wrj:osd3:" + gateway; | ||||
|                 // 查询无人机信息(使用LambdaQueryWrapper,框架规范) | ||||
|                 droProjectDrone = droProjectDroneMapper.selectOne( | ||||
|                     new LambdaQueryWrapper<DroProjectDrone>() | ||||
|                         .eq(DroProjectDrone::getDroneSn, gateway) | ||||
|                 ); | ||||
|                 log.info("【异步消息处理】osd3类型消息,gateway:{}", gateway); | ||||
|                 // 调用setWs方法(非osd4类型) | ||||
|                 setWs(messageContent, gateway, droProjectDrone, false); | ||||
|             } else { | ||||
|                 key = "wrj:osd4:" + gateway; | ||||
|                 droProjectDrone = droProjectDroneMapper.selectOne( | ||||
|                     new LambdaQueryWrapper<DroProjectDrone>() | ||||
|                         .eq(DroProjectDrone::getAirplaneSn, gateway) | ||||
|                 ); | ||||
|                 log.info("【异步消息处理】osd4类型消息,gateway:{}", gateway); | ||||
|                 isOsd4 = true; | ||||
|                 // 调用setWs方法(osd4类型) | ||||
|                 setWs(messageContent, gateway, droProjectDrone, true); | ||||
|             } | ||||
|  | ||||
|             // 6. 存储消息到Redis(使用Objects.requireNonNull避免空指针) | ||||
|             stringRedisTemplate.opsForValue().set(key, Objects.requireNonNull(messageContent)); | ||||
|             log.info("【异步消息处理】Redis存储成功,key:{}", key); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             // 捕获所有异常,避免线程终止 | ||||
|             log.error("【异步消息处理】整体逻辑异常", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void setWs(String message, String gateway, DroProjectDrone droProjectDrone, boolean b) { | ||||
|         //判断是否有连接 | ||||
|         Set<Long> sessionsAll = WebSocketSessionHolder.getSessionsAll(); | ||||
|         if (!sessionsAll.isEmpty()) { | ||||
|             String pushContent = buildPushMessage(gateway, message, droProjectDrone.getProjectId()); | ||||
|             // 发送给指定用户(equipment.getUserId()) | ||||
|             WebSocketMessageDto messageDto = new WebSocketMessageDto(); | ||||
|             messageDto.setMessage(pushContent); | ||||
|             messageDto.setSessionKeys(Collections.singletonList(droProjectDrone.getProjectId())); | ||||
|             WebSocketUtils.publishMessage(messageDto); | ||||
|             System.out.println("大屏已推送消息"); | ||||
|         } | ||||
|         int onlineCount = InitOnStartWebSocketServer.getOnlineCount(); | ||||
|         if (onlineCount > 0){ | ||||
|             String modleId = b ? droProjectDrone.getAirplaneModleId() : droProjectDrone.getDroneModleId(); | ||||
|             if (modleId != null) { | ||||
|                 String ued = ueStructureJsonMessage(message, modleId); | ||||
|                 InitOnStartWebSocketServer.sendToAll(ued); | ||||
|                 System.out.println("ue已推送消息"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private String buildPushMessage(String key, String message, Long projectId) { | ||||
|         JSONObject messageObj = new JSONObject(); | ||||
|         messageObj.put("type", "wrj_DATA_UPDATE"); | ||||
|         messageObj.put("projectId",projectId.toString()); | ||||
|         messageObj.put("clientId",key); | ||||
|         // 位置信息 | ||||
|         JSONObject locationObj = new JSONObject(); | ||||
|         locationObj.put("latitude", JSONUtil.parseObj(message).getJSONObject("data").get("latitude").toString()); // 纬度 | ||||
|         locationObj.put("longitude", JSONUtil.parseObj(message).getJSONObject("data").get("longitude").toString()); // 经度 | ||||
|         messageObj.put("location", locationObj); | ||||
|         return messageObj.toString(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 构建推送消息内容(String类型) | ||||
|      */ | ||||
|     private String ueStructureJsonMessage(String message, String modelId) { | ||||
|         // 构造消息对象(包含关键信息) | ||||
|         JSONObject messageObj = new JSONObject(); | ||||
|         messageObj.put("type", "location"); // 消息类型 | ||||
|  | ||||
|         JSONObject data = new JSONObject(); | ||||
|         data.put("id", modelId); | ||||
|  | ||||
|         // 位置信息 | ||||
|         JSONObject position = new JSONObject(); | ||||
|         position.put("lat", JSONUtil.parseObj(message).getJSONObject("data").get("latitude").toString()); // 纬度 | ||||
|         position.put("lng", JSONUtil.parseObj(message).getJSONObject("data").get("longitude").toString()); // 经度 | ||||
|         position.put("alt", JSONUtil.parseObj(message).getJSONObject("data").get("height").toString()); // 海拔 | ||||
|  | ||||
|         data.put("position", position); | ||||
|         messageObj.put("data", data); // 设备唯一标识 | ||||
|  | ||||
|         // 转换为String类型返回 | ||||
|         return messageObj.toString(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,110 @@ | ||||
| package org.dromara.bigscreen.service.impl;// 路径:com.ruoyi.web.websocket.InitOnStartWebSocketServer | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.websocket.*; | ||||
| import jakarta.websocket.server.ServerEndpoint; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.bigscreen.manager.RedisSubscribeManager; | ||||
| import org.dromara.common.redis.utils.RedisUtils; | ||||
| import org.dromara.drone.domain.DroProjectDrone; | ||||
| import org.dromara.drone.service.IDroProjectDroneService; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
|  | ||||
| /** | ||||
|  * 项目启动即自动启动的 WebSocket 服务端 | ||||
|  * 端点路径:/websocket/init-on-start(可自定义) | ||||
|  */ | ||||
| @Slf4j | ||||
| @ServerEndpoint("/websocket/ue") // 定义 WebSocket 端点路径 | ||||
| @Component // 交给 Spring 管理,确保启动时被扫描 | ||||
| public class InitOnStartWebSocketServer { | ||||
|  | ||||
|     // 2. 静态会话存储(线程安全,项目启动时即初始化) | ||||
|     private static final Map<String, Session> ONLINE_SESSIONS = new ConcurrentHashMap<>(); | ||||
|  | ||||
|     // 3. 静态代码块:项目启动时执行(初始化资源、打印启动日志) | ||||
|     static { | ||||
|         // 此处可添加启动时的初始化逻辑(如加载配置、连接外部资源等) | ||||
|         log.info("✅ WebSocket 服务端已随项目启动初始化!端点路径:/websocket/ue"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 客户端连接时触发(无需手动启动,有客户端连接时自动调用) | ||||
|      */ | ||||
|     @OnOpen | ||||
|     public void onOpen(Session session) { | ||||
|         // 存储新会话 | ||||
|         ONLINE_SESSIONS.put(session.getId(), session); | ||||
| //        RedisUtils.setCacheObject("xmjdap:ws",System.currentTimeMillis() ); | ||||
|         log.info("📌 客户端连接成功!会话ID:{},当前在线数:{}", session.getId(), ONLINE_SESSIONS.size()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 接收客户端消息 | ||||
|      */ | ||||
|     @OnMessage | ||||
|     public void onMessage(String message, Session session) { | ||||
|         log.info("📥 收到会话[{}]消息:{}", session.getId(), message); | ||||
|         // 可选:回复客户端(示例) | ||||
|         try { | ||||
|             session.getBasicRemote().sendText("服务端已收到消息:" + message); | ||||
|         } catch (IOException e) { | ||||
|             log.error("📤 回复会话[{}]失败:{}", session.getId(), e.getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 客户端断开连接 | ||||
|      */ | ||||
|     @OnClose | ||||
|     public void onClose(Session session, CloseReason reason) { | ||||
|         ONLINE_SESSIONS.remove(session.getId()); | ||||
|         log.info("🔌 客户端断开连接!会话ID:{},原因:{},当前在线数:{}", | ||||
|                 session.getId(), reason.getReasonPhrase(), ONLINE_SESSIONS.size()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 连接异常 | ||||
|      */ | ||||
|     @OnError | ||||
|     public void onError(Session session, Throwable error) { | ||||
|         log.error("⚠️  会话[{}]异常:{}", session.getId(), error.getMessage(), error); | ||||
|     } | ||||
|  | ||||
|     // ------------------------------ 工具方法(可选,供其他服务调用) ------------------------------ | ||||
|     /** | ||||
|      * 向所有在线客户端发送消息(项目启动后,其他服务可直接调用) | ||||
|      */ | ||||
|     public static void sendToAll(String message) { | ||||
|         if (ONLINE_SESSIONS.isEmpty()) { | ||||
|             log.warn("⚠️  无在线客户端,无需发送消息"); | ||||
|             return; | ||||
|         } | ||||
|         ONLINE_SESSIONS.values().forEach(session -> { | ||||
|             if (session.isOpen()) { | ||||
|                 try { | ||||
|                     session.getBasicRemote().sendText(message); | ||||
|                 } catch (IOException e) { | ||||
|                     log.error("📤 向会话[{}]发送消息失败:{}", session.getId(), e.getMessage()); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取当前在线数(供外部查询) | ||||
|      */ | ||||
|     public static int getOnlineCount() { | ||||
|         return ONLINE_SESSIONS.size(); | ||||
|     } | ||||
| } | ||||
| @ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.json.JSONArray; | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.annotation.Resource; | ||||
| import org.dromara.bigscreen.domain.dto.TanchuangInfoReq; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectPeopleVo; | ||||
| import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo; | ||||
| @ -15,19 +15,20 @@ import org.dromara.common.core.constant.HttpStatus; | ||||
| import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.redis.utils.RedisUtils; | ||||
| import org.dromara.common.utils.BigDecimalUtil; | ||||
| import org.dromara.common.websocket.dto.WebSocketMessageDto; | ||||
| import org.dromara.common.websocket.utils.WebSocketUtils; | ||||
| import org.dromara.contractor.domain.SubConstructionUser; | ||||
| import org.dromara.contractor.service.ISubConstructionUserService; | ||||
| import org.dromara.drone.service.IDroProjectDroneService; | ||||
| import org.dromara.gps.domain.bo.GpsEquipmentBo; | ||||
| import org.dromara.gps.domain.vo.DeviceVo; | ||||
| import org.dromara.gps.domain.vo.GpsEquipmentSonVo; | ||||
| import org.dromara.gps.domain.vo.LocationVo; | ||||
| import org.dromara.gps.service.IDeviceService; | ||||
| import org.dromara.gps.service.IGpsEquipmentService; | ||||
| import org.dromara.manager.weathermanager.vo.WeatherVo; | ||||
| import org.dromara.other.domain.OthYs7Device; | ||||
| import org.dromara.other.service.IOthYs7DeviceService; | ||||
| import org.dromara.progress.constant.PgsProgressCategoryConstant; | ||||
| import org.dromara.progress.domain.PgsProgressCategory; | ||||
| import org.dromara.progress.domain.enums.PgsProgressUnitTypeEnum; | ||||
| import org.dromara.progress.service.IPgsProgressCategoryService; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.domain.BusProjectTeam; | ||||
| @ -37,16 +38,12 @@ import org.dromara.project.domain.vo.projectnews.BusProjectNewsVo; | ||||
| import org.dromara.project.service.*; | ||||
| import org.dromara.safety.domain.HseRecognizeRecord; | ||||
| import org.dromara.safety.service.IHseRecognizeRecordService; | ||||
| import org.redisson.api.RTopic; | ||||
| import org.redisson.api.RedissonClient; | ||||
| import org.redisson.api.listener.MessageListener; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.data.redis.core.StringRedisTemplate; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.LocalTime; | ||||
| @ -95,6 +92,9 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|     @Lazy | ||||
|     private StringRedisTemplate stringRedisTemplate; | ||||
|  | ||||
|     @Resource | ||||
|     private IDeviceService deviceService; | ||||
|  | ||||
|     /** | ||||
|      * 获取项目天气 | ||||
|      * | ||||
| @ -196,6 +196,7 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|             if (CollUtil.isNotEmpty(attendancePeopleList)) { | ||||
|                 List<SubConstructionUser> users = constructionUserService.lambdaQuery() | ||||
|                     .in(SubConstructionUser::getSysUserId, attendancePeopleList) | ||||
|                     .isNotNull(SubConstructionUser::getTeamId) | ||||
|                     .list(); | ||||
|                 userTeamMap = users.stream() | ||||
|                     .collect(Collectors.groupingBy(SubConstructionUser::getTeamId)); | ||||
| @ -241,9 +242,59 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|      * @return 项目形象进度 | ||||
|      */ | ||||
|     @Override | ||||
|     public ProjectImageProgressVo getProjectImageProgress(Long projectId) { | ||||
|     public List<ProjectImageProgressVo> getProjectImageProgress(Long projectId) { | ||||
|         checkProject(projectId); | ||||
|         ProjectImageProgressVo vo = new ProjectImageProgressVo(); | ||||
|         // 获取当前项目的所有子项目 | ||||
|         List<Long> projectIds = new ArrayList<>(projectService.lambdaQuery() | ||||
|             .select(BusProject::getId) | ||||
|             .eq(BusProject::getPId, projectId) | ||||
|             .list() | ||||
|             .stream() | ||||
|             .map(BusProject::getId) | ||||
|             .toList()); | ||||
|         projectIds.add(projectId); | ||||
|         // 查询该子项目下的顶级进度类别(父ID为0) | ||||
|         List<PgsProgressCategory> list = progressCategoryService.lambdaQuery() | ||||
|             .in(PgsProgressCategory::getProjectId, projectIds) | ||||
|             .eq(PgsProgressCategory::getParentId, PgsProgressCategoryConstant.TOP_PARENT_ID) | ||||
|             .list(); | ||||
|         // 如果没有查询到顶级进度类别,直接返回空集合 | ||||
|         if (CollUtil.isEmpty(list)) { | ||||
|             return List.of(); | ||||
|         } | ||||
|         List<ProjectImageProgressVo> topList = new ArrayList<>(); | ||||
|         // 获取这些顶级类别的所有子节点 | ||||
|         List<Long> ids = list.stream().map(PgsProgressCategory::getId).distinct().toList(); | ||||
|         List<PgsProgressCategory> childrenNodes = progressCategoryService.getChildrenNodeByTopIds(ids); | ||||
|         if (CollUtil.isNotEmpty(list)) { | ||||
|             // 按名称分组(同名的放在一起) | ||||
|             Map<String, List<PgsProgressCategory>> subMap = list.stream() | ||||
|                 .collect(Collectors.groupingBy(PgsProgressCategory::getName)); | ||||
|             for (Map.Entry<String, List<PgsProgressCategory>> entry : subMap.entrySet()) { | ||||
|                 ProjectImageProgressVo topVo = new ProjectImageProgressVo(); | ||||
|                 topVo.setProgressName(entry.getKey()); | ||||
|                 List<PgsProgressCategory> value = entry.getValue(); | ||||
|                 // 获取这些类别下的所有叶子节点 | ||||
|                 List<Long> topIds = value.stream().map(PgsProgressCategory::getId).distinct().toList(); | ||||
|                 List<PgsProgressCategory> leafNodesByTopIds = childrenNodes.stream() | ||||
|                     .filter(node -> { | ||||
|                         Set<Long> ancestorSet = Arrays.stream(node.getAncestors().split(",")) | ||||
|                             .map(Long::parseLong) | ||||
|                             .collect(Collectors.toSet()); | ||||
|                         return topIds.stream().anyMatch(ancestorSet::contains); | ||||
|                     }).toList(); | ||||
|                 // 如果有叶子节点,统计进度和状态;否则初始化为未完成 | ||||
|                 if (CollUtil.isNotEmpty(leafNodesByTopIds)) { | ||||
|                     topVo.setProgressTotal(progressCategoryService.getCompletedPercentage(leafNodesByTopIds)); | ||||
|                 } else { | ||||
|                     topVo.setProgressTotal(BigDecimal.ZERO); | ||||
|                 } | ||||
|                 // 加入结果集 | ||||
|                 topList.add(topVo); | ||||
|             } | ||||
|         } | ||||
|         return topList; | ||||
| /*        ProjectImageProgressVo vo = new ProjectImageProgressVo(); | ||||
|         // 获取所有子项目列表 | ||||
|         List<BusProject> subProjectList = projectService.lambdaQuery() | ||||
|             .eq(BusProject::getPId, projectId) | ||||
| @ -368,7 +419,7 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|                 .add(vo.getBoxTransformerPercentage()) | ||||
|                 .divide(BigDecimal.valueOf(6), 2, RoundingMode.HALF_UP) // 保留两位小数 | ||||
|         ); | ||||
|         return vo; | ||||
|         return vo;*/ | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -400,7 +451,7 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|  | ||||
|     @Override | ||||
|     public List<String> getList(Long projectId) { | ||||
|         if (projectId == null){ | ||||
|         if (projectId == null) { | ||||
|             throw new ServiceException("项目id不能为空!!!"); | ||||
|         } | ||||
|         Object object = RedisUtils.getCacheObject("xmjdp:" + projectId); | ||||
| @ -414,10 +465,10 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|  | ||||
|     @Override | ||||
|     public void setList(GpsEquipmentBo bo) { | ||||
|         if (bo.getProjectId() == null){ | ||||
|         if (bo.getProjectId() == null) { | ||||
|             throw new ServiceException("项目id不能为空!!!"); | ||||
|         } | ||||
|         RedisUtils.setCacheObject("xmjdp:"+bo.getProjectId(), bo.getIdList()); | ||||
|         RedisUtils.setCacheObject("xmjdp:" + bo.getProjectId(), bo.getIdList()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @ -427,11 +478,12 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|  | ||||
|         // 获取当前时间 | ||||
|         LocalDateTime now = LocalDateTime.now(); | ||||
|         List<GpsEquipmentSonVo> voList = gpsEquipmentService.getClientList(projectId,startOfDay,now); | ||||
|         List<GpsEquipmentSonVo> appList = gpsEquipmentService.getUserListByProjectId(projectId,startOfDay,now); | ||||
|         List<GpsEquipmentSonVo> voList = gpsEquipmentService.getClientList(projectId, startOfDay, now); | ||||
|         List<GpsEquipmentSonVo> appList = gpsEquipmentService.getUserListByProjectId(projectId, startOfDay, now); | ||||
|         List<LocationVo> anqmList = deviceService.getUserListByProjectId(projectId, startOfDay, now); | ||||
|         List<OthYs7Device> othYs7DeviceList = othYs7DeviceService.lambdaQuery() | ||||
|             .eq(OthYs7Device::getProjectId, projectId) | ||||
|             .between(OthYs7Device::getUpdateTime, startOfDay, now) | ||||
| //            .between(OthYs7Device::getUpdateTime, startOfDay, now) | ||||
|             .list(); | ||||
|         List<String> wrjKeys = droProjectDroneService.getTopicsByProjectId(projectId); | ||||
|         List<Map<String, Object>> maps = new ArrayList<>(); | ||||
| @ -441,23 +493,20 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|         Map<String, Object> sbMap = new HashMap<>(); | ||||
|         Map<String, Object> wrjMap = new HashMap<>(); | ||||
|         Map<String, Object> sxtMap = new HashMap<>(); | ||||
|         Map<String, Object> wrjMap1 = new HashMap<>(); | ||||
|         Map<String, Object> sxtMap1 = new HashMap<>(); | ||||
|         List<Map<String, Object>> gpsChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> sbChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> appChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> anqmChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> wrjChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> wrjChildrenMap1 = new ArrayList<>(); | ||||
|         List<Map<String, Object>> sxtChildrenMap = new ArrayList<>(); | ||||
|         List<Map<String, Object>> sxtChildrenMap1 = new ArrayList<>(); | ||||
|         if (voList != null && !voList.isEmpty()) { | ||||
|             for (GpsEquipmentSonVo item : voList) { | ||||
|                 Map<String, Object> gps = new HashMap<>(); | ||||
|                 gps.put("id", item.getClientId()); | ||||
|                 gps.put("userId", item.getUserId()); | ||||
|                 gps.put("label", item.getClientId()); | ||||
|                 gps.put("name", item.getDeviceName()); | ||||
|                 gps.put("type", "positioningDevice"); | ||||
|                 gps.put("name", item.getUserId() != null ? item.getUserName() : item.getClientId()); | ||||
|                 gps.put("type", "gps"); | ||||
|                 gps.put("lat", item.getLocLatitude()); | ||||
|                 gps.put("lng", item.getLocLongitude()); | ||||
|                 gps.put("alt", item.getLocAltitude()); | ||||
| @ -467,16 +516,31 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|         if (appList != null && !appList.isEmpty()) { | ||||
|             for (GpsEquipmentSonVo item : appList) { | ||||
|                 Map<String, Object> app = new HashMap<>(); | ||||
|                 app.put("id", item.getClientId()); | ||||
|                 app.put("label", item.getClientId()); | ||||
|                 app.put("name", item.getDeviceName()); | ||||
|                 app.put("type", "positioningDevice"); | ||||
|                 app.put("id", item.getUserId()); | ||||
|                 app.put("userId", item.getUserId()); | ||||
|                 app.put("label", item.getUserId()); | ||||
|                 app.put("name", item.getUserName()); | ||||
|                 app.put("type", "app"); | ||||
|                 app.put("lat", item.getLocLatitude()); | ||||
|                 app.put("lng", item.getLocLongitude()); | ||||
|                 app.put("alt", item.getLocAltitude()); | ||||
|                 appChildrenMap.add(app); | ||||
|             } | ||||
|         } | ||||
|         if (anqmList != null && !anqmList.isEmpty()) { | ||||
|             for (LocationVo item : anqmList) { | ||||
|                 Map<String, Object> anqm = new HashMap<>(); | ||||
|                 anqm.put("id", item.getDevNum()); | ||||
|                 anqm.put("userId", item.getUserId()); | ||||
|                 anqm.put("label", item.getDevNum()); | ||||
|                 anqm.put("name", item.getDevNum()); | ||||
|                 anqm.put("type", "positioningDevice"); | ||||
|                 anqm.put("lat", item.getLatitude()); | ||||
|                 anqm.put("lng", item.getLongitude()); | ||||
|                 anqm.put("alt", item.getElevation()); | ||||
|                 anqmChildrenMap.add(anqm); | ||||
|             } | ||||
|         } | ||||
|         if (othYs7DeviceList != null && !othYs7DeviceList.isEmpty()) { | ||||
|             for (OthYs7Device item : othYs7DeviceList) { | ||||
|                 Map<String, Object> sxt = new HashMap<>(); | ||||
| @ -487,13 +551,20 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|                 sxt.put("lat", item.getLatitude()); | ||||
|                 sxt.put("lng", item.getLongitude()); | ||||
|                 sxt.put("alt", item.getAltitude()); | ||||
|                 sxt.put("status", item.getStatus()); | ||||
|                 sxt.put("detail", item.getDetail()); | ||||
|                 sxtChildrenMap1.add(sxt); | ||||
|                 sxtChildrenMap.add(sxt); | ||||
|             } | ||||
|         } | ||||
|         if (wrjKeys != null && !wrjKeys.isEmpty()) { | ||||
|             for (String key : wrjKeys) { | ||||
|                 Object object = stringRedisTemplate.opsForValue().get("wrj:" + key); | ||||
|                 Object object = stringRedisTemplate.opsForValue().get("wrj:osd4:" + key); | ||||
|                 Object object6 = stringRedisTemplate.opsForValue().get("wrj:osd2:" + key); | ||||
|                 String status = ""; | ||||
|                 if (object6 != null) { | ||||
|                     JSONObject object1 = JSONUtil.parseObj(object6); | ||||
|                     status = object1.getJSONObject("data").get("flighttask_step_code").toString(); | ||||
|                 } | ||||
|                 if (object != null) { | ||||
|                     JSONObject object1 = JSONUtil.parseObj(object); | ||||
|                     Map<String, Object> wrj = new HashMap<>(); | ||||
| @ -501,17 +572,32 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|                     wrj.put("label", key); | ||||
|                     wrj.put("name", key); | ||||
|                     wrj.put("type", "wurenji"); | ||||
|                     wrj.put("status", status); | ||||
|                     wrj.put("lat", object1.getJSONObject("data").get("latitude")); | ||||
|                     wrj.put("lng", object1.getJSONObject("data").get("longitude")); | ||||
|                     wrjChildrenMap1.add(wrj); | ||||
|                     wrj.put("alt", object1.getJSONObject("data").get("height")); | ||||
|                     wrjChildrenMap.add(wrj); | ||||
|                 }else { | ||||
|                     Object object2 = stringRedisTemplate.opsForValue().get("wrj:osd3:" + key); | ||||
|                     if (object2 != null) { | ||||
|                         JSONObject object3 = JSONUtil.parseObj(object2); | ||||
|                         Map<String, Object> wrj = new HashMap<>(); | ||||
|                         wrj.put("id", key); | ||||
|                         wrj.put("label", key); | ||||
|                         wrj.put("name", key); | ||||
|                         wrj.put("type", "wurenji"); | ||||
|                         wrj.put("status", status); | ||||
|                         wrj.put("lat", object3.getJSONObject("data").get("latitude")); | ||||
|                         wrj.put("lng", object3.getJSONObject("data").get("longitude")); | ||||
|                         wrj.put("alt", object3.getJSONObject("data").get("height")); | ||||
|                         wrjChildrenMap.add(wrj); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         gpsChildrenMap.add(sbMap); | ||||
|         gpsChildrenMap.add(appMap); | ||||
|         gpsChildrenMap.add(anqmMap); | ||||
|         sxtChildrenMap.add(sxtMap1); | ||||
|         wrjChildrenMap.add(wrjMap1); | ||||
|  | ||||
|         gpsMap.put("id", 1); | ||||
|         gpsMap.put("label", "人员定位"); | ||||
| @ -528,15 +614,9 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|         sxtMap.put("id", 2); | ||||
|         sxtMap.put("label", "摄像头"); | ||||
|         sxtMap.put("children", sxtChildrenMap); | ||||
|         sxtMap1.put("id", 7); | ||||
|         sxtMap1.put("label", "摄像头"); | ||||
|         sxtMap1.put("children", sxtChildrenMap1); | ||||
|         wrjMap.put("id", 3); | ||||
|         wrjMap.put("label", "无人机"); | ||||
|         wrjMap.put("children",wrjChildrenMap); | ||||
|         wrjMap1.put("id", 8); | ||||
|         wrjMap1.put("label", "无人机"); | ||||
|         wrjMap1.put("children",wrjChildrenMap1); | ||||
|         wrjMap.put("children", wrjChildrenMap); | ||||
|  | ||||
|  | ||||
|         maps.add(gpsMap); | ||||
| @ -544,4 +624,14 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|         maps.add(sxtMap); | ||||
|         return maps; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void setWrjHc() { | ||||
|         RedisUtils.setCacheObject("xmjdap:ws",System.currentTimeMillis() ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Map<String, Map<String, Object>> getInfoData(TanchuangInfoReq req) { | ||||
|         return projectService.getInfoData(req); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.dromara.cailiaoshebei.domain.bo.RemainingReq; | ||||
| import org.dromara.cailiaoshebei.domain.dto.BusMrpDto; | ||||
| import org.dromara.cailiaoshebei.domain.dto.BusMrpExportDto; | ||||
| import org.dromara.cailiaoshebei.domain.vo.BusMrpVo; | ||||
| @ -24,6 +25,10 @@ import org.dromara.design.domain.bo.CoryObtainTheListReq; | ||||
| import org.dromara.design.domain.vo.ObtainTheListRes; | ||||
| import org.dromara.design.service.IBusBillofquantitiesService; | ||||
| import org.dromara.design.service.IBusBillofquantitiesVersionsService; | ||||
| import org.dromara.tender.domain.bo.BusBiddingPlanBo; | ||||
| import org.dromara.tender.domain.vo.BusBiddingPlanVo; | ||||
| import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo; | ||||
| import org.dromara.tender.service.IBusBiddingPlanService; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| @ -59,6 +64,7 @@ public class BusMrpBaseController extends BaseController { | ||||
|     private final IBusBillofquantitiesVersionsService busBillofquantitiesVersionsService; | ||||
|  | ||||
|     private final IBusBillofquantitiesService busBillofquantitiesService; | ||||
|     private final IBusBiddingPlanService  busBiddingPlanService; | ||||
|  | ||||
|     /** | ||||
|      * 查询物资-批次需求计划基础信息列表 | ||||
| @ -141,8 +147,14 @@ public class BusMrpBaseController extends BaseController { | ||||
|      * 获取剩余量 | ||||
|      */ | ||||
|     @GetMapping("/remaining") | ||||
|     public R<Map<String,Object>> remaining(Long projectId, String suppliespriceName,String specification,Long mrpBaseId) { | ||||
|         return R.ok(busMrpBaseService.remaining(projectId,suppliespriceName,specification,mrpBaseId)); | ||||
|     public R<List<Map<String,Object>>> remaining(  RemainingReq req) { | ||||
|         String[] split = req.getLimitListId().split(","); | ||||
|         List<Map<String, Object>> maps = new ArrayList<>(); | ||||
|         for (String id : split) { | ||||
|             Map<String, Object> remaining = busMrpBaseService.remaining(req.getProjectId(), Long.valueOf(id), req.getMrpBaseId()); | ||||
|             maps.add(remaining); | ||||
|         } | ||||
|         return R.ok(maps); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -175,6 +187,35 @@ public class BusMrpBaseController extends BaseController { | ||||
|         return R.ok(list); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取工程量清单列表 | ||||
|      */ | ||||
|     @SaCheckPermission("cailiaoshebei:mrpBase:getZhaoBiaoList") | ||||
|     @GetMapping("/getZhaoBiaoList") | ||||
|     public R<List<BusBiddingPlanVo>> getZhaoBiaoList(CoryObtainTheListReq req) { | ||||
|         BusBiddingPlanBo bo = new BusBiddingPlanBo(); | ||||
|         bo.setProjectId(req.getProjectId()); | ||||
|         bo.setType("3"); | ||||
|         bo.setBidStatus(1); | ||||
|         List<BusBiddingPlanVo> busBiddingPlanVos = busBiddingPlanService.queryList(bo); | ||||
|         return R.ok(busBiddingPlanVos); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 招标计划数据详情 | ||||
|      * @param bo | ||||
|      * @return | ||||
|      */ | ||||
|     @SaCheckPermission("cailiaoshebei:mrpBase:getMore") | ||||
|     @GetMapping("/getMore") | ||||
|     public R<List<BusBillofquantitiesLimitListVo>> getMore(BusBiddingPlanBo bo) { | ||||
|         if (bo.getId() == null) { | ||||
|             throw new ServiceException("id不能为空"); | ||||
|         } | ||||
|         return R.ok(busBiddingPlanService.getMore(bo)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 获取工程量清单列表 | ||||
|      */ | ||||
|  | ||||
| @ -106,8 +106,8 @@ public class BusMrpBaseAppController extends BaseController { | ||||
|      * 获取剩余量 | ||||
|      */ | ||||
|     @GetMapping("/remaining") | ||||
|     public R<Map<String,Object>> remaining(Long projectId, String suppliespriceName,String specification,Long mrpBaseId) { | ||||
|         return R.ok(busMrpBaseService.remaining(projectId,suppliespriceName,specification,mrpBaseId)); | ||||
|     public R<Map<String,Object>> remaining(Long projectId,Long limitListId,Long mrpBaseId) { | ||||
|         return R.ok(busMrpBaseService.remaining(projectId,limitListId,mrpBaseId)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -42,6 +42,10 @@ public class BusPlanDocAssociationBo extends BaseEntity { | ||||
|      * 采购联系单id | ||||
|      */ | ||||
|     private Long docId; | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     private Long suppliespriceId; | ||||
|  | ||||
|     /** | ||||
|      * 需求数量 | ||||
|  | ||||
| @ -0,0 +1,16 @@ | ||||
| package org.dromara.cailiaoshebei.domain.bo; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| @Data | ||||
| public class RemainingReq implements Serializable { | ||||
|  | ||||
|     private Long projectId; | ||||
|  | ||||
|     private String limitListId; | ||||
|  | ||||
|     private Long mrpBaseId; | ||||
| } | ||||
| @ -140,4 +140,12 @@ public class BusMaterialbatchdemandplanVo implements Serializable { | ||||
|      */ | ||||
|     private BigDecimal remaining; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 供应商提供数量 | ||||
|      */ | ||||
|     private BigDecimal tenderQuantity; | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -86,5 +86,5 @@ public interface IBusMrpBaseService extends IService<BusMrpBase>{ | ||||
|     /** | ||||
|      * 获取物资已有数量 | ||||
|      */ | ||||
|     Map<String, Object> remaining(Long projectId, String suppliespriceName, String specification, Long mrpBaseId); | ||||
|     Map<String, Object> remaining(Long projectId,Long limitListId,Long mrpBaseId); | ||||
| } | ||||
|  | ||||
| @ -24,10 +24,13 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.design.domain.BusBillofquantities; | ||||
| import org.dromara.design.service.IBusBillofquantitiesService; | ||||
| import org.dromara.tender.domain.BusBillofquantitiesLimitList; | ||||
| import org.dromara.tender.domain.bo.BusBiddingPlanBo; | ||||
| import org.dromara.tender.domain.vo.BusBiddingPlanVo; | ||||
| import org.dromara.tender.domain.vo.BusBillofquantitiesLimitListVo; | ||||
| import org.dromara.tender.domain.vo.BusTenderPlanningLimitListVo; | ||||
| import org.dromara.tender.service.IBusBiddingPlanService; | ||||
| import org.dromara.tender.service.IBusBillofquantitiesLimitListService; | ||||
| import org.dromara.tender.service.ITenderSupplierInputService; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| @ -41,6 +44,7 @@ import org.dromara.cailiaoshebei.mapper.BusMaterialbatchdemandplanMapper; | ||||
| import org.dromara.cailiaoshebei.service.IBusMaterialbatchdemandplanService; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
| @ -72,6 +76,9 @@ public class BusMaterialbatchdemandplanServiceImpl extends ServiceImpl<BusMateri | ||||
|     @Lazy | ||||
|     @Autowired | ||||
|     private IBusBillofquantitiesService busBillofquantitiesService; | ||||
|     @Lazy | ||||
|     @Autowired | ||||
|     private IBusBillofquantitiesLimitListService busBillofquantitiesLimitListService; | ||||
|  | ||||
|     /** | ||||
|      * 查询物资-批次需求计划 | ||||
| @ -101,22 +108,26 @@ public class BusMaterialbatchdemandplanServiceImpl extends ServiceImpl<BusMateri | ||||
|             bo1.setType("3"); | ||||
|             bo1.setWinningBidderId(bo.getSupplierId()); | ||||
|             List<BusBillofquantitiesLimitListVo> busBiddingPlanVos = busBiddingPlanService.getBillofquantitiesLimitListVo(bo1); | ||||
|             Map<Long, BigDecimal> map = busBiddingPlanService.getCailiaoCount(bo1); | ||||
|             if (busBiddingPlanVos == null || busBiddingPlanVos.isEmpty()) { | ||||
|                 throw new ServiceException("该供应商暂无材料"); | ||||
|             } | ||||
|             Set<String> hashSet = new HashSet<>(); | ||||
|             busBiddingPlanVos.stream().forEach(vo -> { | ||||
|                 hashSet.add(vo.getName()+"+"+vo.getSpecification()); | ||||
|             Set<Long> hashSet = new HashSet<>(); | ||||
|             busBiddingPlanVos.forEach(vo -> { | ||||
|                 hashSet.add(vo.getId()); | ||||
|             }); | ||||
|             List<BusMaterialbatchdemandplanVo> list = result.getRecords().stream().filter(vo -> { | ||||
|                 String key = vo.getName() + "+" + vo.getSpecification(); // 拼接字符串(需与 Set 中格式一致) | ||||
|                 return hashSet.contains(key); // 仅保留 Set 中存在的数据 | ||||
|             }).toList(); | ||||
|             result.setRecords(list); | ||||
|             result.getRecords().stream().filter(vo -> { | ||||
|                 return hashSet.contains(vo.getSuppliespriceId()); // 仅保留 Set 中存在的数据 | ||||
|             }).forEach(item->{ | ||||
|                 if (map.containsKey(item.getId())) { | ||||
|                     item.setTenderQuantity(map.get(item.getId())); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|         result.getRecords().stream().forEach(vo -> { | ||||
|         result.getRecords().forEach(vo -> { | ||||
|             if (vo.getSuppliespricePid() != null){ | ||||
|                 BusBillofquantities billofquantities = busBillofquantitiesService.getById(vo.getSuppliespricePid()); | ||||
|                 BusBillofquantitiesLimitList billofquantities = busBillofquantitiesLimitListService.getById(vo.getSuppliespricePid()); | ||||
|                 vo.setSuppliespricePname(billofquantities.getName()); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
| @ -29,6 +29,10 @@ import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.utils.excel.ExcelDynamicReader; | ||||
| import org.dromara.design.domain.BusBillofquantities; | ||||
| import org.dromara.design.service.IBusBillofquantitiesService; | ||||
| import org.dromara.tender.domain.BusBillofquantitiesLimitList; | ||||
| import org.dromara.tender.domain.BusTenderPlanningLimitList; | ||||
| import org.dromara.tender.service.IBusBillofquantitiesLimitListService; | ||||
| import org.dromara.tender.service.IBusTenderPlanningLimitListService; | ||||
| import org.springframework.context.event.EventListener; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.dromara.cailiaoshebei.domain.bo.BusMrpBaseBo; | ||||
| @ -57,7 +61,10 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|  | ||||
|     private final IBusMaterialbatchdemandplanService planservice; | ||||
|  | ||||
|     private final IBusBillofquantitiesService busBillofquantitiesService; | ||||
|     private final IBusBillofquantitiesLimitListService busBillofquantitiesService; | ||||
|  | ||||
|     private final IBusTenderPlanningLimitListService  tenderPlanningLimitListService; | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
| @ -75,7 +82,7 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|         planBo.setMrpBaseId(id); | ||||
|         List<BusMaterialbatchdemandplanVo> voList = planservice.queryList(planBo); | ||||
|         for (BusMaterialbatchdemandplanVo vo : voList) { | ||||
|             Map<String, Object> map = remaining(vo.getProjectId(),vo.getName(), vo.getSpecification(), id); | ||||
|             Map<String, Object> map = remaining(vo.getProjectId(), vo.getSuppliespriceId(), id); | ||||
|             vo.setRemaining(Convert.toBigDecimal(map.get("remainingQuantity"))); | ||||
|         } | ||||
|         busMrpVo.setMrpBaseBo(busMrpBaseVo); | ||||
| @ -190,14 +197,13 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|  | ||||
|         if (CollectionUtil.isNotEmpty(dto.getPlanList())) { | ||||
|             // 按 suppliespriceId 分组统计本次提交的数量 | ||||
|             Map<String, BigDecimal> batchSumMap = dto.getPlanList().stream() | ||||
|             //                        String name = item.getName() != null ? item.getName() : ""; | ||||
|             //                        String spec = item.getSpecification() != null ? item.getSpecification() : ""; | ||||
|             //                        return name + "&&&" + spec; | ||||
|             Map<Long, BigDecimal> batchSumMap = dto.getPlanList().stream() | ||||
|                 .collect(Collectors.groupingBy( | ||||
|                     // 关键修改:使用 name + specification 拼接作为分组键 | ||||
|                     item -> { | ||||
|                         String name = item.getName() != null ? item.getName() : ""; | ||||
|                         String spec = item.getSpecification() != null ? item.getSpecification() : ""; | ||||
|                         return name + "&&&" + spec; | ||||
|                     }, | ||||
|                     BusMaterialbatchdemandplanBo::getSuppliespriceId, | ||||
|                     Collectors.reducing( | ||||
|                         BigDecimal.ZERO, | ||||
|                         item -> { | ||||
| @ -209,45 +215,36 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|                 )); | ||||
|  | ||||
|             // 检查每种物料是否超出数量限制 | ||||
|             for (Map.Entry<String, BigDecimal> entry : batchSumMap.entrySet()) { | ||||
|                 String biaoshi = entry.getKey(); | ||||
|             for (Map.Entry<Long, BigDecimal> entry : batchSumMap.entrySet()) { | ||||
|                 Long biaoshi = entry.getKey(); | ||||
|                 BigDecimal batchSum = entry.getValue(); | ||||
|                 String[] split = biaoshi.split("&&&"); | ||||
|                 // 获取数据库中已有的数量 | ||||
|                 List<BusMaterialbatchdemandplan> existingList = planservice.list( | ||||
|                     Wrappers.lambdaQuery(BusMaterialbatchdemandplan.class) | ||||
|                         .eq(BusMaterialbatchdemandplan::getName, split[0]) | ||||
|                         .eq(BusMaterialbatchdemandplan::getSpecification,split[1]) | ||||
|                         .eq(BusMaterialbatchdemandplan::getSuppliespriceId, biaoshi) | ||||
|                         .ne(BusMaterialbatchdemandplan::getMrpBaseId, convert.getId()) // 排除当前批次 | ||||
|                 ); | ||||
|  | ||||
|                 //计算数据库保存数量 | ||||
|                 BigDecimal existingSum = existingList.stream() | ||||
|                     .map(BusMaterialbatchdemandplan::getDemandQuantity) | ||||
|                     .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|  | ||||
|                 // 检查总数量是否超出限制 | ||||
|                 List<BusBillofquantities> busBillofquantities = busBillofquantitiesService.getBaseMapper().selectList(new LambdaQueryWrapper<BusBillofquantities>() | ||||
|                     .eq(BusBillofquantities::getProjectId, dto.getMrpBaseBo().getProjectId()) | ||||
|                     .eq(BusBillofquantities::getName, split[0]) | ||||
|                     .eq(BusBillofquantities::getSpecification, split[1])); | ||||
|                 BigDecimal quantity = busBillofquantities.stream() | ||||
|                     .map(BusBillofquantities::getQuantity) | ||||
|                 List<BusTenderPlanningLimitList> busTenderPlanningLimitLists = tenderPlanningLimitListService.getBaseMapper() | ||||
|                     .selectList(new LambdaQueryWrapper<BusTenderPlanningLimitList>() | ||||
|                         .eq(BusTenderPlanningLimitList::getLimitListId, biaoshi)); | ||||
|                 BigDecimal quantity = busTenderPlanningLimitLists.stream() | ||||
|                     .map(BusTenderPlanningLimitList::getNum) | ||||
|                     .filter(Objects::nonNull) | ||||
|                     .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|                 if (existingSum.add(batchSum).compareTo(quantity) > 0) { | ||||
|                     // 找到超出限制的物料名称用于提示 | ||||
|                     String itemName = dto.getPlanList().stream() | ||||
|                         .filter(item -> { | ||||
|                             String name = item.getName() != null ? item.getName() : ""; | ||||
|                             String spec = item.getSpecification() != null ? item.getSpecification() : ""; | ||||
|                             return (name + "&&&" + spec).equals(biaoshi); | ||||
|  | ||||
|                         }) | ||||
|                         .filter(item -> Objects.equals(biaoshi, item.getSuppliespriceId())) | ||||
|                         .findFirst() | ||||
|                         .map(item -> { | ||||
|                             String name = item.getName() != null ? item.getName() : ""; | ||||
|                             String spec = item.getSpecification() != null ? item.getSpecification() : ""; | ||||
|                             return "名称:“"+name + "”,规格:“" + spec+"”"; | ||||
|                             return "名称:“"+name + "”"; | ||||
|                         }) | ||||
|                         .orElse("未知物料"); | ||||
|                     throw new ServiceException(itemName + "超出数量"); | ||||
| @ -257,11 +254,11 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|             // 转换并保存数据 | ||||
|             List<BusMaterialbatchdemandplan> plans = MapstructUtils.convert(dto.getPlanList(), BusMaterialbatchdemandplan.class); | ||||
|             plans.forEach(item -> { | ||||
| //                BusBillofquantities byId = busBillofquantitiesService.getById(item.getSuppliespriceId()); | ||||
| //                if (!"0".equals(byId.getPid())) { | ||||
| //                    BusBillofquantities one = busBillofquantitiesService.getOne(new LambdaQueryWrapper<BusBillofquantities>().eq(BusBillofquantities::getSid, byId.getPid())); | ||||
| //                    item.setSuppliespricePid(one.getId()); | ||||
| //                } | ||||
|                 BusBillofquantitiesLimitList byId = busBillofquantitiesService.getById(item.getSuppliespriceId()); | ||||
|                 if (!"0".equals(byId.getPid())) { | ||||
|                     BusBillofquantitiesLimitList one = busBillofquantitiesService.getOne(new LambdaQueryWrapper<BusBillofquantitiesLimitList>().eq(BusBillofquantitiesLimitList::getSid, byId.getPid())); | ||||
|                     item.setSuppliespricePid(one.getId()); | ||||
|                 } | ||||
|                 item.setMrpBaseId(convert.getId()); | ||||
|                 item.setProjectId(convert.getProjectId()); | ||||
|             }); | ||||
| @ -297,23 +294,21 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public Map<String, Object> remaining(Long projectId, String suppliespriceName, String specification, Long mrpBaseId) { | ||||
|     public Map<String, Object> remaining(Long projectId, Long limitListId,Long mrpBaseId) { | ||||
|         Map<String, Object> map = new HashMap<>(); | ||||
|         List<BusBillofquantities> busBillofquantities = busBillofquantitiesService.getBaseMapper() | ||||
|             .selectList(new LambdaQueryWrapper<BusBillofquantities>() | ||||
|                 .eq(BusBillofquantities::getProjectId, projectId) | ||||
|                 .eq(BusBillofquantities::getName, suppliespriceName) | ||||
|                 .eq(BusBillofquantities::getSpecification,specification)); | ||||
|         BigDecimal quantity = busBillofquantities.stream() | ||||
|             .map(BusBillofquantities::getQuantity) | ||||
|         List<BusTenderPlanningLimitList> busTenderPlanningLimitLists = tenderPlanningLimitListService.getBaseMapper() | ||||
|             .selectList(new LambdaQueryWrapper<BusTenderPlanningLimitList>() | ||||
|                 .eq(BusTenderPlanningLimitList::getLimitListId, limitListId)); | ||||
|         BigDecimal quantity = busTenderPlanningLimitLists.stream() | ||||
|             .map(BusTenderPlanningLimitList::getNum) | ||||
|             .filter(Objects::nonNull) | ||||
|             .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
| //        BusBillofquantities byId = busBillofquantitiesService.getById(suppliespriceId); | ||||
|  | ||||
|         BusBillofquantitiesLimitList busBillofquantities = busBillofquantitiesService.getById(limitListId); | ||||
|         // 获取数据库中已有的数量 | ||||
|         List<BusMaterialbatchdemandplan> existingList = planservice.list( | ||||
|             Wrappers.lambdaQuery(BusMaterialbatchdemandplan.class) | ||||
|                 .eq(BusMaterialbatchdemandplan::getName, suppliespriceName) | ||||
|                 .eq(BusMaterialbatchdemandplan::getSpecification ,specification) | ||||
|                 .eq(BusMaterialbatchdemandplan::getSuppliespriceId ,limitListId) | ||||
|                 .ne(mrpBaseId!=null,BusMaterialbatchdemandplan::getMrpBaseId, mrpBaseId)// 排除当前批次 | ||||
|         ); | ||||
|         BigDecimal reduce = BigDecimal.ZERO; | ||||
| @ -323,10 +318,13 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|         } | ||||
|         map.put("remainingQuantity",quantity.subtract(reduce)); | ||||
|         map.put("specification",busBillofquantities.getFirst().getSpecification()); | ||||
|         map.put("unit",busBillofquantities.getFirst().getUnit()); | ||||
|         map.put("remark",busBillofquantities.getFirst().getRemark()); | ||||
|         map.put("name",busBillofquantities.getFirst().getName()); | ||||
|         map.put("suppliespriceId",limitListId); | ||||
|         if (busBillofquantities != null) { | ||||
|             map.put("specification",busBillofquantities.getSpecification()); | ||||
|             map.put("unit",busBillofquantities.getUnit()); | ||||
|             map.put("remark",busBillofquantities.getRemark()); | ||||
|             map.put("name",busBillofquantities.getName()); | ||||
|         } | ||||
|         return map; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -51,6 +51,8 @@ import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.service.IBusProjectService; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.dromara.tender.domain.BusTenderPlanningLimitList; | ||||
| import org.dromara.tender.service.IBusTenderPlanningLimitListService; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.context.event.EventListener; | ||||
| import org.springframework.scheduling.annotation.Async; | ||||
| @ -98,6 +100,8 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper, | ||||
|  | ||||
|     private final ISysOssService ossService; | ||||
|  | ||||
|     private final IBusTenderPlanningLimitListService tenderPlanningLimitListService; | ||||
|  | ||||
|     /** | ||||
|      * 查询物资-采购联系单 | ||||
|      * | ||||
| @ -187,7 +191,7 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper, | ||||
|  | ||||
|         BusPurchaseDoc add = MapstructUtils.convert(bo, BusPurchaseDoc.class); | ||||
|         validEntityBeforeSave(add); | ||||
|         validNum(bo.getAssociationList()); | ||||
|         validNum(bo.getAssociationList(),add.getSupplierId()); | ||||
|         boolean flag = baseMapper.insert(add) > 0; | ||||
|         if (flag) { | ||||
|             bo.setId(add.getId()); | ||||
| @ -204,20 +208,65 @@ public class BusPurchaseDocServiceImpl extends ServiceImpl<BusPurchaseDocMapper, | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public void validNum(List<BusPlanDocAssociationBo> associationList) { | ||||
|     public void validNum(List<BusPlanDocAssociationBo> associationList, Long supplierId) { | ||||
|  | ||||
|         for (BusPlanDocAssociationBo association : associationList) { | ||||
|  | ||||
|             BusMaterialbatchdemandplan byId = materialbatchdemandplanService.getById(association.getPlanId()); | ||||
|             if(association.getDemandQuantity() == null){ | ||||
|                 throw new ServiceException("请填写需求数量"); | ||||
|             } | ||||
|  | ||||
|             //获取批次需求计划 | ||||
|             BusMaterialbatchdemandplan byId = materialbatchdemandplanService.getById(association.getPlanId()); | ||||
|             List<String> statuss = new ArrayList<>(); | ||||
|             statuss.add(BusinessStatusEnum.DRAFT.getStatus()); | ||||
|             statuss.add(BusinessStatusEnum.FINISH.getStatus()); | ||||
|             statuss.add(BusinessStatusEnum.WAITING.getStatus()); | ||||
|             //查询处于草稿、待审核、已审核状态的联系单 | ||||
|             List<Long> ids = new ArrayList<>(); | ||||
|             //该供应商的联系单 | ||||
|             List<Long> ids1 = new ArrayList<>(); | ||||
|             for (BusPurchaseDoc busPurchaseDoc : baseMapper.selectList(new LambdaQueryWrapper<BusPurchaseDoc>().in(BusPurchaseDoc::getStatus, statuss))) { | ||||
|                 ids.add(busPurchaseDoc.getId()); | ||||
|                 if (busPurchaseDoc.getSupplierId().equals(supplierId)) { | ||||
|                     ids1.add(busPurchaseDoc.getId()); | ||||
|                 } | ||||
|             } | ||||
|             List<BusTenderPlanningLimitList> busTenderPlanningLimitLists = tenderPlanningLimitListService.getBaseMapper() | ||||
|                 .selectList(new LambdaQueryWrapper<BusTenderPlanningLimitList>() | ||||
|                     .eq(BusTenderPlanningLimitList::getLimitListId, association.getSuppliespriceId())); | ||||
|             BigDecimal quantity = busTenderPlanningLimitLists.stream() | ||||
|                 .map(BusTenderPlanningLimitList::getNum) | ||||
|                 .filter(Objects::nonNull) | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|             //查询处于这些采购联系单 | ||||
|             List<BusPlanDocAssociation> list = planDocAssociationService.list(Wrappers.lambdaQuery(BusPlanDocAssociation.class) | ||||
|                 .eq(BusPlanDocAssociation::getPlanId, association.getPlanId())); | ||||
|                 .eq(BusPlanDocAssociation::getPlanId, association.getPlanId()) | ||||
|                 .in(BusPlanDocAssociation::getDocId, ids)); | ||||
|             List<BusMaterialbatchdemandplan> busMaterialbatchdemandplans = materialbatchdemandplanService.getBaseMapper().selectList(new LambdaQueryWrapper<BusMaterialbatchdemandplan>() | ||||
|                 .eq(BusMaterialbatchdemandplan::getSuppliespriceId, association.getSuppliespriceId())); | ||||
|             Set<Long> planids = new HashSet<>(); | ||||
|             busMaterialbatchdemandplans.forEach(busMaterialbatchdemandplan -> { | ||||
|                 planids.add(busMaterialbatchdemandplan.getId()); | ||||
|             }); | ||||
|             if (!ids1.isEmpty()){ | ||||
|                 List<BusPlanDocAssociation> list1 = planDocAssociationService.list(Wrappers.lambdaQuery(BusPlanDocAssociation.class) | ||||
|                     .in(BusPlanDocAssociation::getDocId, ids1)); | ||||
|                 //计算材料已存在的数量 | ||||
|                 BigDecimal cltotal = list1.stream() | ||||
|                     .filter(Objects::nonNull) | ||||
|                     .filter(item->planids.contains(item.getPlanId())) | ||||
|                     .map(BusPlanDocAssociation::getDemandQuantity) | ||||
|                     .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|                 if (cltotal.add(association.getDemandQuantity()).compareTo(quantity) > 0) { | ||||
|                     throw new ServiceException("材料:" + byId.getName() + "已超出供应商提供数量"); | ||||
|                 } | ||||
|             } | ||||
|             //计算采购已存在的数量 | ||||
|             BigDecimal total = list.stream() | ||||
|                 .map(BusPlanDocAssociation::getDemandQuantity) | ||||
|                 .filter(Objects::nonNull) | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|  | ||||
|  | ||||
|             if (total.add(association.getDemandQuantity()).compareTo(byId.getDemandQuantity()) > 0) { | ||||
|                 throw new ServiceException("材料:" + byId.getName() + "已超出计划单的物料批次需求计划数量"); | ||||
|             } | ||||
|  | ||||
| @ -0,0 +1,65 @@ | ||||
| package org.dromara.common.enums; | ||||
|  | ||||
| import lombok.Data; | ||||
| import lombok.Getter; | ||||
|  | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
|  | ||||
| @Getter | ||||
| public enum AppUserTypeEnum { | ||||
|  | ||||
|  | ||||
|     SG("0", "施工人员", 2L), | ||||
|     BZZ("0", "施工人员(班组长)", 3L), | ||||
|     GL("1", "管理", 4L), | ||||
|     FB("2", "分包", 5L), | ||||
|     ; | ||||
|  | ||||
|     private final String type; | ||||
|  | ||||
|     private final String value; | ||||
|  | ||||
|     private final Long roleId; | ||||
|  | ||||
|     AppUserTypeEnum(String type, String value,Long roleId) { | ||||
|         this.type = type; | ||||
|         this.value = value; | ||||
|         this.roleId = roleId; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static final List<Long> ROLE_ID_LIST = Arrays.asList(SG.roleId, BZZ.roleId, FB.roleId, GL.roleId); | ||||
|  | ||||
|     /** | ||||
|      * roleId获取枚举 | ||||
|      * | ||||
|      * @param roleId 角色 | ||||
|      * @return 枚举 | ||||
|      */ | ||||
|     public static AppUserTypeEnum getByRoleId(Long roleId) { | ||||
|         for (AppUserTypeEnum value : AppUserTypeEnum.values()) { | ||||
|             if (value.getRoleId().equals(roleId)) { | ||||
|                 return value; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     /** | ||||
|      * type获取枚举 | ||||
|      * | ||||
|      * @param type 类型 | ||||
|      * @return 枚举 | ||||
|      */ | ||||
|     public static AppUserTypeEnum getByType(String type) { | ||||
|         for (AppUserTypeEnum value : AppUserTypeEnum.values()) { | ||||
|             if (value.getType().equals(type)) { | ||||
|                 return value; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,84 @@ | ||||
| package org.dromara.common.utils; | ||||
|  | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.common.core.utils.MessageUtils; | ||||
| import org.dromara.common.sse.dto.SseMessageDto; | ||||
| import org.dromara.common.sse.utils.SseMessageUtils; | ||||
| import org.dromara.contractor.domain.SubConstructionUser; | ||||
| import org.dromara.mobileAttendanceMachine.DeviceMessageSender; | ||||
| import org.dromara.mobileAttendanceMachine.KqjEntity; | ||||
| import org.dromara.project.domain.BusAttendanceMachine; | ||||
| import org.dromara.project.service.IBusAttendanceMachineService; | ||||
| import org.dromara.sms4j.api.SmsBlend; | ||||
| import org.dromara.sms4j.api.entity.SmsResponse; | ||||
| import org.dromara.sms4j.core.factory.SmsFactory; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.scheduling.annotation.Async; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
|  | ||||
| @Component | ||||
| @Slf4j | ||||
| public class AsyncUtil { | ||||
|  | ||||
|     @Resource | ||||
|     @Lazy | ||||
|     private DeviceMessageSender deviceMessageSender; | ||||
|     @Resource | ||||
|     @Lazy | ||||
|     private ISysOssService ossService; | ||||
|     @Resource | ||||
|     @Lazy | ||||
|     private IBusAttendanceMachineService attendanceMachineService; | ||||
|  | ||||
|     //发送短信 | ||||
|     @Async | ||||
|     public void sendSms(List<String> mobileList, String config) { | ||||
|         SmsBlend smsBlend = SmsFactory.getSmsBlend(config); | ||||
|         for (String mobile : mobileList) { | ||||
|             SmsResponse smsResponse = smsBlend.sendMessage(mobile, new LinkedHashMap<String, String>()); | ||||
|             if (!smsResponse.isSuccess()) { | ||||
|                 log.error("验证码短信发送异常 => {}", smsResponse); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     //发送sse | ||||
|     @Async | ||||
|     public void sendSse(List<Long> userId, String message) { | ||||
|         SseMessageDto sseMessageDto = new SseMessageDto(); | ||||
|         sseMessageDto.setUserIds(userId); | ||||
|         sseMessageDto.setMessage(message); | ||||
|         SseMessageUtils.publishMessage(sseMessageDto); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     //下发考勤人员 | ||||
|     @Async | ||||
|     public void sendPersonnel(Long teamId, SubConstructionUser constructionUser) { | ||||
|         SysOssVo byId = ossService.getById(Long.valueOf(constructionUser.getFacePic())); | ||||
|         List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", teamId).list(); | ||||
|         for (BusAttendanceMachine machine : list) { | ||||
|              deviceMessageSender.sendPersonnelInformation(machine.getSn(), constructionUser.getSysUserId().toString(), constructionUser.getUserName(), byId.getUrl()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     //删除考勤人员 | ||||
|     @Async | ||||
|     public void deletePersonnel(SubConstructionUser constructionUser) { | ||||
|         List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", constructionUser.getTeamId()).list(); | ||||
|         for (BusAttendanceMachine machine : list) { | ||||
|             try { | ||||
|                 deviceMessageSender.deleteUser(machine.getSn(), constructionUser.getSysUserId().toString()); | ||||
|             } catch (Exception e) { | ||||
|                 log.error("删除考勤人员异常", e); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,93 @@ | ||||
| package org.dromara.common.utils; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * 接口错误码匹配工具(用户展示用) | ||||
|  */ | ||||
| public class ErrorCodeMatcher { | ||||
|  | ||||
|     private static final Map<String, String> ERROR_MAP = new HashMap<>(); | ||||
|  | ||||
|     static { | ||||
|         // 基础错误码 | ||||
|         ERROR_MAP.put("1", "抱歉,出现未知错误,请您重试。若问题持续,请联系管理员。"); | ||||
|         ERROR_MAP.put("2", "服务暂时不可用,请稍后重试。若多次尝试仍有问题,请联系管理员。"); | ||||
|         ERROR_MAP.put("3", "调用的接口不存在,请检查请求地址是否正确(建议避免特殊字符,如手动输入重试)。"); | ||||
|         ERROR_MAP.put("4", "当前集群请求量超限,请稍后再试。持续异常请联系管理员。"); | ||||
|         ERROR_MAP.put("6", "暂无该接口调用权限,请联系管理员开通相关权限。"); | ||||
|         ERROR_MAP.put("14", "鉴权失败,请检查密钥是否正确,或联系管理员协助处理。"); | ||||
|         ERROR_MAP.put("17", "今日免费额度已用完。如需继续使用,请联系管理员获取更多资源。"); | ||||
|         ERROR_MAP.put("18", "请求频率超限(QPS限制)。如需提高限制,请联系管理员咨询。"); | ||||
|         ERROR_MAP.put("19", "总请求量已达限额,请联系管理员获取更多资源。"); | ||||
|         ERROR_MAP.put("100", "访问令牌无效,请联系管理员重新获取。"); | ||||
|         ERROR_MAP.put("110", "访问令牌无效(有效期30天),请联系管理员更新。"); | ||||
|         ERROR_MAP.put("111", "访问令牌已过期,请联系管理员重新获取。"); | ||||
|  | ||||
|         // 216xxx系列错误码 | ||||
|         ERROR_MAP.put("216100", "请求中包含无效参数,请检查后重新提交。"); | ||||
|         ERROR_MAP.put("216101", "缺少必要的请求参数,请核对后补充完整。"); | ||||
|         ERROR_MAP.put("216102", "请求的服务暂不支持,请检查调用地址是否正确,或联系管理员确认。"); | ||||
|         ERROR_MAP.put("216103", "部分参数长度超限,请缩短后重新尝试。"); | ||||
|         ERROR_MAP.put("216110", "应用ID不存在,请核对是否为正确ID,或联系管理员确认。"); | ||||
|         ERROR_MAP.put("216200", "上传的图片为空,请检查图片是否正确上传。"); | ||||
|         ERROR_MAP.put("216201", "图片格式不支持,目前仅支持PNG、JPG、JPEG、BMP格式,请转码后重试。"); | ||||
|         ERROR_MAP.put("216202", "图片大小不符合要求,请参考接口文档的限制重新上传,或联系管理员咨询。"); | ||||
|         ERROR_MAP.put("216205", "请求体过大(base64编码后需小于10M),请压缩内容后重试。"); | ||||
|         ERROR_MAP.put("216306", "文件上传失败,请检查请求参数是否符合要求。"); | ||||
|         ERROR_MAP.put("216307", "图片解析失败,若多次尝试仍有问题,请联系管理员。"); | ||||
|         ERROR_MAP.put("216308", "PDF页码参数超过实际页数,请核对后修改。"); | ||||
|         ERROR_MAP.put("216401", "请求提交失败,请稍后重试。"); | ||||
|         ERROR_MAP.put("216402", "获取结果失败,请稍后重试或检查任务状态。"); | ||||
|         ERROR_MAP.put("216603", "无法获取PDF页数,请检查文件是否完整或编码是否正确。"); | ||||
|         ERROR_MAP.put("216604", "请求总量已达限额,请联系管理员获取更多额度。"); | ||||
|         ERROR_MAP.put("216630", "识别失败,请重试。若问题持续,请联系管理员。"); | ||||
|         ERROR_MAP.put("216631", "银行卡识别失败,请确保上传的是银行卡正面完整清晰的图片(异形卡可能无法识别)。"); | ||||
|         ERROR_MAP.put("216633", "身份证识别失败,请确保上传的是身份证完整清晰的图片(非身份证或模糊图片无法识别)。"); | ||||
|         ERROR_MAP.put("216634", "检测失败,请重试。若持续异常,请联系管理员。"); | ||||
|         ERROR_MAP.put("216600", "企业核验服务请求失败,请重试。持续问题请联系管理员(适用于工商信息查询、要素核验等)。"); | ||||
|         ERROR_MAP.put("216601", "企业核验查询成功,但未找到相关结果,请确认信息是否正确后重试。"); | ||||
|         ERROR_MAP.put("216602", "企业核验服务超时,请稍后重试。持续问题请联系管理员。"); | ||||
|  | ||||
|         // 282xxx系列错误码 | ||||
|         ERROR_MAP.put("282000", "服务器内部错误。若使用通用文字识别,可能因图片文字过多导致超时,建议分割图片后重试;其他情况可稍后再试,持续问题请联系管理员。"); | ||||
|         ERROR_MAP.put("282003", "请求缺少必要参数,请核对后补充。"); | ||||
|         ERROR_MAP.put("282005", "批量任务处理出错,请根据具体错误提示排查。"); | ||||
|         ERROR_MAP.put("282006", "批量任务数量超限,单次最多处理10个任务,请减少数量后重试。"); | ||||
|         ERROR_MAP.put("282100", "图片压缩转码失败,请更换图片后重试。"); | ||||
|         ERROR_MAP.put("282102", "未检测到可识别的卡证/票据,请确保图片包含清晰完整的目标(非卡证或模糊图片无法识别)。"); | ||||
|         ERROR_MAP.put("282103", "卡证/票据识别失败,请确保图片包含清晰完整的目标(非对应类型或模糊图片无法识别)。"); | ||||
|         ERROR_MAP.put("282110", "图片URL不存在,请核对地址后重新提交。"); | ||||
|         ERROR_MAP.put("282111", "图片URL格式错误,请检查是否符合接口要求的格式。"); | ||||
|         ERROR_MAP.put("282112", "图片URL下载超时,可能因图片过大(超过3M)、地址无效或存在防盗链。建议更换图片地址或下载后直接上传。"); | ||||
|         ERROR_MAP.put("282113", "图片URL返回无效内容,请检查地址是否正确。"); | ||||
|         ERROR_MAP.put("282114", "图片URL长度不符合要求(需1-1024字节),请修改后重试。"); | ||||
|         ERROR_MAP.put("282134", "增值税发票验真失败,可能因系统维护,建议次日再试。持续问题请联系管理员。"); | ||||
|         ERROR_MAP.put("282808", "请求ID不存在,请核对ID是否正确。"); | ||||
|         ERROR_MAP.put("282809", "返回结果格式错误(需为excel或json),请稍后重试。"); | ||||
|         ERROR_MAP.put("282810", "图像识别失败,请重试。若问题持续,请联系管理员。"); | ||||
|         ERROR_MAP.put("282160", "行驶证核验资源超限,请联系管理员咨询。"); | ||||
|         ERROR_MAP.put("282161", "行驶证核验请求过于频繁,请稍后再试。"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据错误码获取用户友好的错误信息 | ||||
|      * @param errorCode 错误码(字符串/整数) | ||||
|      * @return 优化后的错误提示,未匹配时返回"未知错误(错误码:xxx)" | ||||
|      */ | ||||
|     public static String getFriendlyMessage(String errorCode) { | ||||
|         return ERROR_MAP.getOrDefault(errorCode, "未知错误(错误码:" + errorCode + "),请重试或联系管理员。"); | ||||
|     } | ||||
|  | ||||
|     public static String getFriendlyMessage(int errorCode) { | ||||
|         return getFriendlyMessage(String.valueOf(errorCode)); | ||||
|     } | ||||
|  | ||||
|     // 测试示例 | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println(getFriendlyMessage(1)); // 输出:抱歉,出现未知错误,请您重试... | ||||
|         System.out.println(getFriendlyMessage("216201")); // 输出:图片格式不支持,目前仅支持PNG... | ||||
|         System.out.println(getFriendlyMessage(9999)); // 输出:未知错误(错误码:9999)... | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,89 @@ | ||||
| package org.dromara.common.utils.attendance; | ||||
|  | ||||
|  | ||||
| import cn.hutool.http.HttpUtil; | ||||
| import com.alibaba.fastjson2.JSON; | ||||
| import com.alibaba.fastjson2.JSONArray; | ||||
| import com.alibaba.fastjson2.JSONObject; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.scheduling.annotation.Async; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| @Slf4j | ||||
| public class FaceUtil { | ||||
|  | ||||
|     private static final String FACE_URL = "http://192.168.110.5:1224"; | ||||
|  | ||||
|     /** | ||||
|      * 创建人脸记录  post | ||||
|      * @param name 姓名 | ||||
|      * @param card 身份证 | ||||
|      * @param path 人脸图片HTTP地址(需可公开访问) | ||||
|      */ | ||||
|     public static void createFaceRecord(String name, String card, String path) { | ||||
|         String url = FACE_URL+"/api/faces"; | ||||
|  | ||||
|         HashMap<String, Object> param = new HashMap<>() {{ | ||||
|             put("name", name); | ||||
|             put("card", card); | ||||
|             put("path", path); | ||||
|         }}; | ||||
|         HttpUtil.post(url, param); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 人脸检测 | ||||
|      * @param path 图片HTTP地址(需可公开访问) | ||||
|      */ | ||||
|     public static Map<String, String> faceDetect(String path) { | ||||
|         String url = FACE_URL+"/api/faces/detect"; | ||||
|  | ||||
|         HashMap<String, Object> param = new HashMap<>() {{ | ||||
|             put("path", path); | ||||
|             put("similarity_threshold", 0.8); | ||||
|         }}; | ||||
|         //转成json | ||||
|  | ||||
|         String post = HttpUtil.post(url, param); | ||||
|         Map<String, String> map = new HashMap<>(); | ||||
|         // 遍历检测到的人脸数据 | ||||
|         try { | ||||
|             // 解析返回的JSON数据 | ||||
|             JSONObject response = JSON.parseObject(post); | ||||
|             JSONObject data = response.getJSONObject("data"); | ||||
|             JSONArray detectedFaces = data.getJSONArray("detected_faces"); | ||||
|  | ||||
|             for (int i = 0; i < detectedFaces.size(); i++) { | ||||
|                 JSONObject face = detectedFaces.getJSONObject(i); | ||||
|                 JSONObject matchInfo = face.getJSONObject("match_info"); | ||||
|  | ||||
|                 // 检查相似度是否大于等于阈值 | ||||
|                 double similarity = matchInfo.getDoubleValue("similarity"); | ||||
|                 double threshold = matchInfo.getDoubleValue("threshold"); | ||||
|  | ||||
|                 if (similarity >= threshold) { | ||||
|                     // 提取用户信息 | ||||
|                     JSONObject userInfo = face.getJSONObject("user_info"); | ||||
|                     String name = userInfo.getString("name"); | ||||
|                     String idCard = userInfo.getString("id_card"); | ||||
|                     map.put(idCard, name); | ||||
|                 } | ||||
|             } | ||||
|         }catch (Exception e){ | ||||
|             log.error("人脸检测失败",e); | ||||
|         } | ||||
|         return map; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static void main(String[] args) { | ||||
| //        Map<String, String> map = faceDetect("http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/12/9688ce2474ad47e7bf59c641848cdf8f.jpg"); | ||||
| //        System.out.println(map); | ||||
| //        createFaceRecord("石志强","513022111145632652","http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/10/12/9688ce2474ad47e7bf59c641848cdf8f.jpg"); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -3,6 +3,7 @@ package org.dromara.common.utils.baiduUtil; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.dromara.common.utils.ErrorCodeMatcher; | ||||
| import org.dromara.common.utils.baiduUtil.entity.face.ComparisonRes; | ||||
| import org.dromara.common.utils.baiduUtil.entity.face.HumanFaceReq; | ||||
| import org.dromara.common.utils.baiduUtil.entity.face.HumanFaceRes; | ||||
| @ -208,8 +209,7 @@ public class BaiDuFace { | ||||
|  | ||||
|         // 8. 处理API返回错误 | ||||
|         if (comparisonRep.getErrorCode() != 0) { | ||||
|             throw new RuntimeException("人脸对比失败:" + comparisonRep.getErrorMsg() | ||||
|                 + "(错误码:" + comparisonRep.getErrorCode() + ")"); | ||||
|             throw new RuntimeException("人脸对比失败:" + ErrorCodeMatcher.getFriendlyMessage(comparisonRep.getErrorCode())); | ||||
|         } | ||||
|  | ||||
|         // 9. 校验对比结果 | ||||
|  | ||||
| @ -364,10 +364,11 @@ public class SubConstructionUserController extends BaseController { | ||||
|                     if (user.getEntryDate() != null) { | ||||
|                         vo.setEntryDate(DateUtils.formatDateTime(user.getEntryDate())); | ||||
|                     } | ||||
|                     //0男 1女 2未知 | ||||
|                     String sex = vo.getSex(); | ||||
|                     if (sex != null && sex.equals("1")) { | ||||
|                     if (sex != null && sex.equals("0")) { | ||||
|                         vo.setSex("男"); | ||||
|                     } else if (sex != null && sex.equals("2")) { | ||||
|                     } else if (sex != null && sex.equals("1")) { | ||||
|                         vo.setSex("女"); | ||||
|                     } else { | ||||
|                         vo.setSex("未知"); | ||||
|  | ||||
| @ -3,7 +3,6 @@ package org.dromara.contractor.controller.app; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| @ -136,7 +135,7 @@ public class SubConstructionUserAppController { | ||||
|     @Log(title = "施工人员", businessType = BusinessType.OTHER) | ||||
|     @PostMapping("/face/comparison") | ||||
|     public R<Boolean> faceComparison(@RequestParam("file") MultipartFile file) { | ||||
|         return R.ok(constructionUserService.faceComparison(file)); | ||||
|         return R.ok(constructionUserService.faceComparison(file,null )); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package org.dromara.contractor.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableLogic; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| @ -204,4 +205,10 @@ public class SubConstructionUser extends BaseEntity { | ||||
|     private Long goId; | ||||
|  | ||||
|     private String goOpenid; | ||||
|  | ||||
|     /** | ||||
|      * 删除标志(0代表存在 1代表删除) | ||||
|      */ | ||||
|     @TableLogic | ||||
|     private String delFlag; | ||||
| } | ||||
|  | ||||
| @ -36,7 +36,7 @@ public class SubConstructionUserAuthenticationReq implements Serializable { | ||||
|     private String phone; | ||||
|  | ||||
|     /** | ||||
|      * 0:保密 1:男 2女 | ||||
|      * 0男1女2未知 | ||||
|      */ | ||||
|     @NotBlank(message = "性别不能为空") | ||||
|     private String sex; | ||||
|  | ||||
| @ -101,4 +101,7 @@ public class SubConstructionUserQueryReq implements Serializable { | ||||
|      */ | ||||
|     private String userId; | ||||
|  | ||||
|  | ||||
|     private String phone; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -213,10 +213,11 @@ public interface ISubConstructionUserService extends IService<SubConstructionUse | ||||
|     /** | ||||
|      * 人脸识别 | ||||
|      * | ||||
|      * @param file 图片文件 | ||||
|      * @param file   图片文件 | ||||
|      * @param userId | ||||
|      * @return 是否匹配成功 | ||||
|      */ | ||||
|     Boolean faceComparison(MultipartFile file); | ||||
|     Boolean faceComparison(MultipartFile file, Long userId); | ||||
|  | ||||
|     /** | ||||
|      * 根据系统用户id查询施工人员 | ||||
|  | ||||
| @ -19,12 +19,14 @@ import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.core.utils.DateUtils; | ||||
| import org.dromara.common.core.utils.ObjectUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.enums.AppUserTypeEnum; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.oss.core.OssClient; | ||||
| import org.dromara.common.oss.exception.OssException; | ||||
| import org.dromara.common.oss.factory.OssFactory; | ||||
| import org.dromara.common.satoken.utils.LoginHelper; | ||||
| import org.dromara.common.utils.AsyncUtil; | ||||
| import org.dromara.common.utils.IdCardEncryptorUtil; | ||||
| import org.dromara.common.utils.baiduUtil.BaiDuFace; | ||||
| import org.dromara.common.utils.baiduUtil.BaiDuOCR; | ||||
| @ -45,6 +47,7 @@ import org.dromara.contractor.mapper.SubConstructionUserMapper; | ||||
| import org.dromara.contractor.service.ISubConstructionUserFileService; | ||||
| import org.dromara.contractor.service.ISubConstructionUserService; | ||||
| import org.dromara.contractor.service.ISubContractorService; | ||||
| import org.dromara.mobileAttendanceMachine.DeviceMessageSender; | ||||
| import org.dromara.project.domain.*; | ||||
| import org.dromara.project.domain.enums.BusAttendanceClockStatusEnum; | ||||
| import org.dromara.project.domain.enums.BusAttendanceCommuterEnum; | ||||
| @ -150,6 +153,11 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|     @Resource | ||||
|     private ISysRoleService roleService; | ||||
|  | ||||
|     @Resource | ||||
|     private AsyncUtil asyncUtil; | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询施工人员 | ||||
|      * | ||||
| @ -183,7 +191,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|             List<BusProjectTeamAppVo> byUserId = projectTeamService.getByUserId(userId, req.getProjectId()); | ||||
|  | ||||
|             if (CollectionUtil.isEmpty(byUserId)) { | ||||
|                 return new TableDataInfo<>(); | ||||
|                 return TableDataInfo.build(new ArrayList<>()); | ||||
|             } | ||||
|             list1 = byUserId.stream().map(BusProjectTeamAppVo::getId).toList(); | ||||
|         } | ||||
| @ -201,8 +209,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         LambdaQueryWrapper<SubConstructionUser> lqw = Wrappers.lambdaQuery(); | ||||
|         // 从对象中取值 | ||||
|         String userName = req.getUserName(); | ||||
|         String phone = req.getPhone(); | ||||
|  | ||||
|         // 模糊查询 | ||||
|         lqw.like(StringUtils.isNotBlank(phone), SubConstructionUser::getPhone, phone); | ||||
|         lqw.like(StringUtils.isNotBlank(userName), SubConstructionUser::getUserName, userName); | ||||
|         lqw.isNull(SubConstructionUser::getProjectId); | ||||
|         lqw.isNull(SubConstructionUser::getTeamId); | ||||
| @ -276,7 +286,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         userRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery() | ||||
|             .eq(SysUserRole::getUserId, constructionUser.getSysUserId()) | ||||
|             .eq(SysUserRole::getProjectId, dto.getProjectId()) | ||||
|             .in(SysUserRole::getRoleId, Arrays.asList(2L, 3L)) | ||||
|             .in(SysUserRole::getRoleId, AppUserTypeEnum.ROLE_ID_LIST) | ||||
|         ); | ||||
|         //再添加分配角色 | ||||
|         Long roleId = "0".equals(dto.getPostId()) ? 2L : 3L; | ||||
| @ -289,6 +299,8 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         //强退 | ||||
|         roleService.cleanOnlineUser(Collections.singletonList(constructionUser.getSysUserId())); | ||||
|  | ||||
|         asyncUtil.sendPersonnel(dto.getTeamId(), constructionUser); | ||||
|  | ||||
|         return i > 0; | ||||
|     } | ||||
|  | ||||
| @ -1394,6 +1406,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         SysUserBo sysUserBo = new SysUserBo(); | ||||
|         sysUserBo.setUserId(userId); | ||||
|         sysUserBo.setNickName(user.getUserName()); | ||||
|         sysUserBo.setSex(user.getSex()); | ||||
|         userService.updateUser(sysUserBo); | ||||
|         return user.getId(); | ||||
|     } | ||||
| @ -1417,15 +1430,18 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|     /** | ||||
|      * 人脸识别 | ||||
|      * | ||||
|      * @param file 图片文件 | ||||
|      * @param file   图片文件 | ||||
|      * @param userId | ||||
|      * @return 是否匹配成功 | ||||
|      */ | ||||
|     @Override | ||||
|     public Boolean faceComparison(MultipartFile file) { | ||||
|     public Boolean faceComparison(MultipartFile file, Long userId) { | ||||
|         String reqBase64 = this.getPicBase64(file); | ||||
|         HumanFaceReq request = new HumanFaceReq(); | ||||
|         request.setImage(reqBase64); | ||||
|         Long userId = LoginHelper.getUserId(); | ||||
|         if(userId == null){ | ||||
|            userId = LoginHelper.getUserId(); | ||||
|         } | ||||
|         SubConstructionUser constructionUser = this.getBySysUserId(userId); | ||||
|         if (constructionUser == null || StringUtils.isBlank(constructionUser.getFacePic())) { | ||||
|             throw new ServiceException("未进行实名认证"); | ||||
| @ -1510,8 +1526,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU | ||||
|         lqw.eq(ObjectUtils.isNotEmpty(typeOfWork), SubConstructionUser::getTypeOfWork, typeOfWork); | ||||
|  | ||||
|         lqw.isNull(SubConstructionUser::getTeamId); | ||||
|         lqw.eq(SubConstructionUser::getUserRole, "0"); | ||||
|         if (req.getProjectId() == null) { | ||||
|             lqw.isNull(SubConstructionUser::getProjectId); | ||||
|             lqw.apply("exists (select 1 from sys_user where user_id = sys_user_id and dept_id is null)"); | ||||
|         } else { | ||||
|             lqw.eq(SubConstructionUser::getProjectId, req.getProjectId()); | ||||
|         } | ||||
|  | ||||
| @ -295,7 +295,7 @@ public class SubUserSalaryDetailServiceImpl extends ServiceImpl<SubUserSalaryDet | ||||
|             List<BusProjectTeamAppVo> byUserId = projectTeamService.getByUserId(userId, dto.getProjectId()); | ||||
|  | ||||
|             if(CollectionUtil.isEmpty(byUserId)){ | ||||
|                 return new TableDataInfo<>(); | ||||
|                 return  TableDataInfo.build(new ArrayList<>()); | ||||
|             } | ||||
|             list1 = byUserId.stream().map(BusProjectTeamAppVo::getId).toList(); | ||||
|         } | ||||
|  | ||||
| @ -0,0 +1,116 @@ | ||||
| package org.dromara.ctr.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.ctr.domain.bo.CtrContractProgressSettlementBo; | ||||
| import org.dromara.ctr.domain.dto.CtrContractProgressSettlementCreateReq; | ||||
| import org.dromara.ctr.domain.dto.CtrContractProgressSettlementUpdateReq; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementTotalVo; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementVo; | ||||
| import org.dromara.ctr.service.ICtrContractProgressSettlementService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/ctr/contractProgressSettlement") | ||||
| public class CtrContractProgressSettlementController extends BaseController { | ||||
|  | ||||
|     private final ICtrContractProgressSettlementService ctrContractProgressSettlementService; | ||||
|  | ||||
|     /** | ||||
|      * 查询承包合同进度结算列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<CtrContractProgressSettlementVo> list(CtrContractProgressSettlementBo bo, PageQuery pageQuery) { | ||||
|         return ctrContractProgressSettlementService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出承包合同进度结算列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:export") | ||||
|     @Log(title = "承包合同进度结算", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(CtrContractProgressSettlementBo bo, HttpServletResponse response) { | ||||
|         List<CtrContractProgressSettlementVo> list = ctrContractProgressSettlementService.queryList(bo); | ||||
|         ExcelUtil.exportExcel(list, "承包合同进度结算", CtrContractProgressSettlementVo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取承包合同进度结算详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<CtrContractProgressSettlementVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                                       @PathVariable Long id) { | ||||
|         return R.ok(ctrContractProgressSettlementService.queryById(id)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增承包合同进度结算 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:add") | ||||
|     @Log(title = "承包合同进度结算", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<Void> add(@Validated @RequestBody CtrContractProgressSettlementCreateReq req) { | ||||
|         return toAjax(ctrContractProgressSettlementService.insertByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改承包合同进度结算 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:edit") | ||||
|     @Log(title = "承包合同进度结算", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated @RequestBody CtrContractProgressSettlementUpdateReq req) { | ||||
|         return toAjax(ctrContractProgressSettlementService.updateByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询金额合计 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:query") | ||||
|     @GetMapping("/queryMoneyTotal") | ||||
|     public R<CtrContractProgressSettlementTotalVo> queryMoneyTotal(CtrContractProgressSettlementBo bo) { | ||||
|         return R.ok(ctrContractProgressSettlementService.queryMoneyTotal(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除承包合同进度结算 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:remove") | ||||
|     @Log(title = "承包合同进度结算", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(ctrContractProgressSettlementService.deleteWithValidByIds(List.of(ids), true)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,105 @@ | ||||
| package org.dromara.ctr.controller; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementItemVo; | ||||
| import org.dromara.ctr.domain.bo.CtrContractProgressSettlementItemBo; | ||||
| import org.dromara.ctr.service.ICtrContractProgressSettlementItemService; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算清单 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/ctr/contractProgressSettlementItem") | ||||
| public class CtrContractProgressSettlementItemController extends BaseController { | ||||
|  | ||||
|     private final ICtrContractProgressSettlementItemService ctrContractProgressSettlementItemService; | ||||
|  | ||||
|     /** | ||||
|      * 查询承包合同进度结算清单列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<CtrContractProgressSettlementItemVo> list(CtrContractProgressSettlementItemBo bo, PageQuery pageQuery) { | ||||
|         return ctrContractProgressSettlementItemService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出承包合同进度结算清单列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:export") | ||||
|     @Log(title = "承包合同进度结算清单", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(CtrContractProgressSettlementItemBo bo, HttpServletResponse response) { | ||||
|         List<CtrContractProgressSettlementItemVo> list = ctrContractProgressSettlementItemService.queryList(bo); | ||||
|         ExcelUtil.exportExcel(list, "承包合同进度结算清单", CtrContractProgressSettlementItemVo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取承包合同进度结算清单详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<CtrContractProgressSettlementItemVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                      @PathVariable Long id) { | ||||
|         return R.ok(ctrContractProgressSettlementItemService.queryById(id)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增承包合同进度结算清单 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:add") | ||||
|     @Log(title = "承包合同进度结算清单", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<Void> add(@Validated(AddGroup.class) @RequestBody CtrContractProgressSettlementItemBo bo) { | ||||
|         return toAjax(ctrContractProgressSettlementItemService.insertByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改承包合同进度结算清单 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:edit") | ||||
|     @Log(title = "承包合同进度结算清单", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated(EditGroup.class) @RequestBody CtrContractProgressSettlementItemBo bo) { | ||||
|         return toAjax(ctrContractProgressSettlementItemService.updateByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除承包合同进度结算清单 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlementItem:remove") | ||||
|     @Log(title = "承包合同进度结算清单", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(ctrContractProgressSettlementItemService.deleteWithValidByIds(List.of(ids), true)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,106 @@ | ||||
| package org.dromara.ctr.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.ctr.domain.bo.CtrSubcontractProgressSettlementBo; | ||||
| import org.dromara.ctr.domain.dto.CtrSubcontractProgressSettlementCreateReq; | ||||
| import org.dromara.ctr.domain.dto.CtrSubcontractProgressSettlementUpdateReq; | ||||
| import org.dromara.ctr.domain.vo.CtrSubcontractProgressSettlementVo; | ||||
| import org.dromara.ctr.service.ICtrSubcontractProgressSettlementService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/ctr/subcontractProgressSettlement") | ||||
| public class CtrSubcontractProgressSettlementController extends BaseController { | ||||
|  | ||||
|     private final ICtrSubcontractProgressSettlementService ctrSubcontractProgressSettlementService; | ||||
|  | ||||
|     /** | ||||
|      * 查询分包合同进度结算列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<CtrSubcontractProgressSettlementVo> list(CtrSubcontractProgressSettlementBo bo, PageQuery pageQuery) { | ||||
|         return ctrSubcontractProgressSettlementService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出分包合同进度结算列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:export") | ||||
|     @Log(title = "分包合同进度结算", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(CtrSubcontractProgressSettlementBo bo, HttpServletResponse response) { | ||||
|         List<CtrSubcontractProgressSettlementVo> list = ctrSubcontractProgressSettlementService.queryList(bo); | ||||
|         ExcelUtil.exportExcel(list, "分包合同进度结算", CtrSubcontractProgressSettlementVo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取分包合同进度结算详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<CtrSubcontractProgressSettlementVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                                          @PathVariable Long id) { | ||||
|         return R.ok(ctrSubcontractProgressSettlementService.queryById(id)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增分包合同进度结算 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:add") | ||||
|     @Log(title = "分包合同进度结算", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<Void> add(@Validated @RequestBody CtrSubcontractProgressSettlementCreateReq req) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementService.insertByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改分包合同进度结算 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:edit") | ||||
|     @Log(title = "分包合同进度结算", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated @RequestBody CtrSubcontractProgressSettlementUpdateReq req) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementService.updateByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除分包合同进度结算 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlement:remove") | ||||
|     @Log(title = "分包合同进度结算", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementService.deleteWithValidByIds(List.of(ids), true)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,105 @@ | ||||
| package org.dromara.ctr.controller; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import org.dromara.ctr.domain.vo.CtrSubcontractProgressSettlementItemVo; | ||||
| import org.dromara.ctr.domain.bo.CtrSubcontractProgressSettlementItemBo; | ||||
| import org.dromara.ctr.service.ICtrSubcontractProgressSettlementItemService; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算清单 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/ctr/subcontractProgressSettlementItem") | ||||
| public class CtrSubcontractProgressSettlementItemController extends BaseController { | ||||
|  | ||||
|     private final ICtrSubcontractProgressSettlementItemService ctrSubcontractProgressSettlementItemService; | ||||
|  | ||||
|     /** | ||||
|      * 查询分包合同进度结算清单列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<CtrSubcontractProgressSettlementItemVo> list(CtrSubcontractProgressSettlementItemBo bo, PageQuery pageQuery) { | ||||
|         return ctrSubcontractProgressSettlementItemService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出分包合同进度结算清单列表 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:export") | ||||
|     @Log(title = "分包合同进度结算清单", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(CtrSubcontractProgressSettlementItemBo bo, HttpServletResponse response) { | ||||
|         List<CtrSubcontractProgressSettlementItemVo> list = ctrSubcontractProgressSettlementItemService.queryList(bo); | ||||
|         ExcelUtil.exportExcel(list, "分包合同进度结算清单", CtrSubcontractProgressSettlementItemVo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取分包合同进度结算清单详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<CtrSubcontractProgressSettlementItemVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                      @PathVariable Long id) { | ||||
|         return R.ok(ctrSubcontractProgressSettlementItemService.queryById(id)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增分包合同进度结算清单 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:add") | ||||
|     @Log(title = "分包合同进度结算清单", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<Void> add(@Validated(AddGroup.class) @RequestBody CtrSubcontractProgressSettlementItemBo bo) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementItemService.insertByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改分包合同进度结算清单 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:edit") | ||||
|     @Log(title = "分包合同进度结算清单", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated(EditGroup.class) @RequestBody CtrSubcontractProgressSettlementItemBo bo) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementItemService.updateByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除分包合同进度结算清单 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:subcontractProgressSettlementItem:remove") | ||||
|     @Log(title = "分包合同进度结算清单", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(ctrSubcontractProgressSettlementItemService.deleteWithValidByIds(List.of(ids), true)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,139 @@ | ||||
| package org.dromara.ctr.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算对象 ctr_contract_progress_settlement | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("ctr_contract_progress_settlement") | ||||
| public class CtrContractProgressSettlement extends BaseEntity { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 结算日期 | ||||
|      */ | ||||
|     private LocalDate settlementDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位(客户) | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal settlementMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期扣款金额 | ||||
|      */ | ||||
|     private BigDecimal deductionMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期奖励金额 | ||||
|      */ | ||||
|     private BigDecimal bonus; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal thisSettlementRatio; | ||||
|  | ||||
|     /** | ||||
|      * 支付条款 | ||||
|      */ | ||||
|     private Long paymentTerms; | ||||
|  | ||||
|     /** | ||||
|      * 多文件逗号分隔 | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,107 @@ | ||||
| package org.dromara.ctr.domain; | ||||
|  | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import com.baomidou.mybatisplus.annotation.*; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| import java.io.Serial; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算清单对象 ctr_contract_progress_settlement_item | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("ctr_contract_progress_settlement_item") | ||||
| public class CtrContractProgressSettlementItem extends BaseEntity { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 结算单ID | ||||
|      */ | ||||
|     private Long settlementId; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1合同内清单 2变更增加清单 3合同外清单) | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,123 @@ | ||||
| package org.dromara.ctr.domain; | ||||
|  | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import com.baomidou.mybatisplus.annotation.*; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算对象 ctr_subcontract_progress_settlement | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("ctr_subcontract_progress_settlement") | ||||
| public class CtrSubcontractProgressSettlement extends BaseEntity { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 单据日期 | ||||
|      */ | ||||
|     private LocalDate documentDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位 | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal currentSettlementRate; | ||||
|  | ||||
|     /** | ||||
|      * 文件ID | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      */ | ||||
|     private String auditStatus; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,130 @@ | ||||
| package org.dromara.ctr.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算清单对象 ctr_subcontract_progress_settlement_item | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @TableName("ctr_subcontract_progress_settlement_item") | ||||
| public class CtrSubcontractProgressSettlementItem implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 结算单ID | ||||
|      */ | ||||
|     private Long settlementId; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1合同内清单 2变更增加清单 3合同外清单) | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 税额 | ||||
|      */ | ||||
|     private String tax; | ||||
|  | ||||
|     /** | ||||
|      * WBS工作分解结构 | ||||
|      */ | ||||
|     private String wbs; | ||||
|  | ||||
|     /** | ||||
|      * CBS成本分解结构 | ||||
|      */ | ||||
|     private String cbs; | ||||
|  | ||||
|     /** | ||||
|      * CBS预算总额 | ||||
|      */ | ||||
|     private BigDecimal cbsBudgetTotal; | ||||
|  | ||||
|     /** | ||||
|      * CBS余额 | ||||
|      */ | ||||
|     private BigDecimal cbsBalance; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,150 @@ | ||||
| package org.dromara.ctr.domain.bo; | ||||
|  | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlement; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算业务对象 ctr_contract_progress_settlement | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = CtrContractProgressSettlement.class, reverseConvertGenerate = false) | ||||
| public class CtrContractProgressSettlementBo extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @NotNull(message = "主键ID不能为空", groups = {EditGroup.class}) | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     @NotNull(message = "所属部门不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     @NotBlank(message = "单据编码不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     @NotBlank(message = "标题不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 结算日期 | ||||
|      */ | ||||
|     @NotNull(message = "结算日期不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private LocalDate settlementDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     @NotBlank(message = "合同编码不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1付款 2收款) | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     @NotNull(message = "审批金额不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位(客户) | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal settlementMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期扣款金额 | ||||
|      */ | ||||
|     private BigDecimal deductionMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期奖励金额 | ||||
|      */ | ||||
|     private BigDecimal bonus; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal thisSettlementRatio; | ||||
|  | ||||
|     /** | ||||
|      * 支付条款 | ||||
|      */ | ||||
|     private Long paymentTerms; | ||||
|  | ||||
|     /** | ||||
|      * 多文件逗号分隔 | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,110 @@ | ||||
| package org.dromara.ctr.domain.bo; | ||||
|  | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlementItem; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import jakarta.validation.constraints.*; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算清单业务对象 ctr_contract_progress_settlement_item | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = CtrContractProgressSettlementItem.class, reverseConvertGenerate = false) | ||||
| public class CtrContractProgressSettlementItemBo extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 结算单ID | ||||
|      */ | ||||
|     @NotNull(message = "结算单ID不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private Long settlementId; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1合同内清单 2变更增加清单 3合同外清单) | ||||
|      */ | ||||
|     @NotBlank(message = "类型(1合同内清单 2变更增加清单 3合同外清单)不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     @NotBlank(message = "编码不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     @NotBlank(message = "合同清单名称不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     @NotBlank(message = "计量单位不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,122 @@ | ||||
| package org.dromara.ctr.domain.bo; | ||||
|  | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlement; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import jakarta.validation.constraints.*; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算业务对象 ctr_subcontract_progress_settlement | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = CtrSubcontractProgressSettlement.class, reverseConvertGenerate = false) | ||||
| public class CtrSubcontractProgressSettlementBo extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     @NotBlank(message = "单据编码不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     @NotBlank(message = "标题不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 单据日期 | ||||
|      */ | ||||
|     @NotNull(message = "单据日期不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private LocalDate documentDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     @NotBlank(message = "合同编码不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     @NotNull(message = "审批金额不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位 | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal currentSettlementRate; | ||||
|  | ||||
|     /** | ||||
|      * 文件ID | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      */ | ||||
|     private String auditStatus; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,136 @@ | ||||
| package org.dromara.ctr.domain.bo; | ||||
|  | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlementItem; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import jakarta.validation.constraints.*; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * 分包合同进度结算清单业务对象 ctr_subcontract_progress_settlement_item | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = CtrSubcontractProgressSettlementItem.class, reverseConvertGenerate = false) | ||||
| public class CtrSubcontractProgressSettlementItemBo extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 结算单ID | ||||
|      */ | ||||
|     @NotNull(message = "结算单ID不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private Long settlementId; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1合同内清单 2变更增加清单 3合同外清单) | ||||
|      */ | ||||
|     @NotBlank(message = "类型(1合同内清单 2变更增加清单 3合同外清单)不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     @NotBlank(message = "编码不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     @NotBlank(message = "合同清单名称不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     @NotBlank(message = "计量单位不能为空", groups = { AddGroup.class, EditGroup.class }) | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 税额 | ||||
|      */ | ||||
|     private String tax; | ||||
|  | ||||
|     /** | ||||
|      * WBS工作分解结构 | ||||
|      */ | ||||
|     private String wbs; | ||||
|  | ||||
|     /** | ||||
|      * CBS成本分解结构 | ||||
|      */ | ||||
|     private String cbs; | ||||
|  | ||||
|     /** | ||||
|      * CBS预算总额 | ||||
|      */ | ||||
|     private BigDecimal cbsBudgetTotal; | ||||
|  | ||||
|     /** | ||||
|      * CBS余额 | ||||
|      */ | ||||
|     private BigDecimal cbsBalance; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,148 @@ | ||||
| package org.dromara.ctr.domain.dto; | ||||
|  | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlement; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 承包合同进度结算业务对象 ctr_contract_progress_settlement | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 | ||||
|  */ | ||||
| @Data | ||||
| @AutoMapper(target = CtrContractProgressSettlement.class, reverseConvertGenerate = false) | ||||
| public class CtrContractProgressSettlementCreateReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = -7707258738219359278L; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     @NotNull(message = "所属部门不能为空") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     @NotBlank(message = "标题不能为空") | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 结算日期 | ||||
|      */ | ||||
|     @NotNull(message = "结算日期不能为空") | ||||
|     private LocalDate settlementDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     @NotBlank(message = "合同编码不能为空") | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     @NotNull(message = "审批金额不能为空") | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位(客户) | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal settlementMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期扣款金额 | ||||
|      */ | ||||
|     private BigDecimal deductionMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期奖励金额 | ||||
|      */ | ||||
|     private BigDecimal bonus; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal thisSettlementRatio; | ||||
|  | ||||
|     /** | ||||
|      * 支付条款 | ||||
|      */ | ||||
|     private Long paymentTerms; | ||||
|  | ||||
|     /** | ||||
|      * 多文件逗号分隔 | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|     /** | ||||
|      * 合同内清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemCreateReq> inInventory; | ||||
|  | ||||
|     /** | ||||
|      * 变更增加清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemCreateReq> changeInventory; | ||||
|  | ||||
|     /** | ||||
|      * 合同外清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemCreateReq> outInventory; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,86 @@ | ||||
| package org.dromara.ctr.domain.dto; | ||||
|  | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 17:05 | ||||
|  */ | ||||
| @Data | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class CtrContractProgressSettlementItemCreateReq { | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     @NotBlank(message = "编码不能为空") | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     @NotBlank(message = "合同清单名称不能为空") | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     @NotBlank(message = "计量单位不能为空") | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
| } | ||||
| @ -0,0 +1,91 @@ | ||||
| package org.dromara.ctr.domain.dto; | ||||
|  | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 17:39 | ||||
|  */ | ||||
| @Data | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class CtrContractProgressSettlementItemUpdateReq { | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 编码 | ||||
|      */ | ||||
|     @NotBlank(message = "编码不能为空") | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 合同清单名称 | ||||
|      */ | ||||
|     @NotBlank(message = "合同清单名称不能为空") | ||||
|     private String name; | ||||
|  | ||||
|     /** | ||||
|      * 计量单位 | ||||
|      */ | ||||
|     @NotBlank(message = "计量单位不能为空") | ||||
|     private String unit; | ||||
|  | ||||
|     /** | ||||
|      * 单价 | ||||
|      */ | ||||
|     private BigDecimal unitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 含税单价 | ||||
|      */ | ||||
|     private BigDecimal taxUnitPrice; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算数量 | ||||
|      */ | ||||
|     private BigDecimal currentQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算百分比 | ||||
|      */ | ||||
|     private BigDecimal currentRate; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal currentAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算不含税金额 | ||||
|      */ | ||||
|     private BigDecimal currentNoAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批数量 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedQty; | ||||
|  | ||||
|     /** | ||||
|      * 本期审批金额 | ||||
|      */ | ||||
|     private BigDecimal currentApprovedAmount; | ||||
|  | ||||
|     /** | ||||
|      * 税率(%) | ||||
|      */ | ||||
|     private String taxRate; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
| } | ||||
| @ -0,0 +1,157 @@ | ||||
| package org.dromara.ctr.domain.dto; | ||||
|  | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlement; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 17:30 | ||||
|  */ | ||||
| @Data | ||||
| @AutoMapper(target = CtrContractProgressSettlement.class, reverseConvertGenerate = false) | ||||
| public class CtrContractProgressSettlementUpdateReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = -105855005415297131L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @NotNull(message = "主键ID不能为空") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     @NotNull(message = "所属部门不能为空") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     @NotBlank(message = "单据编码不能为空") | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     @NotBlank(message = "标题不能为空") | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 结算日期 | ||||
|      */ | ||||
|     @NotNull(message = "结算日期不能为空") | ||||
|     private LocalDate settlementDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     @NotBlank(message = "合同编码不能为空") | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     @NotNull(message = "审批金额不能为空") | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位(客户) | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|     private BigDecimal settlementMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期扣款金额 | ||||
|      */ | ||||
|     private BigDecimal deductionMoney; | ||||
|  | ||||
|     /** | ||||
|      * 本期奖励金额 | ||||
|      */ | ||||
|     private BigDecimal bonus; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal thisSettlementRatio; | ||||
|  | ||||
|     /** | ||||
|      * 支付条款 | ||||
|      */ | ||||
|     private Long paymentTerms; | ||||
|  | ||||
|     /** | ||||
|      * 多文件逗号分隔 | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|     /** | ||||
|      * 合同内清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemUpdateReq> inInventory; | ||||
|  | ||||
|     /** | ||||
|      * 变更增加清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemUpdateReq> changeInventory; | ||||
|  | ||||
|     /** | ||||
|      * 合同外清单 | ||||
|      */ | ||||
|     private List<CtrContractProgressSettlementItemUpdateReq> outInventory; | ||||
| } | ||||
| @ -0,0 +1,129 @@ | ||||
| package org.dromara.ctr.domain.dto; | ||||
|  | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlement; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-18 19:14 | ||||
|  */ | ||||
| @Data | ||||
| @AutoMapper(target = CtrSubcontractProgressSettlement.class, reverseConvertGenerate = false) | ||||
| public class CtrSubcontractProgressSettlementCreateReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 770553999547826460L; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|     @NotBlank(message = "标题不能为空") | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 单据日期 | ||||
|      */ | ||||
|     @NotNull(message = "单据日期不能为空") | ||||
|     private LocalDate documentDate; | ||||
|  | ||||
|     /** | ||||
|      * 合同编码 | ||||
|      */ | ||||
|     @NotBlank(message = "合同编码不能为空") | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|     private String contractName; | ||||
|  | ||||
|     /** | ||||
|      * 统计周期 | ||||
|      */ | ||||
|     private String contractProgress; | ||||
|  | ||||
|     /** | ||||
|      * 计量开始日期 | ||||
|      */ | ||||
|     private LocalDate measureDateBegin; | ||||
|  | ||||
|     /** | ||||
|      * 计量结束日期 | ||||
|      */ | ||||
|     private LocalDate measureDateEnd; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 项目名称 | ||||
|      */ | ||||
|     private String projectName; | ||||
|  | ||||
|     /** | ||||
|      * 审批金额 | ||||
|      */ | ||||
|     @NotNull(message = "审批金额不能为空") | ||||
|     private BigDecimal approvalAmount; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位 | ||||
|      */ | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|     private BigDecimal contractAmount; | ||||
|  | ||||
|     /** | ||||
|      * 本次结算比例 | ||||
|      */ | ||||
|     private BigDecimal currentSettlementRate; | ||||
|  | ||||
|     /** | ||||
|      * 文件ID | ||||
|      */ | ||||
|     private String fileId; | ||||
|  | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      */ | ||||
|     private String auditStatus; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|     /** | ||||
|      * 合同内清单 | ||||
|      */ | ||||
|     private List<CtrSubcontractProgressSettlementItemCreateReq> inInventory; | ||||
|  | ||||
|     /** | ||||
|      * 变更增加清单 | ||||
|      */ | ||||
|     private List<CtrSubcontractProgressSettlementItemCreateReq> changeInventory; | ||||
|  | ||||
|     /** | ||||
|      * 合同外清单 | ||||
|      */ | ||||
|     private List<CtrSubcontractProgressSettlementItemCreateReq> outInventory; | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	