Compare commits
	
		
			168 Commits
		
	
	
		
			c7338b45ad
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | 
| @ -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 | ||||
| @ -49,41 +59,41 @@ spring: | ||||
|           driverClassName: com.mysql.cj.jdbc.Driver | ||||
|           # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 | ||||
|           # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) | ||||
| #          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 | ||||
|           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/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 | ||||
|       #          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 | ||||
| @ -354,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,12 +39,18 @@ 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 | ||||
|     dynamic: | ||||
|       # 性能分析插件(有性能损耗 不建议生产环境使用) | ||||
|       p6spy: true | ||||
|       p6spy: false | ||||
|       # 设置默认的数据源或者数据源组,默认值即为 master | ||||
|       primary: master | ||||
|       # 严格模式 匹配不到数据源则报错 | ||||
| @ -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 | ||||
| @ -326,7 +336,7 @@ ys7: | ||||
|   app-key: 3acf9f1a43dc4209841e0893003db0a2 | ||||
|   app-secret: 09e29c70ae1161fbc3ce2030fc09ba2e | ||||
|   job: | ||||
|     capture-enabled: false   # 控制是否启用萤石抓拍任务 | ||||
|     capture-enabled: true   # 控制是否启用萤石抓拍任务 | ||||
|     device-sync-enabled: true # 控制是否同步萤石设备 | ||||
| # 斯巴达算法 | ||||
| sparta: | ||||
| @ -344,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: | ||||
| @ -277,14 +281,16 @@ springdoc: | ||||
|       packages-to-scan: org.dromara.gps | ||||
|     - group: 24.招标模块 | ||||
|       packages-to-scan: org.dromara.tender | ||||
| #    - group: 25.app版本模块 | ||||
| #      packages-to-scan: org.dromara.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 | ||||
| @ -300,6 +306,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.
										
									
								
							| @ -5,7 +5,6 @@ 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.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||||
| @ -30,6 +29,8 @@ 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; | ||||
| @ -56,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; | ||||
|  | ||||
| /** | ||||
| @ -113,6 +116,9 @@ public class DemoTest { | ||||
|     @Resource | ||||
|     private IOthYs7DeviceService ys7DeviceService; | ||||
|  | ||||
|     @Resource | ||||
|     private IOthYs7DeviceImgService ys7DeviceImgService; | ||||
|  | ||||
|     @Resource | ||||
|     private Ys7Manager ys7Manager; | ||||
|  | ||||
| @ -129,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, 10, 13); // 截止时间(2025-09-15) | ||||
|         LocalDate end = LocalDate.of(2025, 10, 20); // 截止时间(2025-09-15) | ||||
|  | ||||
|         // 如果起始不是周一,调整到当周的周一 | ||||
|         if (start.getDayOfWeek() != DayOfWeek.MONDAY) { | ||||
| @ -149,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)) { | ||||
|                 // 下一周 | ||||
| @ -244,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()); | ||||
| @ -253,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; | ||||
| @ -548,4 +554,38 @@ public class DemoTest { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @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.SOLAR)); | ||||
|         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); | ||||
| } | ||||
| @ -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 | ||||
|  | ||||
| @ -15,16 +15,31 @@ | ||||
|         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>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> | ||||
| @ -36,18 +51,18 @@ | ||||
|             </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) --> | ||||
| @ -119,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> | ||||
| @ -280,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); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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,6 +1,5 @@ | ||||
| package org.dromara.bigscreen.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import cn.hutool.core.collection.CollectionUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| @ -10,10 +9,7 @@ import lombok.RequiredArgsConstructor; | ||||
| 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; | ||||
| @ -21,7 +17,12 @@ 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.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| 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.land.domain.BusLandBlock; | ||||
| import org.dromara.land.domain.BusLandTransferLedger; | ||||
| @ -34,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; | ||||
| @ -87,6 +89,8 @@ public class ProjectBigScreenController extends BaseController { | ||||
|  | ||||
|     private final BusLandTransferLedgerSonServiceImpl busLandTransferLedgerSonService; | ||||
|  | ||||
|     private final IFacRedLineService facRedLineService; | ||||
|  | ||||
|     /** | ||||
|      * 查询项目土地统计 | ||||
|      */ | ||||
| @ -272,6 +276,10 @@ public class ProjectBigScreenController extends BaseController { | ||||
|                 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)); | ||||
|     } | ||||
|  | ||||
| @ -296,7 +304,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询GPS设备用户列表 | ||||
|      */ | ||||
|     @SaCheckPermission("project:big:screen") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getList") | ||||
|     public R<List<String>> getList(Long projectId) { | ||||
|         return R.ok(projectBigScreenService.getList(projectId)); | ||||
| @ -316,7 +324,7 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询地图项目分类 | ||||
|      */ | ||||
|     @SaCheckPermission("project:big:screen") | ||||
| //    @SaCheckPermission("project:big:screen") | ||||
|     @GetMapping("/getProjectMapList") | ||||
|     public R<Map<String, Map<String, Map<String, String>>>> getProjectMapList() { | ||||
|         return R.ok(projectService.getProjectMapList()); | ||||
| @ -325,12 +333,28 @@ public class ProjectBigScreenController extends BaseController { | ||||
|     /** | ||||
|      * 查询地图项目分类 | ||||
|      */ | ||||
|     @SaCheckPermission("project:big:screen") | ||||
| //    @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); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询项目地域分散图 | ||||
| @ -369,4 +393,12 @@ public class ProjectBigScreenController extends BaseController { | ||||
|         return R.ok(projectBigScreenService.getInfoData(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询设施-红线列表 | ||||
|      */ | ||||
|     @GetMapping("/redLine/list") | ||||
|     public TableDataInfo<FacRedLineVo> list(FacRedLineBo bo, PageQuery pageQuery) { | ||||
|         return facRedLineService.queryPageList(bo, pageQuery); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| @ -505,7 +505,7 @@ public class ProjectBigScreenServiceImpl implements ProjectBigScreenService { | ||||
|                 gps.put("id", item.getClientId()); | ||||
|                 gps.put("userId", item.getUserId()); | ||||
|                 gps.put("label", item.getClientId()); | ||||
|                 gps.put("name", item.getDeviceName()); | ||||
|                 gps.put("name", item.getUserId() != null ? item.getUserName() : item.getClientId()); | ||||
|                 gps.put("type", "gps"); | ||||
|                 gps.put("lat", item.getLocLatitude()); | ||||
|                 gps.put("lng", item.getLocLongitude()); | ||||
|  | ||||
| @ -318,11 +318,13 @@ public class BusMrpBaseServiceImpl extends ServiceImpl<BusMrpBaseMapper, BusMrpB | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add); | ||||
|         } | ||||
|         map.put("remainingQuantity",quantity.subtract(reduce)); | ||||
|         map.put("specification",busBillofquantities.getSpecification()); | ||||
|         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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,12 +1,21 @@ | ||||
| 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; | ||||
|  | ||||
| @ -17,6 +26,16 @@ import java.util.List; | ||||
| @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) { | ||||
| @ -39,4 +58,27 @@ public class AsyncUtil { | ||||
|     } | ||||
|  | ||||
|  | ||||
|     //下发考勤人员 | ||||
|     @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("未知"); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 查询施工人员 | ||||
|      * | ||||
| @ -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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -6,7 +6,6 @@ import jakarta.validation.constraints.NotEmpty; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| @ -17,6 +16,7 @@ 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; | ||||
| @ -92,6 +92,15 @@ public class CtrContractProgressSettlementController extends BaseController { | ||||
|         return toAjax(ctrContractProgressSettlementService.updateByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询金额合计 | ||||
|      */ | ||||
|     @SaCheckPermission("ctr:contractProgressSettlement:query") | ||||
|     @GetMapping("/queryMoneyTotal") | ||||
|     public R<CtrContractProgressSettlementTotalVo> queryMoneyTotal(CtrContractProgressSettlementBo bo) { | ||||
|         return R.ok(ctrContractProgressSettlementService.queryMoneyTotal(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除承包合同进度结算 | ||||
|      * | ||||
|  | ||||
| @ -29,6 +29,11 @@ public class CtrSubcontractProgressSettlement extends BaseEntity { | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|  | ||||
| @ -60,6 +60,11 @@ public class CtrContractProgressSettlementBo extends BaseEntity { | ||||
|     @NotBlank(message = "合同编码不能为空", groups = {AddGroup.class, EditGroup.class}) | ||||
|     private String contractCode; | ||||
|  | ||||
|     /** | ||||
|      * 类型(1付款 2收款) | ||||
|      */ | ||||
|     private String type; | ||||
|  | ||||
|     /** | ||||
|      * 合同名称 | ||||
|      */ | ||||
|  | ||||
| @ -31,12 +31,6 @@ public class CtrContractProgressSettlementCreateReq implements Serializable { | ||||
|     @NotNull(message = "所属部门不能为空") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
|     @NotBlank(message = "单据编码不能为空") | ||||
|     private String documentCode; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|      */ | ||||
|  | ||||
| @ -24,10 +24,9 @@ public class CtrSubcontractProgressSettlementCreateReq implements Serializable { | ||||
|     private static final long serialVersionUID = 770553999547826460L; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     @NotBlank(message = "单据编码不能为空") | ||||
|     private String documentCode; | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 标题 | ||||
|  | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.dromara.ctr.domain.vo; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-10-21 11:01 | ||||
|  */ | ||||
| @Data | ||||
| public class CtrContractProgressSettlementTotalVo implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1537548228169684228L; | ||||
|  | ||||
|     /** | ||||
|      * 总金额 | ||||
|      */ | ||||
|     private BigDecimal moneyTotal; | ||||
| } | ||||
| @ -41,6 +41,12 @@ public class CtrContractProgressSettlementVo implements Serializable { | ||||
|     @ExcelProperty(value = "所属部门") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 部门名称 | ||||
|      */ | ||||
|     @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "deptId") | ||||
|     private String deptName; | ||||
|  | ||||
|     /** | ||||
|      * 单据编码 | ||||
|      */ | ||||
| @ -114,6 +120,12 @@ public class CtrContractProgressSettlementVo implements Serializable { | ||||
|     @ExcelProperty(value = "结算单位(客户)") | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位名称 | ||||
|      */ | ||||
|     @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "settlementUnit") | ||||
|     private String settlementUnitName; | ||||
|  | ||||
|     /** | ||||
|      * 本期结算金额 | ||||
|      */ | ||||
|  | ||||
| @ -4,6 +4,8 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import org.dromara.common.translation.annotation.Translation; | ||||
| import org.dromara.common.translation.constant.TransConstant; | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlement; | ||||
|  | ||||
| import java.io.Serial; | ||||
| @ -45,6 +47,18 @@ public class CtrSubcontractProgressSettlementVo implements Serializable { | ||||
|     @ExcelProperty(value = "标题") | ||||
|     private String title; | ||||
|  | ||||
|     /** | ||||
|      * 所属部门 | ||||
|      */ | ||||
|     @ExcelProperty(value = "所属部门") | ||||
|     private Long deptId; | ||||
|  | ||||
|     /** | ||||
|      * 部门名称 | ||||
|      */ | ||||
|     @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "deptId") | ||||
|     private String deptName; | ||||
|  | ||||
|     /** | ||||
|      * 单据日期 | ||||
|      */ | ||||
| @ -105,6 +119,12 @@ public class CtrSubcontractProgressSettlementVo implements Serializable { | ||||
|     @ExcelProperty(value = "结算单位") | ||||
|     private Long settlementUnit; | ||||
|  | ||||
|     /** | ||||
|      * 结算单位名称 | ||||
|      */ | ||||
|     @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "settlementUnit") | ||||
|     private String settlementUnitName; | ||||
|  | ||||
|     /** | ||||
|      * 合同金额 | ||||
|      */ | ||||
|  | ||||
| @ -7,6 +7,7 @@ import org.dromara.ctr.domain.CtrContractProgressSettlement; | ||||
| 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 java.util.Collection; | ||||
| @ -45,6 +46,14 @@ public interface ICtrContractProgressSettlementService extends IService<CtrContr | ||||
|      */ | ||||
|     List<CtrContractProgressSettlementVo> queryList(CtrContractProgressSettlementBo bo); | ||||
|  | ||||
|     /** | ||||
|      * 查询金额统计 | ||||
|      * | ||||
|      * @param bo 查询条件 | ||||
|      * @return 金额统计 | ||||
|      */ | ||||
|     CtrContractProgressSettlementTotalVo queryMoneyTotal(CtrContractProgressSettlementBo bo); | ||||
|  | ||||
|     /** | ||||
|      * 新增承包合同进度结算 | ||||
|      * | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package org.dromara.ctr.service.impl; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| @ -8,9 +9,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.core.utils.MapstructUtils; | ||||
| import org.dromara.common.core.utils.ObjectUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.satoken.utils.LoginHelper; | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlement; | ||||
| import org.dromara.ctr.domain.CtrContractProgressSettlementItem; | ||||
| import org.dromara.ctr.domain.bo.CtrContractProgressSettlementBo; | ||||
| @ -19,18 +22,22 @@ import org.dromara.ctr.domain.dto.CtrContractProgressSettlementItemCreateReq; | ||||
| import org.dromara.ctr.domain.dto.CtrContractProgressSettlementItemUpdateReq; | ||||
| import org.dromara.ctr.domain.dto.CtrContractProgressSettlementUpdateReq; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementItemVo; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementTotalVo; | ||||
| import org.dromara.ctr.domain.vo.CtrContractProgressSettlementVo; | ||||
| import org.dromara.ctr.mapper.CtrContractProgressSettlementMapper; | ||||
| import org.dromara.ctr.service.ICtrContractProgressSettlementItemService; | ||||
| import org.dromara.ctr.service.ICtrContractProgressSettlementService; | ||||
| import org.dromara.system.domain.vo.SysDeptVo; | ||||
| import org.dromara.system.service.ISysDeptService; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.math.BigDecimal; | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.format.DateTimeFormatter; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
| @ -46,6 +53,8 @@ public class CtrContractProgressSettlementServiceImpl extends ServiceImpl<CtrCon | ||||
|  | ||||
|     private final ICtrContractProgressSettlementItemService contractProgressSettlementItemService; | ||||
|  | ||||
|     private final ISysDeptService deptService; | ||||
|  | ||||
|     /** | ||||
|      * 查询承包合同进度结算 | ||||
|      * | ||||
| @ -97,11 +106,66 @@ public class CtrContractProgressSettlementServiceImpl extends ServiceImpl<CtrCon | ||||
|         return baseMapper.selectVoList(lqw); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询金额统计 | ||||
|      * | ||||
|      * @param bo 查询条件 | ||||
|      * @return 金额统计 | ||||
|      */ | ||||
|     @Override | ||||
|     public CtrContractProgressSettlementTotalVo queryMoneyTotal(CtrContractProgressSettlementBo bo) { | ||||
|         LambdaQueryWrapper<CtrContractProgressSettlement> lqw = Wrappers.lambdaQuery(); | ||||
|         Long deptId = bo.getDeptId(); | ||||
|         String type = bo.getType(); | ||||
|         if (ObjectUtils.isNotEmpty(deptId) && StringUtils.isNotBlank(type) && !LoginHelper.isSuperAdmin()) { | ||||
|             SysDeptVo sysDeptVo = deptService.selectDeptById(deptId); | ||||
|             List<Long> list = StringUtils.splitTo(sysDeptVo.getAncestors(), Convert::toLong); | ||||
|             if (list.size() == 2 && Objects.equals(type, "1")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getDeptId, deptId); | ||||
|             } else if (list.size() == 2 && Objects.equals(type, "2")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getSettlementUnit, deptId); | ||||
|             } else if (list.size() > 2 && Objects.equals(type, "1")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getDeptId, list.get(2)); | ||||
|             } else if (list.size() > 2 && Objects.equals(type, "2")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getSettlementUnit, list.get(2)); | ||||
|             } | ||||
|         } | ||||
|         List<CtrContractProgressSettlement> settlementList = this.list(lqw); | ||||
|         CtrContractProgressSettlementTotalVo vo = new CtrContractProgressSettlementTotalVo(); | ||||
|         if (CollUtil.isEmpty(settlementList)) { | ||||
|             return vo; | ||||
|         } | ||||
|         if (Objects.equals(type, "1")) { | ||||
|             vo.setMoneyTotal(settlementList.stream().map(CtrContractProgressSettlement::getSettlementMoney) | ||||
|                 .filter(Objects::nonNull) | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add)); | ||||
|         } else if (Objects.equals(type, "2")) { | ||||
|             vo.setMoneyTotal(settlementList.stream().map(CtrContractProgressSettlement::getDeductionMoney) | ||||
|                 .filter(Objects::nonNull) | ||||
|                 .reduce(BigDecimal.ZERO, BigDecimal::add)); | ||||
|         } | ||||
|         return vo; | ||||
|     } | ||||
|  | ||||
|     private LambdaQueryWrapper<CtrContractProgressSettlement> buildQueryWrapper(CtrContractProgressSettlementBo bo) { | ||||
|         Map<String, Object> params = bo.getParams(); | ||||
|         LambdaQueryWrapper<CtrContractProgressSettlement> lqw = Wrappers.lambdaQuery(); | ||||
|         lqw.orderByDesc(CtrContractProgressSettlement::getId); | ||||
|         lqw.eq(bo.getDeptId() != null, CtrContractProgressSettlement::getDeptId, bo.getDeptId()); | ||||
|         Long deptId = bo.getDeptId(); | ||||
|         String type = bo.getType(); | ||||
|         if (ObjectUtils.isNotEmpty(deptId) && StringUtils.isNotBlank(type) && !LoginHelper.isSuperAdmin()) { | ||||
|             SysDeptVo sysDeptVo = deptService.selectDeptById(deptId); | ||||
|             List<Long> list = StringUtils.splitTo(sysDeptVo.getAncestors(), Convert::toLong); | ||||
|             if (list.size() == 2 && Objects.equals(type, "1")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getDeptId, deptId); | ||||
|             } else if (list.size() == 2 && Objects.equals(type, "2")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getSettlementUnit, deptId); | ||||
|             } else if (list.size() > 2 && Objects.equals(type, "1")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getDeptId, list.get(2)); | ||||
|             } else if (list.size() > 2 && Objects.equals(type, "2")) { | ||||
|                 lqw.eq(CtrContractProgressSettlement::getSettlementUnit, list.get(2)); | ||||
|             } | ||||
|         } | ||||
|         lqw.like(StringUtils.isNotBlank(bo.getDocumentCode()), CtrContractProgressSettlement::getDocumentCode, bo.getDocumentCode()); | ||||
|         lqw.eq(StringUtils.isNotBlank(bo.getTitle()), CtrContractProgressSettlement::getTitle, bo.getTitle()); | ||||
|         lqw.eq(bo.getSettlementDate() != null, CtrContractProgressSettlement::getSettlementDate, bo.getSettlementDate()); | ||||
| @ -134,8 +198,25 @@ public class CtrContractProgressSettlementServiceImpl extends ServiceImpl<CtrCon | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Boolean insertByBo(CtrContractProgressSettlementCreateReq req) { | ||||
|         CtrContractProgressSettlement add = MapstructUtils.convert(req, CtrContractProgressSettlement.class); | ||||
|         if (Objects.equals(req.getDeptId(), req.getSettlementUnit())) { | ||||
|             throw new ServiceException("结算单位不能与收款单位相同"); | ||||
|         } | ||||
|         // 生成唯一编号 | ||||
|         LocalDate today = LocalDate.now(); | ||||
|         Long userId = LoginHelper.getUserId(); | ||||
|         boolean flag; | ||||
|         synchronized (userId.toString().intern()) { | ||||
|             LocalDateTime startOfDay = today.atStartOfDay(); | ||||
|             LocalDateTime endOfDay = today.plusDays(1).atStartOfDay().minusNanos(1); | ||||
|             // 获取当天的最大编号 | ||||
|             Long count = this.lambdaQuery() | ||||
|                 .between(CtrContractProgressSettlement::getCreateTime, startOfDay, endOfDay) | ||||
|                 .count(); | ||||
|             String result = String.format("%03d", count + 1); // 3表示长度,0表示补0 | ||||
|             add.setDocumentCode(today.format(DateTimeFormatter.BASIC_ISO_DATE) + "-" + result); | ||||
|             validEntityBeforeSave(add); | ||||
|         boolean flag = baseMapper.insert(add) > 0; | ||||
|             flag = baseMapper.insert(add) > 0; | ||||
|         } | ||||
|         if (flag) { | ||||
|             Long id = add.getId(); | ||||
|             List<CtrContractProgressSettlementItemCreateReq> inInventory = req.getInInventory(); | ||||
| @ -184,6 +265,9 @@ public class CtrContractProgressSettlementServiceImpl extends ServiceImpl<CtrCon | ||||
|     public Boolean updateByBo(CtrContractProgressSettlementUpdateReq req) { | ||||
|         CtrContractProgressSettlement update = MapstructUtils.convert(req, CtrContractProgressSettlement.class); | ||||
|         validEntityBeforeSave(update); | ||||
|         if (Objects.equals(req.getDeptId(), req.getSettlementUnit())) { | ||||
|             throw new ServiceException("结算单位不能与收款单位相同"); | ||||
|         } | ||||
|         Long id = req.getId(); | ||||
|         // 删除旧数据 | ||||
|         List<CtrContractProgressSettlementItem> oldList = contractProgressSettlementItemService.lambdaQuery() | ||||
|  | ||||
| @ -11,6 +11,7 @@ import org.dromara.common.core.utils.MapstructUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.satoken.utils.LoginHelper; | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlement; | ||||
| import org.dromara.ctr.domain.CtrSubcontractProgressSettlementItem; | ||||
| import org.dromara.ctr.domain.bo.CtrSubcontractProgressSettlementBo; | ||||
| @ -26,6 +27,9 @@ import org.dromara.ctr.service.ICtrSubcontractProgressSettlementService; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.format.DateTimeFormatter; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| @ -128,8 +132,22 @@ public class CtrSubcontractProgressSettlementServiceImpl extends ServiceImpl<Ctr | ||||
|     @Override | ||||
|     public Boolean insertByBo(CtrSubcontractProgressSettlementCreateReq req) { | ||||
|         CtrSubcontractProgressSettlement add = MapstructUtils.convert(req, CtrSubcontractProgressSettlement.class); | ||||
|         // 生成唯一编号 | ||||
|         LocalDate today = LocalDate.now(); | ||||
|         Long userId = LoginHelper.getUserId(); | ||||
|         boolean flag; | ||||
|         synchronized (userId.toString().intern()) { | ||||
|             LocalDateTime startOfDay = today.atStartOfDay(); | ||||
|             LocalDateTime endOfDay = today.plusDays(1).atStartOfDay().minusNanos(1); | ||||
|             // 获取当天的最大编号 | ||||
|             Long count = this.lambdaQuery() | ||||
|                 .between(CtrSubcontractProgressSettlement::getCreateTime, startOfDay, endOfDay) | ||||
|                 .count(); | ||||
|             String result = String.format("%03d", count + 1); // 3表示长度,0表示补0 | ||||
|             add.setDocumentCode(today.format(DateTimeFormatter.BASIC_ISO_DATE) + "-" + result); | ||||
|             validEntityBeforeSave(add); | ||||
|         boolean flag = baseMapper.insert(add) > 0; | ||||
|             flag = baseMapper.insert(add) > 0; | ||||
|         } | ||||
|         if (flag) { | ||||
|             Long id = add.getId(); | ||||
|             List<CtrSubcontractProgressSettlementItemCreateReq> inInventory = req.getInInventory(); | ||||
|  | ||||
| @ -0,0 +1,159 @@ | ||||
| package org.dromara.dataTransmission; | ||||
|  | ||||
| import cn.hutool.crypto.asymmetric.KeyType; | ||||
| import cn.hutool.crypto.asymmetric.RSA; | ||||
| import cn.hutool.http.HttpUtil; | ||||
| import com.alibaba.fastjson2.JSONObject; | ||||
| import org.dromara.common.redis.utils.RedisUtils; | ||||
|  | ||||
| import javax.crypto.Cipher; | ||||
| import java.net.URI; | ||||
| import java.net.http.HttpClient; | ||||
| import java.net.http.HttpRequest; | ||||
| import java.net.http.HttpResponse; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.security.KeyFactory; | ||||
| import java.security.PublicKey; | ||||
| import java.security.spec.X509EncodedKeySpec; | ||||
| import java.time.Duration; | ||||
| import java.util.Base64; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import org.springframework.http.HttpHeaders; | ||||
| import org.springframework.stereotype.Component; | ||||
| import java.io.ByteArrayOutputStream; | ||||
|  | ||||
|  | ||||
| @Component | ||||
| public class TokenUtils { | ||||
|  | ||||
|     // Token过期时间:25分钟(与Redis存储过期时间保持一致) | ||||
|     private static final long TOKEN_EXPIRE_SECONDS = 1500; | ||||
|     // HTTP请求超时时间:10秒 | ||||
|     private static final Duration HTTP_TIMEOUT = Duration.ofSeconds(10); | ||||
|     //通用字符 | ||||
|     private static final String USER_NAME = "username"; | ||||
|     private static final String PASSWORD = "password"; | ||||
|     private static final String PUBLIC_KEY = "publicKey"; | ||||
|     private static final String URL = "url"; | ||||
|  | ||||
|     //clientId | ||||
|     public static final String CLARITYPM = "claritypm"; | ||||
|  | ||||
|     //接口信息及参数 | ||||
|     private static final Map<String, Map<String, String>> tokenMap = new HashMap<>(){ | ||||
|         { | ||||
|             put(CLARITYPM, new HashMap<>(){{ | ||||
|                 put(URL, "https://claritypm.powerchina.cn/neSmartsite-api/loginCli"); | ||||
|                 put(USER_NAME, "zhangweiwei"); | ||||
|                 put(PASSWORD, "Hkrsoft@#2023"); | ||||
|                 put(PUBLIC_KEY, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoaejbjbttHyHuEzHL8lIX5GZZ6zIYrqJpEDlPM4V5LHn19rSAYp2FyAr8y5Ctny9uUdaYbkoFiVQgxWrAYo4X/3O0OFDsowE25FMOLQY0Mn5B6CvVR7Sdt3DqzIzM1tUnJCIbVGNfDMgxLrLwFN8RvOW8MPlB6LgOvlGMDbj+OQIDAQAB"); | ||||
|             }}); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     //字段参数 | ||||
|     private static final Map<String, Map<String, String>> paramMap = new HashMap<>(){ | ||||
|         { | ||||
|             put(CLARITYPM, new HashMap<>(){{ | ||||
|  | ||||
|                 put(USER_NAME, "username"); | ||||
|                 put(PASSWORD, "password"); | ||||
|             }}); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * 优先从Redis获取Token,不存在则调用接口获取并存储 | ||||
|      * @param clientId 客户端ID | ||||
|      * @return 有效的Token字符串 | ||||
|      * @throws Exception 当获取过程发生异常时抛出 | ||||
|      */ | ||||
|     public static String getToken(String clientId) throws Exception { | ||||
|         // 1. 定义Redis中的Token键名 | ||||
| //        String redisKey = "data_auth:token:" + clientId; | ||||
| // | ||||
| //        // 2. 尝试从Redis获取Token | ||||
| //        String token = RedisUtils.getCacheObject(redisKey); | ||||
| //        if (token != null && !token.isBlank()) { | ||||
| //            // 缓存命中,直接返回 | ||||
| //            return token; | ||||
| //        } | ||||
|  | ||||
|         // 3. 缓存未命中,调用接口获取Token | ||||
|         Map<String, String> map = tokenMap.get(clientId); | ||||
|         String token = fetchTokenFromApi(clientId,map.get(URL), map.get(USER_NAME), rsaEncrypt(map.get(PASSWORD),map.get(PUBLIC_KEY))); | ||||
|  | ||||
|         // 4. 存储到Redis(设置25分钟过期) | ||||
| //        RedisUtils.setCacheObject(redisKey, token,Duration.ofSeconds(TOKEN_EXPIRE_SECONDS) ); | ||||
|  | ||||
|         return token; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 从接口获取Token的内部方法 | ||||
|      */ | ||||
|     private static String fetchTokenFromApi(String clientId, String authUrl, String username, String encryptedPassword) throws Exception { | ||||
|         // 构建JSON请求体(包含加密后的密码) | ||||
|         // 1. 构建请求头(与原 Go 代码一致的头信息) | ||||
| //        Map<String, String> headers = new HashMap<>(); | ||||
| //        headers.put(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); | ||||
| //        headers.put("User-Agent", "Mozilla/5.0"); | ||||
| //        headers.put(HttpHeaders.ACCEPT, "application/json"); | ||||
| //        headers.put("Origin", "https://claritypm.powerchina.cn"); | ||||
| //        headers.put("Referer", "https://claritypm.powerchina.cn/"); | ||||
|  | ||||
|         // 2. 构建请求体(保持你的原有逻辑) | ||||
|         Map<String, String> map = paramMap.get(clientId); | ||||
|         JSONObject requestBody = new JSONObject(); | ||||
|         requestBody.put(map.get(USER_NAME), username); // 从 map 中获取接口要求的用户名参数名 | ||||
|         requestBody.put(map.get(PASSWORD), encryptedPassword); // 加密后的密码 | ||||
|         String jsonBody = requestBody.toJSONString(); | ||||
|         System.out.println("请求体:" + jsonBody); | ||||
|  | ||||
|         // 3. 带 Header 发送 POST 请求(Hutool HttpUtil 重载方法) | ||||
|         String post = HttpUtil.createPost(authUrl) | ||||
| //            .addHeaders(headers) // 设置所有请求头 | ||||
|             .body(jsonBody) // 设置请求体 | ||||
|             .execute() // 执行请求 | ||||
|             .body(); // 获取响应体 | ||||
|  | ||||
|         System.out.println("响应结果:" + post); | ||||
|         // 3. 解析响应(核心解析逻辑) | ||||
|         JSONObject responseJson = JSONObject.parseObject(post); | ||||
|         int code = responseJson.getIntValue("code"); | ||||
|         String msg = responseJson.getString("msg"); | ||||
|         String token = responseJson.getString("token"); | ||||
|  | ||||
|         // 4. 校验响应有效性 | ||||
|         if (code != 200) { | ||||
|             throw new RuntimeException("获取 Token 失败,响应信息:" + msg + ",状态码:" + code); | ||||
|         } | ||||
|         if (token == null || token.trim().isEmpty()) { | ||||
|             throw new RuntimeException("响应中未包含有效 Token,响应内容:" + post); | ||||
|         } | ||||
|  | ||||
|         return token; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * RSA公钥加密(核心加密方法) | ||||
|      * @param content 待加密内容(原始密码) | ||||
|      * @param publicKeyStr 公钥字符串(Base64编码) | ||||
|      * @return 加密后的Base64字符串 | ||||
|      * @throws Exception 加密过程异常 | ||||
|      */ | ||||
|     public static String rsaEncrypt(String content, String publicKeyStr) throws Exception { | ||||
|         RSA rsa = new RSA(null, publicKeyStr); | ||||
|         byte[] encryptedBytes = rsa.encrypt(content, KeyType.PublicKey); | ||||
|         return Base64.getEncoder().encodeToString(encryptedBytes); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static void main(String[] args) throws Exception { | ||||
|         String claritypm = getToken(CLARITYPM); | ||||
|         System.out.println(claritypm); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,79 @@ | ||||
| package org.dromara.dataTransmission.claritypm; | ||||
|  | ||||
|  | ||||
| import org.dromara.dataTransmission.TokenUtils; | ||||
| import org.dromara.dataTransmission.claritypm.dto.RealUser; | ||||
| import org.springframework.stereotype.Component; | ||||
| import cn.hutool.http.HttpUtil; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.HashMap; | ||||
|  | ||||
| @Component | ||||
| public class ClaritypmClient { | ||||
|  | ||||
|     // 接口地址 | ||||
|     private static final String INSERT_REAL_USER_URL = "https://claritypm.powerchina.cn/neSmartsite-api/realUser/tiandong/insertRealUser"; | ||||
|  | ||||
|     @Autowired | ||||
|     private TokenUtils tokenUtils; // 依赖之前的Token获取服务 | ||||
|  | ||||
|     /** | ||||
|      * 批量新增实名制用户信息 | ||||
|      * @param userList 用户信息列表(建议单次不超过10条) | ||||
|      * @return 接口响应结果(JSON格式) | ||||
|      * @throws Exception 调用异常 | ||||
|      */ | ||||
|     public static String batchInsertRealUser(List<RealUser> userList) throws Exception { | ||||
|         // 1. 校验列表大小(建议不超过10条) | ||||
|         if (userList == null || userList.isEmpty()) { | ||||
|             throw new IllegalArgumentException("用户列表不能为空"); | ||||
|         } | ||||
|         if (userList.size() > 10) { | ||||
|             throw new IllegalArgumentException("单次批量新增不能超过10条数据"); | ||||
|         } | ||||
|  | ||||
|         // 2. 获取Token(从之前的TokenService获取) | ||||
|         String token = TokenUtils.getToken(TokenUtils.CLARITYPM); | ||||
|         if ( token.trim().isEmpty()) { | ||||
|             throw new RuntimeException("获取Token失败,无法调用接口"); | ||||
|         } | ||||
|  | ||||
|         // 3. 构建请求头(包含Token认证) | ||||
|         Map<String, String> headers = new HashMap<>(); | ||||
|         headers.put("Content-Type", "application/json; charset=UTF-8"); | ||||
|         headers.put("User-Agent", "Mozilla/5.0"); | ||||
|         headers.put("Accept", "application/json"); | ||||
|         headers.put("Origin", "https://claritypm.powerchina.cn"); | ||||
|         headers.put("Referer", "https://claritypm.powerchina.cn/"); | ||||
|         headers.put("Authorization", "Bearer " + token); // 假设接口使用Bearer Token认证 | ||||
|  | ||||
|         // 4. 构建请求体(JSONArray格式) | ||||
|         JSONArray requestBody = JSONArray.parseArray(JSON.toJSONString(userList)); | ||||
|         String jsonBody = requestBody.toJSONString(); | ||||
|         System.out.println("批量新增用户请求体:" + jsonBody); | ||||
|  | ||||
|         // 5. 发送POST请求 | ||||
|         String response = HttpUtil.createPost(INSERT_REAL_USER_URL) | ||||
|             .addHeaders(headers) | ||||
|             .body(jsonBody) | ||||
|             .execute() | ||||
|             .body(); | ||||
|         System.out.println("批量新增用户响应:" + response); | ||||
|  | ||||
|         // 6. 解析响应(根据实际响应结构调整,此处假设与登录接口类似) | ||||
|         JSONObject responseJson = JSONObject.parseObject(response); | ||||
|         int code = responseJson.getIntValue("code"); | ||||
|         String msg = responseJson.getString("msg"); | ||||
|         if (code != 200) { | ||||
|             throw new RuntimeException("批量新增用户失败:" + msg + "(状态码:" + code + ")"); | ||||
|         } | ||||
|  | ||||
|         return response; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,92 @@ | ||||
| package org.dromara.dataTransmission.claritypm.dto; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * 实名制用户信息实体类(对应接口参数) | ||||
|  */ | ||||
| @Data | ||||
| public class RealUser { | ||||
|     // 人员姓名(必填) | ||||
|     private String userName; | ||||
|  | ||||
|     // 是否班组长(非必填,0-否 1-是) | ||||
|     private String classManagerFlag; | ||||
|  | ||||
|     // 手机号码(必填) | ||||
|     private String phone; | ||||
|  | ||||
|     // 性别(必填,1.男 2.女 3.未知) | ||||
|     private String sex; | ||||
|  | ||||
|     // 证件类型(必填,0.身份证) | ||||
|     private String cardType; | ||||
|  | ||||
|     // 证件号码(必填,身份证号码) | ||||
|     private String cardNumber; | ||||
|  | ||||
|     // 人员类型(必填,0.作业人员 1.管理人员) | ||||
|     private String userType; | ||||
|  | ||||
|     // 发证机关(非必填) | ||||
|     private String cardDept; | ||||
|  | ||||
|     // 民族(非必填) | ||||
|     private String nation; | ||||
|  | ||||
|     // 生日(非必填,datetime格式) | ||||
|     private LocalDate birthday; | ||||
|  | ||||
|     // 住址(非必填) | ||||
|     private String address; | ||||
|  | ||||
|     // 头像(非必填,http地址) | ||||
|     private String avatar; | ||||
|  | ||||
|     // 采集相片(非必填,http地址) | ||||
|     private String pic; | ||||
|  | ||||
|     // 安全教育表(非必填,http地址) | ||||
|     private String safetyEdu; | ||||
|  | ||||
|     // 技术交底表(非必填,http地址) | ||||
|     private String technology; | ||||
|  | ||||
|     // 证件有效期始(非必填,datetime格式) | ||||
|     private LocalDate cardStartTime; | ||||
|  | ||||
|     // 证件有效期至(非必填,datetime格式) | ||||
|     private LocalDate cardEndTime; | ||||
|  | ||||
|     // 学历(非必填,1-9对应小学至其他) | ||||
|     private String studyLevel; | ||||
|  | ||||
|     // 政治面貌(非必填,0-3对应党员至民主党派) | ||||
|     private String politicsType; | ||||
|  | ||||
|     // 购买保险(非必填,0-否 1-是) | ||||
|     private String insuranceFlag; | ||||
|  | ||||
|     // 重大病史(非必填,0-否 1-是) | ||||
|     private String diseaseFlag; | ||||
|  | ||||
|     // 劳动合同(非必填,0-未签订 1-已签订) | ||||
|     private String laborContractFlag; | ||||
|  | ||||
|     // 紧急联系人(非必填) | ||||
|     private String contacts; | ||||
|  | ||||
|     // 紧急联系人电话(非必填) | ||||
|     private String contactsPhone; | ||||
|  | ||||
|     // 婚姻状况(非必填,0-3对应未婚至丧偶) | ||||
|     private String marryRemark; | ||||
|  | ||||
|     // 企业名称(非必填) | ||||
|     private String companyName; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -1,8 +1,15 @@ | ||||
| package org.dromara.design.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import com.alibaba.excel.EasyExcel; | ||||
| import com.alibaba.excel.ExcelWriter; | ||||
| import com.alibaba.excel.write.metadata.WriteSheet; | ||||
| import com.alibaba.excel.write.metadata.style.WriteCellStyle; | ||||
| import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.apache.poi.ss.usermodel.IndexedColors; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| @ -10,17 +17,17 @@ 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.design.domain.bo.ImportExcelFileReq; | ||||
| import org.dromara.design.domain.bo.ObtainAllVersionNumbersReq; | ||||
| import org.dromara.design.domain.bo.CoryObtainTheListReq; | ||||
| import org.dromara.design.domain.bo.SheetListReq; | ||||
| import org.dromara.design.domain.bo.*; | ||||
| import org.dromara.design.domain.vo.*; | ||||
| import org.dromara.design.exportUtil.bill.*; | ||||
| import org.dromara.design.service.IBusBillofquantitiesVersionsService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.io.IOException; | ||||
| import java.net.URLEncoder; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
|  * 工程量清单版本 | ||||
| @ -103,6 +110,74 @@ public class BusBillofquantitiesVersionsController extends BaseController { | ||||
|         return R.ok(busBillofquantitiesVersionsService.obtainAllClassification(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出工程量清单版本列表 | ||||
|      */ | ||||
|     @Log(title = "工程量清单版本", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(String versions,Long projectId, HttpServletResponse response) throws IOException { | ||||
|         Map<String, List<BillOfQuantitiesExport>> sheetDataMap = busBillofquantitiesVersionsService.export(versions,projectId); | ||||
|  | ||||
|         if (sheetDataMap.isEmpty()) { | ||||
|             response.getWriter().write("无数据可导出"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 2. 设置响应头(同上) | ||||
|         response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); | ||||
|         response.setCharacterEncoding("UTF-8"); | ||||
|         String fileName = URLEncoder.encode( "工程量清单", "UTF-8").replaceAll("\\+", "%20"); | ||||
|         response.setHeader("Content-disposition", "attachment;filename*=UTF-8''" + fileName + ".xlsx"); | ||||
|  | ||||
|         // 3. 构建Excel写入器 | ||||
|         ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build(); | ||||
|         try { | ||||
|             // 4. 遍历每个Sheet分组,创建Sheet并写入数据 | ||||
|             for (Map.Entry<String, List<BillOfQuantitiesExport>> entry : sheetDataMap.entrySet()) { | ||||
|                 String sheetName = entry.getKey(); | ||||
|                 List<BillOfQuantitiesExport> dataList = entry.getValue(); | ||||
|  | ||||
|                 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); | ||||
|                 // 背景设置为红色 | ||||
|                 headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); | ||||
|  | ||||
|                 HorizontalCellStyleStrategy horizontalCellStyleStrategy = | ||||
|                     new HorizontalCellStyleStrategy(headWriteCellStyle,  new WriteCellStyle()); | ||||
|  | ||||
|                 // 定义Sheet(同时注册标题处理器和冻结窗格处理器) | ||||
|                 WriteSheet writeSheet = EasyExcel.writerSheet(sheetName) | ||||
|                     .registerWriteHandler(new FreezePaneWriteHandler()) // 冻结前2行 | ||||
|                     .registerWriteHandler(new ColumnWidthWriteHandler()) // 调整列宽 | ||||
|                     .registerWriteHandler(new CustomRowStyleHandler()) // 新增:边框和标题样式 | ||||
|                     .registerWriteHandler(horizontalCellStyleStrategy) | ||||
|                     .head(head(sheetName)) | ||||
|                     .build(); | ||||
|  | ||||
|                 // 写入数据 | ||||
|                 excelWriter.write(dataList, writeSheet); | ||||
|             } | ||||
|         } finally { | ||||
|             excelWriter.finish(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private List<List<String>> head(String sheetName) { | ||||
|         List<List<String>> list = new ArrayList<List<String>>(); | ||||
|         List<String> list1 = Arrays.asList(sheetName,"编号"); | ||||
|         List<String> list2 = Arrays.asList(sheetName, "名称"); | ||||
|         List<String> list3 = Arrays.asList(sheetName, "规格"); | ||||
|         List<String> list4 = Arrays.asList(sheetName, "单位"); | ||||
|         List<String> list5 = Arrays.asList(sheetName, "数量"); | ||||
|         List<String> list6 = Arrays.asList(sheetName, "备注"); | ||||
|         list.add(list1); | ||||
|         list.add(list2); | ||||
|         list.add(list3); | ||||
|         list.add(list4); | ||||
|         list.add(list5); | ||||
|         list.add(list6); | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
| //    /** | ||||
| //     * 导入物资设备清单 | ||||
|  | ||||
| @ -1,17 +1,40 @@ | ||||
| package org.dromara.design.controller; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.URLEncoder; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import com.deepoove.poi.XWPFTemplate; | ||||
| import com.deepoove.poi.config.Configure; | ||||
| import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.dromara.design.domain.BusDrawingreviewReceipts; | ||||
| import org.dromara.design.domain.DesCollectFile; | ||||
| import org.dromara.design.domain.DesDesignChange; | ||||
| import org.dromara.design.domain.bo.DesUserBo; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignExtendDetailDto; | ||||
| import org.dromara.design.domain.vo.DesCollectFileWordVo; | ||||
| import org.dromara.design.domain.vo.DesUserVo; | ||||
| import org.dromara.design.domain.vo.designchange.DesDesignChangeVo; | ||||
| import org.dromara.design.service.IDesDesignChangeService; | ||||
| import org.dromara.design.service.IDesUserService; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.domain.vo.project.BusSubProjectVo; | ||||
| import org.dromara.project.service.IBusProjectService; | ||||
| import org.dromara.system.service.ISysDictDataService; | ||||
| import org.dromara.system.service.ISysUserService; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| @ -44,6 +67,12 @@ public class BusDrawingreviewReceiptsController extends BaseController { | ||||
|  | ||||
|     private final IDesUserService desUserService; | ||||
|  | ||||
|     private final IDesDesignChangeService desDesignChangeService; | ||||
|  | ||||
|     private final ISysDictDataService dictDataService; | ||||
|  | ||||
|     private final ISysUserService userService; | ||||
|  | ||||
|     /** | ||||
|      * 查询设计-图纸评审验证列表 | ||||
|      */ | ||||
| @ -132,4 +161,85 @@ public class BusDrawingreviewReceiptsController extends BaseController { | ||||
|         return R.ok(desUserService.queryList(bo)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private static final String TEMPLATE_PATH = "template/设计验证表.docx"; | ||||
|     @PostMapping("/downloadWord") | ||||
|     public void generateDesignLeaderDoc(Long id, HttpServletResponse response) { | ||||
|         OutputStream outputStream = null; | ||||
|         try { | ||||
|             // 1. 调用Service生成目标模板的Word字节流 | ||||
|             byte[] docBytes = generateDocBytes(id); | ||||
|  | ||||
|             // 2. 配置响应头:确保前端正确下载(避免中文乱码、指定文件类型) | ||||
|             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // 二进制流类型 | ||||
|             // 下载文件名:格式为“[项目名]-设计负责人任命通知单.docx”(此处用projectId拼接,真实场景可从数据中获取项目名) | ||||
|             String downloadFileName = URLEncoder.encode( | ||||
|                 "设计验证表.docx", | ||||
|                 "UTF-8" | ||||
|             ); | ||||
|             response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName); | ||||
|             response.setContentLength(docBytes.length); // 设置响应体长度(优化下载体验) | ||||
|  | ||||
|             // 3. 将Word字节流写入响应 | ||||
|             outputStream = response.getOutputStream(); | ||||
|             outputStream.write(docBytes); | ||||
|             outputStream.flush(); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             // 异常处理:返回500错误状态码 | ||||
|             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); | ||||
|         } finally { | ||||
|             // 关闭流,避免资源泄漏 | ||||
|             if (outputStream != null) { | ||||
|                 try { | ||||
|                     outputStream.close(); | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public byte[] generateDocBytes(Long id) throws Exception { | ||||
|         // -------------------------- 步骤1:按projectId查询项目数据(模拟真实业务) -------------------------- | ||||
|         // 实际场景替换为数据库查询(如调用DAO获取项目名称、负责人等) | ||||
|         DesDesignChangeVo desDesignChangeVo = desDesignChangeService.queryById(id); | ||||
|         BusDrawingreviewReceipts receipts = busDrawingreviewReceiptsService.lambdaQuery() | ||||
|             .eq(BusDrawingreviewReceipts::getDrawingreviewId, id) | ||||
|             .last("limit 1") | ||||
|             .one(); | ||||
|         DesDesignExtendDetailDto extendDetail = desDesignChangeVo.getExtendDetail(); | ||||
|         String s = dictDataService.selectDictLabel("des_user_major", receipts.getProfessional()); | ||||
|         String designerName = null; | ||||
|         if(StrUtil.isNotBlank(receipts.getDesigner())){ | ||||
|             Long userId = Long.parseLong(receipts.getDesigner()); | ||||
|             designerName= userService.queryNameById(userId); | ||||
|         } | ||||
|  | ||||
|         Map<String, Object> placeholderData = new HashMap<>(); | ||||
|         placeholderData.put("projectName", receipts.getProjectName()); | ||||
|         placeholderData.put("subName",extendDetail.getSubName()); | ||||
|         placeholderData.put("stage", receipts.getStage()); | ||||
|         placeholderData.put("professionalName", s); | ||||
|         placeholderData.put("volume", receipts.getVolume()); | ||||
|         placeholderData.put("designerName", designerName); | ||||
|         placeholderData.put("verificationOpinion", receipts.getVerificationOpinion()); | ||||
|         placeholderData.put("executionOpinion", receipts.getExecutionOpinion()); | ||||
|         // -------------------------- 步骤2:用poi-tl加载目标模板并替换占位符 -------------------------- | ||||
|         // 读取resources下的“设计项目负责人任命通知单.docx”模板 | ||||
|         ClassPathResource templateResource = new ClassPathResource(TEMPLATE_PATH); | ||||
|         try (InputStream templateIs = templateResource.getInputStream(); | ||||
|              ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { | ||||
|  | ||||
|             XWPFTemplate template = XWPFTemplate.compile(templateIs).render(placeholderData); | ||||
|  | ||||
|             // -------------------------- 步骤3:将生成的文档写入字节流 -------------------------- | ||||
|             template.write(outputStream); | ||||
|             template.close(); // 关闭模板资源 | ||||
|             return outputStream.toByteArray(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,14 +1,31 @@ | ||||
| package org.dromara.design.controller; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.URLEncoder; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import com.deepoove.poi.XWPFTemplate; | ||||
| import com.deepoove.poi.config.Configure; | ||||
| import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.dromara.design.domain.DesCollectFile; | ||||
| import org.dromara.design.domain.bo.DesCollectFileBo; | ||||
| import org.dromara.design.domain.dto.ExportDto; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignExtendDetailDto; | ||||
| import org.dromara.design.domain.vo.DesCollectFileVo; | ||||
| import org.dromara.design.domain.vo.DesCollectFileWordVo; | ||||
| import org.dromara.design.domain.vo.designchange.DesDesignChangeVo; | ||||
| import org.dromara.design.service.IDesCollectFileService; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.service.IBusProjectService; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| @ -38,6 +55,8 @@ public class DesCollectFileController extends BaseController { | ||||
|  | ||||
|     private final IDesCollectFileService desCollectFileService; | ||||
|  | ||||
|     private final IBusProjectService projectService; | ||||
|  | ||||
|     /** | ||||
|      * 查询收资文件列表 | ||||
|      */ | ||||
| @ -105,7 +124,6 @@ public class DesCollectFileController extends BaseController { | ||||
|         return toAjax(desCollectFileService.deleteWithValidByIds(List.of(ids), true)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 上传资料文件 | ||||
|      */ | ||||
| @ -117,4 +135,93 @@ public class DesCollectFileController extends BaseController { | ||||
|                            @NotNull(message = "请先选择项目")Long projectId) { | ||||
|         return toAjax(desCollectFileService.addFile(file, catalogueId, projectId)); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/exportZip") | ||||
|     public void exportZip(ExportDto dto, HttpServletResponse response) throws Exception { | ||||
|         desCollectFileService.exportAsZip(dto, response); | ||||
|     } | ||||
|  | ||||
|     private static final String TEMPLATE_PATH = "template/设计输入资料清单及评审表.docx"; | ||||
|     @PostMapping("/downloadWord") | ||||
|     public void generateDesignLeaderDoc(Long projectId, HttpServletResponse response) { | ||||
|         OutputStream outputStream = null; | ||||
|         try { | ||||
|             // 1. 调用Service生成目标模板的Word字节流 | ||||
|             byte[] docBytes = generateDocBytes(projectId); | ||||
|  | ||||
|             // 2. 配置响应头:确保前端正确下载(避免中文乱码、指定文件类型) | ||||
|             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // 二进制流类型 | ||||
|             // 下载文件名:格式为“[项目名]-设计负责人任命通知单.docx”(此处用projectId拼接,真实场景可从数据中获取项目名) | ||||
|             String downloadFileName = URLEncoder.encode( | ||||
|                 "设计输入资料清单及评审表.docx", | ||||
|                 "UTF-8" | ||||
|             ); | ||||
|             response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName); | ||||
|             response.setContentLength(docBytes.length); // 设置响应体长度(优化下载体验) | ||||
|  | ||||
|             // 3. 将Word字节流写入响应 | ||||
|             outputStream = response.getOutputStream(); | ||||
|             outputStream.write(docBytes); | ||||
|             outputStream.flush(); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             // 异常处理:返回500错误状态码 | ||||
|             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); | ||||
|         } finally { | ||||
|             // 关闭流,避免资源泄漏 | ||||
|             if (outputStream != null) { | ||||
|                 try { | ||||
|                     outputStream.close(); | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public byte[] generateDocBytes(Long projectId) throws Exception { | ||||
|         // -------------------------- 步骤1:按projectId查询项目数据(模拟真实业务) -------------------------- | ||||
|         // 实际场景替换为数据库查询(如调用DAO获取项目名称、负责人等) | ||||
|         List<DesCollectFile> list = desCollectFileService.lambdaQuery() | ||||
|             .eq(DesCollectFile::getProjectId, projectId).list(); | ||||
|  | ||||
|         List<DesCollectFileWordVo> files = new ArrayList<>(); | ||||
|         int i = 1; | ||||
|         for (DesCollectFile desCollectFile : list) { | ||||
|             DesCollectFileWordVo desCollectFileWordVo = new DesCollectFileWordVo(); | ||||
|             desCollectFileWordVo.setNum(i); | ||||
|             i++; | ||||
|             desCollectFileWordVo.setFileName(desCollectFile.getFileName()); | ||||
|             files.add(desCollectFileWordVo); | ||||
|          } | ||||
|  | ||||
|         BusProject project = projectService.getById(projectId); | ||||
|  | ||||
|  | ||||
|         Map<String, Object> placeholderData = new HashMap<>(); | ||||
|         placeholderData.put("projectName", project.getProjectName()); | ||||
|         placeholderData.put("files",files); | ||||
|         // -------------------------- 步骤2:用poi-tl加载目标模板并替换占位符 -------------------------- | ||||
|         // 读取resources下的“设计项目负责人任命通知单.docx”模板 | ||||
|         ClassPathResource templateResource = new ClassPathResource(TEMPLATE_PATH); | ||||
|         try (InputStream templateIs = templateResource.getInputStream(); | ||||
|              ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { | ||||
|  | ||||
|             LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); | ||||
|  | ||||
|             Configure config = Configure.builder() | ||||
|                 .bind("files", policy).build(); | ||||
|  | ||||
|             XWPFTemplate template = XWPFTemplate.compile(templateIs, config).render(placeholderData); | ||||
|  | ||||
|             // -------------------------- 步骤3:将生成的文档写入字节流 -------------------------- | ||||
|             template.write(outputStream); | ||||
|             template.close(); // 关闭模板资源 | ||||
|             return outputStream.toByteArray(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,342 @@ | ||||
| package org.dromara.design.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| import org.apache.poi.xwpf.usermodel.*; | ||||
| 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.web.core.BaseController; | ||||
| import org.dromara.design.domain.DesConstructionSchedulePlan; | ||||
| import org.dromara.design.domain.DesUser; | ||||
| import org.dromara.design.domain.dto.constructionscheduleplan.*; | ||||
| import org.dromara.design.domain.vo.DesConstructionSchedulePlanVo; | ||||
| import org.dromara.design.exportUtil.plan.AttachmentPersonnel; | ||||
| import org.dromara.design.service.IDesConstructionSchedulePlanService; | ||||
|  | ||||
|  | ||||
| import org.dromara.design.service.IDesUserService; | ||||
| import org.dromara.system.domain.vo.SysDictDataVo; | ||||
| import org.dromara.system.service.ISysDictDataService; | ||||
| import org.dromara.system.service.ISysDictTypeService; | ||||
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; | ||||
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; | ||||
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.io.*; | ||||
| import java.net.URLEncoder; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.*; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import org.apache.poi.poifs.filesystem.POIFSFileSystem; | ||||
| /** | ||||
|  * 设计计划 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 | ||||
|  */ | ||||
| @Validated | ||||
| @RestController | ||||
| @RequestMapping("/design/constructionSchedulePlan") | ||||
| public class DesConstructionSchedulePlanController extends BaseController { | ||||
|  | ||||
|     @Resource | ||||
|     private IDesConstructionSchedulePlanService desConstructionSchedulePlanService; | ||||
|     @Resource | ||||
|     private  IDesUserService desUserService; | ||||
|     @Resource | ||||
|     private ISysDictTypeService dictTypeService; | ||||
|     /** | ||||
|      * 查询设计计划列表 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:list") | ||||
|     @GetMapping("/list") | ||||
|     public R<List<DesConstructionSchedulePlanVo>> list(DesConstructionSchedulePlanQueryReq req) { | ||||
|         List<DesConstructionSchedulePlanVo> list = desConstructionSchedulePlanService.queryList(req); | ||||
|         return R.ok(list); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导出设计计划列表 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:export") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(DesConstructionSchedulePlanQueryReq req, HttpServletResponse response) { | ||||
|         List<DesConstructionSchedulePlanVo> list = desConstructionSchedulePlanService.queryList(req); | ||||
|         ExcelUtil.exportExcel(list, "施工进度计划", DesConstructionSchedulePlanVo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据项目id导出设计计划模版 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:exportTemplate") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/exportTemplate/{projectId}") | ||||
|     public void exportExcelByProjectId(@NotNull(message = "项目id不能为空") | ||||
|                                        @PathVariable Long projectId, HttpServletResponse response) { | ||||
|         desConstructionSchedulePlanService.exportExcelByProjectId(projectId, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 读取设计计划模版 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:readTemplate") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.IMPORT) | ||||
|     @PostMapping("/readTemplate") | ||||
|     public R<Void> readExcel(@RequestParam("file") MultipartFile file, Long projectId) { | ||||
|         List<DesConstructionSchedulePlanExcelDto> list = desConstructionSchedulePlanService.readExcel(file, projectId); | ||||
|         if (CollUtil.isNotEmpty(list)) { | ||||
|             List<DesConstructionSchedulePlan> planList = desConstructionSchedulePlanService.convertToEntities(list); | ||||
|             return toAjax(desConstructionSchedulePlanService.saveBatch(planList)); | ||||
|         } | ||||
|         return toAjax(true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取设计计划详细信息 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:query") | ||||
|     @GetMapping("/{id}") | ||||
|     public R<DesConstructionSchedulePlanVo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                                     @PathVariable Long id) { | ||||
|         return R.ok(desConstructionSchedulePlanService.queryById(id)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增设计计划 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:add") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<DesConstructionSchedulePlanVo> add(@Validated @RequestBody DesConstructionSchedulePlanCreateReq req) { | ||||
|         return R.ok(desConstructionSchedulePlanService.insertByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改设计计划 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:edit") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated @RequestBody DesConstructionSchedulePlanUpdateReq req) { | ||||
|         return toAjax(desConstructionSchedulePlanService.updateByBo(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改设计计划为完成状态 | ||||
|      * | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:editFinish") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping("/finish") | ||||
|     public R<Void> editFinish(@Validated @RequestBody DesConstructionSchedulePlanFinishReq req) { | ||||
|         return toAjax(desConstructionSchedulePlanService.updateFinish(req)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除设计计划 | ||||
|      * | ||||
|      * @param ids 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("design:constructionSchedulePlan:remove") | ||||
|     @Log(title = "施工进度计划", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{ids}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable Long[] ids) { | ||||
|         return toAjax(desConstructionSchedulePlanService.deleteByIds(List.of(ids))); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/exportSchedule") | ||||
|     public void exportSchedule(HttpServletResponse response, Long projectId) throws IOException { | ||||
|         desConstructionSchedulePlanService.exportSchedule(response,projectId); | ||||
|     } | ||||
|  | ||||
|     private static final String TEMPLATE_RESOURCE_PATH = "template/CCCET-JL-CX-25设计计划表.docx"; | ||||
|     // -------------------------- 2. 核心接口:修复单元格清空逻辑与数据填充 -------------------------- | ||||
|     @PostMapping("/downloadWord") | ||||
|     public void fillCccetTemplate(Long projectId, HttpServletResponse response) { | ||||
|         // 1. 基础参数校验(避免空数据) | ||||
|  | ||||
|         // 2. 读取resource中的模板+填充数据 | ||||
|         try ( | ||||
|             // 关键:通过ClassPathResource读取resource/template下的模板 | ||||
|             InputStream templateIs = new ClassPathResource(TEMPLATE_RESOURCE_PATH).getInputStream(); | ||||
|             XWPFDocument doc = new XWPFDocument(templateIs); // 加载模板 | ||||
|             OutputStream out = response.getOutputStream()    // 响应流 | ||||
|         ) { | ||||
|             // -------------------------- | ||||
|             // 步骤1:填充第1页-主信息表(索引0,固定6列) | ||||
|             // -------------------------- | ||||
| //            XWPFTable mainTable = doc.getTables().get(0); | ||||
| //            // 工程名称(第1行第0列) | ||||
| //            if (mainTable.getRows().size() > 1 && mainTable.getRow(1).getCell(0) != null) { | ||||
| //                mainTable.getRow(1).getCell(0).setText(request.getProjectName() == null ? "" : request.getProjectName()); | ||||
| //            } | ||||
| //            // 工程号(第1行第1列) | ||||
| //            if (mainTable.getRows().size() > 1 && mainTable.getRow(1).getCell(1) != null) { | ||||
| //                mainTable.getRow(1).getCell(1).setText(request.getProjectNo()); | ||||
| //            } | ||||
| //            // 编制日期(第2行第3列) | ||||
| //            if (mainTable.getRows().size() > 2 && mainTable.getRow(2).getCell(3) != null) { | ||||
| //                mainTable.getRow(2).getCell(3).setText(request.getCompileDate() == null ? "" : request.getCompileDate()); | ||||
| //            } | ||||
| //            // 编制人(第3行第0列) | ||||
| //            if (mainTable.getRows().size() > 3 && mainTable.getRow(3).getCell(0) != null) { | ||||
| //                mainTable.getRow(3).getCell(0).setText(request.getCompiler() == null ? "" : request.getCompiler()); | ||||
| //            } | ||||
| //            // 批准人(第3行第2列) | ||||
| //            if (mainTable.getRows().size() > 3 && mainTable.getRow(3).getCell(2) != null) { | ||||
| //                mainTable.getRow(3).getCell(2).setText(request.getApprover() == null ? "" : request.getApprover()); | ||||
| //            } | ||||
| //            // 设计阶段(第3行第4列) | ||||
| //            if (mainTable.getRows().size() > 3 && mainTable.getRow(3).getCell(4) != null) { | ||||
| //                mainTable.getRow(3).getCell(4).setText(request.getDesignStage() == null ? "" : request.getDesignStage()); | ||||
| //            } | ||||
| //            // 设计规模(第4行第0列) | ||||
| //            if (mainTable.getRows().size() > 4 && mainTable.getRow(4).getCell(0) != null) { | ||||
| //                mainTable.getRow(4).getCell(0).setText(request.getDesignScale() == null ? "" : request.getDesignScale()); | ||||
| //            } | ||||
|  | ||||
|             // -------------------------- | ||||
|             // 步骤2:填充第3页-附件1人员配置表(索引2,固定11列) | ||||
|             // -------------------------- | ||||
|             XWPFTable staffTable = doc.getTables().get(2); | ||||
|             // 删除模板中附件1的空数据行(保留第0行表头) | ||||
|             while (staffTable.getRows().size() > 2) { | ||||
|                 staffTable.removeRow(1); | ||||
|             } | ||||
|  | ||||
|             List<AttachmentPersonnel> list = getPersonnelDataByProjectId(projectId); | ||||
|             for (AttachmentPersonnel staff : list) { | ||||
|                 XWPFTableRow newRow = staffTable.createRow(); | ||||
|                 // 补全11列(避免POI默认列数不足导致null) | ||||
|                 while (newRow.getTableCells().size() < 11) { | ||||
|                     newRow.createCell(); | ||||
|                 } | ||||
|                 // 按附件1列顺序填充 | ||||
|                 newRow.getCell(0).setText(staff.getProfessional() == null ? "" : staff.getProfessional()); | ||||
|                 newRow.getCell(1).setText(staff.getLeaderName() == null ? "" : staff.getLeaderName()); | ||||
|                 newRow.getCell(2).setText(staff.getLeaderTitle() == null ? "" : staff.getLeaderTitle()); | ||||
|                 newRow.getCell(3).setText(staff.getDesignerName() == null ? "" : staff.getDesignerName()); | ||||
|                 newRow.getCell(4).setText(staff.getDesignerTitle() == null ? "" : staff.getDesignerTitle()); | ||||
|                 newRow.getCell(5).setText(staff.getReviewerName() == null ? "" : staff.getReviewerName()); | ||||
|                 newRow.getCell(6).setText(staff.getReviewerTitle() == null ? "" : staff.getReviewerTitle()); | ||||
|                 newRow.getCell(7).setText(staff.getCheckerName() == null ? "" : staff.getCheckerName()); | ||||
|                 newRow.getCell(8).setText(staff.getCheckerTitle() == null ? "" : staff.getCheckerTitle()); | ||||
|                 newRow.getCell(9).setText(staff.getApproverName() == null ? "" : staff.getApproverName()); | ||||
|                 newRow.getCell(10).setText(staff.getApproverTitle() == null ? "" : staff.getApproverTitle()); | ||||
|             } | ||||
|  | ||||
|             // -------------------------- | ||||
|             // 步骤3:设置响应头(触发前端下载) | ||||
|             // -------------------------- | ||||
|             response.setContentType("application/octet-stream"); | ||||
|             // 文件名:填充后_工程号_CCCET-JL-CX-25设计计划表.docx | ||||
|             String fileName = "CCCET-JL-CX-25设计计划表.docx"; | ||||
|             response.setHeader("Content-Disposition", | ||||
|                 "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8)); | ||||
|             response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); // 允许前端获取文件名 | ||||
|  | ||||
|             // -------------------------- | ||||
|             // 步骤4:写出文件到前端 | ||||
|             // -------------------------- | ||||
|             doc.write(out); | ||||
|             out.flush(); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             // 异常封装(前端可捕获具体错误) | ||||
|             throw new RuntimeException("CCCET-JL-CX-25模板填充失败:" + e.getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 根据projectId获取数据(仅针对CCCET-JL-CX-25设计计划表.docx附件1) | ||||
|      */ | ||||
|     private List<AttachmentPersonnel> getPersonnelDataByProjectId(Long projectId) { | ||||
|         // 模拟数据库查询(实际项目替换为真实Service调用) | ||||
|         List<DesUser> userList = desUserService.list(Wrappers.<DesUser>lambdaQuery() | ||||
|             .eq(DesUser::getProjectId, projectId) | ||||
|         ); | ||||
|         if (userList.isEmpty()) { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|  | ||||
|         // 专业字典映射(编码→名称) | ||||
|         List<SysDictDataVo> majorDict = dictTypeService.selectDictDataByType("des_user_major"); | ||||
|         Map<String, String> majorMap = majorDict.stream() | ||||
|             .collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel)); | ||||
|  | ||||
|         // 按角色分组(1-专业负责人,2-设计人,3-校审人,4-审定人,5-审核人) | ||||
|         DesUser leader = userList.stream().filter(u -> "1".equals(u.getUserType())).findFirst().orElse(null); | ||||
|         Map<String, List<DesUser>> designerMap = userList.stream() | ||||
|             .filter(u -> "2".equals(u.getUserType())) | ||||
|             .collect(Collectors.groupingBy(DesUser::getUserMajor)); | ||||
|         Map<String, List<DesUser>> reviewerMap = userList.stream() | ||||
|             .filter(u -> "3".equals(u.getUserType())) | ||||
|             .collect(Collectors.groupingBy(DesUser::getUserMajor)); | ||||
|         Map<String, List<DesUser>> checkerMap = userList.stream() | ||||
|             .filter(u -> "5".equals(u.getUserType())) | ||||
|             .collect(Collectors.groupingBy(DesUser::getUserMajor)); | ||||
|         Map<String, List<DesUser>> approverMap = userList.stream() | ||||
|             .filter(u -> "4".equals(u.getUserType())) | ||||
|             .collect(Collectors.groupingBy(DesUser::getUserMajor)); | ||||
|  | ||||
|         // 构建附件1数据(一个专业一行,避免重复) | ||||
|         List<AttachmentPersonnel> dataList = new ArrayList<>(); | ||||
|         for (Map.Entry<String, List<DesUser>> entry : designerMap.entrySet()) { | ||||
|             String majorCode = entry.getKey(); | ||||
|             String majorName = majorMap.getOrDefault(majorCode, majorCode); | ||||
|             List<DesUser> designers = entry.getValue(); | ||||
|  | ||||
|             // 获取对应专业的其他角色 | ||||
|             DesUser reviewer = reviewerMap.getOrDefault(majorCode, Collections.emptyList()).stream().findFirst().orElse(null); | ||||
|             DesUser checker = checkerMap.getOrDefault(majorCode, Collections.emptyList()).stream().findFirst().orElse(null); | ||||
|             DesUser approver = approverMap.getOrDefault(majorCode, Collections.emptyList()).stream().findFirst().orElse(null); | ||||
|             // 封装数据(多个设计人用顿号分隔) | ||||
|             AttachmentPersonnel data = new AttachmentPersonnel(); | ||||
|             data.setProfessional(majorName); | ||||
|             data.setLeaderName(leader != null ? leader.getUserName() : ""); | ||||
|             //data.setLeadeTitle(leader != null ? leader.getUserTitle() : ""); | ||||
|             data.setDesignerName(designers.stream().map(DesUser::getUserName).collect(Collectors.joining("、"))); | ||||
|             //data.setDesignerTitle(designers.stream().map(DesUser::getUserTitle).collect(Collectors.joining("、"))); | ||||
|             data.setReviewerName(reviewer != null ? reviewer.getUserName() : ""); | ||||
|             //data.setReviewerTitle(reviewer != null ? reviewer.getUserTitle() : ""); | ||||
|             data.setCheckerName(checker != null ? checker.getUserName() : ""); | ||||
|             //data.setCheckerTitle(checker != null ? checker.getUserTitle() : ""); | ||||
|             data.setApproverName(approver != null ? approver.getUserName() : ""); | ||||
|             //data.setApproverTitle(approver != null ? approver.getUserTitle() : ""); | ||||
|  | ||||
|             dataList.add(data); | ||||
|         } | ||||
|  | ||||
|         return dataList; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -2,6 +2,7 @@ package org.dromara.design.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import com.deepoove.poi.XWPFTemplate; | ||||
| import jakarta.annotation.Resource; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotEmpty; | ||||
| @ -16,24 +17,36 @@ 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.design.domain.DesUser; | ||||
| import org.dromara.design.domain.DesVolumeCatalog; | ||||
| import org.dromara.design.domain.DesVolumeFile; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignChangeCreateReq; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignChangeQueryReq; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignChangeUpdateReq; | ||||
| import org.dromara.design.domain.dto.designchange.DesDesignExtendDetailDto; | ||||
| import org.dromara.design.domain.dto.volumecatalog.DesVolumeCatalogQueryReq; | ||||
| import org.dromara.design.domain.vo.designchange.DesDesignChangeVo; | ||||
| import org.dromara.design.domain.vo.volumecatalog.DesVolumeCatalogVo; | ||||
| import org.dromara.design.service.IDesDesignChangeService; | ||||
| import org.dromara.design.service.IDesVolumeCatalogService; | ||||
| import org.dromara.design.service.IDesVolumeFileService; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.system.domain.vo.SysOssVo; | ||||
| import org.dromara.system.service.ISysDictDataService; | ||||
| import org.dromara.system.service.ISysOssService; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.URLEncoder; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
| @ -56,6 +69,9 @@ public class DesDesignChangeController extends BaseController { | ||||
|     @Resource | ||||
|     private IDesVolumeFileService desVolumeFileService; | ||||
|  | ||||
|     @Resource | ||||
|     private ISysDictDataService dictDataService; | ||||
|  | ||||
|     /** | ||||
|      * 查询设计变更管理列表 | ||||
|      */ | ||||
| @ -146,4 +162,92 @@ public class DesDesignChangeController extends BaseController { | ||||
|         return R.ok(list); | ||||
|     } | ||||
|  | ||||
|     private static final String TEMPLATE_PATH = "template/设计更改通知单.docx"; | ||||
|  | ||||
|     @PostMapping("/downloadWord") | ||||
|     public void generateDesignLeaderDoc(Long id, HttpServletResponse response) { | ||||
|         OutputStream outputStream = null; | ||||
|         try { | ||||
|             // 1. 调用Service生成目标模板的Word字节流 | ||||
|             byte[] docBytes = generateDocBytes(id); | ||||
|  | ||||
|             // 2. 配置响应头:确保前端正确下载(避免中文乱码、指定文件类型) | ||||
|             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // 二进制流类型 | ||||
|             // 下载文件名:格式为“[项目名]-设计负责人任命通知单.docx”(此处用projectId拼接,真实场景可从数据中获取项目名) | ||||
|             String downloadFileName = URLEncoder.encode( | ||||
|                 "设计更改通知单.docx", | ||||
|                 "UTF-8" | ||||
|             ); | ||||
|             response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName); | ||||
|             response.setContentLength(docBytes.length); // 设置响应体长度(优化下载体验) | ||||
|  | ||||
|             // 3. 将Word字节流写入响应 | ||||
|             outputStream = response.getOutputStream(); | ||||
|             outputStream.write(docBytes); | ||||
|             outputStream.flush(); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             // 异常处理:返回500错误状态码 | ||||
|             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); | ||||
|         } finally { | ||||
|             // 关闭流,避免资源泄漏 | ||||
|             if (outputStream != null) { | ||||
|                 try { | ||||
|                     outputStream.close(); | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public byte[] generateDocBytes(Long id) throws Exception { | ||||
|         // -------------------------- 步骤1:按projectId查询项目数据(模拟真实业务) -------------------------- | ||||
|         // 实际场景替换为数据库查询(如调用DAO获取项目名称、负责人等) | ||||
|         DesDesignChangeVo vo = desDesignChangeService.queryById(id); | ||||
|         DesDesignExtendDetailDto extendDetail = vo.getExtendDetail()==null?new DesDesignExtendDetailDto():vo.getExtendDetail(); | ||||
|  | ||||
|         Map<String, Object> placeholderData = new HashMap<>(); | ||||
|         placeholderData.put("projectName", vo.getProjectName()); | ||||
|         placeholderData.put("designPhase",extendDetail.getDesignPhase()); | ||||
|         placeholderData.put("subName",extendDetail.getSubName()); | ||||
|         String s = dictDataService.selectDictLabel("des_user_major", vo.getSpecialty()); | ||||
|         placeholderData.put("specialty",s); | ||||
|         placeholderData.put("volumeNo",vo.getVolumeNo()); | ||||
|  | ||||
|         String changeReason = vo.getChangeReason(); | ||||
|         List<String> reasons = Arrays.asList("设计漏项", "设计改进", "设计差错", "接口差错", | ||||
|             "业主要求", "施工承包商要求", "外部资料与最终情况不符", "材料代用或其他"); | ||||
|  | ||||
|         String reason = reasons.stream() | ||||
|             .map(item -> changeReason.contains(String.valueOf(reasons.indexOf(item) + 1)) ? "  ☑" + item : "  □" + item) | ||||
|             .collect(Collectors.joining()); | ||||
|  | ||||
|         placeholderData.put("changeReason", reason); | ||||
|         placeholderData.put("designDisposal1", "1".equals(extendDetail.getDesignDisposal())?"☑" : "□"); | ||||
|         placeholderData.put("designDisposal2", "2".equals(extendDetail.getDesignDisposal())?"☑" : "□"); | ||||
|         placeholderData.put("designDisposal3", "3".equals(extendDetail.getDesignDisposal())?"☑" : "□"); | ||||
|         placeholderData.put("changeContent",vo.getChangeContent()); | ||||
|         placeholderData.put("changeCategory1", "1".equals(extendDetail.getChangeCategory())?"☑" : "□"); | ||||
|         placeholderData.put("changeCategory2", "2".equals(extendDetail.getChangeCategory())?"☑" : "□"); | ||||
|         placeholderData.put("involvingProfessions", extendDetail.getInvolvingProfessions()); | ||||
|         // -------------------------- 步骤2:用poi-tl加载目标模板并替换占位符 -------------------------- | ||||
|         // 读取resources下的“设计项目负责人任命通知单.docx”模板 | ||||
|         ClassPathResource templateResource = new ClassPathResource(TEMPLATE_PATH); | ||||
|         try (InputStream templateIs = templateResource.getInputStream(); | ||||
|              ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { | ||||
|  | ||||
|             // 1. 加载模板 2. 注入替换数据 3. 渲染生成新文档 | ||||
|             XWPFTemplate template = XWPFTemplate.compile(templateIs) | ||||
|                 .render(placeholderData); // 自动匹配{{变量名}}占位符 | ||||
|  | ||||
|             // -------------------------- 步骤3:将生成的文档写入字节流 -------------------------- | ||||
|             template.write(outputStream); | ||||
|             template.close(); // 关闭模板资源 | ||||
|             return outputStream.toByteArray(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -129,6 +129,7 @@ public class DesExtractController extends BaseController { | ||||
|     @SaCheckPermission("design:extract:userMajor") | ||||
|     @GetMapping("/userMajor") | ||||
|     public R<List<DesUserVo>> selectUserMajor(DesUserBo bo) { | ||||
|         bo.setUserType("2"); | ||||
|         return R.ok( deUserService.queryList(bo)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.dromara.design.domain.dto.ExportDto; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| @ -128,4 +129,9 @@ public class DesPrelimSchemeController extends BaseController { | ||||
|         return toAjax(desPrelimSchemeService.updateFile(file, projectId,id)); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/exportZipWithStatus") | ||||
|     public void exportZipWithStatus(ExportDto dto, HttpServletResponse response) throws Exception { | ||||
|         desPrelimSchemeService.exportAsZipWithStatusPrefix(dto, response); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.dromara.design.domain.dto.ExportDto; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| @ -126,4 +127,10 @@ public class DesSchemeController extends BaseController { | ||||
|     public R<Void> updateFile(MultipartFile file, Long projectId, @NotNull(message = "主键不能为空")@PathVariable Long id) { | ||||
|         return toAjax(desSchemeService.updateFile(file, projectId,id)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @PostMapping("/exportZipWithStatus") | ||||
|     public void exportZipWithStatus(ExportDto dto, HttpServletResponse response) throws Exception { | ||||
|         desSchemeService.exportAsZipWithStatusPrefix(dto, response); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,16 +1,18 @@ | ||||
| package org.dromara.design.controller; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.URLEncoder; | ||||
| import java.rmi.ServerException; | ||||
| import java.time.LocalDate; | ||||
| import java.time.ZoneId; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.*; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import com.deepoove.poi.XWPFTemplate; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| @ -22,8 +24,15 @@ import org.apache.poi.ss.usermodel.Row; | ||||
| import org.apache.poi.xssf.usermodel.XSSFSheet; | ||||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | ||||
| //import org.dromara.design.domain.DesUserExcelData; | ||||
| import org.dromara.design.domain.DesUser; | ||||
| import org.dromara.design.domain.DesUserExcelData; | ||||
| import org.dromara.design.domain.dto.desUser.DesUserBatchDto; | ||||
| import org.dromara.project.domain.BusProject; | ||||
| import org.dromara.project.service.IBusProjectService; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| @ -54,6 +63,7 @@ import org.springframework.web.multipart.MultipartFile; | ||||
| public class DesUserController extends BaseController { | ||||
|  | ||||
|     private final IDesUserService desUserService; | ||||
|     private final IBusProjectService projectService; | ||||
|  | ||||
|     /** | ||||
|      * 查询设计人员列表 | ||||
| @ -142,5 +152,75 @@ public class DesUserController extends BaseController { | ||||
|         return toAjax(desUserService.batchAddOrUpdate(dto)); | ||||
|     } | ||||
|  | ||||
|     private static final String TEMPLATE_PATH = "template/设计项目负责人任命通知单.docx"; | ||||
|  | ||||
|     @PostMapping("/downloadWord") | ||||
|     public void generateDesignLeaderDoc( Long projectId, | ||||
|         HttpServletResponse response | ||||
|     ) { | ||||
|         OutputStream outputStream = null; | ||||
|         try { | ||||
|             // 1. 调用Service生成目标模板的Word字节流 | ||||
|             byte[] docBytes = generateDocBytes(projectId); | ||||
|  | ||||
|             // 2. 配置响应头:确保前端正确下载(避免中文乱码、指定文件类型) | ||||
|             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); // 二进制流类型 | ||||
|             // 下载文件名:格式为“[项目名]-设计负责人任命通知单.docx”(此处用projectId拼接,真实场景可从数据中获取项目名) | ||||
|             String downloadFileName = URLEncoder.encode( | ||||
|                 "设计负责人任命通知单.docx", | ||||
|                 "UTF-8" | ||||
|             ); | ||||
|             response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName); | ||||
|             response.setContentLength(docBytes.length); // 设置响应体长度(优化下载体验) | ||||
|  | ||||
|             // 3. 将Word字节流写入响应 | ||||
|             outputStream = response.getOutputStream(); | ||||
|             outputStream.write(docBytes); | ||||
|             outputStream.flush(); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             // 异常处理:返回500错误状态码 | ||||
|             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); | ||||
|         } finally { | ||||
|             // 关闭流,避免资源泄漏 | ||||
|             if (outputStream != null) { | ||||
|                 try { | ||||
|                     outputStream.close(); | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public byte[] generateDocBytes(Long projectId) throws Exception { | ||||
|         // -------------------------- 步骤1:按projectId查询项目数据(模拟真实业务) -------------------------- | ||||
|         // 实际场景替换为数据库查询(如调用DAO获取项目名称、负责人等) | ||||
|         BusProject byId = projectService.getById(projectId); | ||||
|         DesUser desUser = desUserService.lambdaQuery().eq(DesUser::getProjectId, projectId) | ||||
|             .eq(DesUser::getUserType, "1") | ||||
|             .last("limit 1").one(); | ||||
|  | ||||
|  | ||||
|         Map<String, Object> placeholderData = new HashMap<>(); | ||||
|         placeholderData.put("projectName", byId==null?"" :byId.getProjectName()); | ||||
|         placeholderData.put("leaderName",desUser==null?"": desUser.getUserName()); | ||||
|  | ||||
|         // -------------------------- 步骤2:用poi-tl加载目标模板并替换占位符 -------------------------- | ||||
|         // 读取resources下的“设计项目负责人任命通知单.docx”模板 | ||||
|         ClassPathResource templateResource = new ClassPathResource(TEMPLATE_PATH); | ||||
|         try (InputStream templateIs = templateResource.getInputStream(); | ||||
|              ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { | ||||
|  | ||||
|             // 1. 加载模板 2. 注入替换数据 3. 渲染生成新文档 | ||||
|             XWPFTemplate template = XWPFTemplate.compile(templateIs) | ||||
|                 .render(placeholderData); // 自动匹配{{变量名}}占位符 | ||||
|  | ||||
|             // -------------------------- 步骤3:将生成的文档写入字节流 -------------------------- | ||||
|             template.write(outputStream); | ||||
|             template.close(); // 关闭模板资源 | ||||
|             return outputStream.toByteArray(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,87 @@ | ||||
| package org.dromara.design.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.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * 施工进度计划对象 pgs_construction_schedule_plan | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("des_construction_schedule_plan") | ||||
| public class DesConstructionSchedulePlan extends BaseEntity { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @TableId(value = "id") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 父ID | ||||
|      */ | ||||
|     private Long parentId; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构 | ||||
|      */ | ||||
|     private Long projectStructure; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 预计开始时间 | ||||
|      */ | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 预计结束时间 | ||||
|      */ | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际开始时间 | ||||
|      */ | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际结束时间 | ||||
|      */ | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,11 @@ | ||||
| package org.dromara.design.domain.dto; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @Data | ||||
| public class ExportDto { | ||||
|     private Long projectId; | ||||
|     private List<Long> ids; | ||||
| } | ||||
| @ -0,0 +1,77 @@ | ||||
| package org.dromara.design.domain.dto.constructionscheduleplan; | ||||
|  | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 14:05 | ||||
|  */ | ||||
| @Data | ||||
| public class DesConstructionSchedulePlanCreateReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 4060838737379600701L; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     @NotNull(message = "项目ID不能为空") | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 父ID | ||||
|      */ | ||||
|     private Long parentId; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     @NotBlank(message = "节点名称不能为空") | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构 | ||||
|      */ | ||||
|     private Long projectStructure; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 预计开始时间 | ||||
|      */ | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 预计结束时间 | ||||
|      */ | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际开始时间 | ||||
|      */ | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际结束时间 | ||||
|      */ | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
| } | ||||
| @ -0,0 +1,71 @@ | ||||
| package org.dromara.design.domain.dto.constructionscheduleplan; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-09-06 17:12 | ||||
|  */ | ||||
| @Data | ||||
| @AllArgsConstructor | ||||
| public class DesConstructionSchedulePlanExcelDto { | ||||
|  | ||||
|     /** | ||||
|      * 编号(1, 1.1, 1.1.1) | ||||
|      */ | ||||
|     private String number; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构 | ||||
|      */ | ||||
|     private Long projectStructure; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 预计开始时间 | ||||
|      */ | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 预计结束时间 | ||||
|      */ | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际开始时间 | ||||
|      */ | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际结束时间 | ||||
|      */ | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,31 @@ | ||||
| package org.dromara.design.domain.dto.constructionscheduleplan; | ||||
|  | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-09-17 10:15 | ||||
|  */ | ||||
| @Data | ||||
| public class DesConstructionSchedulePlanFinishReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 8139653508791280689L; | ||||
|  | ||||
|     /** | ||||
|      * 主键 | ||||
|      */ | ||||
|     @NotNull(message = "主键不能为空") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 完成时间 | ||||
|      */ | ||||
|     @NotNull(message = "完成时间不能为空") | ||||
|     private LocalDate finishDate; | ||||
| } | ||||
| @ -0,0 +1,37 @@ | ||||
| package org.dromara.design.domain.dto.constructionscheduleplan; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 14:05 | ||||
|  */ | ||||
| @Data | ||||
| public class DesConstructionSchedulePlanQueryReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 9021370369055688811L; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     private String status; | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| package org.dromara.design.domain.dto.constructionscheduleplan; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| /** | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 14:06 | ||||
|  */ | ||||
| @Data | ||||
| public class DesConstructionSchedulePlanUpdateReq implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 6955873817030428268L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 父ID | ||||
|      */ | ||||
|     private Long parentId; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构 | ||||
|      */ | ||||
|     private Long projectStructure; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 预计开始时间 | ||||
|      */ | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 预计结束时间 | ||||
|      */ | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际开始时间 | ||||
|      */ | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际结束时间 | ||||
|      */ | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| package org.dromara.design.domain.vo; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| @Data | ||||
| public class DesCollectFileWordVo { | ||||
|  | ||||
|     private Integer num; | ||||
|  | ||||
|     private String fileName; | ||||
|  | ||||
|     private String opinion; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,104 @@ | ||||
| package org.dromara.design.domain.vo; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import org.dromara.common.excel.annotation.ExcelDictFormat; | ||||
| import org.dromara.common.excel.convert.ExcelDictConvert; | ||||
| import org.dromara.progress.domain.PgsConstructionSchedulePlan; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * 施工进度计划视图对象 pgs_construction_schedule_plan | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 | ||||
|  */ | ||||
| @Data | ||||
| @ExcelIgnoreUnannotated | ||||
| @AutoMapper(target = PgsConstructionSchedulePlan.class) | ||||
| public class DesConstructionSchedulePlanVo implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @ExcelProperty(value = "主键ID") | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 项目ID | ||||
|      */ | ||||
|     @ExcelProperty(value = "项目ID") | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
|      * 父ID | ||||
|      */ | ||||
|     @ExcelProperty(value = "父ID") | ||||
|     private Long parentId; | ||||
|  | ||||
|     /** | ||||
|      * 节点名称 | ||||
|      */ | ||||
|     @ExcelProperty(value = "节点名称") | ||||
|     private String nodeName; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构 | ||||
|      */ | ||||
|     @ExcelProperty(value = "对应项目结构") | ||||
|     private Long projectStructure; | ||||
|  | ||||
|     /** | ||||
|      * 对应项目结构名称 | ||||
|      */ | ||||
|     @ExcelProperty(value = "对应项目结构名称") | ||||
|     private String projectStructureName; | ||||
|  | ||||
|     /** | ||||
|      * 预计开始时间 | ||||
|      */ | ||||
|     @ExcelProperty(value = "预计开始时间") | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 预计结束时间 | ||||
|      */ | ||||
|     @ExcelProperty(value = "预计结束时间") | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际开始时间 | ||||
|      */ | ||||
|     @ExcelProperty(value = "实际开始时间") | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     /** | ||||
|      * 实际结束时间 | ||||
|      */ | ||||
|     @ExcelProperty(value = "实际结束时间") | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     /** | ||||
|      * 状态 | ||||
|      */ | ||||
|     @ExcelProperty(value = "状态", converter = ExcelDictConvert.class) | ||||
|     @ExcelDictFormat(dictType = "project_construction_status") | ||||
|     private String status; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     @ExcelProperty(value = "备注") | ||||
|     private String remark; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -1,5 +1,7 @@ | ||||
| package org.dromara.design.domain.vo; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelIgnore; | ||||
| import com.alibaba.excel.annotation.format.DateTimeFormat; | ||||
| import org.dromara.design.domain.DesSubcontract; | ||||
| import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| @ -31,13 +33,13 @@ public class DesSubcontractVo implements Serializable { | ||||
|     /** | ||||
|      * 主键ID | ||||
|      */ | ||||
|     @ExcelProperty(value = "主键ID") | ||||
|     @ExcelIgnore | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 项目id | ||||
|      */ | ||||
|     @ExcelProperty(value = "项目id") | ||||
|     @ExcelIgnore | ||||
|     private Long projectId; | ||||
|  | ||||
|     /** | ||||
| @ -49,7 +51,13 @@ public class DesSubcontractVo implements Serializable { | ||||
|     /** | ||||
|      * 分包要求 | ||||
|      */ | ||||
|     @ExcelProperty(value = "说明") | ||||
|     private String requirement; | ||||
|  | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @DateTimeFormat("yyyy-MM-dd") | ||||
|     @ExcelProperty(value = "创建时间") | ||||
|     private Date createTime; | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,33 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import com.alibaba.excel.annotation.format.NumberFormat; | ||||
| import com.alibaba.excel.annotation.write.style.HeadStyle; | ||||
| import com.alibaba.excel.enums.poi.FillPatternTypeEnum; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.math.BigDecimal; | ||||
|  | ||||
| @Data | ||||
| @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 9) | ||||
| public class BillOfQuantitiesExport { | ||||
|     @ExcelProperty(value = "编号", index = 0) | ||||
|     private String num; | ||||
|  | ||||
|     @ExcelProperty(value = "名称及规格", index = 1) | ||||
|     private String name; | ||||
|  | ||||
|     @ExcelProperty(value = "规格", index = 2) | ||||
|     private String specification; | ||||
|  | ||||
|     @ExcelProperty(value = "单位", index = 3) | ||||
|     @NumberFormat("#") // 若单位为文本,可去掉此注解 | ||||
|     private String unit; | ||||
|  | ||||
|     @ExcelProperty(value = "数量", index = 4) | ||||
|     @NumberFormat("#,##0.00") // 数量格式化(保留两位小数) | ||||
|     private BigDecimal quantity; | ||||
|  | ||||
|     @ExcelProperty(value = "备注", index = 5) | ||||
|     private String remark; | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import com.alibaba.excel.write.handler.SheetWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; | ||||
| import org.apache.poi.ss.usermodel.Sheet; | ||||
|  | ||||
| /** | ||||
|  * 调整指定列的宽度(第二列和第五列) | ||||
|  */ | ||||
| public class ColumnWidthWriteHandler implements SheetWriteHandler { | ||||
|  | ||||
|     @Override | ||||
|     public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { | ||||
|         Sheet sheet = writeSheetHolder.getSheet(); | ||||
|  | ||||
|         // 设置列宽(单位:字符数,1字符≈256个单位,这里按实际需求调整) | ||||
|         // 第二列(索引1):例如设置宽度为30个字符 | ||||
|         sheet.setColumnWidth(1, 30 * 256); | ||||
|         // 第五列(索引4):例如设置宽度为15个字符 | ||||
|         sheet.setColumnWidth(4, 15 * 256); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import com.alibaba.excel.write.handler.RowWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteTableHolder; | ||||
| import org.apache.poi.ss.usermodel.*; | ||||
|  | ||||
| /** | ||||
|  * 行样式处理器: | ||||
|  * 1. 第二行(索引1)及以后所有行添加边框 | ||||
|  * 2. 第二行(索引1)的第二列(索引1)标题栏加粗加大 | ||||
|  */ | ||||
| import com.alibaba.excel.write.handler.RowWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteTableHolder; | ||||
| import org.apache.poi.ss.usermodel.*; | ||||
|  | ||||
| public class CustomRowStyleHandler implements RowWriteHandler { | ||||
|  | ||||
|     @Override | ||||
|     public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) { | ||||
|         // 关键修改:通过 writeSheetHolder 获取 Workbook(兼容所有版本) | ||||
|         Workbook workbook = writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook(); | ||||
|         int rowIndex = row.getRowNum(); | ||||
|  | ||||
|         // 1. 第二行(索引1)及以后的行添加边框 | ||||
|         if (rowIndex >= 1) { | ||||
|             CellStyle borderStyle = ExcelStyleUtils.createBorderStyle(workbook); | ||||
|  | ||||
|             for (int i = 0; i <= 5; i++) { | ||||
|                 Cell cell = row.getCell(i); | ||||
|                 if (cell == null) { | ||||
|                     cell = row.createCell(i); | ||||
|                 } | ||||
|                 cell.setCellStyle(borderStyle); | ||||
|             } | ||||
|  | ||||
|             // 2. 第二行(索引1)的第二列(索引1)标题栏加粗加大 | ||||
|             if (rowIndex == 1) { | ||||
|                 for (int i = 0; i <= 5; i++) { | ||||
|                     Cell secondColumnCell = row.getCell(i); | ||||
|                     if (secondColumnCell != null) { | ||||
|                         CellStyle headerStyle = ExcelStyleUtils.createSecondColumnHeaderStyle(workbook); | ||||
|                         secondColumnCell.setCellStyle(headerStyle); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,57 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import org.apache.poi.ss.usermodel.*; | ||||
|  | ||||
| /** | ||||
|  * 样式工具类(定义边框、字体等样式) | ||||
|  */ | ||||
| public class ExcelStyleUtils { | ||||
|     // 边框样式(细实线) | ||||
|     public static final BorderStyle BORDER_STYLE = BorderStyle.THIN; | ||||
|     // 边框颜色(黑色) | ||||
|     public static final short BORDER_COLOR = IndexedColors.BLACK.getIndex(); | ||||
|  | ||||
|     /** | ||||
|      * 创建带边框的单元格样式 | ||||
|      */ | ||||
|     public static CellStyle createBorderStyle(Workbook workbook) { | ||||
|         CellStyle style = workbook.createCellStyle(); | ||||
|         // 上下左右边框 | ||||
|         style.setBorderTop(BORDER_STYLE); | ||||
|         style.setBorderBottom(BORDER_STYLE); | ||||
|         style.setBorderLeft(BORDER_STYLE); | ||||
|         style.setBorderRight(BORDER_STYLE); | ||||
|         // 边框颜色 | ||||
|         style.setTopBorderColor(BORDER_COLOR); | ||||
|         style.setBottomBorderColor(BORDER_COLOR); | ||||
|         style.setLeftBorderColor(BORDER_COLOR); | ||||
|         style.setRightBorderColor(BORDER_COLOR); | ||||
|         // 单元格内容居中(可选) | ||||
|         style.setAlignment(HorizontalAlignment.CENTER); | ||||
|         style.setVerticalAlignment(VerticalAlignment.CENTER); | ||||
|         return style; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建第二列标题栏样式(加粗、字号加大) | ||||
|      */ | ||||
|     public static CellStyle createSecondColumnHeaderStyle(Workbook workbook) { | ||||
|         CellStyle style = createBorderStyle(workbook); // 继承边框样式 | ||||
|         Font font = workbook.createFont(); | ||||
|         font.setBold(true); // 加粗 | ||||
|         font.setFontHeightInPoints((short) 12); // 字号加大(默认11,这里设12) | ||||
|         style.setFont(font); | ||||
|         return style; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 创建第一行(合并标题行)的白色背景样式 | ||||
|      */ | ||||
|     public static CellStyle createFirstRowWhiteStyle(Workbook workbook) { | ||||
|         CellStyle style = workbook.createCellStyle(); | ||||
|         // 设置白色背景 | ||||
|         style.setFillForegroundColor(IndexedColors.WHITE.getIndex()); | ||||
|         style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 纯色填充 | ||||
|         return style; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import com.alibaba.excel.write.handler.SheetWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; | ||||
| import org.apache.poi.ss.usermodel.Sheet; | ||||
|  | ||||
| /** | ||||
|  * 冻结前3行的处理器(滚动时前3行固定) | ||||
|  */ | ||||
| public class FreezePaneWriteHandler implements SheetWriteHandler { | ||||
|  | ||||
|     @Override | ||||
|     public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { | ||||
|         Sheet sheet = writeSheetHolder.getSheet(); | ||||
|         // 参数说明:冻结0列,冻结2行,从第0列、第2行开始滚动 | ||||
|         // 前2行(索引0和1)将固定在顶部 | ||||
|         sheet.createFreezePane(0, 2, 0, 2); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,41 @@ | ||||
| package org.dromara.design.exportUtil.bill; | ||||
|  | ||||
| import com.alibaba.excel.write.handler.SheetWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; | ||||
| import org.apache.poi.ss.usermodel.Cell; | ||||
| import org.apache.poi.ss.usermodel.Row; | ||||
| import org.apache.poi.ss.usermodel.Sheet; | ||||
| import org.apache.poi.ss.usermodel.Workbook; | ||||
| import org.apache.poi.ss.util.CellRangeAddress; | ||||
|  | ||||
| public class SheetHeaderWriteHandler implements SheetWriteHandler { | ||||
|  | ||||
|     private final String sheetName; | ||||
|  | ||||
|     public SheetHeaderWriteHandler( String sheetName) { | ||||
|         this.sheetName = sheetName; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { | ||||
|         Sheet sheet = writeSheetHolder.getSheet(); | ||||
|         Workbook workbook = writeWorkbookHolder.getWorkbook(); | ||||
|  | ||||
|         // 第一行(索引0):合并标题 + 白色背景 | ||||
|         Row titleRow = sheet.createRow(0); | ||||
|         Cell titleCell = titleRow.createCell(0); | ||||
|         titleCell.setCellValue(sheetName); | ||||
|         // 应用白色背景样式 | ||||
|         titleCell.setCellStyle(ExcelStyleUtils.createFirstRowWhiteStyle(workbook)); | ||||
|         // 合并第一行的0-5列 | ||||
|         sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 5)); | ||||
|  | ||||
|         // 第2行(索引1):字段标题栏(手动指定,覆盖实体类默认表头) | ||||
|         Row headerRow = sheet.createRow(1); | ||||
|         String[] headers = {"编号", "名称", "规格", "单位", "数量", "备注"}; | ||||
|         for (int i = 0; i < headers.length; i++) { | ||||
|             headerRow.createCell(i).setCellValue(headers[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package org.dromara.design.exportUtil.plan; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
|  | ||||
| @Data | ||||
| @AllArgsConstructor | ||||
| @NoArgsConstructor | ||||
| public class AttachmentPersonnel { | ||||
|     String professional;  // 专业及人员分工 | ||||
|     String leaderName;    // 专业负责人姓名 | ||||
|     String leaderTitle;   // 专业负责人职称 | ||||
|     String designerName;  // 设计人姓名 | ||||
|     String designerTitle; // 设计人职称 | ||||
|     String reviewerName;  // 校审人姓名 | ||||
|     String reviewerTitle; // 校审人职称 | ||||
|     String checkerName;   // 审核人姓名 | ||||
|     String checkerTitle;  // 审核人职称 | ||||
|     String approverName;  // 审定人姓名 | ||||
|     String approverTitle; // 审定人职称 | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,48 @@ | ||||
| package org.dromara.design.exportUtil.plan; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelIgnore; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import com.alibaba.excel.annotation.format.DateTimeFormat; | ||||
| import com.alibaba.excel.converters.localdate.LocalDateStringConverter; | ||||
| import lombok.Data; | ||||
| import org.dromara.common.excel.annotation.ExcelDictFormat; | ||||
| import org.dromara.common.excel.convert.ExcelDictConvert; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| @Data | ||||
| public class ConstructionScheduleExport { | ||||
|     @ExcelProperty(value = "编号", index = 0) | ||||
|     private String levelCode; // 层级编号(如1、1.1、1.1.1) | ||||
|  | ||||
|     @ExcelProperty(value = "节点名称", index = 1) | ||||
|     private String nodeName; | ||||
|  | ||||
|  | ||||
|     @DateTimeFormat("yyyy-MM-dd") | ||||
|     @ExcelProperty(value = "预计开始时间", index = 2) | ||||
|     private LocalDate planStartDate; | ||||
|  | ||||
|     @DateTimeFormat("yyyy-MM-dd") | ||||
|     @ExcelProperty(value = "预计结束时间", index = 3) | ||||
|     private LocalDate planEndDate; | ||||
|  | ||||
|     @DateTimeFormat("yyyy-MM-dd") | ||||
|     @ExcelProperty(value = "实际开始时间", index = 4) | ||||
|     private LocalDate practicalStartDate; | ||||
|  | ||||
|     @DateTimeFormat("yyyy-MM-dd") | ||||
|     @ExcelProperty(value = "实际结束时间", index = 5) | ||||
|     private LocalDate practicalEndDate; | ||||
|  | ||||
|     @ExcelProperty(value = "状态", index = 6,converter = ExcelDictConvert.class) | ||||
|     @ExcelDictFormat(dictType = "project_construction_status") | ||||
|     private String status; | ||||
|  | ||||
|     // 用于构建层级关系的临时字段(不导出) | ||||
|     @ExcelIgnore | ||||
|     private Long id; | ||||
|  | ||||
|     @ExcelIgnore | ||||
|     private Long parentId; | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package org.dromara.design.exportUtil.plan; | ||||
|  | ||||
| import com.alibaba.excel.write.handler.SheetWriteHandler; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | ||||
| import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; | ||||
| import org.apache.poi.ss.usermodel.Cell; | ||||
| import org.apache.poi.ss.usermodel.Row; | ||||
| import org.apache.poi.ss.usermodel.Sheet; | ||||
| import org.apache.poi.ss.usermodel.Workbook; | ||||
| import org.apache.poi.ss.util.CellRangeAddress; | ||||
|  | ||||
| public class ScheduleHeaderWriteHandler implements SheetWriteHandler { | ||||
|     @Override | ||||
|     public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { | ||||
|         Sheet sheet = writeSheetHolder.getSheet(); | ||||
|  | ||||
|         // 第一行直接作为标题栏 | ||||
|         Row titleRow = sheet.createRow(0); | ||||
|         String[] titles = {"编号", "节点名称", "预计开始时间", "预计结束时间", "实际开始时间", "实际结束时间", "状态"}; | ||||
|         for (int i = 0; i < titles.length; i++) { | ||||
|             Cell cell = titleRow.createCell(i); | ||||
|             cell.setCellValue(titles[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package org.dromara.design.mapper; | ||||
|  | ||||
| import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; | ||||
| import org.dromara.design.domain.DesConstructionSchedulePlan; | ||||
| import org.dromara.design.domain.vo.DesConstructionSchedulePlanVo; | ||||
| import org.dromara.progress.domain.PgsConstructionSchedulePlan; | ||||
| import org.dromara.progress.domain.vo.constructionscheduleplan.PgsConstructionSchedulePlanVo; | ||||
|  | ||||
| /** | ||||
|  * 施工进度计划Mapper接口 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 | ||||
|  */ | ||||
| public interface DesConstructionSchedulePlanMapper extends BaseMapperPlus<DesConstructionSchedulePlan, DesConstructionSchedulePlanVo> { | ||||
|  | ||||
| } | ||||
| @ -3,14 +3,15 @@ package org.dromara.design.service; | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.design.domain.BusBillofquantities; | ||||
| import org.dromara.design.domain.BusBillofquantitiesVersions; | ||||
| import org.dromara.design.domain.bo.*; | ||||
| import org.dromara.design.domain.vo.*; | ||||
| import org.dromara.design.exportUtil.bill.BillOfQuantitiesExport; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * 工程量清单版本Service接口 | ||||
| @ -100,4 +101,7 @@ public interface IBusBillofquantitiesVersionsService extends IService<BusBillofq | ||||
|     List<BusBillofquantitiesMaterialTotalVo> queryMaterialTotalListByProject(Long projectId); | ||||
|  | ||||
|     List<BusBillofquantitiesVo> obtainAllClassification(ObtainAllVersionNumbersReq bo); | ||||
|  | ||||
|  | ||||
|     Map<String, List<BillOfQuantitiesExport>> export(String versions,Long projectId); | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,14 @@ | ||||
| package org.dromara.design.service; | ||||
|  | ||||
|  | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
|  | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.dromara.design.domain.DesCollectFile; | ||||
| import org.dromara.design.domain.bo.DesCollectFileBo; | ||||
| import org.dromara.design.domain.dto.ExportDto; | ||||
| import org.dromara.design.domain.vo.DesCollectFileVo; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| @ -79,5 +81,6 @@ public interface IDesCollectFileService extends IService<DesCollectFile>{ | ||||
|     Boolean addFile(MultipartFile file, Long catalogueId, Long projectId); | ||||
|  | ||||
|  | ||||
|     void exportAsZip(ExportDto dto, HttpServletResponse response) throws Exception; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,121 @@ | ||||
| package org.dromara.design.service; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.dromara.design.domain.DesConstructionSchedulePlan; | ||||
| import org.dromara.design.domain.dto.constructionscheduleplan.*; | ||||
| import org.dromara.design.domain.vo.DesConstructionSchedulePlanVo; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 施工进度计划Service接口 | ||||
|  * | ||||
|  * @author lilemy | ||||
|  * @date 2025-08-01 | ||||
|  */ | ||||
| public interface IDesConstructionSchedulePlanService extends IService<DesConstructionSchedulePlan> { | ||||
|  | ||||
|     /** | ||||
|      * 查询施工进度计划 | ||||
|      * | ||||
|      * @param id 主键 | ||||
|      * @return 施工进度计划 | ||||
|      */ | ||||
|     DesConstructionSchedulePlanVo queryById(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 查询符合条件的施工进度计划列表 | ||||
|      * | ||||
|      * @param req 查询条件 | ||||
|      * @return 施工进度计划列表 | ||||
|      */ | ||||
|     List<DesConstructionSchedulePlanVo> queryList(DesConstructionSchedulePlanQueryReq req); | ||||
|  | ||||
|     /** | ||||
|      * 新增施工进度计划 | ||||
|      * | ||||
|      * @param req 施工进度计划 | ||||
|      * @return 新增施工进度计划封装 | ||||
|      */ | ||||
|     DesConstructionSchedulePlanVo insertByBo(DesConstructionSchedulePlanCreateReq req); | ||||
|  | ||||
|     /** | ||||
|      * 修改施工进度计划 | ||||
|      * | ||||
|      * @param req 施工进度计划 | ||||
|      * @return 是否修改成功 | ||||
|      */ | ||||
|     Boolean updateByBo(DesConstructionSchedulePlanUpdateReq req); | ||||
|  | ||||
|     /** | ||||
|      * 修改施工进度计划为完成状态 | ||||
|      * | ||||
|      * @param req 施工进度计划 | ||||
|      * @return 是否修改成功 | ||||
|      */ | ||||
|     Boolean updateFinish(DesConstructionSchedulePlanFinishReq req); | ||||
|  | ||||
|     /** | ||||
|      * 批量删除施工进度计划信息 | ||||
|      * | ||||
|      * @param ids 待删除的主键集合 | ||||
|      * @return 是否删除成功 | ||||
|      */ | ||||
|     Boolean deleteByIds(Collection<Long> ids); | ||||
|  | ||||
|     /** | ||||
|      * 获取施工进度计划视图对象 | ||||
|      * | ||||
|      * @param constructionSchedulePlan 施工进度计划对象 | ||||
|      * @return 施工进度计划视图对象 | ||||
|      */ | ||||
|     DesConstructionSchedulePlanVo getVo(DesConstructionSchedulePlan constructionSchedulePlan); | ||||
|  | ||||
|     /** | ||||
|      * 获取施工进度计划查询条件封装 | ||||
|      * | ||||
|      * @param req 查询条件 | ||||
|      * @return 查询条件封装 | ||||
|      */ | ||||
|     LambdaQueryWrapper<DesConstructionSchedulePlan> buildQueryWrapper(DesConstructionSchedulePlanQueryReq req); | ||||
|  | ||||
|     /** | ||||
|      * 获取施工进度计划分页对象视图 | ||||
|      * | ||||
|      * @param constructionSchedulePlanList 施工进度计划分页对象 | ||||
|      * @return 施工进度计划分页对象视图 | ||||
|      */ | ||||
|     List<DesConstructionSchedulePlanVo> getVoList(List<DesConstructionSchedulePlan> constructionSchedulePlanList); | ||||
|  | ||||
|     /** | ||||
|      * 导出Excel | ||||
|      * | ||||
|      * @param projectId 项目id | ||||
|      */ | ||||
|     void exportExcelByProjectId(Long projectId, HttpServletResponse response); | ||||
|  | ||||
|     /** | ||||
|      * 读取Excel文件 | ||||
|      * | ||||
|      * @param file      Excel文件 | ||||
|      * @param projectId 项目ID | ||||
|      * @return 读取的数据列表 | ||||
|      */ | ||||
|     List<DesConstructionSchedulePlanExcelDto> readExcel(MultipartFile file, Long projectId); | ||||
|  | ||||
|     /** | ||||
|      * 将Excel数据转换为实体列表 | ||||
|      * | ||||
|      * @param excelList Excel数据列表 | ||||
|      * @return 实体列表 | ||||
|      */ | ||||
|     List<DesConstructionSchedulePlan> convertToEntities(List<DesConstructionSchedulePlanExcelDto> excelList); | ||||
|  | ||||
|  | ||||
|     void exportSchedule(HttpServletResponse response, Long projectId) throws IOException; | ||||
| } | ||||
| @ -1,6 +1,7 @@ | ||||
| package org.dromara.design.service; | ||||
|  | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.dromara.design.domain.dto.ExportDto; | ||||
| import org.dromara.design.domain.vo.DesPrelimSchemeVo; | ||||
| import org.dromara.design.domain.bo.DesPrelimSchemeBo; | ||||
| import org.dromara.design.domain.DesPrelimScheme; | ||||
| @ -8,7 +9,6 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
|  | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import java.util.Collection; | ||||
| @ -81,4 +81,7 @@ public interface IDesPrelimSchemeService extends IService<DesPrelimScheme>{ | ||||
|      * 修改文件 | ||||
|      */ | ||||
|     Boolean updateFile(MultipartFile file, Long projectId, Long id); | ||||
|  | ||||
|  | ||||
|     void exportAsZipWithStatusPrefix(ExportDto dto, HttpServletResponse response) throws Exception; | ||||
| } | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	