Author SHA1 Message Date
王奎兴 c2e3de244b feign地址修改; 2026-09-12 17:50:48 +08:00
王奎兴 9453aea60f feign地址修改; 2026-09-12 17:36:09 +08:00
王奎兴 c877696eca Merge branch 'dev' into dev-bms-260826
# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/OmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/YmsServiceFeign.java
#	mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/feign/ThirdPartyServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/infrastructure/feign/ThirdPartyServiceFeign.java
2026-09-12 17:28:12 +08:00
王奎兴 7f6006ca48 feign地址修改; 2026-09-12 17:20:01 +08:00
王奎兴 edcfa0b510 月度汇总明细接口; 2026-09-12 14:52:03 +08:00
王奎兴 03b168abc0 token参数名 2026-09-12 14:02:47 +08:00
王奎兴 c9bd81c8f2 返回值判断 2026-09-12 11:46:01 +08:00
赵辉 defc8c3709 31 2026-09-12 10:03:33 +08:00
王奎兴 3c21c2c848 发30 2026-09-12 10:00:45 +08:00
王奎兴 71936b50a7 Merge remote-tracking branch 'origin/dev' into dev 2026-09-12 09:59:56 +08:00
赵辉 9cfffe1224 去除验证码校验 2026-09-12 09:59:39 +08:00
王奎兴 d7574d188a 客户月结报告; 2026-09-12 09:59:30 +08:00
赵辉 1c1b06c1bf 去除验证码校验 2026-09-12 09:24:11 +08:00
rcx 117019c55c 30 2026-09-11 17:46:07 +08:00
rcx 171909b68d 31 2026-09-11 17:44:15 +08:00
王奎兴 9ac60e446a 客户月结报告; 2026-09-11 17:39:29 +08:00
王奎兴 5ba179d29d 客户月结报告; 2026-09-11 17:36:38 +08:00
赵辉 31c27c16c6 user31 2026-09-11 17:28:40 +08:00
赵辉 8dfe9545aa user30 2026-09-11 17:22:50 +08:00
王奎兴 6613eeb3fb 批量红冲; 2026-09-11 16:36:23 +08:00
王奎兴 0ca8548c06 查询参数; 2026-09-11 15:56:48 +08:00
王奎兴 3653c37914 查询参数; 2026-09-11 15:52:02 +08:00
赵辉 028afb57d7 用户-yms同步新增与修改密码 2026-09-11 15:45:15 +08:00
王奎兴 c1bbda9f9a 撤销付款逻辑修改; 2026-09-11 15:33:59 +08:00
rcx 37dd374bda fix(wms): 入库单导入"该货主下不存在该料号"误报修复
- 根因:Excel客户名称按USER表user_name解析货主ID,同名双账号(如3519/3525)解析到非档案归属账号,带错误shipperId查物料必为空
- 料号匹配:主查询(料号+顶级组织+解析shipperId)为空时,去掉货主条件按档案shipper_name与Excel客户名称等值兜底匹配,命中后以档案货主纠正单据shipperId/shipperCode/shipperName
- 新增pickMaterialByCode挑选:料号精确等值优先于LIKE模糊命中,避免子串料号截胡
- SKU校验:档案条码barCode为空时跳过比对,档案有值时仍严格校验
- 校验失败输出诊断日志并附解析shipperId/登录topOrganizationId,区分货主错配(原因A)与组织口径(原因B)
2026-09-11 15:14:46 +08:00
秦鸿展 0077e5d673 30 2026-09-10 23:29:33 +08:00
秦鸿展 4b5ed4d0e1 调整同步TMS修改 2026-09-10 23:07:59 +08:00
秦鸿展 3b8c0ffe8f 调整同步TMS修改 2026-09-10 22:53:22 +08:00
秦鸿展 21db0bc5da 调整同步TMS修改 2026-09-10 22:43:45 +08:00
秦鸿展 eaeb100b22 调整同步TMS修改 2026-09-10 22:21:41 +08:00
秦鸿展 8d6c252eb4 调整同步TMS修改 2026-09-10 22:16:47 +08:00
秦鸿展 86c4c07708 调整修改 2026-09-10 21:55:02 +08:00
秦鸿展 db31711ad0 驳回订单修改 2026-09-10 21:20:09 +08:00
秦鸿展 6282849468 驳回订单修改 2026-09-10 21:15:14 +08:00
秦鸿展 60381ad7c9 OMS订单费用修改 2026-09-10 20:42:16 +08:00
秦鸿展 cd4ceecf98 OMS调整字段映射 2026-09-10 20:17:05 +08:00
王奎兴 cf3299165d 定时任务方法; 2026-09-10 17:29:09 +08:00
王奎兴 432f71de06 json解析修改; 2026-09-10 17:11:12 +08:00
王奎兴 6efd37fe0e json解析修改; 2026-09-10 17:00:48 +08:00
秦鸿展 d69af9ef20 30 2026-09-10 16:49:24 +08:00
秦鸿展 9704dbfb07 导入物料组织覆盖问题 2026-09-10 16:20:59 +08:00
王奎兴 65fdac5354 定时任务生成发票; 2026-09-10 16:18:32 +08:00
王奎兴 3387d1712d 红冲接口 2026-09-10 15:33:51 +08:00
秦鸿展 3276792bb5 告警修改 2026-09-10 13:20:07 +08:00
秦鸿展 b57db4b8cc 30 2026-09-10 11:49:34 +08:00
秦鸿展 8a31ed9974 BI月台指标检测修改 2026-09-10 11:46:34 +08:00
王奎兴 76ded7ed01 Merge branch 'dev' into dev-bms-260826 2026-09-10 11:19:16 +08:00
王奎兴 bbde788aa4 撤销收款接口 2026-09-10 11:17:58 +08:00
王奎兴 10012b3437 Merge remote-tracking branch 'origin/dev-bms-260826' into dev-bms-260826 2026-09-10 10:32:09 +08:00
王奎兴 7a5e84453c xxljob 2026-09-10 10:31:56 +08:00
秦鸿展 9777156959 31 2026-09-09 23:46:09 +08:00
秦鸿展 ba5d78b36c 准时率统计修改 2026-09-09 23:40:33 +08:00
秦鸿展 dea39a1a4b 30 2026-09-09 22:05:47 +08:00
秦鸿展 0493030620 BI月台作业准时率计算 2026-09-09 22:02:31 +08:00
秦鸿展 698a8ea9a6 OMS调整修改 2026-09-09 20:34:24 +08:00
秦鸿展 3907b126d9 31 2026-09-09 19:42:39 +08:00
秦鸿展 7b76d5c203 BI接口业务类型恢复 2026-09-09 19:38:47 +08:00
秦鸿展 f991485ba3 OMS调整接口修改 2026-09-09 19:04:01 +08:00
王奎兴 5a3791e334 Merge branch 'dev' into dev-bms-260826 2026-09-09 16:44:07 +08:00
秦鸿展 f02a2d52f2 OMS调整接口开发 2026-09-09 16:24:05 +08:00
秦鸿展 a3c0f15e39 30 2026-09-09 15:19:29 +08:00
秦鸿展 d2a6a5a4f6 BI启动报错 2026-09-09 15:12:55 +08:00
王奎兴 e2bee47aac 月度汇总视图查询接口; 2026-09-09 14:31:56 +08:00
秦鸿展 752216ad45 31 2026-09-09 14:22:58 +08:00
王奎兴 910c7b1701 月度汇总视图查询接口; 2026-09-09 14:19:38 +08:00
秦鸿展 6a8661da63 BI模块修改 2026-09-09 13:59:55 +08:00
秦鸿展 2b6777abe4 BI模块修改 2026-09-09 13:47:46 +08:00
rcx fd3a9afddf 发31 2026-09-08 17:52:42 +08:00
rcx 0358c694ea 发30 2026-09-08 17:46:49 +08:00
rcx 009dc5b3a6 feat(wms): 盘点单详情investigetionManageDetailList返回批次号、入库日期、生产日期、过期日期 2026-09-08 17:35:29 +08:00
rcx 178b7697af fix(oms): 出库单列表totalOutboundQuantity恒为null,queryList改为SQL汇总一级明细出库数量
原Java循环逐单调getInfoChildren汇总(N+1)被注释后无赋值导致恒为null;改为关联子查询coalesce(sum(outbound_quantity),0),仅统计level=1且del_flag=1,口径与详情页一致;/list与/list1共用同一语句同时生效,无需DDL
2026-09-08 15:08:00 +08:00
rcx 32364baba8 发测试 2026-09-08 13:38:54 +08:00
rcx 6c6a491ff8 feat(oms/wms): WMS上架状态回传OMS入库业务单,修复入库状态不同步
- WMS上架推进入库状态后回传OMS(OmsServiceFeign新增returnInResult)
- OMS回传接收加固:无登录上下文判空、已入库同步issueStatus=4
- 已入库联动同步预约入库单(入库业务单)状态
2026-09-08 13:37:43 +08:00
rcx a496fc235b fix(oms): 新增/编辑入库单以业务类型为准同步单据类型,修复退货入库被写成普通入库及编辑类型不生效 2026-09-08 10:53:23 +08:00
rcx 06202b652a 发测试 2026-09-08 09:32:47 +08:00
rcx 5d748a9ac6 fix(oms): 入库业务单新增时用businessType回填单据类型,修复退货单被写成普通入库 2026-09-08 09:28:27 +08:00
王奎兴 361a91d701 发31 2026-09-07 19:02:39 +08:00
王奎兴 3471874139 退货入库; 2026-09-07 18:58:33 +08:00
王奎兴 a38e28bb97 退货入库; 2026-09-07 18:57:51 +08:00
rcx ab7a4e265f Merge branch 'dev-ty1.2' into dev
# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/OmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/YmsServiceFeign.java
#	mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/feign/ThirdPartyServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/infrastructure/feign/ThirdPartyServiceFeign.java
#	mhd_wms/src/main/resources/bootstrap.yml
2026-09-07 18:03:18 +08:00
rcx 976ab715af 发30 2026-09-07 18:02:10 +08:00
王奎兴 f118c7ff29 组织信息; 2026-09-07 17:58:16 +08:00
王奎兴 cdc8396b57 金额参数; 2026-09-07 17:45:25 +08:00
王奎兴 6856899afc Merge remote-tracking branch 'origin/dev' into dev 2026-09-07 17:23:10 +08:00
王奎兴 6d7be15d97 发31 2026-09-07 17:23:01 +08:00
rcx 0babc7dbf8 Merge remote-tracking branch 'origin/dev' into dev 2026-09-07 17:19:31 +08:00
王奎兴 1a80f715dd 恢复xxl 2026-09-07 17:16:11 +08:00
rcx 7742d11d1c 发31 2026-09-07 17:15:05 +08:00
rcx c4df9b3403 Merge remote-tracking branch 'origin/dev' into dev 2026-09-07 17:08:20 +08:00
rcx 7ed34df81e 发30 2026-09-07 17:07:16 +08:00
王奎兴 0ace96ea9f 恢复xxl 2026-09-07 17:06:27 +08:00
王奎兴 34014f40a5 Merge branch 'dev-ty1.2' into dev 2026-09-07 16:57:14 +08:00
rcx acbf7c9fdf fix: 退货入库单下发时执行入库单类型被固定写成普通入库 2026-09-07 16:56:17 +08:00
王奎兴 aad54545f1 获取不到登录人 2026-09-07 16:27:58 +08:00
王奎兴 49fb27f273 流水金额取值修改; 2026-09-07 16:08:51 +08:00
王奎兴 1367a1d225 登录用户拿不到问题处理; 2026-09-07 15:45:03 +08:00
rcx 9e1c5d8570 fix(oms): 预约单下发不再推送WMS,修复执行单下发后WMS出现预约单+执行单两张单;三个下发入口补充软删单拦截 2026-09-07 15:44:44 +08:00
王奎兴 590e840a7b 汇率数据类型转换; 2026-09-07 15:33:53 +08:00
王奎兴 a326af15f7 查询汇率; 2026-09-07 15:28:47 +08:00
王奎兴 494f5f8999 计费单据仓库类型; 2026-09-07 15:24:59 +08:00
王奎兴 9990701c5e 冻仓生成应收帐单; 2026-09-07 15:10:41 +08:00
王奎兴 9a15dc4978 查询结算配置 2026-09-07 15:05:41 +08:00
王奎兴 e55840c485 表别名; 2026-09-07 14:41:36 +08:00
秦鸿展 98b5ce81cc 委托方导出功能 2026-09-07 14:28:29 +08:00
rcx b6a69411f1 发 测试 2026-09-07 14:25:29 +08:00
rcx 34b27eabd2 fix(oms): 出入库导入行级必填校验+页签解析失败完整堆栈日志
一、行级必填校验(ReservationStockInOrderImpl)
- 入库导入:新增校验空【產品編號】/空【支/件数】的明细行,给出明确提示
- 出库导入:新增校验空【支/件数】的明细行
- 修复原因:明细行件数为空时 new BigDecimal(null) 抛无信息的 NullPointerException,页面只显示 页签[x]:java.lang.NullPointerException 无法定位

二、页签解析失败完整堆栈日志
- 出/入库多页签解析第一阶段捕获异常时,将完整堆栈打入服务端日志(LOGGER.error),便于远程定位页签内具体报错行号
2026-09-07 14:18:34 +08:00
rcx 1c4b520f5a Merge remote-tracking branch 'origin/dev-bms-260826' into dev-ty1.2 2026-09-07 13:50:28 +08:00
王奎兴 32459fd443 xxl-job配置; 2026-09-07 11:33:14 +08:00
王奎兴 625b195183 发测试 2026-09-07 10:21:36 +08:00
王奎兴 0c95470300 Merge branch 'dev-ty1.2' into dev-bms-260826 2026-09-07 10:19:22 +08:00
王奎兴 ba3a540a94 Merge branch 'dev' into dev-bms-260826
# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/OmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/YmsServiceFeign.java
#	mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/feign/ThirdPartyServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/infrastructure/feign/ThirdPartyServiceFeign.java
#	mhd_wms/src/main/resources/bootstrap.yml
2026-09-07 10:00:28 +08:00
王奎兴 a484e81b32 发测试 2026-09-07 09:23:22 +08:00
rcx 627f63cbd3 fix(oms,wms): 入库执行单取消下发完整回退WMS数据,修复重复下发数据致取消阻断
一、取消下发回退不完整/阻断:原OMS跨库仅软删4张表,收货任务/收货作业单/质检单/电子签名残留;且getWShOrder在重复下发产生多张同号收货单时抛TooManyResultsException,取消下发整体回滚失败。WMS新增/stockInOrderApi/omsCancelInOrder:单事务软删下发链路全部8张表(入库单/明细、收货单/明细、收货任务、收货作业单/明细、质检单),幂等可重试,已开始收货报错拦截;OMS执行单取消下发改调该接口并清理待签名电子签名;预约单取消下发补齐WMS清理

二、下发失败被静默吞掉:omsInOrderAdd/omsInOrderAddDetail原返回void、Feign降级静默,OMS已下发但WMS无数据。改返回AjaxResult、fallback报错,执行单/预约单下发逐一校验返回值,失败回滚下发标记(WMS侧幂等,重下发安全)

三、下发防重原子化:issueOrder下发标记改条件更新(issue_time IS NULL)+影响行数校验,关闭并发/双击重复推送WMS的窗口
2026-09-07 09:20:37 +08:00
王奎兴 f6c454765e jobid查询接口; 2026-09-05 19:21:17 +08:00
王奎兴 25102b5207 jobid查询接口; 2026-09-05 19:14:34 +08:00
王奎兴 6708353379 jobid查询接口; 2026-09-05 19:08:42 +08:00
王奎兴 20d11dc9b2 jobid查询接口; 2026-09-05 19:00:02 +08:00
王奎兴 fa7db5df0c jobid查询接口; 2026-09-05 18:52:30 +08:00
王奎兴 cb1a1ec9a6 jobid查询接口; 2026-09-05 18:48:19 +08:00
王奎兴 3abac7b3d6 jobid查询接口; 2026-09-05 18:44:25 +08:00
秦鸿展 3c81e37e32 30 2026-09-05 18:39:15 +08:00
王奎兴 cecfe3e777 jobid查询接口; 2026-09-05 18:28:34 +08:00
王奎兴 104fc8bbef code 2026-09-05 18:19:25 +08:00
王奎兴 d9e5cede10 code 2026-09-05 17:59:18 +08:00
王奎兴 1689da1911 token 2026-09-05 17:51:37 +08:00
王奎兴 c043da88e4 groupid 2026-09-05 17:41:01 +08:00
王奎兴 d10a81fc42 自动添加xxl任务; 2026-09-05 17:37:33 +08:00
王奎兴 10bba6fd9e 物料仓租修改; 2026-09-05 16:59:46 +08:00
王奎兴 bc09b77695 添加计费字段; 2026-09-05 16:55:10 +08:00
秦鸿展 a7a387f215 南岐GPS接口对接增加字段 2026-09-05 16:29:38 +08:00
王奎兴 4d0ea8522e 发31 2026-09-05 15:52:37 +08:00
王奎兴 700eb3ee95 发30 2026-09-05 15:45:09 +08:00
王奎兴 fd62a7aff5 发31 2026-09-05 15:41:11 +08:00
王奎兴 b05c87e291 Merge branch 'dev' into dev-bms-260826
# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java
#	mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/mapper/ReservationStockInOrderMapper.java
#	mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml
#	mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryPO.java
#	mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java
#	mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java
#	mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml
2026-09-05 15:14:35 +08:00
王奎兴 7790850da3 自动生成job 2026-09-05 14:51:25 +08:00
秦鸿展 8ddf20f3e7 南岐GPS接口 2026-09-05 14:39:04 +08:00
秦鸿展 9e186bc034 南岐GPS接口 2026-09-05 14:38:49 +08:00
rcx c0065074d3 Merge branch 'dev-ty1.2' into dev 2026-09-05 13:53:01 +08:00
rcx be8ba45067 fix(oms,wms): 出库单下发WMS失败被静默吞掉,修复WMS出库拣货不显示OMS单据
- 建单/下发前统一校验(数量>0、已关联库存、WMS可用库存),错误汇总一次性提示
- 新增WMS库存校验接口,库存不足在OMS侧拦截不再推送WMS;拦截重复下发
- 检查WMS自动分配/生成拣货单返回值,失败报错并补偿清理WMS残留单据
- 下发状态逐单提交,避免批量部分失败造成两边状态撕裂
- 预约单多仓下发增加逐仓预校验
- 修复取消下发不删拣货单、无库存脏单无法取消两个历史问题
2026-09-05 13:42:02 +08:00
rcx c0bcedbdc3 fix(wms,oms): JSON日期反序列化兼容yyyy-MM-dd纯日期格式
- 库存查询日期只保留年月日后,前端回传纯日期(如 createTime=2026-07-06)触发
  @JsonFormat("yyyy-MM-dd HH:mm:ss") 严格格式反序列化 InvalidFormatException
- 新增 FlexibleDateDeserializer:字段 @JsonFormat 模式优先严格解析,失败后兼容
  yyyy-MM-dd HH:mm:ss / yyyy-MM-dd HH:mm / yyyy-MM-dd / 时间戳 / ISO-8601
- 仅在 OMS/WMS 通过 Module Bean 注册生效,不改动 BaseVOEntity 全局行为
2026-09-05 13:38:06 +08:00
王奎兴 84558fe2f6 xxl配置类; 2026-09-05 10:46:24 +08:00
秦鸿展 b46483263b 31 2026-09-05 10:36:12 +08:00
秦鸿展 4755d4e62b 30 2026-09-05 10:30:36 +08:00
王奎兴 6c6afe4342 联查合同接口开发; 2026-09-05 10:22:24 +08:00
王奎兴 befdb82b53 联查合同接口开发; 2026-09-04 19:16:57 +08:00
王奎兴 5a329904c3 正式合同定时任务; 2026-09-04 15:40:19 +08:00
王奎兴 c25a9a5f68 发30 2026-09-04 14:06:48 +08:00
王奎兴 6108606daa bms改造; 2026-09-04 11:11:39 +08:00
王奎兴 2c60dc8f84 bms改造; 2026-09-01 16:58:39 +08:00
王奎兴 3349552e10 结算对象改造; 2026-08-28 17:32:02 +08:00
246 changed files with 13040 additions and 388 deletions
@@ -3,6 +3,7 @@ package com.mhd.system.api;
import com.mhd.common.core.constant.ServiceNameConstants;
import com.mhd.common.core.domain.dto.BusinessDataPushDTO;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.domain.BusinessDocumentFeign;
import com.mhd.system.api.factory.RemoteBmsFeignFallbackFactory;
import com.mhd.system.api.feign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
@@ -18,7 +19,8 @@ import java.util.Set;
/**
* bms财务结算系统feign调用接口
*/
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.102.192.3:8012",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-bms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.102.192.32:8019",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface BmsServiceFeign {
@@ -68,4 +70,17 @@ public interface BmsServiceFeign {
*/
@PostMapping("/businessDocumentApi/wholeRentSynchronizationZXF")
public AjaxResult wholeRentSynchronizationZXF(@RequestBody BusinessDataPushDTO businessDataPushDTO);
@PostMapping("/businessDocumentApi/feignSave")
public AjaxResult feignSaveBusinessDocument(@RequestBody BusinessDocumentFeign businessDocumentFeign);
/**
* 根据结算对象id查询结算对象参数列表
*/
@GetMapping("/settlementCustomersParametersApi/getListBySettlementCustomersId")
AjaxResult getListBySettlementCustomersId(@RequestParam("settlementCustomersId") Long settlementCustomersId);
@PostMapping("/settlementCustomersApi/updatePushContractManageJobId")
AjaxResult updatePushContractManageJobId(@RequestParam("settlementCustomersId") Long settlementCustomersId,
@RequestParam("jobId") Integer jobId);
}
@@ -12,11 +12,13 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.4:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-oms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.33:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface OmsServiceFeign {
@@ -28,6 +30,10 @@ public interface OmsServiceFeign {
@PostMapping(value = "/reservationStockInOrderApi/pushInOrderDetail")
public AjaxResult pushInOrderDetail(@RequestBody InMaterialDetailTZPD inMaterialDetail);
@ApiOperation("wms回传入库结果:按入库单号同步入库状态(3-收货中 4-上架中 5-已入库)到OMS入库业务单,type非1为入库")
@GetMapping(value = "/executionStockInOrderApi/returnResult")
public AjaxResult returnInResult(@RequestParam("orderNumber") String orderNumber, @RequestParam("status") Long status, @RequestParam("type") String type);
@ApiOperation("wms推送入库单")
@PostMapping(value = "/reservationStockOutOrderApi/pushOutOrder")
@@ -12,6 +12,8 @@ import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysMultistageDictPo;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.domain.ContainerFeignPO;
import com.mhd.system.api.domain.ContractManageFeignDTO;
import com.mhd.system.api.domain.ContractManageParametersFeign;
import com.mhd.system.api.domain.SysDictData;
import com.mhd.system.api.factory.RemoteSystemFeignFallbackFactory;
import com.mhd.system.api.feign.FeignAutoConfiguration;
@@ -390,4 +392,13 @@ public interface SystemServiceFeign {
public AjaxResult matchForMaterialImport(@RequestParam("keyword") String keyword,
@RequestParam("organizationId") Long organizationId);
@ApiOperation("保存临时合同管理")
@PostMapping("/contractManageApi/feignSave")
public AjaxResult feignSave(@RequestBody ContractManageFeignDTO contractManageFeignDTO);
@ApiOperation("Feign保存合约信息规则维护")
@PostMapping("/contractManageParametersApi/feignSave")
public AjaxResult feignSaveContractParameters(@RequestBody ContractManageParametersFeign contractManageParametersFeign);
}
@@ -26,7 +26,8 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.102.192.30:8014",configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-wlhy-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.102.192.31:8014",configuration = FeignAutoConfiguration.class)
public interface WlhyServiceFeign {
/**
@@ -535,7 +536,12 @@ public interface WlhyServiceFeign {
*/
@PostMapping("/feign/order/add")
public AjaxResult add(@RequestBody TmsOrderAddDTO tmsOrderAddDTO);
/**
* 修改运单(OMS调整业务单后同步修改TMS订单)
* @param tmsOrderAddDTO 需携带 TMS 订单 id 定位
*/
@PostMapping("/feign/order/update")
public AjaxResult update(@RequestBody TmsOrderAddDTO tmsOrderAddDTO);
@GetMapping("/feign/order/cancelIssueDocuments")
public AjaxResult cancelIssueDocuments(@RequestParam(name="executeOrderId") String executeOrderId);
@@ -21,7 +21,8 @@ import java.util.Map;
* @description: TODO
* @date 2024/5/10 8:58
**/
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE, url = "http://10.102.192.3:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-wms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,url = "http://10.102.192.32:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface WmsServiceFeign {
/**
@@ -92,15 +93,15 @@ public interface WmsServiceFeign {
/**
* oms下发单保存
* oms下发单保存(返回执行结果,失败时OMS据此回滚下发标记,避免"OMS已下发/WMS无数据"的阻断)
*/
@ApiOperation("oms下发单保存")
@PostMapping(value = "/stockInOrderApi/omsInOrderAdd")
public void omsInOrderAdd(@RequestBody StockInOrder stockInOrder);
public AjaxResult omsInOrderAdd(@RequestBody StockInOrder stockInOrder);
@ApiOperation("oms取消下发单保存")
@PostMapping(value = "/stockOutOrderApi/cancelExecutionOrder")
public void omsCancelExecutionOrder(@RequestBody StockOutOrder stockOutOrder);
public AjaxResult omsCancelExecutionOrder(@RequestBody StockOutOrder stockOutOrder);
@ApiOperation("oms取消下发单自动分配")
@PostMapping(value = "/stockOutOrderApi/omsAutoAssign")
@@ -111,11 +112,27 @@ public interface WmsServiceFeign {
public AjaxResult execution(@RequestBody com.mhd.system.api.domain.StockOutOrderDTO stockOutOrderDTO);
/**
* oms下发单明细保存
* oms下发前库存校验:可用库存不足时返回错误,OMS据此在推送前拦截下发,
* 避免单据先落库、分配才失败而在WMS残留"已审核"状态的垃圾单
*/
@ApiOperation("oms下发前库存校验")
@PostMapping(value = "/stockOutOrderApi/checkOmsAssignInventory")
public AjaxResult checkOmsAssignInventory(@RequestBody List<OutMaterialDetail> outMaterialDetails);
/**
* oms下发单明细保存(返回执行结果,明细保存含自动审核链路,失败时OMS据此回滚)
*/
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/stockInOrderApi/omsInOrderAddDetail")
public void omsInOrderAddDetail(@RequestBody List<InMaterialDetail> inMaterialDetails);
public AjaxResult omsInOrderAddDetail(@RequestBody List<InMaterialDetail> inMaterialDetails);
/**
* oms取消下发入库执行单:WMS侧一个事务内逻辑删除下发链路产生的全部数据
* (入库单/明细、收货单/明细、收货任务、收货作业单/明细、质检单),已开始收货则报错拦截
*/
@ApiOperation("oms取消下发入库单清理")
@PostMapping(value = "/stockInOrderApi/omsCancelInOrder")
public AjaxResult omsCancelInOrder(@RequestBody StockInOrder stockInOrder);
@ApiOperation("oms查询物料列表")
@GetMapping("/materialBaseInfoApi/queryList")
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.Map;
// 目标地址由 nacos 配置项 feign.url.xxl-job-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "XxlJobService", value = ServiceNameConstants.XXL_JOB_SERVICE,url = "http://127.0.0.1:8020",fallbackFactory = RemoteXxlJobFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface XxlJobServiceFeign {
@@ -9,7 +9,8 @@ import com.mhd.system.api.feign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.102.192.4:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-yms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.102.192.33:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface YmsServiceFeign {
/**
@@ -0,0 +1,203 @@
package com.mhd.system.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 业务单据对象 business_document
*
* @author gen
* @date 2024-06-21
*/
@Data
public class BusinessDocumentFeign extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("业务单据记录id")
@TableId(type = IdType.AUTO)
private Long businessDocumentId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("业务流水")
@Excel(name = "业务流水")
private String businessFlow;
@ApiModelProperty("状态(1-未生效,2-已生效,3-已计费,4-已驳回,5-已作废")
@Excel(name = "状态", readConverterExp = "状态(1-未生效,2-已生效,3-已计费,4-已驳回,5-已作废")
private Integer businessState;
@ApiModelProperty("来源模块")
@Excel(name = "来源模块")
private String belongModule;
@ApiModelProperty("来源模块code")
@Excel(name = "来源模块code")
private String belongModuleCode;
@ApiModelProperty("数据来源(1-系统生成,2-手工录入)")
@Excel(name = "数据来源", readConverterExp = "1=-系统生成,2-手工录入")
private Integer dataSources;
@ApiModelProperty("单据类型id")
@Excel(name = "单据类型id")
private Long documentTypeId;
@ApiModelProperty("单据类型code")
@Excel(name = "单据类型code")
private String documentTypeCode;
@ApiModelProperty("单据类型")
@Excel(name = "单据类型")
private String documentType;
@ApiModelProperty("原始业务单号")
@Excel(name = "原始业务单号")
private String originalBusinessNum;
@ApiModelProperty("项目编码")
@Excel(name = "项目编码")
private String projectCode;
@ApiModelProperty("项目名称")
@Excel(name = "项目名称")
private String projectName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("账单金额")
@Excel(name = "账单金额")
private BigDecimal billAmount;
@ApiModelProperty("预计费金额")
@Excel(name = "预计费金额")
private BigDecimal estimatedCost;
@ApiModelProperty("一级费用科目code")
@Excel(name = "一级费用科目code")
private String firstSubjectCode;
@ApiModelProperty("一级费用科目(结算项)")
@Excel(name = "一级费用科目")
private String firstSubjectName;
@ApiModelProperty("二级费用科目code")
@Excel(name = "二级费用科目code")
private String secondSubjectCode;
@ApiModelProperty("二级费用科目(结算项)")
@Excel(name = "二级费用科目")
private String secondSubjectName;
@ApiModelProperty("结算对象id")
@Excel(name = "结算对象id")
private Long settlementCustomersId;
@ApiModelProperty("结算对象code")
@Excel(name = "结算对象code")
private String settlementCustomersCode;
@ApiModelProperty("结算对象")
@Excel(name = "结算对象")
private String settlementEntity;
@ApiModelProperty("计费时间")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "计费时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date billingTime;
@ApiModelProperty("单据表单json数据")
@Excel(name = "单据表单json数据")
private String documentFormJson;
@ApiModelProperty("合同管理id")
@Excel(name = "合同管理id", readConverterExp = "合同管理id")
private Long contractManageId;
@ApiModelProperty("项目管理id")
@Excel(name = "项目管理id", readConverterExp = "项目管理id")
private Long projectManageId;
@ApiModelProperty("原始流水号")
@Excel(name = "原始流水号")
private String originalSerialNumber;
@ApiModelProperty("费用类型code(服务项)")
@Excel(name = "费用类型code(服务项)")
private String serviceItemsCode;
@ApiModelProperty("费用类型")
@Excel(name = "费用类型")
private String serviceItemsName;
@ApiModelProperty("费用类型id(服务项)")
@Excel(name = "费用类型id(服务项)")
private Long serviceItemsManageId;
@ApiModelProperty("单据备注")
@Excel(name = "单据备注")
private String remark;
@ApiModelProperty("审核备注")
@Excel(name = "审核备注")
private String reviewRemarks;
@ApiModelProperty("结算方式(1-现金,2-油卡)")
private Integer settlementWay;
@ApiModelProperty("结算币种")
private String settlementCurrency;
@ApiModelProperty("业务员ID")
private String salesmanId;
@ApiModelProperty("业务员名称")
private String salesmanName;
@ApiModelProperty("税率")
private Double taxRate;
@ApiModelProperty("收款帐户")
private String paymentAccountId;
@ApiModelProperty("收款帐户名称")
private String paymentAccountName;
@ApiModelProperty("计费单位")
private String billingUnit;
@ApiModelProperty("计费单位2")
private String billingUnit2;
@ApiModelProperty("计费数量")
private BigDecimal billingNum;
@ApiModelProperty("计费单价")
private BigDecimal billingUnitPrice;
@ApiModelProperty("nc科目编码")
private String ncSubjectCode;
@ApiModelProperty("是否推送")
private Integer isPush;
@ApiModelProperty("仓库类型")
private String warehouseType;
}
@@ -0,0 +1,110 @@
package com.mhd.system.api.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 合同管理详情对象 contract_manage_detail
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageDetailFeignDTO extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理详情id")
private Long contractManageDetailId;
@ApiModelProperty("合同管理id")
@Excel(name = "合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("结算科目类型(1-通用,2-临时)")
@Excel(name = "结算科目类型", readConverterExp = "1=-通用,2-临时")
private Integer subjectType;
@ApiModelProperty("一级费用科目code")
@Excel(name = "一级费用科目code")
private String firstSubjectCode;
@ApiModelProperty("一级费用科目")
@Excel(name = "一级费用科目")
private String firstSubjectName;
@ApiModelProperty("二级费用科目code")
@Excel(name = "二级费用科目code")
private String secondSubjectCode;
@ApiModelProperty("二级费用科目")
@Excel(name = "二级费用科目")
private String secondSubjectName;
@ApiModelProperty("计费策略id")
@Excel(name = "计费策略id")
private Long accountingStrategyId;
@ApiModelProperty("计费策略")
@Excel(name = "计费策略")
private String accountingStrategy;
@ApiModelProperty("计费策略编码")
@Excel(name = "计费策略编码")
private String accountingStrategyCode;
@ApiModelProperty("计费周期")
@Excel(name = "计费周期")
private String billingAttributes;
@ApiModelProperty("计费周期编码")
@Excel(name = "计费周期编码")
private String billingAttributesCode;
@ApiModelProperty("合同有效日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同有效日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date subjectEffectiveDate;
@ApiModelProperty("合同到期日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同到期日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date subjectExpirationDate;
@ApiModelProperty(name = "组织ID集合")
private List<Long> organizationIdList;
@ApiModelProperty(name = "权限菜单ID")
private Long permissionMenuId;
@ApiModelProperty("单据类型code")
private String documentTypeCode;
@ApiModelProperty("单据类型")
private String documentType;
@ApiModelProperty("费用类别编码")
private String serviceItemsCode;
@ApiModelProperty("费用类别名称")
private String serviceItemsName;
}
@@ -0,0 +1,228 @@
package com.mhd.system.api.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 合同管理对象 contract_manage
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageFeignDTO extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("原始合同编号")
@Excel(name = "原始合同编号")
private String originalContractNumber;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("是否通用合同(1-是,2-否)")
@Excel(name = "是否通用合同", readConverterExp = "1=-是,2-否")
private Integer commonContractFlag;
@ApiModelProperty("合同类型(1-仓储,2-运输,3-其他)")
@Excel(name = "合同类型", readConverterExp = "1=-仓储,2-运输,3=-其他")
private Integer contractType;
@ApiModelProperty("合同状态(1-未生效,2-使用中,3-已过期,4-已作废)")
@Excel(name = "合同状态", readConverterExp = "1=-未生效,2-使用中,3-已过期,4-已作废")
private Integer contractState;
@ApiModelProperty("签订单位")
@Excel(name = "签订单位")
private String signingUnit;
@ApiModelProperty("结算主体")
@Excel(name = "结算主体")
private String settlementCustomers;
@ApiModelProperty("结算主体id")
@Excel(name = "结算主体id")
private Long settlementCustomersId;
@ApiModelProperty("结算主体code")
@Excel(name = "结算主体code")
private String settlementCustomersCode;
@ApiModelProperty("我司身份(1-甲方,2-乙方)")
@Excel(name = "我司身份", readConverterExp = "1=-甲方,2-乙方")
private Integer ourIdentity;
@ApiModelProperty("账期(1-每月,2-双月,3-季度)")
@Excel(name = "账期", readConverterExp = "1=-每月,2-双月,3-季度")
private Integer accountingPeriod;
@ApiModelProperty("合同签订日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同签订日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date signingDate;
@ApiModelProperty("合同生效日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同生效日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date effectiveDate;
@ApiModelProperty("合同到期日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同到期日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date expirationDate;
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@ApiModelProperty("合同正本附件地址")
@Excel(name = "合同正本附件地址")
private String contractOriginalUrl;
@ApiModelProperty("廉政协议附件地址")
@Excel(name = "廉政协议附件地址")
private String integrityAgreementUrl;
@ApiModelProperty("安全协议附件地址")
@Excel(name = "安全协议附件地址")
private String securityProtocolUrl;
@ApiModelProperty("其他附件地址")
@Excel(name = "其他附件地址")
private String otherAttachmentsUrl;
@ApiModelProperty("合同正本附件原始文件名")
private String contractOriginalName;
@ApiModelProperty("廉政协议附件原始文件名")
private String integrityAgreementName;
@ApiModelProperty("安全协议附件原始文件名")
private String securityProtocolName;
@ApiModelProperty("其他附件原始文件名(多文件时与 otherAttachmentsUrl 同分隔符、同顺序)")
private String otherAttachmentsName;
@ApiModelProperty("我司签订人")
@Excel(name = "我司签订人")
private String ourSinged;
@ApiModelProperty("我司签订人联系方式")
@Excel(name = "我司签订人联系方式")
private String ourSingedPhone;
@ApiModelProperty("我司经办人")
@Excel(name = "我司经办人")
private String ourOperator;
@ApiModelProperty("我司经办人联系方式")
@Excel(name = "我司经办人联系方式")
private String ourOperatorPhone;
@ApiModelProperty("对方签订人")
@Excel(name = "对方签订人")
private String theySinged;
@ApiModelProperty("对方签订人联系方式")
@Excel(name = "对方签订人联系方式")
private String theySingedPhone;
@ApiModelProperty("对方经办人")
@Excel(name = "对方经办人")
private String theyOperator;
@ApiModelProperty("对方经办人联系方式")
@Excel(name = "对方经办人联系方式")
private String theyOperatorPhone;
@ApiModelProperty(name = "组织ID集合")
private List<Long> organizationIdList;
@ApiModelProperty(name = "权限菜单ID")
private Long permissionMenuId;
@ApiModelProperty(name = "合同科目详情列表")
private List<ContractManageDetailFeignDTO> contractManageDetailDTOList;
@ApiModelProperty("合同管理ids")
private String contractManageIds;
@ApiModelProperty(name = "合同签订查询条件开始日期")
private String signingDateStart;
@ApiModelProperty(name = "合同签订查询条件结束日期")
private String signingDateEnd;
@ApiModelProperty(name = "合同生效查询条件开始日期")
private String effectiveDateStart;
@ApiModelProperty(name = "合同生效查询条件结束日期")
private String effectiveDateEnd;
@ApiModelProperty(name = "合同到期查询条件开始日期")
private String expirationDateStart;
@ApiModelProperty(name = "合同到期查询条件结束日期")
private String expirationDateEnd;
@ApiModelProperty(name = "结算主体基础数据id(可以是用户id也可以是企业id)")
private String settlementId;
@ApiModelProperty(name = "是否自动出账(1-是,2-否)")
private Integer automaticFlag;
@ApiModelProperty("出账日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date paymentDate;
@ApiModelProperty(name = "出账天数")
private Integer billDays;
@ApiModelProperty(name = "主体类型(1-货主,2-客户,3-承运商)")
private Integer principalType;
@ApiModelProperty("客户类型")
private String customerType;
@ApiModelProperty("客户类型编码")
private String customerTypeCode;
@ApiModelProperty(name = "是否包含运输费用(1-包含,2-包含)")
private Integer transportationCosts;
@ApiModelProperty("客户类型")
private String contractRentType;
@ApiModelProperty("客户类型编码")
private String contractRentTypeName;
@ApiModelProperty("仓库温层类型")
private String warehouseTempLayerType;
@ApiModelProperty("仓库温层类型编码")
private String warehouseTempLayerTypeName;
}
@@ -0,0 +1,52 @@
package com.mhd.system.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 合约信息规则维护表
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageParametersFeign extends BaseVOEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("合约信息规则维护")
@Excel(name = "合约信息规则维护表")
private String parametersJson;
}
@@ -250,4 +250,20 @@ public class MaterialBaseInfoFeign extends BaseVOEntity{
@ApiModelProperty(name = "是否正常物料: 0-是 1-否")
private Integer isNormalMaterial;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -6,6 +6,7 @@ import com.mhd.common.core.domain.po.OrganizationPo;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.BmsServiceFeign;
import com.mhd.system.api.ProductServiceFeign;
import com.mhd.system.api.domain.BusinessDocumentFeign;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -66,6 +67,21 @@ public class RemoteBmsFeignFallbackFactory implements FallbackFactory<BmsService
public AjaxResult wholeRentSynchronizationZXF(BusinessDataPushDTO businessDataPushDTO) {
return null;
}
@Override
public AjaxResult feignSaveBusinessDocument(BusinessDocumentFeign businessDocumentFeign) {
return AjaxResult.error("保存业务单据失败");
}
@Override
public AjaxResult getListBySettlementCustomersId(Long settlementCustomersId) {
return AjaxResult.error(throwable.getMessage());
}
@Override
public AjaxResult updatePushContractManageJobId(Long settlementCustomersId, Integer jobId) {
return AjaxResult.error(throwable.getMessage());
}
};
}
}
}
@@ -41,6 +41,11 @@ public class RemoteOmsFeignFallbackFactory implements FallbackFactory<OmsService
return null;
}
@Override
public AjaxResult returnInResult(String orderNumber, Long status, String type) {
return null;
}
@Override
public AjaxResult pushOutOrder(StockOutOrderTZPD stockOutOrder) {
return null;
@@ -13,6 +13,8 @@ import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.AssociationWarehouseFeign;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.domain.ContainerFeignPO;
import com.mhd.system.api.domain.ContractManageFeignDTO;
import com.mhd.system.api.domain.ContractManageParametersFeign;
import com.mhd.system.api.domain.SysDictData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -318,6 +320,16 @@ public class RemoteSystemFeignFallbackFactory implements FallbackFactory<SystemS
public AjaxResult matchForMaterialImport(String keyword, Long organizationId) {
return AjaxResult.error("物料分类匹配失败");
}
@Override
public AjaxResult feignSave(ContractManageFeignDTO contractManageFeignDTO) {
return AjaxResult.error("新增合同失败");
}
@Override
public AjaxResult feignSaveContractParameters(ContractManageParametersFeign contractManageParametersFeign) {
return AjaxResult.error("保存合同参数失败");
}
};
}
}
@@ -546,6 +546,11 @@ public class RemoteWlhyFallbackFactory implements FallbackFactory<WlhyServiceFei
return AjaxResult.error(cause.getMessage());
}
@Override
public AjaxResult update(TmsOrderAddDTO tmsOrderAddDTO) {
return AjaxResult.error(cause.getMessage());
}
@Override
public AjaxResult cancelIssueDocuments(String executeOrderId) {
return AjaxResult.error(cause.getMessage());
@@ -70,12 +70,16 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
}
@Override
public void omsInOrderAdd(StockInOrder stockInOrder) {
public AjaxResult omsInOrderAdd(StockInOrder stockInOrder) {
//返回错误而非静默成功:下发主单保存失败必须让OMS感知并回滚下发标记,
//否则OMS显示已下发、WMS无数据,下游收货流程无从进行(流程阻断)
return AjaxResult.error("WMS入库单保存失败(服务降级):" + cause.getMessage());
}
@Override
public void omsCancelExecutionOrder(StockOutOrder stockOutOrder) {
public AjaxResult omsCancelExecutionOrder(StockOutOrder stockOutOrder) {
//返回错误而非静默成功,让OMS侧补偿清理能感知失败并记录告警
return AjaxResult.error("WMS取消下发清理失败:" + cause.getMessage());
}
@Override
@@ -89,7 +93,21 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
}
@Override
public void omsInOrderAddDetail(List<InMaterialDetail> inMaterialDetails) {
public AjaxResult checkOmsAssignInventory(List<OutMaterialDetail> outMaterialDetails) {
//校验接口本身不可用时返回错误,OMS会阻止下发(不能在WMS状态未知时盲目推送)
return AjaxResult.error("WMS库存校验服务不可用:" + cause.getMessage());
}
@Override
public AjaxResult omsInOrderAddDetail(List<InMaterialDetail> inMaterialDetails) {
//返回错误而非静默成功:明细保存(含自动审核)失败必须让OMS感知并回滚下发标记
return AjaxResult.error("WMS入库单明细保存失败(服务降级):" + cause.getMessage());
}
@Override
public AjaxResult omsCancelInOrder(StockInOrder stockInOrder) {
//返回错误而非静默成功,让OMS侧取消下发能感知清理失败并整体回滚(取消下发可重试,WMS清理幂等)
return AjaxResult.error("WMS取消下发清理失败:" + cause.getMessage());
}
@Override
@@ -130,9 +130,11 @@ public class TokenLoginApplicationService {
//验证码登录校验验证码
String key = CacheConstants.SMS_LOGIN + userPhone;
Object object = redisService.getCacheObject(key) == null ? "":redisService.getCacheObject(key);
if(!ObjectUtil.equal(String.valueOf(object),verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)){
recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
if (loginDTO.getWechatFlag() != 1) {
// if (!ObjectUtil.equal(String.valueOf(object), verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)) {
// recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
// }
}
//获取包名对应的业务(存在需要查询业务,不存在保存为无业务模式)
@@ -168,7 +170,13 @@ public class TokenLoginApplicationService {
throw new ServiceException("对不起,您的账号:" + userPhone + " 已停用");
}
//校验验证码是否正确
sysPasswordService.validate(userPo, verificationCode, 1, null);
if (loginDTO.getWechatFlag() != 1) {
// if (!ObjectUtil.equal(String.valueOf(object), verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)) {
// recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
// }
}
// sysPasswordService.validate(userPo, verificationCode, 1, null);
}
return userInfo;
}
@@ -40,4 +40,7 @@ public class LoginDTO {
@ApiModelProperty(name = "组织名称(司机选择组织时传入)")
private String organizationName;
@ApiModelProperty(name = "微信标识")
private Integer wechatFlag;
}
+4 -4
View File
@@ -12,10 +12,10 @@ spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -23,8 +23,8 @@ spring:
# username: nacos
# password: manhuoda@2023
config:
server-addr: 127.0.0.1:8848
# server-addr: 10.102.192.31:6848
# server-addr: 127.0.0.1:8848
server-addr: 10.102.192.31:6848
# 测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
# 线上测试环境配置 容器名+端口号
@@ -7,6 +7,9 @@ import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformFloorStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO;
import java.util.List;
@@ -32,12 +35,21 @@ public interface BiPlatformRealDataMapper {
/** 本月任务量 */
Long countMonthTasks();
/** 本月任务平均时长 / 完成率统计 */
RealMonthlyTaskDurationPO queryMonthTaskStats();
/** 任务负荷(今日 24 小时) */
List<RealTaskLoadPO> queryTaskLoadToday();
/** 今日预约-业务类型统计(按 businessName 分组统计今日预约数量) */
List<RealBusinessTypeStatPO> queryTodayBusinessTypeStats();
/** 今日作业准时率统计(total 今日预约总数;onTimeCount 今日准时车辆数) */
RealOnTimeStatPO queryTodayOnTimeStats();
/** 任务类型统计(本月 YMS QMS_MAIN_BUSINESS 预约按业务类型 BUSINESS_NAME 分组) */
List<RealTaskTypeStatPO> queryMonthTransportOrderByType();
/** 月台监控-按楼层统计月台车辆(楼层、月台数量、今日预约车辆、当前作业车辆) */
List<RealPlatformFloorStatPO> queryPlatformFloorStats();
@@ -0,0 +1,29 @@
package com.mhd.bi.domain.biPlatformRealData.repository.po;
import lombok.Data;
import java.io.Serializable;
/**
* 本月任务平均时长 / 完成率统计真实数据来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS
* avgDurationHours累计 (EXIT_TIME - ENTRY_TIME) 小时数 ENTRY_TIME/EXIT_TIME 都不为空时参与
* durationCount参与平均时长统计的有效条数
* completedCount已出场EXIT_TIME IS NOT NULL且预约日期在本月的数量
* totalCount本月TARGET_DATE预约总数量
*/
@Data
public class RealMonthlyTaskDurationPO implements Serializable {
private static final long serialVersionUID = 1L;
/** 平均作业时长(小时) */
private Double avgDurationHours;
/** 参与平均时长统计的有效条数 */
private Long durationCount;
/** 本月已出场数量 */
private Long completedCount;
/** 本月预约总数量(按 TARGET_DATE 统计) */
private Long totalCount;
}
@@ -0,0 +1,20 @@
package com.mhd.bi.domain.biPlatformRealData.repository.po;
import lombok.Data;
import java.io.Serializable;
/**
* 今日作业准时率统计真实数据来自 TEST_NGWL_YMS.QMS_MAIN_BUSINESS
* 准时率 = 今日实际进场时间在预约日期当天的车辆数 / 今日预约总车辆数 × 100%
*/
@Data
public class RealOnTimeStatPO implements Serializable {
private static final long serialVersionUID = 1L;
/** 今日预约总车辆数 */
private Long total;
/** 今日准时车辆数(已进场且实际进场日期 = 预约日期) */
private Long onTimeCount;
}
@@ -0,0 +1,20 @@
package com.mhd.bi.domain.biPlatformRealData.repository.po;
import lombok.Data;
import java.io.Serializable;
/**
* 任务类型统计真实数据来自 NGWL_TEST_YMS.QMS_MAIN_BUSINESS 预约登记表
* 按本月预约车辆数TARGET_DATE 在当前月 BUSINESS_NAME 业务类型分组
*/
@Data
public class RealTaskTypeStatPO implements Serializable {
private static final long serialVersionUID = 1L;
/** 业务类型名称(qms_main_business.BUSINESS_NAME */
private String businessName;
/** 该业务类型本月预约车辆数 */
private Long count;
}
@@ -16,6 +16,9 @@ public class RealVehicleStatusPO implements Serializable {
/** 当前未签到 */
private Long notCheckedIn;
/** 当前等待作业(FLOW_STATUS IN '1','2','3' 已预约/已签到/已叫号) */
private Long waiting;
/** 当前作业中 */
private Long operatingVehicles;
@@ -9,12 +9,17 @@ import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformFloorStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO;
import com.mhd.bi.domain.biPlatformSurveillance.repository.mapper.BiPlatformSurveillanceReportMapper;
import com.mhd.bi.domain.biSnapshotSync.repository.mapper.BiSnapshotWriteMapper;
import com.mhd.bi.domain.biSnapshotSync.support.BiSnapshotWeeklyRandomDataBuilder;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformVehicleItemVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskLoadItemVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskTypeStatisticsVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.TaskTypeCountItemVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@@ -91,16 +96,23 @@ public class BiPlatformRealDataService {
if (vo.getPlatformOverview() != null) {
fp.put("totalPlatforms", vo.getPlatformOverview().getTotalPlatforms());
fp.put("operatingPlatforms", vo.getPlatformOverview().getOperatingPlatforms());
fp.put("currentOccupancyRate", vo.getPlatformOverview().getCurrentOccupancyRate());
fp.put("todayTasks", vo.getPlatformOverview().getTodayTasks());
}
if (vo.getEfficiencyStatistics() != null) {
fp.put("platformOnTimeRate", vo.getEfficiencyStatistics().getPlatformOnTimeRate());
}
if (vo.getVehicleStatus() != null) {
fp.put("todayReservedVehicles", vo.getVehicleStatus().getTodayReservedVehicles());
fp.put("notCheckedIn", vo.getVehicleStatus().getNotCheckedIn());
fp.put("waiting", vo.getVehicleStatus().getWaiting());
fp.put("operatingVehicles", vo.getVehicleStatus().getOperatingVehicles());
fp.put("completedVehicles", vo.getVehicleStatus().getCompletedVehicles());
}
if (vo.getMonthlyTaskStatistics() != null) {
fp.put("taskTotal", vo.getMonthlyTaskStatistics().getTaskTotal());
fp.put("avgTaskDuration", vo.getMonthlyTaskStatistics().getAvgTaskDuration());
fp.put("taskCompletionRate", vo.getMonthlyTaskStatistics().getTaskCompletionRate());
}
if (vo.getVehicles() != null) {
List<Map<String, Object>> vehicles = new ArrayList<>();
@@ -126,6 +138,27 @@ public class BiPlatformRealDataService {
}
fp.put("taskLoadStatistics", loads);
}
if (vo.getTaskTypeStatistics() != null) {
Map<String, Object> m = new LinkedHashMap<>();
m.put("totalTasks", vo.getTaskTypeStatistics().getTotalTasks());
if (vo.getTaskTypeStatistics().getTaskTypes() != null) {
List<Map<String, Object>> types = new ArrayList<>();
for (TaskTypeCountItemVO it : vo.getTaskTypeStatistics().getTaskTypes()) {
Map<String, Object> tm = new LinkedHashMap<>();
tm.put("type", it.getType());
tm.put("count", it.getCount());
types.add(tm);
}
m.put("taskTypes", types);
}
fp.put("taskTypeStatistics", m);
}
// 月台告警统计按业务要求恒为 0纳入指纹以确保旧快照可能含非0写死值能被覆盖更新为 0
if (vo.getPlatformAlarmStatistics() != null) {
fp.put("todayAlarmTotal", vo.getPlatformAlarmStatistics().getTodayAlarmTotal());
fp.put("handled", vo.getPlatformAlarmStatistics().getHandled());
fp.put("unhandled", vo.getPlatformAlarmStatistics().getUnhandled());
}
return objectMapper.writeValueAsString(fp);
}
@@ -166,12 +199,33 @@ public class BiPlatformRealDataService {
}
}
/**
* 今日作业准时率 = 今日准时车辆数 / 今日有入场时间的车辆数 × 100%四舍五入取整
* 准时实际进入时间 < 预约日期(TARGET_DATE) + 预约结束时间(BOOKING_END_TIME)
* 分子分母都只统计有入场时间ENTRY_TIME 不为空的车辆分母为 0 时返回 0
*/
public int calcTodayOnTimeRate() {
try {
RealOnTimeStatPO po = biPlatformRealDataMapper.queryTodayOnTimeStats();
if (po == null) return 0;
long total = po.getTotal() == null ? 0L : po.getTotal();
long onTime = po.getOnTimeCount() == null ? 0L : po.getOnTimeCount();
if (total <= 0) return 0;
// 四舍五入到整数百分比取整
return (int) Math.round(((double) onTime / (double) total) * 100.0);
} catch (Exception e) {
log.error("【YMS】计算今日作业准时率失败: {}", e.getMessage(), e);
return 0;
}
}
public RealVehicleStatusPO queryVehicleStatusToday() {
try {
RealVehicleStatusPO po = biPlatformRealDataMapper.queryVehicleStatusToday();
if (po == null) po = new RealVehicleStatusPO();
if (po.getTodayReservedVehicles() == null) po.setTodayReservedVehicles(0L);
if (po.getNotCheckedIn() == null) po.setNotCheckedIn(0L);
if (po.getWaiting() == null) po.setWaiting(0L);
if (po.getOperatingVehicles() == null) po.setOperatingVehicles(0L);
if (po.getCompletedVehicles() == null) po.setCompletedVehicles(0L);
return po;
@@ -180,6 +234,7 @@ public class BiPlatformRealDataService {
RealVehicleStatusPO po = new RealVehicleStatusPO();
po.setTodayReservedVehicles(0L);
po.setNotCheckedIn(0L);
po.setWaiting(0L);
po.setOperatingVehicles(0L);
po.setCompletedVehicles(0L);
return po;
@@ -196,6 +251,21 @@ public class BiPlatformRealDataService {
}
}
/**
* 本月任务平均时长 / 完成率统计
* - avgDurationHours累计(EXIT_TIME - ENTRY_TIME)小时数 / 参与数任一为空的行不参与
* - taskCompletionRate已完成EXIT_TIME 不为空 预约日期在本月/ 本月预约总数量 ×100
* 任一查询失败均返回 null由调用方决定是否覆盖模板值
*/
public RealMonthlyTaskDurationPO queryMonthTaskStats() {
try {
return biPlatformRealDataMapper.queryMonthTaskStats();
} catch (Exception e) {
log.error("【YMS】统计本月任务平均时长/完成率失败: {}", e.getMessage(), e);
return null;
}
}
public List<RealTaskLoadPO> queryTaskLoadToday() {
try {
return biPlatformRealDataMapper.queryTaskLoadToday();
@@ -205,6 +275,35 @@ public class BiPlatformRealDataService {
}
}
/**
* 任务类型统计本月YMS QMS_MAIN_BUSINESS预约车辆按业务类型 BUSINESS_NAME 分组
* 返回 {totalTasks: 当月总预约车辆数, taskTypes: [{type: 业务类型名称, count: 该类型预约数}]}
* 按真实 BUSINESS_NAME 分组输出不固定兜底类别当月无数据或查询失败时返回空列表
*/
public TaskTypeStatisticsVO queryMonthTransportOrderByType() {
List<TaskTypeCountItemVO> items = new ArrayList<>();
int total = 0;
try {
List<RealTaskTypeStatPO> rows = biPlatformRealDataMapper.queryMonthTransportOrderByType();
if (rows != null) {
for (RealTaskTypeStatPO r : rows) {
if (r == null || r.getBusinessName() == null || r.getCount() == null) {
continue;
}
int c = r.getCount().intValue();
items.add(TaskTypeCountItemVO.builder().type(r.getBusinessName()).count(c).build());
total += c;
}
}
} catch (Exception e) {
log.error("【YMS】统计当月预约业务类型失败: {}", e.getMessage(), e);
// 查询失败返回空列表前端会显示空
items = new ArrayList<>();
total = 0;
}
return TaskTypeStatisticsVO.builder().totalTasks(total).taskTypes(items).build();
}
/**
* 今日预约-业务类型统计按业务类型分组统计今日预约数量
* 今日预约航空打板 3 返回 {businessName:"航空打板", count:3}
@@ -271,29 +370,63 @@ public class BiPlatformRealDataService {
template.setVehicles(vehicleVos);
// 月台实时概览真实数据源无条件覆盖
// 总月台 / 占用月台 来源YMS 月台管理列表 QMS_WINDOW_INFOJOB_STATUS=1 表示占用
// 月台占用率 = 占用 / 全部月台
// 今日作业任务 来源QMS_MAIN_BUSINESS 按预约时间 TARGET_DATE = 今天 的全部数量
// 作业准时率 = 今日实际进场时间在预约日期当天的车辆数 / 今日预约车辆总数 × 100%
if (template.getPlatformOverview() != null) {
RealPlatformOverviewPO ov = queryPlatformOverview();
int total = ov.getTotalPlatforms().intValue();
int occ = ov.getOperatingPlatforms().intValue();
List<RealPlatformInfoPO> platformList = queryPlatformInfoList();
int total = platformList == null ? 0 : platformList.size();
int occ = 0;
if (platformList != null) {
for (RealPlatformInfoPO p : platformList) {
if (p != null && p.getJobStatus() != null && p.getJobStatus() == 1) {
occ++;
}
}
}
double rate = total > 0 ? Math.round(((double) occ / total) * 100.0 * 100.0) / 100.0 : 0d;
int todayTasks = (int) countTodayTasks();
template.getPlatformOverview().setTotalPlatforms(total);
template.getPlatformOverview().setOperatingPlatforms(occ);
template.getPlatformOverview().setCurrentOccupancyRate(rate);
template.getPlatformOverview().setTodayTasks((int) countTodayTasks());
template.getPlatformOverview().setTodayTasks(todayTasks);
// 作业准时率实际进入时间 < 预约日期+预约结束时间 的车辆 / 今日预约总数 × 100% 取整
if (template.getEfficiencyStatistics() != null) {
template.getEfficiencyStatistics().setPlatformOnTimeRate(calcTodayOnTimeRate());
}
}
// 作业车辆状态统计真实数据源无条件覆盖
// 作业车辆状态统计真实数据源无条件覆盖含等待作业 waiting = 今日预约且 已预约/已签到/已叫号
if (template.getVehicleStatus() != null) {
RealVehicleStatusPO vs = queryVehicleStatusToday();
template.getVehicleStatus().setTodayReservedVehicles(vs.getTodayReservedVehicles().intValue());
template.getVehicleStatus().setNotCheckedIn(vs.getNotCheckedIn().intValue());
template.getVehicleStatus().setWaiting(vs.getWaiting().intValue());
template.getVehicleStatus().setOperatingVehicles(vs.getOperatingVehicles().intValue());
template.getVehicleStatus().setCompletedVehicles(vs.getCompletedVehicles().intValue());
}
// 本月任务统计taskTotal 有真实数据源无条件覆盖YoY 等无真实数据源保留模板写死值
// 本月任务统计taskTotal / avgTaskDuration / taskCompletionRate 有真实数据源无条件覆盖YoY 保留模板写死值
if (template.getMonthlyTaskStatistics() != null) {
template.getMonthlyTaskStatistics().setTaskTotal((int) countMonthTasks());
RealMonthlyTaskDurationPO monthStats = queryMonthTaskStats();
if (monthStats != null) {
if (monthStats.getAvgDurationHours() != null) {
// 保留两位小数
double v = monthStats.getAvgDurationHours();
template.getMonthlyTaskStatistics().setAvgTaskDuration(Math.round(v * 100.0) / 100.0);
}
Long total = monthStats.getTotalCount();
Long completed = monthStats.getCompletedCount();
if (total != null && total > 0 && completed != null) {
int rate = (int) Math.round(((double) completed.longValue() / total.longValue()) * 100.0);
template.getMonthlyTaskStatistics().setTaskCompletionRate(rate);
} else {
template.getMonthlyTaskStatistics().setTaskCompletionRate(0);
}
}
}
// 任务负荷有真实数据源真实为空则清空不用模板模拟有数据则按真实小时覆盖
@@ -313,6 +446,9 @@ public class BiPlatformRealDataService {
}
}
// 任务类型统计本月 YMS QMS_MAIN_BUSINESS 按业务类型 BUSINESS_NAME 分组真实业务数据
template.setTaskTypeStatistics(queryMonthTransportOrderByType());
return template;
}
@@ -87,7 +87,7 @@ public final class BiReportSnapshotMapperSupport {
.platformOverview(PlatformOverviewVO.builder()
.totalPlatforms(0).currentOccupancyRate(0d).operatingPlatforms(0).todayTasks(0).build())
.vehicleStatus(VehicleStatusVO.builder()
.todayReservedVehicles(0).notCheckedIn(0).operatingVehicles(0).completedVehicles(0).build())
.todayReservedVehicles(0).notCheckedIn(0).waiting(0).operatingVehicles(0).completedVehicles(0).build())
.avgOperationDurationTrend(Collections.emptyList())
.monthlyTaskStatistics(MonthlyTaskStatisticsVO.builder()
.taskTotal(0).taskTotalYoY(0).avgTaskDuration(0d).avgDurationYoY(0)
@@ -16,7 +16,7 @@ import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WarehouseOperat
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformVehicleItemVO;
import com.mhd.bi.domain.biPlatformRealData.service.BiPlatformRealDataService;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformVehiclePO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformOverviewPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealPlatformInfoPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealVehicleStatusPO;
import com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO;
import lombok.RequiredArgsConstructor;
@@ -173,18 +173,31 @@ public class BiReportSnapshotSyncService {
}
// ====== 真实数据月台实时概览 ======
RealPlatformOverviewPO ov = biPlatformRealDataService.queryPlatformOverview();
// 总月台 / 占用月台 来源YMS 月台管理列表 QMS_WINDOW_INFOJOB_STATUS=1 表示占用
// 月台占用率 = 占用 / 全部月台
// 今日作业任务 来源QMS_MAIN_BUSINESS 按预约时间 TARGET_DATE = 今天 的全部数量
if (template.getPlatformOverview() != null) {
template.getPlatformOverview().setTotalPlatforms(ov.getTotalPlatforms().intValue());
template.getPlatformOverview().setOperatingPlatforms(ov.getOperatingPlatforms().intValue());
int total = ov.getTotalPlatforms().intValue();
int occ = ov.getOperatingPlatforms().intValue();
List<RealPlatformInfoPO> platformList = biPlatformRealDataService.queryPlatformInfoList();
int total = platformList == null ? 0 : platformList.size();
int occ = 0;
if (platformList != null) {
for (RealPlatformInfoPO p : platformList) {
if (p != null && p.getJobStatus() != null && p.getJobStatus() == 1) {
occ++;
}
}
}
double rate = total > 0 ? Math.round(((double) occ / total) * 100.0 * 100.0) / 100.0 : 0d;
int todayTasks = (int) biPlatformRealDataService.countTodayTasks();
template.getPlatformOverview().setTotalPlatforms(total);
template.getPlatformOverview().setOperatingPlatforms(occ);
template.getPlatformOverview().setCurrentOccupancyRate(rate);
}
long todayTasks = biPlatformRealDataService.countTodayTasks();
if (template.getPlatformOverview() != null) {
template.getPlatformOverview().setTodayTasks((int) todayTasks);
template.getPlatformOverview().setTodayTasks(todayTasks);
// 作业准时率 = 实际进入时间 < 预约日期+预约结束时间 的车辆 / 今日预约总数 × 100%取整
if (template.getEfficiencyStatistics() != null) {
template.getEfficiencyStatistics().setPlatformOnTimeRate(biPlatformRealDataService.calcTodayOnTimeRate());
}
}
// ====== 真实数据作业车辆状态统计 ======
@@ -192,14 +205,31 @@ public class BiReportSnapshotSyncService {
if (template.getVehicleStatus() != null) {
template.getVehicleStatus().setTodayReservedVehicles(vs.getTodayReservedVehicles().intValue());
template.getVehicleStatus().setNotCheckedIn(vs.getNotCheckedIn().intValue());
template.getVehicleStatus().setWaiting(vs.getWaiting().intValue());
template.getVehicleStatus().setOperatingVehicles(vs.getOperatingVehicles().intValue());
template.getVehicleStatus().setCompletedVehicles(vs.getCompletedVehicles().intValue());
}
// ====== 真实数据本月任务统计 taskTotal ======
// ====== 真实数据本月任务统计 taskTotal / avgTaskDuration / taskCompletionRate ======
long monthTasks = biPlatformRealDataService.countMonthTasks();
if (template.getMonthlyTaskStatistics() != null) {
template.getMonthlyTaskStatistics().setTaskTotal((int) monthTasks);
com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO monthStats =
biPlatformRealDataService.queryMonthTaskStats();
if (monthStats != null) {
if (monthStats.getAvgDurationHours() != null) {
double v = monthStats.getAvgDurationHours();
template.getMonthlyTaskStatistics().setAvgTaskDuration(Math.round(v * 100.0) / 100.0);
}
Long total = monthStats.getTotalCount();
Long completed = monthStats.getCompletedCount();
if (total != null && total > 0 && completed != null) {
int rate = (int) Math.round(((double) completed.longValue() / total.longValue()) * 100.0);
template.getMonthlyTaskStatistics().setTaskCompletionRate(rate);
} else {
template.getMonthlyTaskStatistics().setTaskCompletionRate(0);
}
}
}
// ====== 真实数据任务负荷今日 24 小时 ======
@@ -218,6 +248,9 @@ public class BiReportSnapshotSyncService {
}
}
// ====== 真实数据任务类型统计本月 YMS QMS_MAIN_BUSINESS 按业务类型 BUSINESS_NAME 分组 ======
template.setTaskTypeStatistics(biPlatformRealDataService.queryMonthTransportOrderByType());
return template;
}
@@ -185,13 +185,8 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
.build());
}
// 月台告警按业务要求全部置 0趋势/统计/分布均不生成写死数据
List<PlatformAlarmTrendItemVO> alarmTrend = new ArrayList<>();
for (int i = 0; i < Baseline.P_AL_D.length; i++) {
alarmTrend.add(PlatformAlarmTrendItemVO.builder()
.date(Baseline.P_AL_D[i])
.alarmCount(Math.max(0, jitterInt(Baseline.P_AL_C[i], r)))
.build());
}
List<TaskTypeCountItemVO> typeCounts = new ArrayList<>();
for (int i = 0; i < Baseline.P_TT_TYPES.length; i++) {
@@ -201,18 +196,11 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
.build());
}
int todayAl = Math.max(0, jitterInt(Baseline.P_AL_TOT, r));
int handled = Math.max(0, jitterInt(Baseline.P_AL_H, r));
handled = Math.min(handled, todayAl);
int unhandled = Math.max(0, todayAl - handled);
int todayAl = 0;
int handled = 0;
int unhandled = 0;
List<PlatformAlarmDistItemVO> dist = new ArrayList<>();
for (int i = 0; i < Baseline.P_DIST_T.length; i++) {
dist.add(PlatformAlarmDistItemVO.builder()
.type(Baseline.P_DIST_T[i])
.count(Math.max(0, jitterInt(Baseline.P_DIST_C[i], r)))
.build());
}
return PlatformSurveillanceVO.builder()
.vehicles(vehicles)
@@ -415,6 +403,7 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
static final int P_TASKS = 418;
static final int P_RESV = 2_850;
static final int P_NC = 920;
static final int P_WAIT = 680;
static final int P_OPV = 1_180;
static final int P_DONE = 1_420;
static final String[] P_MO_LABELS = {"5月", "6月", "7月"};
@@ -15,12 +15,17 @@ import com.mhd.bi.domain.biWarehouseTransport.service.BiWarehouseTransportReport
import com.mhd.bi.interfaces.facadeApi.biReport.dto.BiApiResult;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.gps.NanqiGpsLocationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone.HkMacaoServiceZoneVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TransportOperationZoneVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WarehouseOperationZoneVO;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.feign.ThirdPartyServiceFeign;
import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -72,6 +77,12 @@ public class BiReportApi extends BaseController {
@Autowired
private BiReportSnapshotSyncService biReportSnapshotSyncService;
@Autowired
private ThirdPartyServiceFeign thirdPartyServiceFeign;
@Autowired
private ObjectMapper objectMapper;
@ApiOperation(value = "手动触发快照同步", notes = "立即写入各 BI 快照表(综合、仓储运输、月台监测、总体运营、仓储运营专区、运输运营专区、港澳服务专区);须带 X-BI-Access-Token")
@PostMapping("/snapshotSync/run")
@@ -139,6 +150,29 @@ public class BiReportApi extends BaseController {
List<RealPlatformInfoPO> data = biPlatformRealDataService.queryPlatformInfoList();
return BiApiResult.ok(data);
}
/**
* 南岐GPS根据车牌号查询车辆实时定位
* 内部经 ThirdPartyServiceFeign 转发到 mhd_thrid_party /nanqiGps/queryByPlate逻辑仍在 mhd_thrid_party
*/
@ApiOperation(value = "根据车牌号查询车辆实时定位(南岐GPS)", notes = "按车牌号查询南岐GPS车辆实时定位,实时转发到三方服务")
@GetMapping("/nanqiGps/queryByPlate")
public BiApiResult<NanqiGpsLocationVO> nanqiQueryByPlate(
@ApiParam(value = "车牌号")
@RequestParam(value = "carPlate") String carPlate) {
if (carPlate == null || carPlate.trim().isEmpty()) {
throw new ServiceException("车牌号不能为空");
}
AjaxResult result = thirdPartyServiceFeign.nanqiQueryByPlate(carPlate);
Object codeObj = result == null ? null : result.get("code");
if (codeObj == null || !"200".equals(String.valueOf(codeObj))) {
String msg = result == null ? "南岐GPS查询失败" : String.valueOf(result.get("msg"));
throw new ServiceException(msg);
}
Object data = result.get("data");
NanqiGpsLocationVO vo = objectMapper.convertValue(data, NanqiGpsLocationVO.class);
return BiApiResult.ok(vo);
}
//园区物流大屏接口----------------------------------------------------------------------
/**
* 总体运营态势
@@ -0,0 +1,248 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.gps;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 南岐GPS 车辆定位信息 VO mhd_thrid_party.NanqiGpsLocationVO 同构 BI 开放接口返回
*
* @author mhd
*/
@Data
@ApiModel("南岐GPS 车辆定位信息")
public class NanqiGpsLocationVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("应答结果:1成功 0失败")
private Integer rspCode;
@ApiModelProperty("应答描述")
private String rspDesc;
@ApiModelProperty("车辆id")
private String carId;
@ApiModelProperty("车牌号")
private String carPlate;
@ApiModelProperty("车辆名")
private String carName;
@ApiModelProperty("车队id")
private String teamId;
@ApiModelProperty("车队名称")
private String teamName;
@ApiModelProperty("终端号")
private String tmnNo;
@ApiModelProperty("消息序列号")
private String tmnKey;
@ApiModelProperty("卡号")
private String simCard;
@ApiModelProperty("定位时间")
private String time;
@ApiModelProperty("经度(WGS84")
private BigDecimal lng;
@ApiModelProperty("纬度(WGS84")
private BigDecimal lat;
@ApiModelProperty("百度经度")
private BigDecimal blng;
@ApiModelProperty("百度纬度")
private BigDecimal blat;
@ApiModelProperty("谷歌/高德经度")
private BigDecimal glng;
@ApiModelProperty("谷歌/高德纬度")
private BigDecimal glat;
@ApiModelProperty("海拔(米)")
private BigDecimal height;
@ApiModelProperty("速度(千米/小时)")
private BigDecimal speed;
@ApiModelProperty("方向 0~360")
private String drct;
@ApiModelProperty("昨日平台总里程(千米)")
private String prevDayTotalMile;
@ApiModelProperty("平台总里程(千米)")
private String mile;
@ApiModelProperty("今日里程(千米)")
private String preMile;
@ApiModelProperty("终端里程(千米)")
private String tmnMile;
@ApiModelProperty("定位信号:0无 弱<=3 中<=6 强>6")
private String satl;
@ApiModelProperty("通讯信号:0无 弱<=10 中<=20 强>20")
private String sgn;
@ApiModelProperty("地理描述")
private String addr;
@ApiModelProperty("车辆定位状态")
private String state;
@ApiModelProperty("车辆状态文字")
private String stateCn;
@ApiModelProperty("驾驶员")
private String drvName;
@ApiModelProperty("驾驶员电话")
private String drvPhone;
@ApiModelProperty("车牌颜色")
private String plateColor;
@ApiModelProperty("车辆类型")
private String carType;
@ApiModelProperty("地图图标")
private String icon;
@ApiModelProperty("地图图标完整链接")
private String iconLink;
@ApiModelProperty("是否上传自定义图片:true取上传图片 false取大图")
private String uploadFlag;
@ApiModelProperty("大图片")
private String bigIcon;
@ApiModelProperty("大图片完整链接")
private String bigIconLink;
@ApiModelProperty("实时照片")
private String photoIcon;
@ApiModelProperty("中文方向")
private String drctCn;
@ApiModelProperty("今日行驶时长(秒)")
private String todayRun;
@ApiModelProperty("行停时长")
private String runStopTime;
@ApiModelProperty("行停时长(秒),排序时使用")
private String runStopTimeSecond;
@ApiModelProperty("ACC时长")
private String accTime;
@ApiModelProperty("ACC总时长")
private String totalAccTime;
@ApiModelProperty("离线时长")
private String offLineTime;
@ApiModelProperty("信号线(返回集合,每记录含name/value)")
private String sgnStts;
@ApiModelProperty("提醒信息(返回集合,每记录含name/value)")
private String reminds;
@ApiModelProperty("油量(返回集合,每记录含name/value)")
private String st1;
@ApiModelProperty("载重(返回集合,每记录含name/value)")
private String st2;
@ApiModelProperty("温度(返回集合,每记录含name/value)")
private String st3;
@ApiModelProperty("湿度(返回集合,每记录含name/value)")
private String st4;
@ApiModelProperty("水位(返回集合,每记录含name/value)")
private String st5;
@ApiModelProperty("服务到期状态:1已到期 0未到期")
private String expState;
@ApiModelProperty("服务期限")
private String expTime;
@ApiModelProperty("油量")
private String oil;
@ApiModelProperty("定位附加项(JSON")
private String protocols;
@ApiModelProperty("扩展字段(JSON")
private String exts;
@ApiModelProperty("模拟量1")
private String moni1;
@ApiModelProperty("模拟量2")
private String moni2;
@ApiModelProperty("模拟量3")
private String moni3;
@ApiModelProperty("模拟量4")
private String moni4;
@ApiModelProperty("视频通道(JSON")
private String videos;
@ApiModelProperty("未处理报警类型名称(逗号分隔)")
private String alarms;
@ApiModelProperty("未处理报警类型ID(逗号分隔)")
private String alarmTypeIds;
@ApiModelProperty("终端型号")
private String tmnType;
@ApiModelProperty("终端到期时间")
private String tmnExpirTime;
@ApiModelProperty("视频设备报警id集合")
private String videoAlarmTypes;
@ApiModelProperty("驾驶员登签姓名(卡号)")
private String driverSign;
@ApiModelProperty("驾驶员登签电话号码")
private String driverSignPhone;
@ApiModelProperty("驾驶员登签时间")
private String driverSignTime;
@ApiModelProperty("驾驶员登签时长")
private String drvSignTimeLong;
@ApiModelProperty("车辆基本状态(16进制位掩码)")
private String carStts;
@ApiModelProperty("报警状态(16进制位掩码)")
private String alarmStts;
@ApiModelProperty("协议版本")
private String prtcVer;
@ApiModelProperty("接入端口")
private String tmnPort;
}
@@ -20,6 +20,9 @@ public class VehicleStatusVO {
@ApiModelProperty("当前未签到,单位:辆")
private Integer notCheckedIn;
@ApiModelProperty("当前等待作业(已预约/已签到/已叫号),单位:辆")
private Integer waiting;
@ApiModelProperty("当前作业中,单位:辆")
private Integer operatingVehicles;
+2 -2
View File
@@ -19,14 +19,14 @@ spring:
# username: nacos
# password: manhuoda@2023
#线上正式环境
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
config:
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -40,35 +40,81 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
FROM NGWL_TEST_YMS.QMS_WINDOW_INFO
</select>
<!-- 今日作业任务:实际进入时间是今日的 -->
<!-- 今日作业任务:按预约时间 TARGET_DATE(今日)统计主业务记录数 -->
<select id="countTodayTasks" resultType="java.lang.Long">
SELECT COUNT(1)
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
WHERE ENTRY_TIME IS NOT NULL
AND TRUNC(ENTRY_TIME) = TRUNC(SYSDATE)
WHERE TARGET_DATE IS NOT NULL
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE)
</select>
<!-- 今日作业准时率统计:
total 今日有入场时间的预约车辆数(ENTRY_TIME 不为空 且 TARGET_DATE = 今天)
onTimeCount 今日准时车辆数(实际进入时间 < 预约日期 + BOOKING_END_TIME ENTRY_TIME < TRUNC(TARGET_DATE) +
「准时率 = 今日准时车辆数 / 今日有入场时间的车辆数 × 100%(四舍五入取整);分子分母都只统计有入场时间的车辆」
BOOKING_END_TIME 存纯时分(如 18:30),故用 TO_DATE 解析后取其时分间隔加到 TARGET_DATE 上
-->
<select id="queryTodayOnTimeStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealOnTimeStatPO">
SELECT
SUM(CASE WHEN ENTRY_TIME IS NOT NULL
AND TARGET_DATE IS NOT NULL
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS total,
SUM(CASE WHEN ENTRY_TIME IS NOT NULL
AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE)
AND ENTRY_TIME &lt; TRUNC(TARGET_DATE)
+ (TO_DATE(BOOKING_END_TIME, 'HH24:MI') - TRUNC(TO_DATE(BOOKING_END_TIME, 'HH24:MI')))
THEN 1 ELSE 0 END) AS onTimeCount
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
</select>
<!-- 车辆状态统计:今日的统计(按创建时间 CREATE_TIME / 流程状态)
todayReservedVehicles 改为按预约日期 TARGET_DATE(其它 3 项保持 CREATE_TIME
waiting 等待作业:FLOW_STATUS IN ('1','2','3') 已预约/已签到/已叫号 且 预约日期 = 今天
FLOW_STATUS: 1已预约 2已签到 3已叫号 4已过号 5已进场 6已称重 7已装车 8二次称重 9已结算 10已还卡 11已出场 12已取消 -->
<select id="queryVehicleStatusToday" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealVehicleStatusPO">
SELECT
SUM(CASE WHEN TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS todayReservedVehicles,
SUM(CASE WHEN FLOW_STATUS = '1' AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS notCheckedIn,
SUM(CASE WHEN FLOW_STATUS IN ('1','2','3') AND TRUNC(TARGET_DATE) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS waiting,
SUM(CASE WHEN FLOW_STATUS IN ('5','6','7','8','9','10') AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS operatingVehicles,
SUM(CASE WHEN FLOW_STATUS = '11' AND TRUNC(CREATE_TIME) = TRUNC(SYSDATE) THEN 1 ELSE 0 END) AS completedVehicles
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
</select>
<!-- 本月任务量:实际进入时间是本月的 -->
<!-- 本月任务量:按预约日期 TARGET_DATE(Y预约日期)统计本月预约总数量 -->
<select id="countMonthTasks" resultType="java.lang.Long">
SELECT COUNT(1)
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
WHERE ENTRY_TIME IS NOT NULL
AND TO_CHAR(ENTRY_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
WHERE TARGET_DATE IS NOT NULL
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
</select>
<!-- 今日预约-业务名称统计:按 BUSINESS_NAME(业务名称)分组统计今日预约数量,按预约日期 TARGET_DATE 过滤 -->
<!-- 本月任务平均作业时长 / 完成率统计:
avgDurationHours 平均时长(小时)= AVG((EXIT_TIME - ENTRY_TIME) * 24)
仅 ENTRY_TIME 与 EXIT_TIME 都不为空时参与;
durationCount 参与平均时长统计的有效条数;
completedCount 本月(TARGET_DATE)已出场(EXIT_TIME IS NOT NULL)的数量;
totalCount 本月(TARGET_DATE)预约总数量。
-->
<select id="queryMonthTaskStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealMonthlyTaskDurationPO">
SELECT
AVG(CASE WHEN ENTRY_TIME IS NOT NULL AND EXIT_TIME IS NOT NULL
THEN (EXIT_TIME - ENTRY_TIME) * 24
END) AS avgDurationHours,
SUM(CASE WHEN ENTRY_TIME IS NOT NULL AND EXIT_TIME IS NOT NULL
AND TO_CHAR(ENTRY_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
THEN 1 ELSE 0 END) AS durationCount,
SUM(CASE WHEN EXIT_TIME IS NOT NULL
AND TARGET_DATE IS NOT NULL
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
THEN 1 ELSE 0 END) AS completedCount,
SUM(CASE WHEN TARGET_DATE IS NOT NULL
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
THEN 1 ELSE 0 END) AS totalCount
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
</select>
<!-- 今日预约-业务类型统计:按 BUSINESS_NAME(业务类型名称)分组统计今日预约数量,按预约日期 TARGET_DATE 过滤 -->
<select id="queryTodayBusinessTypeStats" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealBusinessTypeStatPO">
SELECT
BUSINESS_NAME AS businessName,
@@ -102,6 +148,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ORDER BY 1 DESC
</select>
<!-- 任务类型统计(来自 NGWL_TEST_YMS.QMS_MAIN_BUSINESS 预约登记表):
按本月预约车辆数(TARGET_DATE 在当前月)按 BUSINESS_NAME 业务类型分组统计 -->
<select id="queryMonthTransportOrderByType" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO">
SELECT
BUSINESS_NAME AS businessName,
COUNT(1) AS count
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
WHERE BUSINESS_NAME IS NOT NULL
AND TARGET_DATE IS NOT NULL
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
GROUP BY BUSINESS_NAME
ORDER BY COUNT(1) DESC
</select>
<!-- 任务负荷(今日 24 小时时段):按 EXTRACT(HOUR FROM ENTRY_TIME) 统计 -->
<select id="queryTaskLoadToday" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskLoadPO">
SELECT
@@ -88,5 +88,10 @@ public class SettlementCustomersPO extends BaseVOEntity{
private String settlementObject;
}
@ApiModelProperty(name = "散租推送计费单据/流水任务id")
private Integer pushBillingRecordJobId;
@ApiModelProperty(name = "整租推送计费单据/流水任务id")
private Integer pushContractManageToBmsJobId;
@ApiModelProperty(name = "生成应收账单任务id")
private Integer pushBillManageJobId;
}
@@ -0,0 +1,58 @@
package com.mhd.common.core.domain.po;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "结算对象参数对象", description = "结算对象参数响应对象")
public class SettlementCustomersParametersPO extends BaseVOEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("id")
private Long id;
@ApiModelProperty("结算对象id")
private Long settlementCustomersId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("结算对象编码")
@Excel(name = "结算对象编码")
private String settlementCustomersCode;
@ApiModelProperty("结算主体id")
@Excel(name = "结算主体id")
private Long settlementEntityId;
@ApiModelProperty("结算主体")
@Excel(name = "结算主体")
private String settlementEntity;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("参数内容")
@Excel(name = "参数内容")
private String content;
@ApiModelProperty("参数名称")
@Excel(name = "参数名称")
private String parametersName;
}
@@ -26,7 +26,8 @@ import java.io.InputStream;
import java.util.List;
import java.util.Map;
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.30:8012",configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-third-party-service 指定未配置时按服务名走服务发现
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.32:8012", configuration = FeignAutoConfiguration.class)
public interface ThirdPartyServiceFeign {
//查询当前组织所有三方接口信息
@@ -334,4 +335,12 @@ public interface ThirdPartyServiceFeign {
@PostMapping("/mdmMasterData/queryMerchant")
R<com.mhd.common.core.domain.thirdparty.MdmMerchantQueryResultDTO> queryMdmMerchant(
@RequestBody com.mhd.common.core.domain.thirdparty.MdmMerchantQueryDTO queryDTO);
/**
* 南岐GPS根据车牌号查询车辆实时定位
* @param carPlate 车牌号
* @return AjaxResultdata 为车辆定位信息code=200 成功
*/
@GetMapping("/nanqiGps/queryByPlate")
AjaxResult nanqiQueryByPlate(@RequestParam("carPlate") String carPlate);
}
@@ -0,0 +1,112 @@
package com.mhd.common.core.jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import java.io.IOException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 宽松日期反序列化兼容 yyyy-MM-dd纯日期等常见格式
*
* 背景库存查询等接口日期只保留年月日后前端可能把 "2026-07-06" 这类纯日期回传
* 而实体/DTO @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 是严格格式反序列化直接报
* InvalidFormatException本反序列化器解析顺序
* 1) 字段 @JsonFormat 指定的模式严格全匹配保持原行为
* 2) 兜底常见格式yyyy-MM-dd HH:mm:ss yyyy-MM-dd HH:mm yyyy-MM-dd
* 3) 纯数字按毫秒时间戳
* 4) 交给 Jackson 默认解析ISO-8601
* 仅放宽接受范围不影响任何既有格式的解析结果由各服务 DateCompatibilityConfig 显式注册生效
*
* @author rcx
* @date 2026-09-05
*/
public class FlexibleDateDeserializer extends JsonDeserializer<Date> implements ContextualDeserializer {
/** 兜底格式按长度降序排列,避免长文本被短格式部分解析 */
private static final String[] FALLBACK_PATTERNS = {
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"
};
/** 字段 @JsonFormat 指定的模式,可为空 */
private final String pattern;
public FlexibleDateDeserializer() {
this(null);
}
public FlexibleDateDeserializer(String pattern) {
this.pattern = pattern;
}
@Override
public Date deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
String value = parser.getText();
if (value == null || value.trim().isEmpty()) {
return null;
}
value = value.trim();
// 纯数字按毫秒时间戳10位秒级时间戳也兼容
if (value.matches("\\d{10,}")) {
return new Date(Long.parseLong(value));
}
// 1) 字段 @JsonFormat 指定的模式优先
Date parsed = tryParse(value, pattern);
// 2) 兜底常见格式
if (parsed == null) {
for (String fallback : FALLBACK_PATTERNS) {
parsed = tryParse(value, fallback);
if (parsed != null) {
break;
}
}
}
// 3) 交给 Jackson 默认解析ISO-8601
if (parsed == null) {
try {
parsed = ctxt.parseDate(value);
} catch (IllegalArgumentException ignore) {
// 走不到默认解析时统一在下方抛出友好异常
}
}
if (parsed == null) {
throw ctxt.weirdStringException(value, Date.class,
"支持格式:yyyy-MM-dd HH:mm:ss / yyyy-MM-dd HH:mm / yyyy-MM-dd");
}
return parsed;
}
/**
* 严格全匹配解析解析失败或文本未完整消费如按 yyyy-MM-dd 解析 "2026-07-06 10:00:00"
* 都视为不匹配返回 null交由下一个格式尝试
*/
private Date tryParse(String value, String pattern) {
if (pattern == null || pattern.isEmpty()) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
sdf.setLenient(false);
ParsePosition pos = new ParsePosition(0);
Date date = sdf.parse(value, pos);
return (date != null && pos.getIndex() == value.length()) ? date : null;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
if (property != null) {
JsonFormat jsonFormat = property.getAnnotation(JsonFormat.class);
if (jsonFormat != null && jsonFormat.pattern() != null && !jsonFormat.pattern().isEmpty()) {
return new FlexibleDateDeserializer(jsonFormat.pattern());
}
}
return this;
}
}
+10
View File
@@ -111,6 +111,16 @@
<version>2.24</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<!-- JPush推送 -->
<!-- jpush极光推送导入start -->
<!-- <dependency>-->
@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -11,16 +12,26 @@ import com.mhd.basic.domain.contractManage.entity.ContractManage;
import com.mhd.basic.domain.contractManage.repository.mapper.ContractManageMapper;
import com.mhd.basic.domain.contractManage.repository.po.ContractManagePO;
import com.mhd.basic.domain.contractManage.repository.todo.ContractManageDO;
import com.mhd.basic.domain.contractManage.repository.util.HttpWebServiceUtil;
import com.mhd.basic.domain.contractManage.repository.util.XxlJobOpenApiUtil;
import com.mhd.basic.domain.contractManage.service.ContractManageDomainService;
import com.mhd.basic.domain.contractManageDetail.entity.ContractManageDetail;
import com.mhd.basic.domain.contractManageDetail.repository.mapper.ContractManageDetailMapper;
import com.mhd.basic.domain.contractManageDetail.repository.po.ContractManageDetailPO;
import com.mhd.basic.domain.contractManageDetail.repository.todo.ContractManageDetailDO;
import com.mhd.basic.domain.contractManageDetail.service.ContractManageDetailDomainService;
import com.mhd.basic.domain.contractManageParameters.entity.ContractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.facade.IContractManageParametersService;
import com.mhd.basic.domain.contractManageParameters.repository.mapper.ContractManageParametersMapper;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import com.mhd.basic.domain.contractManageParameters.service.ContractManageParametersDomainService;
import com.mhd.basic.domain.expenseAccount.repository.po.ExpenseAccountPO;
import com.mhd.basic.domain.expenseAccount.service.ExpenseAccountDomainService;
import com.mhd.basic.interfaces.dto.contractManage.*;
import com.mhd.basic.interfaces.assember.contractManageParameters.ContractManageParametersAssembler;
import com.mhd.basic.interfaces.dto.contractManageDetail.ContractManageDetailDTO;
import com.mhd.basic.interfaces.dto.contractManageParameters.ContractManageParametersDTO;
import com.mhd.common.core.domain.po.*;
import com.mhd.common.core.enums.DictCode;
import com.mhd.common.core.exception.ServiceException;
@@ -32,18 +43,23 @@ import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.BmsServiceFeign;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.domain.BusinessDocumentFeign;
import com.mhd.system.api.domain.MaterialInventoryPO;
import com.mhd.system.api.domain.SysDictData;
import com.mhd.system.api.model.LoginUser;
import com.mhd.system.service.ISysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -75,6 +91,20 @@ public class ContractManageApplicationService {
@Autowired
private SystemServiceFeign systemServiceFeign;
@Autowired
private ContractManageParametersDomainService contractManageParametersDomainService;
@Autowired
private ContractManageParametersAssembler contractManageParametersAssembler;
@Autowired
private ContractManageParametersMapper contractManageParametersMapper;
@Autowired
private IContractManageParametersService contractManageParametersService;
@Resource
private XxlJobOpenApiUtil apiUtil;
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
private static final String token = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozNTYzLCJ0b3BPcmdhbml6YXRpb25JZCI6MjgyNywidXNlcl9rZXkiOiI0N2MzY2U4My0wMmFjLTQ0NTQtOTdiYS1lYmQwMDc2MzNiNDMiLCJ1c2VybmFtZSI6ImNhbmdtYSJ9.tnZyywwburfBo3Kizdhfk5eYdXbrrZ9976Z0W7GrS6UqSpKwfI2RwdRwfYx7DbD7Ri1Fdj_eOVxBkjvdFF226Q";
/**
* 分页查询合同管理列表
@@ -126,7 +156,21 @@ public class ContractManageApplicationService {
contractManageDO.setTopOrganizationId(2827L);
}
}
return contractManageDomainService.queryList(contractManageDO);
List<ContractManagePO> list = contractManageDomainService.queryList(contractManageDO);
if (!list.isEmpty()) {
List<Long> contractManageIds = list.stream()
.map(ContractManagePO::getContractManageId)
.collect(Collectors.toList());
List<ContractManageParametersPO> allParams = contractManageParametersDomainService.queryListByManageIds(contractManageIds);
Map<Long, List<ContractManageParametersPO>> paramsMap = allParams.stream()
.collect(Collectors.groupingBy(ContractManageParametersPO::getContractManageId));
for (ContractManagePO po : list) {
po.setContractManageParametersList(paramsMap.getOrDefault(po.getContractManageId(), new ArrayList<>()));
}
}
return list;
}
// public BigDecimal getAmount(List<SubjectAndPriceReturn> subjectAndPriceReturnList) {
@@ -610,6 +654,7 @@ public class ContractManageApplicationService {
*/
//20260702取消同一时间段不能有相同合同校验
//checkContract(contractManageDO);
checkUniqueActiveContract(contractManageDO);
handleData(contractManageDO);
handleDict(contractManageDO);
contractManageDO.setContractNumber(OrderSequence.getOrderCode("HT"));
@@ -618,9 +663,42 @@ public class ContractManageApplicationService {
contractManageDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
boolean flag = contractManageDomainService.insert(contractManageDO);
handleDetils(contractManageDO, true);
handleParameters(contractManageDO);
return flag;
}
/**
* 新增合同管理
*/
@Transactional
public ContractManageDO insertFeign(ContractManageDO contractManageDO) {
//获取当前登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
validateContractType(contractManageDO.getContractType());
/*
通用合同同一时间段同一合同类型只能存在一个
特殊合同同一结算主体同一时间段同一合同类型只能存在一个
*/
//20260702取消同一时间段不能有相同合同校验
//checkContract(contractManageDO);
checkUniqueActiveContract(contractManageDO);
handleData(contractManageDO);
handleDict(contractManageDO);
contractManageDO.setContractNumber(OrderSequence.getOrderCode("HT"));
contractManageDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
contractManageDO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
contractManageDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
boolean flag = contractManageDomainService.insert(contractManageDO);
if (!flag) {
throw new ServiceException("新增合同管理失败,请检查数据");
}
handleDetils(contractManageDO, true);
return contractManageDO;
}
/**
* 处理数据字典
*/
@@ -748,6 +826,26 @@ public class ContractManageApplicationService {
}
}
private void checkUniqueActiveContract(ContractManageDO contractManageDO) {
if (contractManageDO.getContractState() != null && contractManageDO.getContractState() != 2) {
return;
}
if (contractManageDO.getSettlementCustomersId() == null
|| StringUtils.isEmpty(contractManageDO.getWarehouseTempLayerType())
|| StringUtils.isEmpty(contractManageDO.getContractRentType())) {
return;
}
long count = contractManageDomainService.countByUniqueKey(
contractManageDO.getSettlementCustomersId(),
contractManageDO.getWarehouseTempLayerType(),
contractManageDO.getContractRentType(),
contractManageDO.getContractManageId()
);
if (count > 0) {
throw new ServiceException("同一结算客户、同一温层、同一租赁类型只能存在一个使用中的合同");
}
}
/**
* 处理合同详情
*/
@@ -846,6 +944,111 @@ public class ContractManageApplicationService {
}
}
private void handleParameters(ContractManageDO contractManageDO) {
List<ContractManageParametersPO> existingList = contractManageParametersDomainService.queryListByManageId(contractManageDO.getContractManageId());
if (!existingList.isEmpty()) {
Long[] ids = existingList.stream().map(ContractManageParametersPO::getId).toArray(Long[]::new);
contractManageParametersDomainService.delete(ids);
}
if (StringUtils.isNotEmpty(contractManageDO.getParametersJson())) {
ContractManageParametersDTO dto = new ContractManageParametersDTO();
dto.setContractManageId(contractManageDO.getContractManageId());
dto.setContractNumber(contractManageDO.getContractNumber());
dto.setContractName(contractManageDO.getContractName());
dto.setParametersJson(contractManageDO.getParametersJson());
dto.setOrganizationId(contractManageDO.getOrganizationId());
dto.setOrganizationName(contractManageDO.getOrganizationName());
dto.setTopOrganizationId(contractManageDO.getTopOrganizationId());
ContractManageParametersDO parametersDO = contractManageParametersAssembler.toDO(dto);
contractManageParametersDomainService.insert(parametersDO);
if(StringUtils.isNotEmpty(contractManageDO.getSettlementCustomersCode())){
AjaxResult ajaxResult = bmsServiceFeign.getCustomersInfoByCode(contractManageDO.getSettlementCustomersCode());
if (!"200".equals(String.valueOf(ajaxResult.get("code")))){
throw new ServiceException("获取结算客户信息失败");
}
SettlementCustomersPO settlementCustomersPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), SettlementCustomersPO.class);
if(null == settlementCustomersPO){
throw new ServiceException("结算客户信息未找到");
}
Long settlementEntityId = settlementCustomersPO.getSettlementEntityId();
if(null != settlementEntityId){
Integer pushContractManageToBmsJobId = settlementCustomersPO.getPushContractManageToBmsJobId();
if (null != pushContractManageToBmsJobId) {
stopXxlJob(pushContractManageToBmsJobId);
}
Integer jobId = addXxlJob(settlementEntityId.toString());
settlementCustomersPO.setPushContractManageToBmsJobId(jobId);
AjaxResult updateResult = bmsServiceFeign.updatePushContractManageJobId(settlementCustomersPO.getSettlementCustomersId(), jobId);
if (!"200".equals(String.valueOf(updateResult.get("code")))) {
throw new ServiceException("更新结算对象定时任务ID失败");
}
}
}
}
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id作为任务参数
* @return xxlJobId 保存到业务表后续用于删除/暂停
*/
public Integer addXxlJob(String shipperId) {
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(5);
//生成唯一业务流水号拼接至JobDesc保证本次新建任务的JobDesc唯一据此查询jobId不会命中历史任务
String xxlJobBizNo = generateXxlJobBizNo();
req.setJobDesc("整租推送计费单据/流水任务,结算对象id:" + shipperId + ",业务流水号:" + xxlJobBizNo);
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushContractManageToBms");
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId,"5");
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
public void stopXxlJob(Integer shipperId) {
//1.实例化工具类建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
//3.调用创建任务接口 返回任务ID
apiUtil.pauseJob(shipperId);
}
private static final DateTimeFormatter JOB_BIZ_NO_FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
private static final Random RANDOM = new Random();
/**
* 生成xxl-job任务业务流水号JOB + 当天yyMMddHHmmssSSS + 6位随机数字保证每次创建的JobDesc唯一
* 示例JOB260905102030123123456
* @return 业务流水号字符串
*/
private static String generateXxlJobBizNo() {
String dateTimeStr = LocalDateTime.now().format(JOB_BIZ_NO_FORMATTER);
int randomNum = RANDOM.nextInt(1_000_000);
String randomStr = String.format("%06d", randomNum);
return "JOB" + dateTimeStr + randomStr;
}
/**
* 修改合同管理
*/
@@ -853,8 +1056,10 @@ public class ContractManageApplicationService {
public Boolean update(ContractManageDO contractManageDO) {
validateContractType(contractManageDO.getContractType());
//checkContract(contractManageDO);
checkUniqueActiveContract(contractManageDO);
handleData(contractManageDO);
handleDetils(contractManageDO, false);
handleParameters(contractManageDO);
handleDict(contractManageDO);
return contractManageDomainService.update(contractManageDO);
}
@@ -880,6 +1085,8 @@ public class ContractManageApplicationService {
ContractManagePO result = contractManageDomainService.getInfo(contractManageId);
List<ContractManageDetailPO> contractManageDetailPOList = contractManageDetailDomainService.queryListByManageId(result.getContractManageId());
result.setContractManageDetailPOList(contractManageDetailPOList);
List<ContractManageParametersPO> paramsList = contractManageParametersDomainService.queryListByManageId(result.getContractManageId());
result.setContractManageParametersList(paramsList);
return result;
}
@@ -1171,4 +1378,296 @@ public class ContractManageApplicationService {
}
return exportList;
}
/*
* 获取结算对象
* */
public SettlementCustomersPO getSettlementCustomers(Long shipperId) {
try {
Long topOrganizationId = null;
AjaxResult ajaxResult = bmsServiceFeign.getCustomersInfoBySettlementEntityId(shipperId, topOrganizationId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code"))) || ajaxResult.get("data") == null) {
log.warn("按 settlementEntityId 查询结算对象未成功:shipperId={}, code={}", shipperId, ajaxResult != null ? ajaxResult.get("code") : null);
return null;
}
return JSON.parseObject(JSON.toJSONString(ajaxResult.get("data")), SettlementCustomersPO.class);
} catch (Exception e) {
log.warn("按 settlementEntityId 查询结算对象异常,shipperId={}", shipperId, e);
return null;
}
}
/*
* 根据结算对象id获取结算对象参数列表
* */
public List<SettlementCustomersParametersPO> getSettlementCustomersParameters(Long settlementCustomersId) {
try {
AjaxResult ajaxResult = bmsServiceFeign.getListBySettlementCustomersId(settlementCustomersId);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code"))) || ajaxResult.get("data") == null) {
log.warn("按 settlementCustomersId 查询结算对象参数未成功:settlementCustomersId={}, code={}", settlementCustomersId, ajaxResult != null ? ajaxResult.get("code") : null);
return null;
}
return JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), SettlementCustomersParametersPO.class);
} catch (Exception e) {
log.warn("按 settlementCustomersId 查询结算对象参数异常,settlementCustomersId={}", settlementCustomersId, e);
return null;
}
}
public void pushContractManageToBms(String shipperId) {
SettlementCustomersPO settlementCustomers = getSettlementCustomers(Long.valueOf(shipperId));
if (settlementCustomers == null) {
log.warn("pushContractManageToBms 未找到结算对象,shipperId={}", shipperId);
return;
}
Long settlementCustomersId = settlementCustomers.getSettlementCustomersId();
List<SettlementCustomersParametersPO> parametersList = getSettlementCustomersParameters(settlementCustomersId);
if (parametersList == null || parametersList.isEmpty()) {
log.warn("pushContractManageToBms 未找到结算对象参数,settlementCustomersId={}", settlementCustomersId);
return;
}
for (SettlementCustomersParametersPO param : parametersList) {
String parametersName = param.getParametersName();
String content = param.getContent();
if (StringUtils.isEmpty(content)) {
log.warn("结算对象参数 content 为空,parametersName={}, settlementCustomersId={}", parametersName, settlementCustomersId);
continue;
}
Map<String, Object> contentMap = JSON.parseObject(content, new TypeReference<Map<String, Object>>() {});
Integer sfzdcz = Integer.valueOf(contentMap.get("sfzdcz").toString());
if (sfzdcz != 1) {
log.info("结算对象参数 sfzdcz 不为1,跳过推送,parametersName={}, sfzdcz={}", parametersName, sfzdcz);
continue;
}
String warehouseTempLayerType;
String serviceItemsName;
Boolean isGc = false;
if ("冻仓计费配置".equals(parametersName)) {
warehouseTempLayerType = "DC";
serviceItemsName = "冻仓仓租费用";
} else if ("干仓计费配置".equals(parametersName)) {
warehouseTempLayerType = "GC";
serviceItemsName = "干仓仓租费用";
isGc=true;
} else {
log.warn("未知的结算对象参数类型,parametersName={}", parametersName);
continue;
}
List<ContractManage> contractManages = contractManageMapper.selectList(new LambdaQueryWrapper<ContractManage>()
.eq(ContractManage::getContractRentType, "NORMAL")
.eq(ContractManage::getContractState, 2)
.eq(ContractManage::getDelFlag, 1)
.eq(ContractManage::getSettlementCustomersId, settlementCustomersId)
.eq(ContractManage::getWarehouseTempLayerType, warehouseTempLayerType));
if (contractManages == null || contractManages.isEmpty()) {
log.warn("未找到正式合同,warehouseTempLayerType={}, settlementCustomersId={}", warehouseTempLayerType, settlementCustomersId);
continue;
}
for (ContractManage contractManage : contractManages) {
Long contractManageId = contractManage.getContractManageId();
ContractManageParameters contractManageParameters = contractManageParametersService.getOne(new LambdaQueryWrapper<ContractManageParameters>()
.eq(ContractManageParameters::getContractManageId, contractManageId), false);
if (contractManageParameters == null) {
continue;
}
String parametersJson = contractManageParameters.getParametersJson();
Map<String, Object> parametersMap = JSON.parseObject(parametersJson, new TypeReference<Map<String, Object>>() {});
BigDecimal hyj = (BigDecimal) parametersMap.get("hyj");
buildBusinessDocument(hyj, settlementCustomers, contractManage, "0D01", "租金(固定租)", warehouseTempLayerType, serviceItemsName);
}
}
}
private void buildBusinessDocument(BigDecimal fee, SettlementCustomersPO settlementCustomers, ContractManage contractManage, String code, String name, String warehouseType, String serviceItemsName) {
Long settlementCustomersId = settlementCustomers.getSettlementCustomersId();
Long settlementEntityId = settlementCustomers.getSettlementEntityId();
String settlementEntity = settlementCustomers.getSettlementEntity();
String settlementCustomersCode = settlementCustomers.getSettlementCustomersCode();
BusinessDocumentFeign businessDocumentFeign = new BusinessDocumentFeign();
businessDocumentFeign.setBillAmount(fee);
businessDocumentFeign.setOrganizationId(contractManage.getOrganizationId());
businessDocumentFeign.setOrganizationName(contractManage.getOrganizationName());
businessDocumentFeign.setTopOrganizationId(contractManage.getTopOrganizationId());
businessDocumentFeign.setBelongModuleCode("wms");
businessDocumentFeign.setBelongModule("WMS");
businessDocumentFeign.setDataSources(1);
businessDocumentFeign.setSettlementEntity(settlementEntity);
businessDocumentFeign.setSettlementCustomersId(settlementCustomersId);
businessDocumentFeign.setSettlementCustomersCode(settlementCustomersCode);
businessDocumentFeign.setDocumentTypeId(4l);
businessDocumentFeign.setDocumentTypeCode("CM_ZL");
businessDocumentFeign.setDocumentType("仓库租赁单");
businessDocumentFeign.setFirstSubjectCode(code);
businessDocumentFeign.setFirstSubjectName(name);
businessDocumentFeign.setBillingTime(new Date());
businessDocumentFeign.setServiceItemsCode("GC_CZ");
businessDocumentFeign.setServiceItemsName(serviceItemsName);
businessDocumentFeign.setSettlementWay(1);
businessDocumentFeign.setOriginalBusinessNum(contractManage.getContractNumber());
businessDocumentFeign.setWarehouseType(warehouseType);
String contractName = contractManage.getContractName();
String contractNumber = contractManage.getContractNumber();
Long contractManageId = contractManage.getContractManageId();
businessDocumentFeign.setContractName(contractName);
businessDocumentFeign.setContractNumber(contractNumber);
businessDocumentFeign.setContractManageId(contractManageId);
businessDocumentFeign.setBusinessFlow(OrderSequence.getOrderCode("LS"));
businessDocumentFeign.setIsPush(1);
AjaxResult ajaxResult = bmsServiceFeign.feignSaveBusinessDocument(businessDocumentFeign);
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
log.error("保存业务单据失败: {}", ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常");
}
}
private static final String WEBSERVICE_URL = "http://10.33.0.116:8080/sys/webservice/ngLegalByFindWebserviceService";
public List<com.alibaba.fastjson.JSONObject> getContractNosByCompanyName(String companyName, int pageNum, int pageSize) {
List<com.alibaba.fastjson.JSONObject> contractList = new ArrayList<>();
try {
log.info("=== 开始查询合同列表 ===");
log.info("查询公司: {}, 页码: {}, 每页数量: {}", companyName, pageNum, pageSize);
String httpRequest = buildXmlRequest(companyName, pageNum, pageSize);
log.info("XML请求: {}", httpRequest);
log.info("XML请求生成完成,长度: {} 字符", httpRequest.length());
log.info("正在调用WebService...");
String httpResponse = HttpWebServiceUtil.callWebService(httpRequest, WEBSERVICE_URL);
String jsonData = extractJsonFromResponse(httpResponse);
log.info("正在解析JSON..."+jsonData);
if (jsonData == null || jsonData.trim().isEmpty()) {
log.warn("未提取到JSON数据,返回空列表");
return contractList;
}
log.info("提取到JSON数据,长度: {} 字符", jsonData.length());
List<com.alibaba.fastjson.JSONObject> result = parseContractListFromJson(jsonData);
contractList.addAll(result);
log.info("=== 查询完成 ===");
log.info("找到 {} 个合同", contractList.size());
} catch (Exception e) {
log.error("查询合同列表失败", e);
throw new RuntimeException("查询合同列表失败: " + e.getMessage(), e);
}
return contractList;
}
/**
* 构建XML请求 - 动态分页
*/
private String buildXmlRequest(String companyName, int pageNum, int pageSize) {
String jsonParam = "{\"fdName\":\"" + companyName + "\"}";
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
" xmlns:web=\"http://webservice.legal.ng.kmss.landray.com/\">" +
"<soapenv:Body>" +
"<web:findNgLegal>" +
"<arg0 xmlns=\"\">" +
"<fdPageNo>" + pageNum + "</fdPageNo>" +
"<fdRowSize>" + pageSize + "</fdRowSize>" +
"<fdRelativePerson><![CDATA[" + jsonParam + "]]></fdRelativePerson>" +
"<fdContractNo></fdContractNo>" +
"<fdPersonNo>NA0301</fdPersonNo>" +
"<fdSponsor></fdSponsor>" +
"<docCreateTimeStar></docCreateTimeStar>" +
"<docCreateTimeEnd></docCreateTimeEnd>" +
"</arg0>" +
"</web:findNgLegal>" +
"</soapenv:Body>" +
"</soapenv:Envelope>";
}
/**
* 从SOAP响应中提取JSON
*/
private String extractJsonFromResponse(String soapResponse) {
if (soapResponse == null || soapResponse.isEmpty()) {
return null;
}
// 直接查找JSON部分
int jsonStart = soapResponse.indexOf("{\"returnState\":");
int jsonEnd = soapResponse.indexOf("}</return>");
if (jsonStart != -1 && jsonEnd != -1) {
// 找到JSON结束位置
jsonEnd = jsonEnd + 1; // 包含右大括号
String json = soapResponse.substring(jsonStart, jsonEnd);
log.info("直接提取JSON成功");
return json;
}
// 备用方法查找<return>标签
int start = soapResponse.indexOf("<return>");
int end = soapResponse.indexOf("</return>");
if (start != -1 && end != -1) {
start += "<return>".length();
String json = soapResponse.substring(start, end);
// 解码XML实体
json = json.replace("&lt;", "<")
.replace("&gt;", ">")
.replace("&amp;", "&")
.replace("&quot;", "\"")
.replace("&apos;", "'");
log.info("从<return>标签提取JSON成功");
return json.trim();
}
log.warn("无法从响应中提取JSON");
return null;
}
/**
* 解析JSON获取完整合同列表
*/
private List<com.alibaba.fastjson.JSONObject> parseContractListFromJson(String jsonData) {
List<com.alibaba.fastjson.JSONObject> contractList = new ArrayList<>();
try {
com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(jsonData);
String returnState = jsonObject.getString("returnState");
if (!"2".equals(returnState)) {
log.warn("返回状态异常: {}", returnState);
return contractList;
}
JSONArray dataArray = jsonObject.getJSONArray("data");
if (dataArray == null || dataArray.isEmpty()) {
log.info("查询成功,但未找到合同数据");
return contractList;
}
log.info("找到 {} 个合同", dataArray.size());
for (int i = 0; i < dataArray.size(); i++) {
com.alibaba.fastjson.JSONObject contract = dataArray.getJSONObject(i);
contractList.add(contract);
}
} catch (Exception e) {
log.error("JSON解析失败", e);
log.error("原始JSON: {}", jsonData);
}
return contractList;
}
}
@@ -0,0 +1,72 @@
package com.mhd.basic.application.service.contractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import com.mhd.basic.domain.contractManageParameters.service.ContractManageParametersDomainService;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 合约信息规则维护表ApplicationService
*
* @author gen
* @date 2024-06-07
*/
@Service
@Slf4j
public class ContractManageParametersApplicationService {
@Autowired
private ContractManageParametersDomainService contractManageParametersDomainService;
/**
* 分页查询合约信息规则维护表列表
*/
public List<ContractManageParametersPO> queryList(ContractManageParametersDO contractManageParametersDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null){
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1){
contractManageParametersDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
}
return contractManageParametersDomainService.queryList(contractManageParametersDO);
}
/**
* 新增合约信息规则维护表
*/
public Boolean insert(ContractManageParametersDO contractManageParametersDO) {
return contractManageParametersDomainService.insert(contractManageParametersDO);
}
/**
* 修改合约信息规则维护表
*/
public Boolean update(ContractManageParametersDO contractManageParametersDO) {
return contractManageParametersDomainService.update(contractManageParametersDO);
}
/**
* 批量删除合约信息规则维护表
*/
public boolean delete(Long[] ids) {
return contractManageParametersDomainService.delete(ids);
}
/**
* 获取合约信息规则维护表详细信息
*/
public ContractManageParametersPO getInfo(Long id)
{
return contractManageParametersDomainService.getInfo(id);
}
}
@@ -192,4 +192,30 @@ public class ContractManage extends BaseVOEntity{
@ApiModelProperty(name = "是否包含运输费用(1-包含,2-包含)")
private Integer transportationCosts;
@ApiModelProperty("合同租赁类型")
private String contractRentType;
@ApiModelProperty("合同租赁类型")
private String contractRentTypeName;
@ApiModelProperty("仓库温层类型")
private String warehouseTempLayerType;
@ApiModelProperty("仓库温层类型")
private String warehouseTempLayerTypeName;
@ApiModelProperty("续期提前天数")
private Integer renewalAdvanceDays;
@ApiModelProperty("标的物")
private String subjectMatter;
@ApiModelProperty("性质")
private String nature;
@ApiModelProperty("合同最初起始日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同最初起始日", width = 30, dateFormat = "yyyy-MM-dd")
private Date initialStartDate;
}
@@ -1,6 +1,7 @@
package com.mhd.basic.domain.contractManage.repository.po;
import com.mhd.basic.domain.contractManageDetail.repository.po.ContractManageDetailPO;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.interfaces.dto.contractManageDetail.ContractManageDetailDTO;
import com.mhd.common.core.annotation.Excel;
import lombok.Data;
@@ -195,5 +196,35 @@ public class ContractManagePO extends BaseVOEntity{
@ApiModelProperty(name = "是否包含运输费用(1-包含,2-包含)")
private Integer transportationCosts;
@ApiModelProperty("客户类型")
private String contractRentType;
@ApiModelProperty("客户类型编码")
private String contractRentTypeName;
@ApiModelProperty("仓库温层类型")
private String warehouseTempLayerType;
@ApiModelProperty("仓库温层类型编码")
private String warehouseTempLayerTypeName;
private String isMany;
@ApiModelProperty("合约信息规则维护列表")
private List<ContractManageParametersPO> contractManageParametersList;
@ApiModelProperty("续期提前天数")
private Integer renewalAdvanceDays;
@ApiModelProperty("标的物")
private String subjectMatter;
@ApiModelProperty("性质")
private String nature;
@ApiModelProperty("合同最初起始日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同最初起始日", width = 30, dateFormat = "yyyy-MM-dd")
private Date initialStartDate;
}
@@ -226,6 +226,34 @@ public class ContractManageDO extends BaseVOEntity{
@ApiModelProperty(name = "是否包含运输费用(1-包含,2-包含)")
private Integer transportationCosts;
@ApiModelProperty("客户类型")
private String contractRentType;
@ApiModelProperty("客户类型编码")
private String contractRentTypeName;
@ApiModelProperty("仓库温层类型")
private String warehouseTempLayerType;
@ApiModelProperty("仓库温层类型编码")
private String warehouseTempLayerTypeName;
@ApiModelProperty("一级费用科目code")
private String firstSubjectCode;
@ApiModelProperty("合约信息规则维护JSON")
private String parametersJson;
@ApiModelProperty("续期提前天数")
private Integer renewalAdvanceDays;
@ApiModelProperty("标的物")
private String subjectMatter;
@ApiModelProperty("性质")
private String nature;
@ApiModelProperty("合同最初起始日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date initialStartDate;
}
@@ -0,0 +1,96 @@
package com.mhd.basic.domain.contractManage.repository.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.zip.GZIPInputStream;
@Slf4j
@Component
public class HttpWebServiceUtil {
/**
* 调用HTTP WebService
*/
public static String callWebService(String requestBody, String endpointUrl) {
try {
// 创建RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 设置请求头
HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.TEXT_XML);
// headers.setAccept(Collections.singletonList(MediaType.TEXT_XML));
headers.setContentType(MediaType.parseMediaType("text/xml; charset=UTF-8")); // 核心修复
headers.setAccept(Collections.singletonList(MediaType.ALL));
headers.set("SOAPAction", "");
headers.set("User-Agent", "PostmanRuntime/7.26.10");
headers.set("Cache-Control", "no-cache");
headers.set("Accept-Encoding", "gzip, deflate");
headers.set("Connection", "keep-alive");
// 创建请求实体
HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
log.info("发送请求到: {}", endpointUrl);
// 发送请求
ResponseEntity<byte[]> response = restTemplate.exchange(
endpointUrl,
HttpMethod.POST,
entity,
byte[].class
);
log.info("响应状态: {}", response.getStatusCode());
// 处理响应
byte[] rawResponse = response.getBody();
if (rawResponse == null) {
return "";
}
// 检查是否gzip压缩
String contentEncoding = response.getHeaders().getFirst("Content-Encoding");
String responseBody;
if ("gzip".equalsIgnoreCase(contentEncoding)) {
responseBody = decompressGzip(rawResponse);
log.info("已解压gzip响应,长度: {} 字符", responseBody.length());
} else {
responseBody = new String(rawResponse, StandardCharsets.UTF_8);
log.info("响应长度: {} 字符", responseBody.length());
}
return responseBody;
} catch (Exception e) {
log.error("WebService调用失败", e);
throw new RuntimeException("WebService调用失败: " + e.getMessage(), e);
}
}
/**
* 解压缩GZIP内容
*/
private static String decompressGzip(byte[] compressedData) throws IOException {
try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressedData));
InputStreamReader reader = new InputStreamReader(gis, StandardCharsets.UTF_8)) {
StringBuilder sb = new StringBuilder();
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) != -1) {
sb.append(buffer, 0, len);
}
return sb.toString();
}
}
}
@@ -0,0 +1,20 @@
package com.mhd.basic.domain.contractManage.repository.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class XxlJobBusinessConfig {
@Value("${xxl.job.admin.address}")
private String adminAddress;
@Value("${xxl.job.admin.cookie}")
private String adminCookie;
@Bean
public XxlJobOpenApiUtil xxlJobOpenApiUtil() {
return new XxlJobOpenApiUtil(adminAddress, adminCookie);
}
}
@@ -0,0 +1,218 @@
package com.mhd.basic.domain.contractManage.repository.util;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
/**
* 调用XXLJOB后台页面接口
* 列表接口返回JSON不再返回HTML
*/
@Slf4j
public class XxlJobOpenApiUtil {
private final String adminUrl;
private final String cookie;
public XxlJobOpenApiUtil(String adminUrl, String cookie) {
this.adminUrl = StrUtil.removeSuffix(adminUrl, "/");
this.cookie = cookie;
}
/**
* 新增定时任务 POST /jobinfo/add
* @param addReq 请求实体与浏览器payload字段完全对齐
* @return true=新增成功false=失败
*/
public boolean addJob(JobInfoAddReq addReq) {
String url = adminUrl + "/jobinfo/add";
try {
Map<String, Object> formMap = BeanUtil.beanToMap(addReq);
HttpResponse response = HttpRequest.post(url)
.header("Authorization", cookie)
.form(formMap)
.execute();
int status = response.getStatus();
log.info("[XxlJob] addJob status:{}", status);
// 新增成功200重定向到列表页
return status == 200 || status == 302;
} catch (Exception e) {
log.error("[XxlJob] addJob异常", e);
return false;
}
}
/**
* 根据任务描述+执行器参数查询jobId
* 适配返回JSON格式的pageList接口
* @param jobDesc 任务描述
* @param executorParam 任务参数(业务shipperId)
* @return jobId查不到返回null
*/
public Integer queryJobIdByDescAndParam(String jobDesc, String executorParam,String jobGroup) {
StringBuilder querySb = new StringBuilder();
// start length必须
querySb.append("start=0&length=10");
// jobGroup为空就不拼接这个参数不要 jobGroup=""
// 你们业务固定jobGroup=3直接写死3不用传空
if(StrUtil.isNotBlank(jobGroup)){
querySb.append("&jobGroup=").append(jobGroup);
}
// jobDesc
if(StrUtil.isNotBlank(jobDesc)){
querySb.append("&jobDesc=").append(cn.hutool.core.net.URLEncodeUtil.encode(jobDesc));
}
// executorParam
if(StrUtil.isNotBlank(executorParam)){
querySb.append("&executorParam=").append(cn.hutool.core.net.URLEncodeUtil.encode(executorParam));
}
// executorHandler为空直接不携带
// triggerStatus=-1
querySb.append("&triggerStatus=-1");
String url = adminUrl + "/jobinfo/pageList?" + querySb;
log.info("[XxlJob] pageList请求url:{}",url);
try {
HttpResponse response = HttpRequest.get(url)
.header("Authorization", cookie)
.execute();
String jsonStr = response.body();
log.info("[XxlJob] pageList响应:{}",jsonStr);
if (StrUtil.isBlank(jsonStr)) {
log.warn("[XxlJob] pageList返回空响应");
return null;
}
JSONObject jsonObj = JSON.parseObject(jsonStr);
JSONArray jsonArray = jsonObj.getJSONArray("data");
if(jsonArray == null){
return null;
}
List<JobPageItem> dataList = jsonArray.toList(JobPageItem.class);
if (dataList == null || dataList.isEmpty()) {
return null;
}
for (JobPageItem item : dataList) {
if (StrUtil.equals(item.jobDesc, jobDesc) && StrUtil.equals(item.executorParam, executorParam)) {
return item.id;
}
}
return null;
} catch (Exception e) {
log.error("[XxlJob] queryJobId异常", e);
return null;
}
}
/**
* 暂停任务 POST /jobinfo/pause
* @param jobId xxl任务id
* @return true成功
*/
public boolean pauseJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/pause";
try {
HttpResponse response = HttpRequest.post(url)
.header("Authorization", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 200 || response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] pauseJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 开启任务 POST /jobinfo/start
* @param jobId xxl任务id
* @return true成功
*/
public boolean startJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/start";
try {
HttpResponse response = HttpRequest.post(url)
.header("Authorization", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 200 || response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] startJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* 删除任务 POST /jobinfo/remove
* @param jobId xxl任务id
* @return true成功
*/
public boolean removeJob(Integer jobId) {
if (jobId == null) {
return false;
}
String url = adminUrl + "/jobinfo/remove";
try {
HttpResponse response = HttpRequest.post(url)
.header("Authorization", cookie)
.form("id", jobId)
.execute();
return response.getStatus() == 200 || response.getStatus() == 302;
} catch (Exception e) {
log.error("[XxlJob] removeJob jobId:{}异常", jobId, e);
return false;
}
}
/**
* pageList 返回data数组中每一项实体
*/
@Data
public static class JobPageItem {
private Integer id;
private String jobDesc;
private String executorParam;
}
/**
* add接口请求实体与浏览器F12抓包payload字段一一对应
*/
@Data
public static class JobInfoAddReq {
private Integer jobGroup;
private String jobDesc;
private String author;
private String alarmEmail;
private String scheduleType;
private String scheduleConf;
private String glueType;
private String executorHandler;
private String executorParam;
private String glueRemark;
private String glueSource;
private String executorRouteStrategy;
private Integer childJobId;
private String misfireStrategy;
private String executorBlockStrategy;
private Integer executorTimeout;
private Integer executorFailRetryCount;
}
}
@@ -23,10 +23,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -193,6 +190,22 @@ public class ContractManageDomainService {
}
/**
* 同结算客户+同温层+同租赁类型+使用中 的合同数量用于唯一性校验
*/
public long countByUniqueKey(Long settlementCustomersId, String warehouseTempLayerType, String contractRentType, Long excludeId) {
LambdaQueryWrapper<ContractManage> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ContractManage::getSettlementCustomersId, settlementCustomersId);
wrapper.eq(ContractManage::getWarehouseTempLayerType, warehouseTempLayerType);
wrapper.eq(ContractManage::getContractRentType, contractRentType);
wrapper.eq(ContractManage::getContractState, 2);
wrapper.eq(ContractManage::getDelFlag, 1);
if (excludeId != null) {
wrapper.ne(ContractManage::getContractManageId, excludeId);
}
return contractManageService.count(wrapper);
}
public ContractManagePO getGeneralContract() {
ContractManagePO contractManagePO = new ContractManagePO();
LambdaQueryWrapper<ContractManage> queryWrapper = new LambdaQueryWrapper<>();
@@ -228,4 +241,6 @@ public class ContractManageDomainService {
}
return contractManagePO;
}
}
@@ -0,0 +1,52 @@
package com.mhd.basic.domain.contractManageParameters.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mhd.common.core.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import com.mhd.common.core.web.domain.BaseVOEntity;
import lombok.Data;
/**
* 合约信息规则维护表
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageParameters extends BaseVOEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("合约信息规则维护")
@Excel(name = "合约信息规则维护表")
private String parametersJson;
}
@@ -0,0 +1,47 @@
package com.mhd.basic.domain.contractManageParameters.repository.facade;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mhd.basic.domain.contractManageParameters.entity.ContractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import java.util.List;
/**
* 合约信息规则维护表Service接口
*
* @author gen
* @date 2024-06-07
*/
public interface IContractManageParametersService extends IService<ContractManageParameters>
{
/**
* 分页查询合约信息规则维护表列表
*/
public List<ContractManageParametersPO> queryList(ContractManageParametersDO contractManageParametersDO);
/**
* 新增合约信息规则维护表
*/
public Boolean insert(ContractManageParametersDO contractManageParametersDO);
/**
* 修改合约信息规则维护表
*/
public Boolean update(ContractManageParametersDO contractManageParametersDO);
/**
* 批量删除合约信息规则维护表
*/
public Boolean delete(Long[] ids);
/**
* 查询合约信息规则维护表
*/
public ContractManageParametersPO getInfo(Long id);
/**
* 根据合同管理id查询合约信息规则维护列表
*/
List<ContractManageParametersPO> getListByContractManageId(Long contractManageId);
}
@@ -0,0 +1,26 @@
package com.mhd.basic.domain.contractManageParameters.repository.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mhd.basic.domain.contractManageParameters.entity.ContractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import org.apache.ibatis.annotations.Param;
/**
* 合约信息规则维护表Mapper接口
*
* @author gen
* @date 2024-06-07
*/
public interface ContractManageParametersMapper extends BaseMapper<ContractManageParameters>
{
/**
* 查询合约信息规则维护表列表
*/
public List<ContractManageParametersPO> queryList(@Param("contractManageParametersDO") ContractManageParametersDO contractManageParametersDO);
/**
* 根据合同管理id查询合约信息规则维护列表
*/
List<ContractManageParametersPO> getListByContractManageId(@Param("contractManageId") Long contractManageId);
}
@@ -0,0 +1,86 @@
package com.mhd.basic.domain.contractManageParameters.repository.persistence;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.basic.domain.contractManageParameters.entity.ContractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.facade.IContractManageParametersService;
import com.mhd.basic.domain.contractManageParameters.repository.mapper.ContractManageParametersMapper;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 合约信息规则维护表Service业务层处理
*
* @author gen
* @date 2024-06-07
*/
@Service
public class ContractManageParametersImpl extends ServiceImpl<ContractManageParametersMapper, ContractManageParameters> implements IContractManageParametersService{
@Autowired
private ContractManageParametersMapper contractManageParametersMapper;
/**
* 查询合约信息规则维护表列表
*/
@Override
public List<ContractManageParametersPO> queryList(ContractManageParametersDO contractManageParametersDO)
{
return contractManageParametersMapper.queryList(contractManageParametersDO);
}
/**
* 新增合约信息规则维护表
*/
@Override
public Boolean insert(ContractManageParametersDO contractManageParametersDO) {
ContractManageParameters contractManageParameters = new ContractManageParameters();
BeanUtils.copyProperties(contractManageParametersDO,contractManageParameters);
return this.save(contractManageParameters);
}
/**
* 修改合约信息规则维护表
*/
@Override
public Boolean update(ContractManageParametersDO contractManageParametersDO) {
ContractManageParameters contractManageParameters = new ContractManageParameters();
BeanUtils.copyProperties(contractManageParametersDO,contractManageParameters);
return this.updateById(contractManageParameters);
}
/**
* 批量删除合约信息规则维护表
*/
@Override
public Boolean delete(Long[] ids ) {
List<ContractManageParameters> list = new ArrayList<>();
for (Long id : ids) {
ContractManageParameters contractManageParameters = new ContractManageParameters();
contractManageParameters.setId(id);
contractManageParameters.setDelFlag(2);
list.add(contractManageParameters);
}
return this.updateBatchById(list);
}
/**
* 查询合约信息规则维护表
*/
@Override
public ContractManageParametersPO getInfo(Long id) {
ContractManageParameters contractManageParameters = this.getById(id);
ContractManageParametersPO contractManageParametersPO = new ContractManageParametersPO();
BeanUtils.copyProperties(contractManageParameters,contractManageParametersPO);
return contractManageParametersPO;
}
@Override
public List<ContractManageParametersPO> getListByContractManageId(Long contractManageId) {
return contractManageParametersMapper.getListByContractManageId(contractManageId);
}
}
@@ -0,0 +1,51 @@
package com.mhd.basic.domain.contractManageParameters.repository.po;
import com.mhd.common.core.annotation.Excel;
import lombok.Data;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.mhd.common.core.web.domain.BaseVOEntity;
/**
* 合约信息规则维护表对象 contract_manage_parameters
*
* @author gen
* @date 2024-06-07
*/
@Data
@ApiModel(value = "合约信息规则维护表对象", description = "合约信息规则维护表响应对象")
public class ContractManageParametersPO extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
private Long id;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("合约信息规则维护")
@Excel(name = "合约信息规则维护表")
private String parametersJson;
}
@@ -0,0 +1,49 @@
package com.mhd.basic.domain.contractManageParameters.repository.todo;
import com.mhd.common.core.annotation.Excel;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import com.mhd.common.core.web.domain.BaseVOEntity;
/**
* 合约信息规则维护表对象 contract_manage_parameters
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageParametersDO extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
private Long id;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("合约信息规则维护")
@Excel(name = "合约信息规则维护表")
private String parametersJson;
}
@@ -0,0 +1,105 @@
package com.mhd.basic.domain.contractManageParameters.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mhd.basic.domain.contractManageParameters.entity.ContractManageParameters;
import com.mhd.basic.domain.contractManageParameters.repository.facade.IContractManageParametersService;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* 合约信息规则维护表
*
* @author gen
* @date 2024-06-07
*/
@Service
@Slf4j
public class ContractManageParametersDomainService {
@Autowired
private IContractManageParametersService contractManageParametersService;
/**
* 分页查询合约信息规则维护表列表
*/
public List<ContractManageParametersPO> queryList(ContractManageParametersDO contractManageParametersDO) {
return contractManageParametersService.queryList(contractManageParametersDO);
}
/**
* 新增合约信息规则维护表
*/
public Boolean insert(ContractManageParametersDO contractManageParametersDO) {
return contractManageParametersService.insert(contractManageParametersDO);
}
/**
* 修改合约信息规则维护表
*/
public Boolean update(ContractManageParametersDO contractManageParametersDO) {
return contractManageParametersService.update(contractManageParametersDO);
}
/**
* 批量删除合约信息规则维护表
*/
public Boolean delete(Long[] ids) {
return contractManageParametersService.delete(ids);
}
/**
* 获取合约信息规则维护表详细信息
*/
public ContractManageParametersPO getInfo(Long id)
{
return contractManageParametersService.getInfo(id);
}
/**
* 根据合同管理id查询合约信息规则维护列表
* @param contractManageId
* @return
*/
public List<ContractManageParametersPO> queryListByManageId(Long contractManageId) {
List<ContractManageParametersPO> resultList = new ArrayList<>();
LambdaQueryWrapper<ContractManageParameters> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ContractManageParameters::getContractManageId,contractManageId);
queryWrapper.eq(ContractManageParameters::getDelFlag,1);
List<ContractManageParameters> contractManageParametersList = contractManageParametersService.list(queryWrapper);
if(contractManageParametersList.size()>0){
for (ContractManageParameters contractManageParameters : contractManageParametersList) {
ContractManageParametersPO contractManageParametersPO = new ContractManageParametersPO();
BeanUtils.copyProperties(contractManageParameters,contractManageParametersPO);
resultList.add(contractManageParametersPO);
}
}
return resultList;
}
public List<ContractManageParametersPO> queryListByManageIds(Collection<Long> contractManageIds) {
List<ContractManageParametersPO> resultList = new ArrayList<>();
if (contractManageIds == null || contractManageIds.isEmpty()) {
return resultList;
}
LambdaQueryWrapper<ContractManageParameters> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ContractManageParameters::getContractManageId, contractManageIds);
queryWrapper.eq(ContractManageParameters::getDelFlag, 1);
List<ContractManageParameters> entityList = contractManageParametersService.list(queryWrapper);
for (ContractManageParameters entity : entityList) {
ContractManageParametersPO po = new ContractManageParametersPO();
BeanUtils.copyProperties(entity, po);
resultList.add(po);
}
return resultList;
}
}
@@ -413,4 +413,20 @@ public class MaterialBaseInfo extends BaseVOEntity{
@ApiModelProperty(name = "是否正常物料: 0-是 1-否")
private Integer isNormalMaterial;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -399,4 +399,20 @@ public class MaterialBaseInfoPO extends BaseVOEntity{
@ApiModelProperty(name = "是否正常物料: 0-是 1-否")
private Integer isNormalMaterial;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -405,4 +405,20 @@ public class MaterialBaseInfoDO extends BaseVOEntity{
@ApiModelProperty(name = "是否正常物料: 0-是 1-否")
private Integer isNormalMaterial;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -82,4 +82,20 @@ public class MaterialClassify extends BaseVOEntity{
@Excel(name = "单位")
private String unit;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -89,4 +89,20 @@ public class MaterialClassifyPO extends BaseVOEntity{
@Excel(name = "单位")
private String unit;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -89,4 +89,20 @@ public class MaterialClassifyDO extends BaseVOEntity{
@ApiModelProperty("单位")
@Excel(name = "单位")
private String unit;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -0,0 +1,65 @@
package com.mhd.basic.interfaces.assember.contractManageParameters;
import cn.hutool.core.util.ObjectUtil;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import com.mhd.basic.interfaces.dto.contractManageParameters.ContractManageParametersDTO;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 合约信息规则维护表Assembler
*
* @author gen
* @date 2024-06-07
*/
@Component
public class ContractManageParametersAssembler {
/**
* 转换实体
*/
public ContractManageParametersDO toDO(ContractManageParametersDTO contractManageParametersDTO) {
ContractManageParametersDO contractManageParametersDO = new ContractManageParametersDO();
// 拷贝
BeanUtils.copyProperties(contractManageParametersDTO, contractManageParametersDO, IgnoreNullUtil.getNullPropertyNames(contractManageParametersDTO));
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
String userName = loginUser.getUsername();
// 获取登录人id
Long userId = loginUser.getUserid();
if(contractManageParametersDTO.getId() != null){
if(userId != null){
contractManageParametersDO.setUpdateBy(userId);
}else {
contractManageParametersDO.setUpdateBy(new Long("0"));
}
contractManageParametersDO.setUpdateByName(userName);
contractManageParametersDO.setUpdateTime(new Date());
}else {
if(userId != null){
contractManageParametersDO.setCreateBy(userId);
contractManageParametersDO.setUpdateBy(userId);
}else {
contractManageParametersDO.setCreateBy(new Long("0"));
contractManageParametersDO.setUpdateBy(new Long("0"));
}
contractManageParametersDO.setCreateByName(userName);
contractManageParametersDO.setUpdateByName(userName);
contractManageParametersDO.setCreateTime(new Date());
contractManageParametersDO.setUpdateTime(new Date());
contractManageParametersDO.setDelFlag(1);
}
return contractManageParametersDO;
}
}
@@ -216,4 +216,33 @@ public class ContractManageDTO extends BaseVOEntity{
@ApiModelProperty(name = "是否包含运输费用(1-包含,2-包含)")
private Integer transportationCosts;
@ApiModelProperty("合同租赁类型code")
private String contractRentType;
@ApiModelProperty("合同租赁类型名称")
private String contractRentTypeName;
@ApiModelProperty("仓库温层类型code")
private String warehouseTempLayerType;
@ApiModelProperty("仓库温层类型编码名称")
private String warehouseTempLayerTypeName;
@ApiModelProperty("合约信息规则维护JSON")
private String parametersJson;
@ApiModelProperty("续期提前天数")
private Integer renewalAdvanceDays;
@ApiModelProperty("标的物")
private String subjectMatter;
@ApiModelProperty("性质")
private String nature;
@ApiModelProperty("合同最初起始日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "合同最初起始日", width = 30, dateFormat = "yyyy-MM-dd")
private Date initialStartDate;
}
@@ -0,0 +1,48 @@
package com.mhd.basic.interfaces.dto.contractManageParameters;
import com.mhd.common.core.annotation.Excel;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import com.mhd.common.core.web.domain.BaseVOEntity;
/**
* 合约信息规则维护表对象 contract_manage_parameters
*
* @author gen
* @date 2024-06-07
*/
@Data
public class ContractManageParametersDTO extends BaseVOEntity{
private static final long serialVersionUID = 1L;
@ApiModelProperty("合同管理id")
private Long id;
@ApiModelProperty("合同管理id")
private Long contractManageId;
@ApiModelProperty("一级组织表ID")
@Excel(name = "一级组织表ID")
private Long topOrganizationId;
@ApiModelProperty("组织表ID")
@Excel(name = "组织表ID")
private Long organizationId;
@ApiModelProperty("组织名称")
@Excel(name = "组织名称")
private String organizationName;
@ApiModelProperty("合同编号")
@Excel(name = "合同编号")
private String contractNumber;
@ApiModelProperty("合同名称")
@Excel(name = "合同名称")
private String contractName;
@ApiModelProperty("合约信息规则维护")
@Excel(name = "合约信息规则维护表")
private String parametersJson;
}
@@ -385,4 +385,19 @@ public class MaterialBaseInfoDTO extends BaseVOEntity{
@ApiModelProperty(name = "是否正常物料: 0-是 1-否")
private Integer isNormalMaterial;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -89,4 +89,20 @@ public class MaterialClassifyDTO extends BaseVOEntity{
@ApiModelProperty("单位")
@Excel(name = "单位")
private String unit;
@ApiModelProperty("每月仓租")
@Excel(name = "每月仓租")
private BigDecimal monthlyWarehouseRent;
@ApiModelProperty("半月仓租")
@Excel(name = "半月仓租")
private BigDecimal halfMonthWarehouseRent;
@ApiModelProperty("每月仓租单位")
@Excel(name = "每月仓租单位")
private String monthlyWarehouseRentUnit;
@ApiModelProperty("半月仓租单位")
@Excel(name = "半月仓租单位")
private String halfMonthWarehouseRentUnit;
}
@@ -1,5 +1,7 @@
package com.mhd.basic.interfaces.facade.contractManage;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
@@ -8,6 +10,10 @@ import com.mhd.basic.interfaces.assember.contractManage.ContractManageAssembler;
import com.mhd.basic.interfaces.dto.contractManage.ContractManageExportVO;
import com.mhd.basic.interfaces.dto.contractManage.SubjectAndPriceDTO;
import com.mhd.basic.interfaces.dto.contractManage.SubjectAndPriceReturn;
import com.mhd.common.core.utils.sms.Result;
import com.mhd.system.api.domain.ContractManageFeignDTO;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -119,6 +125,25 @@ public class ContractManageApi extends BaseController{
}
}
/**
* 保存合同管理
*/
@ApiOperation("保存临时合同管理")
@PostMapping("/feignSave")
public AjaxResult feignSave(@RequestBody ContractManageFeignDTO contractManageFeignDTO)
{
try {
//转换实体
ContractManageDTO contractManageDTO = new ContractManageDTO();
BeanUtils.copyProperties(contractManageFeignDTO, contractManageDTO);
ContractManageDO contractManageDO = contractManageAssembler.toDO(contractManageDTO);
ContractManageDO insert = contractManageApplicationService.insertFeign(contractManageDO);
return AjaxResult.success(insert);
}catch (Exception e){
return AjaxResult.error(e.getMessage());
}
}
/**
* 批量删除合同管理
*/
@@ -230,4 +255,45 @@ public class ContractManageApi extends BaseController{
util.exportExcel(response, list, "合同导出");
}
/**
* 1. 简单任务示例Bean模式
* 这里的 demoJobHandler 必须和调度中心配置一致
*/
@XxlJob("pushContractManageToBms")
public void pushContractManageToBms() {
// 获取任务参数(货主id)
String shipperId = XxlJobHelper.getJobParam();
logger.info("XXL-JOB 开始入库业务单推送bms计费流水,货主id参数:{}", shipperId);
try {
contractManageApplicationService.pushContractManageToBms(shipperId);
// 设置任务执行结果
XxlJobHelper.handleSuccess("入库业务单推送bms计费流水执行成功");
} catch (Exception e) {
logger.error("XXL-JOB 执行失败", e);
XxlJobHelper.handleFail("入库业务单推送bms计费流水执行失败:" + e.getMessage());
}
}
/**
* 根据公司名称获取合同列表(完整合同内容,支持分页)
* @param companyName 公司名称
* @param pageNum 页码
* @param pageSize 每页数量
* @return 合同列表
*/
@GetMapping("/contractNos")
public TableDataInfo getContractNosByCompanyName(
@RequestParam String companyName,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
List<JSONObject> list = contractManageApplicationService.getContractNosByCompanyName(companyName, pageNum, pageSize);
TableDataInfo tableDataInfo = new TableDataInfo(list, list.size());
tableDataInfo.setCode(200);
tableDataInfo.setMsg("查询成功");
return tableDataInfo;
}
}
@@ -0,0 +1,105 @@
package com.mhd.basic.interfaces.facade.contractManageParameters;
import java.util.List;
import com.mhd.basic.interfaces.assember.contractManageParameters.ContractManageParametersAssembler;
import com.mhd.system.api.domain.ContractManageParametersFeign;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mhd.basic.interfaces.dto.contractManageParameters.ContractManageParametersDTO;
import com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO;
import com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO;
import com.mhd.basic.application.service.contractManageParameters.ContractManageParametersApplicationService;
import javax.annotation.Resource;
import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
/**
* 合约信息规则维护表Api
*
* @author gen
* @date 2024-06-07
*/
@RestController
@RequestMapping("/contractManageParametersApi")
public class ContractManageParametersApi extends BaseController{
@Autowired
private ContractManageParametersApplicationService contractManageParametersApplicationService;
@Resource
private ContractManageParametersAssembler contractManageParametersAssembler;
/**
* 分页查询合约信息规则维护表列表
*/
@ApiOperation("查询合约信息规则维护表列表")
@GetMapping("/list")
public TableDataInfo list(ContractManageParametersDTO contractManageParametersDTO)
{
//转换实体
ContractManageParametersDO contractManageParametersDO = contractManageParametersAssembler.toDO(contractManageParametersDTO);
startPage();
List<ContractManageParametersPO> list = contractManageParametersApplicationService.queryList(contractManageParametersDO);
return getDataTable(list);
}
/**
* 编辑合约信息规则维护表
*/
@ApiOperation("编辑合约信息规则维护表")
@PostMapping("/edit")
public AjaxResult edit(@RequestBody ContractManageParametersDTO contractManageParametersDTO)
{
//转换实体
ContractManageParametersDO contractManageParametersDO = contractManageParametersAssembler.toDO(contractManageParametersDTO);
if(contractManageParametersDTO.getId() != null){
return toAjax(contractManageParametersApplicationService.update(contractManageParametersDO));
}else {
return toAjax(contractManageParametersApplicationService.insert(contractManageParametersDO));
}
}
/**
* 批量删除合约信息规则维护表
*/
@ApiOperation("批量删除合约信息规则维护表")
@DeleteMapping("/deleteByIds/{ids}")
public AjaxResult delete(@PathVariable Long[] ids)
{
return toAjax(contractManageParametersApplicationService.delete(ids));
}
/**
* 获取合约信息规则维护表详细信息
*/
@ApiOperation("获取合约信息规则维护表")
@GetMapping(value = "/getInfo/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return AjaxResult.success(contractManageParametersApplicationService.getInfo(id));
}
@ApiOperation("Feign保存合约信息规则维护")
@PostMapping("/feignSave")
public AjaxResult feignSave(@RequestBody ContractManageParametersFeign contractManageParametersFeign)
{
try {
ContractManageParametersDTO contractManageParametersDTO = new ContractManageParametersDTO();
BeanUtils.copyProperties(contractManageParametersFeign, contractManageParametersDTO);
ContractManageParametersDO contractManageParametersDO = contractManageParametersAssembler.toDO(contractManageParametersDTO);
return toAjax(contractManageParametersApplicationService.insert(contractManageParametersDO));
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}
}
@@ -0,0 +1,54 @@
package com.mhd.basic.util;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* XXL-JOB 配置类
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
@@ -13,17 +13,17 @@ spring:
cloud:
nacos:
discovery:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境
# server-addr: 10.102.192.105:6848
config:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -201,9 +201,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="contractManageDO.topOrganizationId != null">
and a.top_organization_id = #{contractManageDO.topOrganizationId}
</if>
<if test="contractManageDO.contractRentType != null and contractManageDO.contractRentType != ''">
and a.contract_rent_type = #{contractManageDO.contractRentType}
</if>
<if test="contractManageDO.warehouseTempLayerType != null and contractManageDO.warehouseTempLayerType != ''">
and a.warehouse_temp_layer_type = #{contractManageDO.warehouseTempLayerType}
</if>
<if test="contractManageDO.firstSubjectCode != null and contractManageDO.firstSubjectCode != ''">
and b.FIRST_SUBJECT_CODE = #{contractManageDO.firstSubjectCode}
</if>
<if test="contractManageDO.renewalAdvanceDays != null">
and a.renewal_advance_days = #{contractManageDO.renewalAdvanceDays}
</if>
<if test="contractManageDO.subjectMatter != null and contractManageDO.subjectMatter != ''">
and a.subject_matter like concat('%', #{contractManageDO.subjectMatter}, '%')
</if>
<if test="contractManageDO.nature != null and contractManageDO.nature != ''">
and a.nature = #{contractManageDO.nature}
</if>
<if test="contractManageDO.initialStartDate != null">
and a.initial_start_date = #{contractManageDO.initialStartDate}
</if>
</sql>
</mapper>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mhd.basic.domain.contractManageParameters.repository.mapper.ContractManageParametersMapper">
<sql id="selectContractManageParametersPo">
select
*
from contract_manage_parameters
</sql>
<sql id="selectContractManageParametersPo1">
<where>
<if test="contractManageId != null ">
and contract_manage_id = #{contractManageId}
</if>
<if test="topOrganizationId != null ">
and top_organization_id = #{topOrganizationId}
</if>
<if test="organizationId != null ">
and organization_id = #{organizationId}
</if>
<if test="organizationName != null and organizationName != ''">
and organization_name like concat('%', #{organizationName}, '%')
</if>
<if test="contractNumber != null and contractNumber != ''">
and contract_number like concat('%', #{contractNumber}, '%')
</if>
<if test="contractName != null and contractName != ''">
and contract_name like concat('%', #{contractName}, '%')
</if>
</where>
</sql>
<select id="queryList" parameterType="com.mhd.basic.domain.contractManageParameters.repository.todo.ContractManageParametersDO"
resultType="com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO">
<include refid="selectContractManageParametersPo"/>
<include refid="selectContractManageParametersPo1"/>
</select>
<select id="getListByContractManageId"
resultType="com.mhd.basic.domain.contractManageParameters.repository.po.ContractManageParametersPO" parameterType="java.lang.Long">
SELECT
*
FROM
contract_manage_parameters
WHERE
contract_manage_id = #{contractManageId}
</select>
</mapper>
@@ -27,13 +27,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="delFlag" column="del_flag" />
<result property="chargeStandard" column="charge_standard" />
<result property="unit" column="unit" />
<result property="monthlyWarehouseRent" column="monthly_warehouse_rent" />
<result property="halfMonthWarehouseRent" column="half_month_warehouse_rent" />
<result property="monthlyWarehouseRentUnit" column="monthly_warehouse_rent_unit" />
<result property="halfMonthWarehouseRentUnit" column="half_month_warehouse_rent_unit" />
</resultMap>
<sql id="selectMaterialClassifyPo">
select material_classify_id, organization_id, organization_name, top_organization_id, code, name, level, parent_code,
parent_name, code_path, name_path, remark, nullify, create_time, create_by, create_by_name, update_time, update_by,
update_by_name, del_flag,CHARGE_STANDARD,unit
update_by_name, del_flag,CHARGE_STANDARD,unit,
monthly_warehouse_rent, half_month_warehouse_rent, monthly_warehouse_rent_unit, half_month_warehouse_rent_unit
from material_classify
</sql>
@@ -97,6 +97,7 @@ import com.mhd.system.api.model.LoginUser;
import com.mhd.user.interfaces.dto.addDTO.UserDriverDTO;
import com.mhd.user.interfaces.dto.queryDTO.UserDocumentWarningQueryDTO;
import com.mhd.user.interfaces.dto.updateDTO.UpdateHasDefaultAddressDTO;
import com.mhd.user.interfaces.dto.updateDTO.PasswordChangeDTO;
import com.mhd.user.interfaces.facadeApi.Po.UserDriverCountPo;
import com.mhd.user.interfaces.vo.QueryAllShipperInfoVo;
import lombok.extern.slf4j.Slf4j;
@@ -214,6 +215,61 @@ public class UserApplicationService {
@Autowired
private UserShipperMapper userShipperMapper;
/**
* 修改密码 - 同步 wlhy yms
*/
@Transactional(rollbackFor = Exception.class)
public void changePassword(PasswordChangeDTO passwordChangeDTO) {
// 1. 获取当前登录用户
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
Long userId = loginUser.getUserPo().getUserId();
if (userId == null) {
throw new ServiceException("用户未登录");
}
// 2. 查询用户信息
UserPo userPO = userDomainService.selectByUserId(userId);
UserEntity userEntity = new UserEntity();
BeanUtils.copyProperties(userPO,userEntity);
if (ObjectUtil.isNull(userEntity)) {
throw new ServiceException("用户不存在");
}
// 3. 解密并加密新密码
String salt = userEntity.getUserSalt();
String newPassword = decrypt(passwordChangeDTO.getNewPassword());
String encodedPassword = PasswordUtil.encrypt(userEntity.getUserAccount(), newPassword, salt);
// 4. 更新本地密码
UserDO userDO = new UserDO();
userDO.setUserId(userId);
userDO.setUserPassword(encodedPassword);
userDomainService.updateUser(userDO);
// 5. 同步到网货平台wlhy
try {
userEntity.setUserPassword(encodedPassword);
wlhyDomainService.addOrEditPlatformUser(userEntity);
} catch (Exception e) {
log.warn("同步密码到网货平台失败,但不影响主流程:{}", e.getMessage());
}
// 6. 同步到 YMS 平台
try {
Integer isQueue = userMapper.getOrdIsQueue(userEntity.getOrganizationId());
if (isQueue != null && isQueue == 1) {
userEntity.setUserPassword(newPassword);
ymsDomainService.addOrEditYmsUser(userEntity);
}
} catch (Exception e) {
log.warn("同步密码到 YMS 平台失败,但不影响主流程:{}", e.getMessage());
}
}
/**
* @Description 查询用户列表
* @Author Alex
@@ -1971,6 +2027,11 @@ public class UserApplicationService {
if (StrUtil.isEmpty(userDO.getUserName())) {
userDO.setUserName("用户" + userDO.getUserPhone().substring(userDO.getUserPhone().length() - 4));
}
//密码为空则给默认密码
if (StrUtil.isEmpty(userDO.getUserPassword())) {
String defaultPassword = "Aa123456";
userDO.setUserPassword(PasswordUtil.encrypt(userDO.getUserAccount(), defaultPassword, userDO.getUserSalt()));
}
UserEntity userEntity = userDomainService.addUser(userDO);
//给小程序注册用户分配默认普通用户角色must本组织没有则找上级
userEntity.setUserPassword("Aa123456"); // 三方同步需要密码
@@ -100,6 +100,7 @@ public class UserYmsDomainService {
ymsSysUserDTO.setPhonenumber(userEntity.getUserPhone());
ymsSysUserDTO.setAvatar(userEntity.getAvatar());
ymsSysUserDTO.setUserAccountType(userEntity.getUserAccountType());
ymsSysUserDTO.setPassword(userEntity.getUserPassword());
if (StringUtils.isNotBlank(userEntity.getRoleCode())){
ymsSysUserDTO.setRoleCodes(Arrays.asList(userEntity.getRoleCode().split(",")));
@@ -0,0 +1,20 @@
package com.mhd.user.interfaces.dto.updateDTO;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 修改密码 DTO
* @author AI
* @date 2026/09/10
*/
@Data
public class PasswordChangeDTO {
/**
* 新密码
*/
@NotBlank(message = "新密码不能为空")
private String newPassword;
}
@@ -32,6 +32,7 @@ import com.mhd.common.security.annotation.InnerAuth;
import com.mhd.common.security.service.TokenService;
import com.mhd.system.api.model.LoginUser;
import com.mhd.user.interfaces.dto.queryDTO.UserDocumentWarningQueryDTO;
import com.mhd.user.interfaces.dto.updateDTO.PasswordChangeDTO;
import com.mhd.user.interfaces.dto.updateDTO.UpdateHasDefaultAddressDTO;
import com.mhd.user.interfaces.vo.QueryAllShipperInfoVo;
import io.swagger.annotations.Api;
@@ -1037,4 +1038,16 @@ public class UserAPI extends BaseController {
public R<String> finShipperEnterpriseNamedByUserId(@PathVariable("userId") Long userId) {
return R.ok(userApplicationService.finShipperEnterpriseNamedByUserId(userId));
}
/**
* 修改密码 - 同步 wlhy yms
* 根据当前登录用户判断是谁修改只传新密码不需要校验旧密码
*/
@Log(title = "用户中台管理 - 修改密码", description ="修改当前登录用户密码",businessType = BusinessType.UPDATE)
@ApiOperation("修改密码")
@PostMapping("/changePassword")
public AjaxResult changePassword(@RequestBody PasswordChangeDTO passwordChangeDTO) {
userApplicationService.changePassword(passwordChangeDTO);
return AjaxResult.success();
}
}
@@ -3,6 +3,7 @@ package com.mhd.user.interfaces.facade;
import com.github.pagehelper.PageHelper;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.core.utils.poi.ExcelUtil;
import com.mhd.common.log.annotation.Log;
import com.mhd.common.log.enums.BusinessType;
import com.mhd.common.security.utils.SecurityUtils;
@@ -24,6 +25,7 @@ import com.mhd.user.application.service.WechatMiniAppService;
import com.mhd.user.interfaces.dto.updateDTO.SettlementInfoUpdateDTO;
import com.mhd.user.interfaces.vo.SettlementInfoQueryVo;
import com.mhd.user.interfaces.vo.ShipperMasterDataSyncTimeVo;
import com.mhd.user.interfaces.vo.UserShipperExportVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -31,6 +33,9 @@ import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
@Api(tags = "用户中台管理-托运人管理")
@@ -128,6 +133,33 @@ public class UserShipperAPI extends BaseController {
return getDataTable(list);
}
@Log(title = "托运人管理-导出", description ="导出托运人列表",businessType = BusinessType.EXPORT)
@ApiOperation("导出托运人列表")
@GetMapping(value = "/exportUserShipper", produces = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public void exportUserShipper(UserShipperDTO userShipperDTO, HttpServletResponse response) throws IOException {
//转换实体
UserShipperDO userShipperDO = userShipperAssember.toUserShipperDO(userShipperDTO);
//查询全量不分页复用列表查询逻辑含数据权限过滤
List<UserShipperPo> list = userShipperApplicationService.userShipperList(userShipperDO);
List<UserShipperExportVO> exportList = new ArrayList<>();
if (list != null) {
for (UserShipperPo po : list) {
UserShipperExportVO vo = new UserShipperExportVO();
BeanUtils.copyProperties(po, vo);
exportList.add(vo);
}
}
//设置下载头防止浏览器乱码
String fileName = URLEncoder.encode("托运人列表", "UTF-8").replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
ExcelUtil<UserShipperExportVO> util = new ExcelUtil<>(UserShipperExportVO.class);
util.exportExcel(response, exportList, "托运人列表");
}
@ApiOperation("查询托运人列表统计表单")
@GetMapping("/userShipperCount")
@@ -0,0 +1,73 @@
package com.mhd.user.interfaces.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 托运人委托方列表导出对象
*
* @author gen
*/
@Data
@ApiModel(value = "托运人列表导出对象", description = "托运人列表导出对象")
public class UserShipperExportVO {
@Excel(name = "登录账号", sort = 1, width = 20)
@ApiModelProperty(value = "登录账号")
private String userAccount;
@Excel(name = "公司名称", sort = 2, width = 30)
@ApiModelProperty(value = "公司名称")
private String shipperEnterpriseName;
@Excel(name = "联系人", sort = 3, width = 15)
@ApiModelProperty(value = "联系人")
private String emergencyContactName;
@Excel(name = "联系电话", sort = 4, width = 18)
@ApiModelProperty(value = "联系电话")
private String emergencyContactPhone;
@Excel(name = "地址", sort = 5, width = 30)
@ApiModelProperty(value = "企业注册地址")
private String shipperEnterpriseAddress;
@Excel(name = "详细地址", sort = 6, width = 30)
@ApiModelProperty(value = "详细地址")
private String userAreaAddressShipper;
@Excel(name = "备注", sort = 7, width = 25)
@ApiModelProperty(value = "备注")
private String remark;
@Excel(name = "结算币种", sort = 8, width = 12)
@ApiModelProperty(value = "结算币种")
private String settlementCurrency;
@Excel(name = "信用额度", sort = 9, width = 15)
@ApiModelProperty(value = "信用额度(授权额度)")
private BigDecimal authorizedQuota;
@Excel(name = "信用占用", sort = 10, width = 15)
@ApiModelProperty(value = "信用占用")
private BigDecimal authorizedUsedAmount;
@Excel(name = "信用余额", sort = 11, width = 15)
@ApiModelProperty(value = "信用余额")
private BigDecimal creditAmount;
@Excel(name = "客户协议", sort = 12, width = 12)
@ApiModelProperty(value = "客户协议数量")
private BigDecimal agreementCount;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "最近同步信用时间", sort = 13, width = 22, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "最近同步信用时间")
private Date limitTime;
}
@@ -18,15 +18,15 @@ spring:
cloud:
nacos:
discovery:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
config:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置
@@ -49,4 +49,8 @@ feign:
readTimeout: 120000
mhd-third-party-service:
connectTimeout: 10000
readTimeout: 120000
readTimeout: 120000
#wechat:
# miniapp:
# appId: wxc9dd2810a77e4e30
# appSecret: 9354ff1215a82785ef14f2355fbf2185
+11
View File
@@ -94,6 +94,17 @@
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.1.193</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
<!--添加druid连接池 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
@@ -33,6 +33,7 @@ import com.mhd.bms.infrastructure.constant.BillLogsConstants;
import com.mhd.bms.interfaces.assembler.billManage.BillManageAssembler;
import com.mhd.bms.interfaces.dto.billManage.BillDetailDTO;
import com.mhd.bms.interfaces.dto.billManage.BillManageDTO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import com.mhd.bms.interfaces.dto.billingStatement.BillingStatementDTO;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
@@ -138,6 +139,74 @@ public class BillManageApplicationService {
String billNumber = billManagePO.getBillNumber(); // 获取账单编号
// 原有 - 前端列表用不变
List<BillDetail> billDetails = billDetailMapper.selectList(new LambdaQueryWrapper<BillDetail>().eq(BillDetail::getBillNumber, billNumber));
BigDecimal totalTaxAmount = billDetails.stream().map(BillDetail::getTaxAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalTaxFreeFee = billDetails.stream().map(BillDetail::getTaxFreeFee).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
billManagePO.setTaxAmount(totalTaxAmount);
billManagePO.setTaxFreeFee(totalTaxFreeFee);
billManagePO.setBillDetailList(billDetails);
// 新增 - 导出用LEFT JOIN billing_statement 拿到费用科目
List<BillDetailPO> billDetailPOs = billDetailMapper.getDetailsByBillManageId(billManagePO.getBillManageId());
billManagePO.setBillDetailPOList(billDetailPOs);
}
return billManagePOS;
}
public List<BillManagePO> customerMonthlyReport(BillManageDO billManageDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long userOrganizationId = loginUser.getUserPo().getOrganizationId();
Long frontendOrganizationId = billManageDO.getOrganizationId(); // 前端传递的 organizationId
// 当前登录用户的 organizationId 2827 可查全部组织数据其他组织只能查自己
if (userOrganizationId != null && userOrganizationId == 2827L) {
// 南光组织organizationId=2827可以查询所有组织的数据
if (frontendOrganizationId != null) {
// 前端传递了 organizationId包括2827或其他组织使用前端传递的值进行过滤
billManageDO.setOrganizationId(frontendOrganizationId);
billManageDO.setTopOrganizationId(null); // 明确设置为 null避免使用 topOrganizationId 条件
} else {
// 前端没有传递 organizationId清空组织过滤条件查询所有组织的数据
billManageDO.setOrganizationId(null);
billManageDO.setTopOrganizationId(null);
}
} else {
// 其他组织设置organizationId只查询当前组织的数据
// 如果前端传递了 organizationId验证是否与当前登录用户的组织ID一致
if (frontendOrganizationId != null && userOrganizationId != null) {
// 前端传递了 organizationId验证是否与当前登录用户的组织ID一致
if (!frontendOrganizationId.equals(userOrganizationId)) {
// 前端传递了其他组织的 organizationId强制使用当前登录用户的组织ID防止越权查询
billManageDO.setOrganizationId(userOrganizationId);
}
// 如果前端传递的 organizationId 与当前登录用户的组织ID一致使用前端传递的值
} else {
// 前端没有传递 organizationId使用当前登录用户的组织ID
if (userOrganizationId != null) {
billManageDO.setOrganizationId(userOrganizationId);
}
}
// 如果 organizationId 不为 null则优先使用 organizationId不使用 topOrganizationId
if (billManageDO.getOrganizationId() == null) {
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1) {
billManageDO.setTopOrganizationId(topOrganizationId);
}
} else {
// 对于非2827组织必须设置 topOrganizationId=2827
billManageDO.setTopOrganizationId(2827L);
}
}
}
List<BillManagePO> billManagePOS = billManageDomainService.customerMonthlyReport(billManageDO);
for (BillManagePO billManagePO : billManagePOS) {
String billNumber = billManagePO.getBillNumber(); // 获取账单编号
// 原有 - 前端列表用不变
List<BillDetail> billDetails = billDetailMapper.selectList(new LambdaQueryWrapper<BillDetail>().eq(BillDetail::getBillNumber, billNumber));
BigDecimal totalTaxAmount = billDetails.stream().map(BillDetail::getTaxAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalTaxFreeFee = billDetails.stream().map(BillDetail::getTaxFreeFee).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
billManagePO.setTaxAmount(totalTaxAmount);
billManagePO.setTaxFreeFee(totalTaxFreeFee);
billManagePO.setBillDetailList(billDetails);
// 新增 - 导出用LEFT JOIN billing_statement 拿到费用科目
List<BillDetailPO> billDetailPOs = billDetailMapper.getDetailsByBillManageId(billManagePO.getBillManageId());
@@ -184,6 +253,10 @@ public class BillManageApplicationService {
return billManageDomainService.save(billingStatementDTO);
}
public Boolean saveBillJob(BillingStatementDTO billingStatementDTO) {
return billManageDomainService.saveJob(billingStatementDTO);
}
/**
* 批量删除账单管理
*/
@@ -287,6 +360,28 @@ public class BillManageApplicationService {
return billManageDomainService.confirmBilling(billManageDO);
}
@Transactional
public Boolean confirmBillingJob(BillManageDTO billManageDTO) {
//确认账单未收款状态之前都可以进行确认账单跳过核账流程直接到未收款状态
if(!StringUtils.isNotEmpty(billManageDTO.getBillManageIds())){
throw new ServiceException("账单管理ids不能为空");
}
//校验
Set<String> billManageIds = Stream.of(billManageDTO.getBillManageIds().split(",")).collect(Collectors.toSet());
BillManageDO billManageDO = new BillManageDO();
billManageDO.setBillManageIdSet(billManageIds);
List<BillManagePO> billManageList = billManageDomainService.queryList(billManageDO);
for (BillManagePO billManage : billManageList) {
if(billManage.getBillState() > 2){
throw new ServiceException("选中数据"+ billManage.getBillNumber() + "状态不可操作确认账单");
}
}
billManageDO.setOrganizationId(billManageDTO.getOrganizationId());
billManageDO.setOrganizationName(billManageDTO.getOrganizationName());
billManageDO.setTopOrganizationId(billManageDTO.getTopOrganizationId());
return billManageDomainService.confirmBillingJob(billManageDO);
}
public int editIsInvoice(String billNumber, Integer isInvoice, String invoiceId, String invoiceMakeTime,String applyNumber)
{
@@ -621,6 +716,22 @@ public class BillManageApplicationService {
return originalBill;
}
/**
* 应收账单-红冲
*/
@Transactional
public Boolean redFlushBill(BillManageDTO billManageDTO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
if (StringUtils.isEmpty(billManageDTO.getBillManageIds())) {
throw new ServiceException("账单id不能为空");
}
return billManageDomainService.redFlushBill(billManageDTO);
}
/**
* 应收账单-客户确认
*/
@@ -872,5 +983,66 @@ public class BillManageApplicationService {
return flag && flagTwo;
}
/**
* 客户每月账单分组查询
*/
public List<CustomerMonthBillVO> queryCustomerMonthBillList(BillManageDO billManageDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long userOrganizationId = loginUser.getUserPo().getOrganizationId();
Long frontendOrganizationId = billManageDO.getOrganizationId();
if (userOrganizationId != null && userOrganizationId == 2827L) {
if (frontendOrganizationId != null) {
billManageDO.setOrganizationId(frontendOrganizationId);
billManageDO.setTopOrganizationId(null);
} else {
billManageDO.setOrganizationId(null);
billManageDO.setTopOrganizationId(null);
}
} else {
if (frontendOrganizationId != null && userOrganizationId != null) {
if (!frontendOrganizationId.equals(userOrganizationId)) {
billManageDO.setOrganizationId(userOrganizationId);
}
} else {
if (userOrganizationId != null) {
billManageDO.setOrganizationId(userOrganizationId);
}
}
if (billManageDO.getOrganizationId() == null) {
Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
if (topOrganizationId != null && topOrganizationId != 1) {
billManageDO.setTopOrganizationId(topOrganizationId);
}
} else {
billManageDO.setTopOrganizationId(2827L);
}
}
}
List<CustomerMonthBillVO> list = billManageDomainService.queryCustomerMonthBillList(billManageDO);
// 计算付款状态
for (CustomerMonthBillVO vo : list) {
BigDecimal totalAmount = vo.getTotalBillAmount() != null ? vo.getTotalBillAmount() : BigDecimal.ZERO;
BigDecimal settledAmount = vo.getTotalSettledAmount() != null ? vo.getTotalSettledAmount() : BigDecimal.ZERO;
if (totalAmount.compareTo(BigDecimal.ZERO) == 0) {
vo.setPaymentStatus(3);
vo.setPaymentStatusName("已付款");
} else if (settledAmount.compareTo(BigDecimal.ZERO) == 0) {
vo.setPaymentStatus(1);
vo.setPaymentStatusName("未付款");
} else if (settledAmount.compareTo(totalAmount) >= 0) {
vo.setPaymentStatus(3);
vo.setPaymentStatusName("已付款");
} else {
vo.setPaymentStatus(2);
vo.setPaymentStatusName("部分付款");
}
}
return list;
}
}
@@ -147,6 +147,25 @@ public class ReceiptManageApplicationService {
}
/**
* 撤销收款
*/
@Transactional
public Boolean cancelCollection(ReceiptManageDO receiptManageDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
return receiptManageDomainService.cancelCollection(receiptManageDO);
}
/**
* 撤销收款-查询账单涉及的收款单id用于加锁防止并发撤销时收款单金额重算冲突
*/
public Set<Long> queryCancelCollectionReceiptManageIds(String billManageIds) {
return receiptManageDomainService.queryReceiptManageIdsByBillManageIds(billManageIds);
}
/**
* 退款
*/
@@ -575,6 +575,8 @@ public class ReportFormApplicationService {
//收款单
QueryWrapper<ReceiptManage> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("top_organization_id", loginUser.getUserPo().getTopOrganizationId());
//过滤已撤销逻辑删除的收款单
queryWrapper.eq("del_flag", 1);
for (int i = 0; i < formQueryParamsList.size(); i++) {
FormQueryParams formQueryParams = formQueryParamsList.get(i);
FormQueryParams beforeFormQueryParams = null;
@@ -1,5 +1,6 @@
package com.mhd.bms.application.server.settlementCustomers;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
@@ -9,12 +10,16 @@ import com.mhd.bms.domain.settlementCustomers.repository.mapper.SettlementCustom
import com.mhd.bms.domain.settlementCustomers.repository.po.SettlementCustomersPO;
import com.mhd.bms.domain.settlementCustomers.repository.todo.SettlementCustomersDO;
import com.mhd.bms.domain.settlementCustomers.repository.persistence.SettlementCustomersImpl;
import com.mhd.bms.domain.settlementCustomers.repository.util.XxlJobOpenApiUtil;
import com.mhd.bms.domain.settlementCustomers.service.SettlementCustomersDomainService;
import com.mhd.bms.domain.settlementCustomersNcConfig.entity.SettlementCustomersNcConfig;
import com.mhd.bms.domain.settlementCustomersNcConfig.repository.facade.ISettlementCustomersNcConfigService;
import com.mhd.bms.domain.settlementCustomersParameters.entity.SettlementCustomersParameters;
import com.mhd.bms.domain.settlementCustomersParameters.repository.facade.ISettlementCustomersParametersService;
import com.mhd.bms.interfaces.dto.settlementCustomers.SettlementCustomersDTO;
import com.mhd.common.core.domain.po.SysDictDataVo;
import com.mhd.common.core.domain.po.UserDriverPo;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.domain.po.UserShipperPo;
import com.mhd.bms.interfaces.dto.settlementCustomersNcConfig.SettlementCustomersNcConfigDTO;
import com.mhd.bms.interfaces.dto.settlementCustomersParameters.SettlementCustomersParametersDTO;
import com.mhd.common.core.domain.po.*;
import com.mhd.common.core.enums.DictCode;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
@@ -25,19 +30,25 @@ import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.system.api.domain.BatchDetailFeignPO;
import com.mhd.system.api.domain.ContractManageFeignDTO;
import com.mhd.system.api.domain.ContractManageParametersFeign;
import com.mhd.system.api.domain.WarehouseFeignPO;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -60,9 +71,17 @@ public class SettlementCustomersApplicationService {
private SettlementCustomersMapper settlementCustomersMapper;
@Autowired
private SettlementCustomersImpl settlementCustomersImpl;
@Autowired
private ISettlementCustomersParametersService settlementCustomersParametersService;
@Autowired
private ISettlementCustomersNcConfigService settlementCustomersNcConfigService;
private static final int SYNC_BATCH_SIZE = 500;
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
private static final String token = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjozNTYzLCJ0b3BPcmdhbml6YXRpb25JZCI6MjgyNywidXNlcl9rZXkiOiI0N2MzY2U4My0wMmFjLTQ0NTQtOTdiYS1lYmQwMDc2MzNiNDMiLCJ1c2VybmFtZSI6ImNhbmdtYSJ9.tnZyywwburfBo3Kizdhfk5eYdXbrrZ9976Z0W7GrS6UqSpKwfI2RwdRwfYx7DbD7Ri1Fdj_eOVxBkjvdFF226Q";
@Resource
private XxlJobOpenApiUtil apiUtil;
/**
* 分页查询结算对象列表
*/
@@ -138,7 +157,38 @@ public class SettlementCustomersApplicationService {
settlementCustomersDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
settlementCustomersDO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
settlementCustomersDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
return settlementCustomersDomainService.insert(settlementCustomersDO);
Boolean insert = settlementCustomersDomainService.insert(settlementCustomersDO);
if (insert) {
List<SettlementCustomersNcConfigDTO> settlementCustomersNcConfigDTOList = settlementCustomersDO.getSettlementCustomersNcConfigs();
if (CollectionUtil.isNotEmpty(settlementCustomersNcConfigDTOList)) {
for (SettlementCustomersNcConfigDTO settlementCustomersNcConfigDTO : settlementCustomersNcConfigDTOList) {
SettlementCustomersNcConfig settlementCustomersNcConfig = new SettlementCustomersNcConfig();
settlementCustomersNcConfigDTO.setSettlementCustomersId(settlementCustomersDO.getSettlementCustomersId());
settlementCustomersNcConfigDTO.setOrganizationId(settlementCustomersDO.getOrganizationId());
settlementCustomersNcConfigDTO.setTopOrganizationId(settlementCustomersDO.getTopOrganizationId());
settlementCustomersNcConfigDTO.setOrganizationName(settlementCustomersDO.getOrganizationName());
BeanUtils.copyProperties(settlementCustomersNcConfigDTO, settlementCustomersNcConfig);
settlementCustomersNcConfigService.save(settlementCustomersNcConfig);
}
}
List<SettlementCustomersParametersDTO> settlementCustomersParametersDTOList = settlementCustomersDO.getSettlementCustomersParameters();
if (CollectionUtil.isNotEmpty(settlementCustomersParametersDTOList)) {
for (SettlementCustomersParametersDTO settlementCustomersParametersDTO : settlementCustomersParametersDTOList) {
SettlementCustomersParameters settlementCustomersParameters = new SettlementCustomersParameters();
settlementCustomersParametersDTO.setSettlementCustomersId(settlementCustomersDO.getSettlementCustomersId());
settlementCustomersParametersDTO.setOrganizationId(settlementCustomersDO.getOrganizationId());
settlementCustomersParametersDTO.setTopOrganizationId(settlementCustomersDO.getTopOrganizationId());
settlementCustomersParametersDTO.setOrganizationName(settlementCustomersDO.getOrganizationName());
settlementCustomersParametersDTO.setSettlementCustomersCode(settlementCustomersDO.getSettlementCustomersCode());
settlementCustomersParametersDTO.setSettlementEntity(settlementCustomersDO.getSettlementEntity());
settlementCustomersParametersDTO.setSettlementEntityId(settlementCustomersDO.getSettlementEntityId());
BeanUtils.copyProperties(settlementCustomersParametersDTO, settlementCustomersParameters);
settlementCustomersParametersService.save(settlementCustomersParameters);
}
}
}
return insert;
}
/**
@@ -203,6 +253,7 @@ public class SettlementCustomersApplicationService {
/**
* 修改结算对象
*/
@Transactional
public Boolean update(SettlementCustomersDO settlementCustomersDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
@@ -216,9 +267,211 @@ public class SettlementCustomersApplicationService {
}
//处理数据字典
handleDict(settlementCustomersDO);
List<SettlementCustomersNcConfigDTO> settlementCustomersNcConfigDTOList = settlementCustomersDO.getSettlementCustomersNcConfigs();
if (CollectionUtil.isNotEmpty(settlementCustomersNcConfigDTOList)) {
settlementCustomersNcConfigService.remove(new LambdaQueryWrapper<SettlementCustomersNcConfig>()
.eq(SettlementCustomersNcConfig::getSettlementCustomersId, settlementCustomersDO.getSettlementCustomersId()));
for (SettlementCustomersNcConfigDTO settlementCustomersNcConfigDTO : settlementCustomersNcConfigDTOList) {
SettlementCustomersNcConfig settlementCustomersNcConfig = new SettlementCustomersNcConfig();
settlementCustomersNcConfigDTO.setSettlementCustomersId(settlementCustomersDO.getSettlementCustomersId());
settlementCustomersNcConfigDTO.setOrganizationId(settlementCustomersDO.getOrganizationId());
settlementCustomersNcConfigDTO.setTopOrganizationId(settlementCustomersDO.getTopOrganizationId());
settlementCustomersNcConfigDTO.setOrganizationName(settlementCustomersDO.getOrganizationName());
BeanUtils.copyProperties(settlementCustomersNcConfigDTO, settlementCustomersNcConfig);
settlementCustomersNcConfigService.save(settlementCustomersNcConfig);
}
}
List<SettlementCustomersParametersDTO> settlementCustomersParametersDTOList = settlementCustomersDO.getSettlementCustomersParameters();
if (CollectionUtil.isNotEmpty(settlementCustomersParametersDTOList)) {
settlementCustomersParametersService.remove(new LambdaQueryWrapper<SettlementCustomersParameters>()
.eq(SettlementCustomersParameters::getSettlementCustomersId, settlementCustomersDO.getSettlementCustomersId()));
for (SettlementCustomersParametersDTO settlementCustomersParametersDTO : settlementCustomersParametersDTOList) {
SettlementCustomersParameters settlementCustomersParameters = new SettlementCustomersParameters();
settlementCustomersParametersDTO.setSettlementCustomersId(settlementCustomersDO.getSettlementCustomersId());
settlementCustomersParametersDTO.setOrganizationId(settlementCustomersDO.getOrganizationId());
settlementCustomersParametersDTO.setTopOrganizationId(settlementCustomersDO.getTopOrganizationId());
settlementCustomersParametersDTO.setOrganizationName(settlementCustomersDO.getOrganizationName());
settlementCustomersParametersDTO.setSettlementCustomersCode(settlementCustomersDO.getSettlementCustomersCode());
settlementCustomersParametersDTO.setSettlementEntity(settlementCustomersDO.getSettlementEntity());
settlementCustomersParametersDTO.setSettlementEntityId(settlementCustomersDO.getSettlementEntityId());
BeanUtils.copyProperties(settlementCustomersParametersDTO, settlementCustomersParameters);
Long contractManageId1 = settlementCustomersParameters.getContractManageId();
if (contractManageId1==null) {
ContractManageFeignDTO contractManageDTO = new ContractManageFeignDTO();
contractManageDTO.setSettlementCustomersCode(settlementCustomersDO.getSettlementCustomersCode());
contractManageDTO.setContractRentType("TEMP");
contractManageDTO.setContractRentTypeName("临时合同");
contractManageDTO.setOriginalContractNumber(generateHtCode());
contractManageDTO.setContractName("临时合同");
contractManageDTO.setSigningUnit(settlementCustomersDO.getOrganizationName());
contractManageDTO.setCustomerTypeCode("1");
contractManageDTO.setCommonContractFlag(2);
contractManageDTO.setSigningDate(new Date());
contractManageDTO.setEffectiveDate(new Date());
Calendar calendar = Calendar.getInstance();
calendar.set(9999, Calendar.DECEMBER, 31, 0, 0, 0);
Date date = calendar.getTime();
contractManageDTO.setExpirationDate(date);
contractManageDTO.setContractState(2);
contractManageDTO.setPaymentDate(new Date());
contractManageDTO.setBillDays(10);
contractManageDTO.setContractType(1);
AjaxResult ajaxResult = systemServiceFeign.feignSave(contractManageDTO);
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
ContractManageFeignDTO contractManageFeignDTO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), ContractManageFeignDTO.class);
Long contractManageId = contractManageFeignDTO.getContractManageId();
String originalContractNumber = contractManageFeignDTO.getOriginalContractNumber();
settlementCustomersParameters.setContractManageId(contractManageId);
settlementCustomersParameters.setContractNumber(originalContractNumber);
ContractManageParametersFeign contractManageParametersFeign = new ContractManageParametersFeign();
contractManageParametersFeign.setContractManageId(contractManageId);
contractManageParametersFeign.setContractName(contractManageFeignDTO.getContractName());
contractManageParametersFeign.setContractNumber(contractManageFeignDTO.getContractNumber());
contractManageParametersFeign.setParametersJson(settlementCustomersParametersDTO.getContent());
contractManageParametersFeign.setOrganizationId(settlementCustomersDO.getOrganizationId());
contractManageParametersFeign.setOrganizationName(settlementCustomersDO.getOrganizationName());
contractManageParametersFeign.setTopOrganizationId(settlementCustomersDO.getTopOrganizationId());
AjaxResult paramResult = systemServiceFeign.feignSaveContractParameters(contractManageParametersFeign);
if (paramResult == null || !"200".equals(String.valueOf(paramResult.get("code")))) {
throw new ServiceException("保存合同参数失败");
}
Long settlementEntityId = settlementCustomersDO.getSettlementEntityId();
if (settlementEntityId != null) {
stopXxlJob(settlementCustomersDO.getPushBillingRecordJobId());
stopXxlJob(settlementCustomersDO.getPushBillManageJobId());
//生成唯一业务流水号拼接至JobDesc保证本次新建任务的JobDesc唯一据此查询jobId不会命中历史任务
String xxlJobBizNo = generateXxlJobBizNo();
Integer jobId = addXxlJob(String.valueOf(settlementEntityId), xxlJobBizNo);
Integer jobId1 = addXxlJob1(String.valueOf(settlementEntityId), xxlJobBizNo);
settlementCustomersDO.setPushBillingRecordJobId(jobId);
settlementCustomersDO.setPushBillManageJobId(jobId1);
}
} else {
throw new ServiceException("创建临时合同失败");
}
}
settlementCustomersParametersService.save(settlementCustomersParameters);
}
}
return settlementCustomersDomainService.update(settlementCustomersDO);
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id作为任务参数
* @param bizNo 业务流水号拼接进JobDesc保证每个任务描述唯一据此精确查询本次新建的xxlJobId
* @return xxlJobId 保存到业务表后续用于删除/暂停
*/
public Integer addXxlJob(String shipperId, String bizNo) {
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(3);
req.setJobDesc("散租推送计费单据/流水任务,结算对象id:" + shipperId + ",业务流水号:" + bizNo);
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushBillingRecord");
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId,"3");
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
/**
* 创建夜间23点定时任务
* @param shipperId 结算对象id作为任务参数
* @param bizNo 业务流水号拼接进JobDesc保证每个任务描述唯一据此精确查询本次新建的xxlJobId
* @return xxlJobId 保存到业务表后续用于删除/暂停
*/
public Integer addXxlJob1(String shipperId, String bizNo) {
XxlJobOpenApiUtil.JobInfoAddReq req = new XxlJobOpenApiUtil.JobInfoAddReq();
req.setJobGroup(6);
req.setJobDesc("计费单据/流水生成发票任务,结算对象id:" + shipperId + ",业务流水号:" + bizNo);
req.setAuthor("system");
req.setAlarmEmail("");
req.setScheduleType("CRON");
// 每天晚上23点执行
req.setScheduleConf("0 0 1 * * ?");
req.setGlueType("BEAN");
req.setExecutorHandler("pushBillManage");
req.setExecutorParam(shipperId);
req.setGlueRemark("");
req.setGlueSource("");
req.setExecutorRouteStrategy("FIRST");
req.setChildJobId(null);
req.setMisfireStrategy("DO_NOTHING");
req.setExecutorBlockStrategy("SERIAL_EXECUTION");
req.setExecutorTimeout(0);
req.setExecutorFailRetryCount(0);
boolean addOk = apiUtil.addJob(req);
if (!addOk) {
throw new RuntimeException("创建夜间定时任务失败");
}
Integer xxlJobId = apiUtil.queryJobIdByDescAndParam(req.getJobDesc(), shipperId,"6");
if (xxlJobId == null) {
throw new RuntimeException("定时任务创建成功,但查询jobId失败");
}
return xxlJobId;
}
public void stopXxlJob(Integer shipperId) {
//1.实例化工具类建议交给Spring管理
XxlJobOpenApiUtil apiUtil = new XxlJobOpenApiUtil(adminAddresses,token);
//3.调用创建任务接口 返回任务ID
apiUtil.pauseJob(shipperId);
}
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyMMdd");
private static final DateTimeFormatter JOB_BIZ_NO_FORMATTER = DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");
private static final Random RANDOM = new Random();
/**
* 生成编码HT + 当天yyMMdd + 6位随机数字
* 示例HT260828123456
* @return 编码字符串
*/
public static String generateHtCode() {
// 当天yyMMdd
String dateStr = LocalDate.now().format(FORMATTER);
// 6位随机数 000000999999
int randomNum = RANDOM.nextInt(1_000_000);
String randomStr = String.format("%06d", randomNum);
return "HT" + dateStr + randomStr;
}
/**
* 生成xxl-job任务业务流水号JOB + 当天yyMMddHHmmssSSS + 6位随机数字保证每次创建的JobDesc唯一
* 示例JOB260905102030123123456
* @return 业务流水号字符串
*/
public static String generateXxlJobBizNo() {
String dateTimeStr = LocalDateTime.now().format(JOB_BIZ_NO_FORMATTER);
int randomNum = RANDOM.nextInt(1_000_000);
String randomStr = String.format("%06d", randomNum);
return "JOB" + dateTimeStr + randomStr;
}
/**
* 批量删除结算对象
*/
@@ -433,9 +686,17 @@ public class SettlementCustomersApplicationService {
? userShipperPo.getTopOrganizationId()
: loginUser.getUserPo().getTopOrganizationId());
saveEntity.setCreateTime(new Date());
saveEntity.setOrgCode(userShipperPo.getOrgCode());
return saveEntity;
}
public Boolean updatePushContractManageToBmsJobId(Long settlementCustomersId, Integer jobId) {
return settlementCustomersImpl.lambdaUpdate()
.eq(SettlementCustomers::getSettlementCustomersId, settlementCustomersId)
.set(SettlementCustomers::getPushContractManageToBmsJobId, jobId)
.update();
}
private SettlementCustomersDO buildDriverSettlementCustomerDO(UserDriverPo userDriverPo, LoginUser loginUser, Long organizationId) {
SettlementCustomersDO saveEntity = new SettlementCustomersDO();
saveEntity.setSettlementEntityId(userDriverPo.getUserId());
@@ -0,0 +1,87 @@
package com.mhd.bms.application.server.settlementCustomersNcConfig;
import cn.hutool.core.util.ObjectUtil;
import com.mhd.bms.domain.settlementCustomersNcConfig.entity.SettlementCustomersNcConfig;
import com.mhd.bms.domain.settlementCustomersNcConfig.repository.po.SettlementCustomersNcConfigPO;
import com.mhd.bms.domain.settlementCustomersNcConfig.repository.todo.SettlementCustomersNcConfigDO;
import com.mhd.bms.domain.settlementCustomersNcConfig.service.SettlementCustomersNcConfigDomainService;
import com.mhd.bms.interfaces.dto.settlementCustomersNcConfig.SettlementCustomersNcConfigDTO;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 结算对象NC配置ApplicationService
*
* @author gen
* @date 2024-06-17
*/
@Service
@Slf4j
public class SettlementCustomersNcConfigApplicationService {
@Autowired
private SettlementCustomersNcConfigDomainService settlementCustomersNcConfigDomainService;
/**
* 分页查询结算对象NC配置列表
*/
public List<SettlementCustomersNcConfigPO> queryList(SettlementCustomersNcConfigDO settlementCustomersNcConfigDO) {
return settlementCustomersNcConfigDomainService.queryList(settlementCustomersNcConfigDO);
}
/**
* 新增结算对象NC配置
*/
public Boolean insert(SettlementCustomersNcConfigDO settlementCustomersNcConfigDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
settlementCustomersNcConfigDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
settlementCustomersNcConfigDO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
settlementCustomersNcConfigDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
return settlementCustomersNcConfigDomainService.insert(settlementCustomersNcConfigDO);
}
/**
* 修改结算对象NC配置
*/
public Boolean update(SettlementCustomersNcConfigDO settlementCustomersNcConfigDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
return settlementCustomersNcConfigDomainService.update(settlementCustomersNcConfigDO);
}
/**
* 获取结算对象NC配置详细信息
*/
public SettlementCustomersNcConfigPO getInfo(Long id) {
return settlementCustomersNcConfigDomainService.getInfo(id);
}
/**
* 批量删除结算对象NC配置
*/
public Boolean deleteByIds(SettlementCustomersNcConfigDTO settlementCustomersNcConfigDTO) {
if (!StringUtils.isNotEmpty(settlementCustomersNcConfigDTO.getIds())) {
throw new ServiceException("id不能为空");
}
Set<String> idSet = Stream.of(settlementCustomersNcConfigDTO.getIds().split(",")).collect(Collectors.toSet());
Long[] ids = idSet.stream().map(Long::valueOf).toArray(Long[]::new);
return settlementCustomersNcConfigDomainService.delete(ids);
}
}
@@ -0,0 +1,94 @@
package com.mhd.bms.application.server.settlementCustomersParameters;
import cn.hutool.core.util.ObjectUtil;
import com.mhd.bms.domain.settlementCustomersParameters.entity.SettlementCustomersParameters;
import com.mhd.bms.domain.settlementCustomersParameters.repository.po.SettlementCustomersParametersPO;
import com.mhd.bms.domain.settlementCustomersParameters.repository.todo.SettlementCustomersParametersDO;
import com.mhd.bms.domain.settlementCustomersParameters.service.SettlementCustomersParametersDomainService;
import com.mhd.bms.interfaces.dto.settlementCustomersParameters.SettlementCustomersParametersDTO;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 结算对象参数ApplicationService
*
* @author gen
* @date 2024-06-17
*/
@Service
@Slf4j
public class SettlementCustomersParametersApplicationService {
@Autowired
private SettlementCustomersParametersDomainService settlementCustomersParametersDomainService;
/**
* 分页查询结算对象参数列表
*/
public List<SettlementCustomersParametersPO> queryList(SettlementCustomersParametersDO settlementCustomersParametersDO) {
return settlementCustomersParametersDomainService.queryList(settlementCustomersParametersDO);
}
/**
* 新增结算对象参数
*/
public Boolean insert(SettlementCustomersParametersDO settlementCustomersParametersDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
settlementCustomersParametersDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
settlementCustomersParametersDO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
settlementCustomersParametersDO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
return settlementCustomersParametersDomainService.insert(settlementCustomersParametersDO);
}
/**
* 修改结算对象参数
*/
public Boolean update(SettlementCustomersParametersDO settlementCustomersParametersDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
return settlementCustomersParametersDomainService.update(settlementCustomersParametersDO);
}
/**
* 获取结算对象参数详细信息
*/
public SettlementCustomersParametersPO getInfo(Long id) {
return settlementCustomersParametersDomainService.getInfo(id);
}
/**
* 批量删除结算对象参数
*/
public Boolean deleteByIds(SettlementCustomersParametersDTO settlementCustomersParametersDTO) {
if (!StringUtils.isNotEmpty(settlementCustomersParametersDTO.getIds())) {
throw new ServiceException("id不能为空");
}
Set<String> idSet = Stream.of(settlementCustomersParametersDTO.getIds().split(",")).collect(Collectors.toSet());
Long[] ids = idSet.stream().map(Long::valueOf).toArray(Long[]::new);
return settlementCustomersParametersDomainService.delete(ids);
}
/**
* 根据结算对象id查询结算对象参数列表
*/
public List<SettlementCustomersParametersPO> getListBySettlementCustomersId(Long settlementCustomersId) {
return settlementCustomersParametersDomainService.getListBySettlementCustomersId(settlementCustomersId);
}
}
@@ -47,8 +47,8 @@ public class BillManage extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.mhd.bms.domain.billManage.entity.BillManage;
import com.mhd.bms.domain.billManage.repository.po.BillManagePO;
import com.mhd.bms.domain.billManage.repository.todo.BillManageDO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import java.util.List;
@@ -20,6 +21,14 @@ public interface IBillManageService extends IService<BillManage>
*/
public List<BillManagePO> queryList(BillManageDO billManageDO);
public List<BillManagePO> customerMonthlyReport(BillManageDO billManageDO);
/**
* 客户每月账单分组查询
*/
public List<CustomerMonthBillVO> queryCustomerMonthBillList(BillManageDO billManageDO);
/**
* 新增账单管理
*/
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mhd.bms.domain.billManage.entity.BillManage;
import com.mhd.bms.domain.billManage.repository.po.BillManagePO;
import com.mhd.bms.domain.billManage.repository.todo.BillManageDO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import org.apache.ibatis.annotations.Param;
/**
* 账单管理Mapper接口
@@ -19,6 +20,13 @@ public interface BillManageMapper extends BaseMapper<BillManage>
*/
public List<BillManagePO> queryList(@Param("billManageDO") BillManageDO billManageDO);
public List<BillManagePO> customerMonthlyReport(@Param("billManageDO") BillManageDO billManageDO);
/**
* 客户每月账单分组查询
*/
public List<CustomerMonthBillVO> queryCustomerMonthBillList(@Param("billManageDO") BillManageDO billManageDO);
String getInvoiceItemName(@Param("invoiceItemId") String invoiceItemId);
String getInvoiceItemNcCode(@Param("invoiceItemId") String invoiceItemId);
@@ -31,6 +31,7 @@ import com.mhd.bms.domain.settlementCustomers.entity.SettlementCustomers;
import com.mhd.bms.domain.settlementCustomers.repository.facade.ISettlementCustomersService;
import com.mhd.bms.interfaces.dto.billManage.BillDetailDTO;
import com.mhd.bms.interfaces.dto.billManage.BillManageDTO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import com.mhd.common.core.domain.dto.ReconciliationDTO;
import com.mhd.common.core.domain.dto.nc.*;
import com.mhd.common.core.domain.entity.R;
@@ -126,6 +127,14 @@ public class BillManageImpl extends ServiceImpl<BillManageMapper, BillManage> im
return billManageMapper.queryList(billManageDO);
}
@Override
public List<BillManagePO> customerMonthlyReport(BillManageDO billManageDO)
{
return billManageMapper.customerMonthlyReport(billManageDO);
}
/**
* 新增账单管理
*/
@@ -1504,4 +1513,9 @@ public class BillManageImpl extends ServiceImpl<BillManageMapper, BillManage> im
return 0;
}
@Override
public List<CustomerMonthBillVO> queryCustomerMonthBillList(BillManageDO billManageDO) {
return billManageMapper.queryCustomerMonthBillList(billManageDO);
}
}
@@ -2,6 +2,7 @@ package com.mhd.bms.domain.billManage.repository.po;
import com.mhd.bms.domain.billManage.entity.BillDetail;
import com.mhd.bms.domain.billingStatement.repository.po.BillingStatementPO;
import com.mhd.bms.domain.receiptManage.entity.ReceiptDetail;
import com.mhd.common.core.annotation.Excel;
import lombok.Data;
import java.util.Date;
@@ -52,8 +53,8 @@ public class BillManagePO extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -262,9 +263,12 @@ public class BillManagePO extends BaseVOEntity{
@ApiModelProperty("收款帐户名称")
private String paymentAccountName;
private List<BillDetail> billDetailList;
private List<ReceiptDetail> receiptDetailList;
@ApiModelProperty("最近收款时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "最近收款时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date collectionTime;
@ApiModelProperty("合同编码")
private String contractNumbers;
}
@@ -47,8 +47,8 @@ public class BillManageDO extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -266,4 +266,7 @@ public class BillManageDO extends BaseVOEntity{
private String paymentAccountName;
@ApiModelProperty("业务员ID")
private String salesmanId;
@ApiModelProperty("账单月份(yyyy-MM,按创建时间月份筛选,用于客户月账单分组查询)")
private String billMonth;
}
@@ -12,7 +12,9 @@ import com.mhd.bms.domain.billManage.repository.facade.IBillManageService;
import com.mhd.bms.domain.billManage.repository.po.BillManagePO;
import com.mhd.bms.domain.billManage.repository.todo.BillDetailDO;
import com.mhd.bms.domain.billManage.repository.todo.BillManageDO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import com.mhd.bms.domain.billOperationLog.entity.BillOperationLog;
import com.mhd.bms.domain.billOperationLog.repository.po.BillOperationLogPO;
import com.mhd.bms.domain.billOperationLog.repository.todo.BillOperationLogDO;
import com.mhd.bms.domain.billOperationLog.service.BillOperationLogDomainService;
import com.mhd.bms.domain.billingStatement.entity.BillingStatement;
@@ -44,6 +46,7 @@ import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -85,6 +88,10 @@ public class BillManageDomainService {
return billManageService.queryList(billManageDO);
}
public List<BillManagePO> customerMonthlyReport(BillManageDO billManageDO) {
return billManageService.customerMonthlyReport(billManageDO);
}
/**
* 新增账单管理
@@ -233,6 +240,124 @@ public class BillManageDomainService {
return flag && flagTwo && three;
}
public Boolean saveBillJob(List<BillingStatementPO> billingStatementPOS,String billingRemark,Date billCreateTime,BillingStatementDTO billingStatementDTO) {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (ObjectUtil.isNull(loginUser)) {
//// throw new DigitalLogisticsException(UserError.TIMEOUT);
// }
BigDecimal taxAmount = billingStatementDTO.getTaxAmount(); // 获取税额
Double taxRate = billingStatementDTO.getTaxRate(); // 获取税率
BigDecimal taxFreeFee = billingStatementDTO.getTaxFreeFee(); // 获取税免金额
String settlementCurrency = billingStatementDTO.getSettlementCurrency(); // 获取结算币种
BillManage billManage = new BillManage();
billManage.setTaxAmount(taxAmount);
billManage.setTaxRate(taxRate);
billManage.setTaxFreeFee(taxFreeFee);
billManage.setSettlementCurrency(settlementCurrency);
// billManage.setCreateBy(loginUser.getUserPo().getUserId());
// billManage.setCreateByName(loginUser.getUserPo().getUserName());
billManage.setCreateTime(billCreateTime==null ? new Date():billCreateTime);
billManage.setDelFlag(1);
billManage.setBillNumber(OrderSequence.getOrderCode("ZD"));
billManage.setTopOrganizationId(billingStatementDTO.getTopOrganizationId());
billManage.setOrganizationId(billingStatementDTO.getOrganizationId());
billManage.setOrganizationName(billingStatementDTO.getOrganizationName());
billManage.setBillType(billingStatementPOS.get(0).getAccountExpenseType());
billManage.setBelongModule(billingStatementPOS.get(0).getBelongModule());
billManage.setBelongModuleCode(billingStatementPOS.get(0).getBelongModuleCode());
billManage.setSettlementCustomersId(billingStatementPOS.get(0).getSettlementCustomersId());
billManage.setSettlementEntity(billingStatementPOS.get(0).getSettlementEntity());
billManage.setSettlementCustomersCode(billingStatementPOS.get(0).getSettlementCustomersCode());
billManage.setSalesmanId(billingStatementPOS.get(0).getSalesmanId());
billManage.setSalesmanName(billingStatementPOS.get(0).getSalesmanName());
billManage.setPaymentAccountId(billingStatementPOS.get(0).getPaymentAccountId());
billManage.setPaymentAccountName(billingStatementPOS.get(0).getPaymentAccountName());
billManage.setBillRemark(billingRemark);
//查询结算对象信息
SettlementCustomersPO settlementCustomersPO = settlementCustomersDomainService.getInfo(billingStatementPOS.get(0).getSettlementCustomersId());
if(null == settlementCustomersPO){
throw new ServiceException("结算对象信息未找到");
}
billManage.setSettlementMethod(settlementCustomersPO.getSettlementMethod());
billManage.setSettlementMethodCode(settlementCustomersPO.getSettlementMethodCode());
// if(settlementCustomersPO.getMainRole()==1){
// billManage.setBillType(1);
// }else {
// billManage.setBillType(2);
// }
//计算所有流水列表中的最早周期开始时间和晚周期结束时间
List<Date> cycleBeginTimeSet = billingStatementPOS.stream().map(BillingStatementPO::getCycleBeginTime).collect(Collectors.toList());
List<Date> cycleEndTimeSet = billingStatementPOS.stream().map(BillingStatementPO::getCycleEndTime).collect(Collectors.toList());
cycleBeginTimeSet.removeIf(Objects::isNull);
cycleEndTimeSet.removeIf(Objects::isNull);
if(cycleBeginTimeSet.size()>0){
billManage.setCycleBeginTime(Collections.min(cycleBeginTimeSet));
}
if(cycleEndTimeSet.size()>0){
billManage.setCycleEndTime(Collections.max(cycleEndTimeSet));
}
//将所有的流水金额相加
billManage.setBillTotalAmount(billingStatementPOS.stream().map(BillingStatementPO::getBillingAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
billManage.setBillAmount(billManage.getBillTotalAmount());
billManage.setBillAmountUnsettled(billManage.getBillTotalAmount());
boolean flag = billManageService.save(billManage);
billingStatementDTO.setBillManageId(billManage.getBillManageId());
List<BillDetail> billDetailList = new ArrayList<>();
for (BillingStatementPO billingStatementPO : billingStatementPOS) {
//生成对账单详情
BillDetail billDetail = new BillDetail();
billDetail.setTopOrganizationId(billingStatementPO.getTopOrganizationId());
billDetail.setOrganizationId(billingStatementPO.getOrganizationId());
billDetail.setOrganizationName(billingStatementPO.getOrganizationName());
billDetail.setCreateBy(billManage.getCreateBy());
billDetail.setCreateByName(billManage.getCreateByName());
billDetail.setCreateTime(billManage.getCreateTime());
billDetail.setBillManageId(billManage.getBillManageId());
billDetail.setBillNumber(billManage.getBillNumber());
billDetail.setBillingStatementId(billingStatementPO.getBillingStatementId());
billDetail.setBillingFlow(billingStatementPO.getBillingFlow());
billDetail.setBillingTotalAmount(billingStatementPO.getBillingAmount());
billDetail.setBillingAmount(billingStatementPO.getBillingAmount());
billDetail.setBillType(billingStatementPO.getAccountExpenseType());
billDetail.setTaxAmount(billingStatementPO.getTaxAmount());
billDetail.setTaxRate(billingStatementPO.getTaxRate());
billDetail.setTaxFreeFee(billingStatementPO.getTaxFreeFee());
billDetail.setSettlementCurrency(billingStatementPO.getSettlementCurrency());
billDetail.setFeeType(billingStatementPO.getFeeType());
billDetail.setInvoiceItem(billingStatementPO.getInvoiceItem());
billDetail.setInvoiceItemName(billingStatementPO.getInvoiceItemName());
billDetailList.add(billDetail);
}
boolean flagTwo = billDetailDomainService.insertBatch(billDetailList);
//保存账单操作记录
BillOperationLogDO billOperationLogDO = new BillOperationLogDO();
billOperationLogDO.setBillManageId(billManage.getBillManageId());
billOperationLogDO.setOperationInfo(StringUtils.format(BillLogsConstants.create_bill_text, billManage.getBillNumber(), billManage.getBillTotalAmount()));
billOperationLogDO.setOperationType(1);
billOperationLogDO.setCreateByName(billManage.getCreateByName());
billOperationLogDO.setUpdateByName(billManage.getUpdateByName());
billOperationLogDO.setCreateTime(new Date());
billOperationLogDO.setUpdateTime(new Date());
billOperationLogDO.setDelFlag(1);
billOperationLogDO.setCreateBy(billManage.getCreateBy());
billOperationLogDO.setUpdateBy(billManage.getUpdateBy());
billOperationLogDO.setTopOrganizationId(billManage.getTopOrganizationId());
billOperationLogDO.setOrganizationId(billManage.getOrganizationId());
billOperationLogDO.setOrganizationName(billManage.getOrganizationName());
boolean three = billOperationLogDomainService.saveBillOperationLogJob(billOperationLogDO);
//修改流水记录
/*billingStatementDTO.getBillingStatementList().forEach(billingStatementADDVO -> {
billingStatementMapper.update(null,
new LambdaUpdateWrapper<BillingStatement>().set(BillingStatement::getTaxAmount,billingStatementADDVO.getTaxAmount())
.set(BillingStatement::getTaxRate,billingStatementADDVO.getTaxRate())
.set(BillingStatement::getTaxFreeFee,billingStatementADDVO.getTaxFreeFee())
.set(BillingStatement::getSettlementCurrency,billingStatementADDVO.getSettlementCurrency())
.eq(BillingStatement::getBillingStatementId,billingStatementADDVO.getBillingStatementId()));
});*/
return flag && flagTwo && three;
}
/**
* 保存账单
* @param billingStatementDTO
@@ -296,6 +421,64 @@ public class BillManageDomainService {
return saveBill(distinctList,billingStatementDTO.getBillingRemark(),billingStatementDTO.getBillCreateTime(),billingStatementDTO);
}
public Boolean saveJob(BillingStatementDTO billingStatementDTO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
// throw new DigitalLogisticsException(UserError.TIMEOUT);
}
//根据前端传的流水id查询计费流水信息列表
Set<String> billingSet = Stream.of(billingStatementDTO.getBillingStatementIds().split(",")).collect(Collectors.toSet());
BillingStatementDO billingStatementDO = new BillingStatementDO();
billingStatementDO.setBillingStatementIdSet(billingSet);
List<BillingStatementPO> billingStatementPOS = billingStatementDomainService.queryList(billingStatementDO);
//获取最新一条的业务员信息
String salesmanId = null;
String salesmanName = null;
if (billingStatementPOS != null && !billingStatementPOS.isEmpty()) {
billingStatementPOS.sort((a, b) -> {
if (a.getCreateTime() == null && b.getCreateTime() == null) return 0;
if (a.getCreateTime() == null) return 1;
if (b.getCreateTime() == null) return -1;
return b.getCreateTime().compareTo(a.getCreateTime());
});
salesmanId = billingStatementPOS.get(0).getSalesmanId();
salesmanName = billingStatementPOS.get(0).getSalesmanName();
}
List<BillingStatementADDVO> billingStatementList = billingStatementDTO.getBillingStatementList();
for (BillingStatementPO billingStatementPO : billingStatementPOS) {
String billingStatementId = billingStatementPO.getBillingStatementId() == null ? "" : String.valueOf(billingStatementPO.getBillingStatementId());
BillingStatementADDVO billingStatementADDVO = billingStatementList.stream().filter(billingStatementADDVO1 -> billingStatementADDVO1.getBillingStatementId().contains(billingStatementId)).findFirst().orElse(null);
billingStatementPO.setTaxAmount(billingStatementADDVO.getTaxAmount()); // 设置税额
billingStatementPO.setTaxRate(billingStatementADDVO.getTaxRate()); // 设置税率
billingStatementPO.setTaxFreeFee(billingStatementADDVO.getTaxFreeFee()); // 设置税免金额
billingStatementPO.setSettlementCurrency(billingStatementADDVO.getSettlementCurrency());//设置结算币种
billingStatementPO.setFeeType(billingStatementADDVO.getFeeType());
billingStatementPO.setInvoiceItem(billingStatementADDVO.getInvoiceItem());
billingStatementPO.setInvoiceItemName(billingStatementADDVO.getInvoiceItemName());
billingStatementPO.setBillingAmount(billingStatementADDVO.getBillingAmount());
billingStatementPO.setBillingStatementIdStr(billingStatementADDVO.getBillingStatementId());
if (salesmanName != null && !salesmanName.isEmpty() && salesmanId != null && !salesmanId.isEmpty()) {
billingStatementPO.setSalesmanId(salesmanId);
billingStatementPO.setSalesmanName(salesmanName);
}
}
List<BillingStatementPO> distinctList = billingStatementPOS.stream()
.filter(Objects::nonNull)
.collect(Collectors.toMap(
BillingStatementPO::getBillingStatementIdStr, // key去重字段
po -> po, // value对象本身
(existing, replacement) -> existing // 重复时保留第一个
))
.values()
.stream().collect(Collectors.toList());
if(billingStatementPOS==null || billingStatementPOS.size()==0){
throw new ServiceException("所选流水信息未找到");
}
return saveBillJob(distinctList,billingStatementDTO.getBillingRemark(),billingStatementDTO.getBillCreateTime(),billingStatementDTO);
}
public List<BillManage> queryListLambda(LambdaQueryWrapper<BillManage> queryWrapper) {
return billManageService.list(queryWrapper);
@@ -378,6 +561,32 @@ public class BillManageDomainService {
return flag && three;
}
public Boolean confirmBillingJob(BillManageDO billManageDO) {
//直接修改状态到未收款3状态
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (ObjectUtil.isNull(loginUser)) {
// throw new DigitalLogisticsException(UserError.TIMEOUT);
// }
LambdaUpdateWrapper<BillManage> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(BillManage::getBillManageId,billManageDO.getBillManageIdSet())
.set(BillManage::getBillStep,4)
.set(BillManage::getBillState,3)
// .set(BillManage::getUpdateBy,loginUser.getUserPo().getUserId())
// .set(BillManage::getUpdateByName,loginUser.getUserPo().getUserName())
.set(BillManage::getUpdateTime,new Date());
boolean flag = billManageService.update(updateWrapper);
//保存账单操作记录
BillOperationLogDO billOperationLogDO = new BillOperationLogDO();
billOperationLogDO.setBillManageIdSet(billManageDO.getBillManageIdSet());
billOperationLogDO.setOperationInfo(BillLogsConstants.confirm_bill_text);
billOperationLogDO.setOperationType(3);
billOperationLogDO.setOrganizationId(billManageDO.getOrganizationId());
billOperationLogDO.setOrganizationName(billManageDO.getOrganizationName());
billOperationLogDO.setTopOrganizationId(billManageDO.getTopOrganizationId());
boolean three = billOperationLogDomainService.saveBillOperationLogBatchJob(billOperationLogDO);
return flag && three;
}
public int editIsInvoice(String billNumber, Integer isInvoice, String invoiceId, String invoiceMakeTime,String applyNumber)
{
@@ -504,6 +713,261 @@ public class BillManageDomainService {
}
/**
* 撤销收款账单恢复为收款为0状态并保存撤销收款操作日志
*/
public Boolean cancelCollectionInfo(List<ReceiptDetail> receiptDetails) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
//按账单分组收款明细一个账单可能对应多个收款单
Map<Long, List<ReceiptDetail>> billDetailMap = receiptDetails.stream().collect(Collectors.groupingBy(ReceiptDetail::getBillManageId));
LambdaQueryWrapper<BillManage> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(BillManage::getBillManageId,billDetailMap.keySet());
List<BillManage> billManageList = billManageService.list(queryWrapper);
if(billManageList == null || billManageList.size()==0){
throw new ServiceException("账单信息未找到");
}
List<BillManage> billManageListSave = new ArrayList<>();
List<BillOperationLog> billOperationLogSave = new ArrayList<>();
for (BillManage billManage : billManageList) {
List<ReceiptDetail> receiptDetailList = billDetailMap.get(billManage.getBillManageId());
if(null == receiptDetailList || receiptDetailList.size() == 0){
continue;
}
BillManage billManageSave = new BillManage();
billManageSave.setBillManageId(billManage.getBillManageId());
//账单恢复为收款为0状态
billManageSave.setBillAmountSettlement(BigDecimal.ZERO);
billManageSave.setBillAmountUnsettled(billManage.getBillAmount());
billManageSave.setActualReceivedAmount(BigDecimal.ZERO);
billManageSave.setSettlementDiscountsAmount(BigDecimal.ZERO);
billManageSave.setBillState(3);
billManageSave.setUpdateBy(loginUser.getUserPo().getUserId());
billManageSave.setUpdateByName(loginUser.getUserPo().getUserName());
billManageSave.setUpdateTime(new Date());
billManageListSave.add(billManageSave);
//汇总该账单本次撤销的收款金额与收款单号
BigDecimal collectedDiscount = receiptDetailList.stream().map(info -> info.getCollectedDiscount() == null ? BigDecimal.ZERO : info.getCollectedDiscount()).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal collectedAmount = receiptDetailList.stream().map(info -> info.getCollectedAmount() == null ? BigDecimal.ZERO : info.getCollectedAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal all = collectedAmount.add(collectedDiscount);
String collectionNums = receiptDetailList.stream().map(ReceiptDetail::getCollectionNum).filter(StringUtils::isNotEmpty).distinct().collect(Collectors.joining(","));
//保存账单操作记录
BillOperationLog billOperationLog = new BillOperationLog();
billOperationLog.setBillManageId(billManage.getBillManageId());
billOperationLog.setOperationInfo(StringUtils.format(BillLogsConstants.cancel_collection_bill_text,collectionNums,all,collectedAmount,collectedDiscount));
billOperationLog.setOperationType(12);
billOperationLog.setDelFlag(1);
billOperationLogSave.add(billOperationLog);
}
Boolean three = billOperationLogDomainService.insertBatch(billOperationLogSave);
Boolean flag = billManageService.updateBatchById(billManageListSave);
return flag && three;
}
/**
* 应收账单红冲生成金额为负数的红冲账单对冲原账单不操作收款单等数据支持批量
*/
public Boolean redFlushBill(BillManageDTO billManageDTO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
if (StringUtils.isEmpty(billManageDTO.getBillManageIds())) {
throw new ServiceException("账单id不能为空");
}
Set<Long> billManageIdSet = Stream.of(billManageDTO.getBillManageIds().split(",")).filter(StringUtils::isNotEmpty).map(String::trim).map(Long::valueOf).collect(Collectors.toSet());
if (billManageIdSet.size() == 0) {
throw new ServiceException("账单id不能为空");
}
//查询账单信息
LambdaQueryWrapper<BillManage> queryWrapperBill = new LambdaQueryWrapper<>();
queryWrapperBill.in(BillManage::getBillManageId, billManageIdSet);
queryWrapperBill.eq(BillManage::getDelFlag, 1);
List<BillManage> billManageList = billManageService.list(queryWrapperBill);
if (null == billManageList || billManageList.size() == 0) {
throw new ServiceException("账单信息未找到");
}
if (billManageList.size() != billManageIdSet.size()) {
throw new ServiceException("部分账单信息未找到,请刷新后重试");
}
//逐个账单红冲任一账单校验不通过时事务整体回滚
Boolean flag = true;
for (BillManage originalBill : billManageList) {
flag = redFlushSingleBill(originalBill, billManageDTO.getRedFlushRemark(), loginUser) && flag;
}
return flag;
}
/**
* 红冲单个账单生成金额为负数的红冲账单对冲原账单同步镜像计费流水与账单明细
*/
private Boolean redFlushSingleBill(BillManage originalBill, String redFlushRemark, LoginUser loginUser) {
if (ObjectUtil.equal(originalBill.getBillType(), 2)) {
throw new ServiceException("账单" + originalBill.getBillNumber() + "为付款账单,仅支持应收账单红冲");
}
if (!ObjectUtil.equal(originalBill.getBillState(), 5)) {
throw new ServiceException("账单" + originalBill.getBillNumber() + "不是已收款状态,仅已收款状态的账单可以红冲,请刷新后重试");
}
//校验账单是否已红冲避免重复生成红冲账单
BillOperationLogDO redFlushLogQuery = new BillOperationLogDO();
redFlushLogQuery.setBillManageId(originalBill.getBillManageId());
redFlushLogQuery.setOperationType(13);
List<BillOperationLogPO> redFlushLogList = billOperationLogDomainService.queryList(redFlushLogQuery);
if (null != redFlushLogList && redFlushLogList.stream().anyMatch(info -> ObjectUtil.equal(info.getDelFlag(), 1))) {
throw new ServiceException("账单" + originalBill.getBillNumber() + "已红冲,不能重复红冲");
}
//生成红冲账单编号
String billNumber = OrderSequence.getOrderCode("ZD");
BigDecimal redFlushAmount = negateAmount(originalBill.getBillAmount());
//构建红冲账单金额全部取负对冲原账单
BillManage redBill = new BillManage();
BeanUtils.copyProperties(originalBill, redBill);
redBill.setBillManageId(null);
redBill.setBillNumber(billNumber);
redBill.setBillAmount(redFlushAmount);
redBill.setBillTotalAmount(negateAmount(originalBill.getBillTotalAmount()));
redBill.setBillDiscountAmount(negateAmount(originalBill.getBillDiscountAmount()));
redBill.setBillAmountSettlement(negateAmount(originalBill.getBillAmountSettlement()));
redBill.setBillAmountUnsettled(BigDecimal.ZERO);
redBill.setActualReceivedAmount(negateAmount(originalBill.getActualReceivedAmount()));
redBill.setSettlementDiscountsAmount(negateAmount(originalBill.getSettlementDiscountsAmount()));
redBill.setTaxAmount(negateAmount(originalBill.getTaxAmount()));
redBill.setTaxFreeFee(negateAmount(originalBill.getTaxFreeFee()));
//红冲账单状态为红冲已核对无误
redBill.setBillState(8);
redBill.setBillStep(4);
redBill.setReconciliationStatus(4);
redBill.setSettlementTime(new Date());
//重置对账审核开票同步等状态红冲账单不需要再走这些流程
redBill.setBillExpectedAmount(null);
redBill.setReconciliationOpinion(null);
redBill.setVoucherAddress(null);
redBill.setFinancialReviewFlag(null);
redBill.setFinancialReviewOpinion(null);
redBill.setIsInvoice(0);
redBill.setInvoiceId(null);
redBill.setInvoiceMakeTime(null);
redBill.setApplyNumber(null);
redBill.setSynchronousStatus(0);
redBill.setSynchronousTime(null);
redBill.setNcId(null);
redBill.setSkSynchronousStatus(0);
redBill.setSkSynchronousTime(null);
redBill.setSkNcId(null);
//红冲原因写入账单备注
String billRemark = "红冲原账单编号:" + originalBill.getBillNumber();
if (StringUtils.isNotEmpty(redFlushRemark)) {
billRemark = billRemark + ",红冲原因:" + redFlushRemark;
}
redBill.setBillRemark(billRemark);
redBill.setDelFlag(1);
redBill.setCreateBy(loginUser.getUserid());
redBill.setCreateByName(loginUser.getUserPo().getUserName());
redBill.setCreateTime(new Date());
redBill.setUpdateBy(loginUser.getUserid());
redBill.setUpdateByName(loginUser.getUserPo().getUserName());
redBill.setUpdateTime(new Date());
Boolean flag = billManageService.save(redBill);
if (!flag || null == redBill.getBillManageId()) {
throw new ServiceException("生成红冲账单失败");
}
//镜像红冲计费流水金额取负并记录原流水id与新流水的映射
Map<Long, BillingStatementDO> statementMapping = new HashMap<>();
List<BillingStatementPO> originalStatementList = billingStatementDomainService.getDetailsByManageId(originalBill.getBillManageId());
if (null != originalStatementList && originalStatementList.size() > 0) {
for (BillingStatementPO originalStatement : originalStatementList) {
BillingStatementDO redStatement = new BillingStatementDO();
BeanUtils.copyProperties(originalStatement, redStatement);
redStatement.setBillingStatementId(null);
redStatement.setBillManageId(redBill.getBillManageId());
redStatement.setBillingFlow(OrderSequence.getOrderCode("JFLS"));
redStatement.setBillingAmount(negateAmount(originalStatement.getBillingAmount()));
redStatement.setTaxAmount(negateAmount(originalStatement.getTaxAmount()));
redStatement.setTaxFreeFee(negateAmount(originalStatement.getTaxFreeFee()));
redStatement.setBillingState(3);
redStatement.setRedFlushState(1);
redStatement.setRedFlushRemark("红冲自计费流水:" + originalStatement.getBillingFlow());
redStatement.setReviewRemarks(null);
redStatement.setBusinessDocumentId(null);
redStatement.setDelFlag(1);
redStatement.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
redStatement.setOrganizationId(loginUser.getUserPo().getOrganizationId());
redStatement.setOrganizationName(loginUser.getUserPo().getOrganizationName());
redStatement.setCreateBy(loginUser.getUserid());
redStatement.setCreateByName(loginUser.getUserPo().getUserName());
redStatement.setCreateTime(new Date());
redStatement.setUpdateBy(loginUser.getUserid());
redStatement.setUpdateByName(loginUser.getUserPo().getUserName());
redStatement.setUpdateTime(new Date());
redStatement.setBillingStatementId(billingStatementDomainService.insertAndReturnId(redStatement));
statementMapping.put(originalStatement.getBillingStatementId(), redStatement);
}
}
//镜像红冲账单明细金额取负并关联新计费流水
Boolean flagTwo = true;
LambdaQueryWrapper<BillDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
detailQueryWrapper.eq(BillDetail::getBillManageId, originalBill.getBillManageId());
detailQueryWrapper.eq(BillDetail::getDelFlag, 1);
List<BillDetail> originalDetailList = billDetailDomainService.queryByLambda(detailQueryWrapper);
if (null != originalDetailList && originalDetailList.size() > 0) {
List<BillDetail> redDetailList = new ArrayList<>();
for (BillDetail originalDetail : originalDetailList) {
BillDetail redDetail = new BillDetail();
BeanUtils.copyProperties(originalDetail, redDetail);
redDetail.setBillDetailId(null);
redDetail.setBillManageId(redBill.getBillManageId());
redDetail.setBillNumber(billNumber);
redDetail.setBillingTotalAmount(negateAmount(originalDetail.getBillingTotalAmount()));
redDetail.setBillingAmount(negateAmount(originalDetail.getBillingAmount()));
redDetail.setBillingDiscountAmount(negateAmount(originalDetail.getBillingDiscountAmount()));
redDetail.setTaxAmount(negateAmount(originalDetail.getTaxAmount()));
redDetail.setTaxFreeFee(negateAmount(originalDetail.getTaxFreeFee()));
redDetail.setBillingExpectedAmount(null);
BillingStatementDO redStatement = statementMapping.get(originalDetail.getBillingStatementId());
if (null != redStatement) {
redDetail.setBillingStatementId(redStatement.getBillingStatementId());
redDetail.setBillingFlow(redStatement.getBillingFlow());
} else {
redDetail.setBillingStatementId(null);
redDetail.setBillingFlow(null);
}
redDetail.setDelFlag(1);
redDetail.setCreateBy(loginUser.getUserid());
redDetail.setCreateByName(loginUser.getUserPo().getUserName());
redDetail.setCreateTime(new Date());
redDetail.setUpdateBy(loginUser.getUserid());
redDetail.setUpdateByName(loginUser.getUserPo().getUserName());
redDetail.setUpdateTime(new Date());
redDetailList.add(redDetail);
}
flagTwo = billDetailDomainService.insertBatch(redDetailList);
}
//红冲账单保存创建账单操作日志
BillOperationLogDO redBillLog = new BillOperationLogDO();
redBillLog.setBillManageId(redBill.getBillManageId());
redBillLog.setOperationInfo(StringUtils.format(BillLogsConstants.create_bill_text, billNumber, redFlushAmount));
redBillLog.setOperationType(1);
Boolean flagThree = billOperationLogDomainService.saveBillOperationLog(redBillLog);
//原账单保存红冲操作日志
BillOperationLogDO originalBillLog = new BillOperationLogDO();
originalBillLog.setBillManageId(originalBill.getBillManageId());
originalBillLog.setOperationInfo(StringUtils.format(BillLogsConstants.red_flush_bill_text, billNumber, null == redFlushAmount ? BigDecimal.ZERO : redFlushAmount.abs()));
originalBillLog.setOperationType(13);
Boolean flagFour = billOperationLogDomainService.saveBillOperationLog(originalBillLog);
return flag && flagTwo && flagThree && flagFour;
}
/**
* 金额取负空值返回null
*/
private BigDecimal negateAmount(BigDecimal amount) {
return null == amount ? null : amount.negate();
}
/**
* 更改账单状态付款
*/
@@ -600,4 +1064,11 @@ public class BillManageDomainService {
{
return billManageService.synchronousNcSK(businessDocumentDetaliIds);
}
/**
* 客户每月账单分组查询
*/
public List<CustomerMonthBillVO> queryCustomerMonthBillList(BillManageDO billManageDO) {
return billManageService.queryCustomerMonthBillList(billManageDO);
}
}
@@ -42,8 +42,8 @@ public class BillOperationLog extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -41,8 +41,8 @@ public class BillOperationLogPO extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -42,8 +42,8 @@ public class BillOperationLogDO extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -95,6 +95,12 @@ public class BillOperationLogDomainService {
return billOperationLogService.insert(billOperationLogDO);
}
public Boolean saveBillOperationLogJob(BillOperationLogDO billOperationLogDO) {
billOperationLogDO.setDelFlag(1);
return billOperationLogService.insert(billOperationLogDO);
}
/**
* 批量保存操作日志
@@ -133,6 +139,40 @@ public class BillOperationLogDomainService {
return billOperationLogService.saveBatch(saveList);
}
public Boolean saveBillOperationLogBatchJob(BillOperationLogDO billOperationLogDO) {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (ObjectUtil.isNull(loginUser)) {
// throw new DigitalLogisticsException(UserError.TIMEOUT);
// }
if(billOperationLogDO.getBillManageIdSet()==null || billOperationLogDO.getBillManageIdSet().size()==0){
throw new ServiceException("账单集合不能为空");
}
// String userName = loginUser.getUserPo().getUserName();
// // 获取登录人id
// Long userId = loginUser.getUserid();
BillOperationLogDO common = new BillOperationLogDO();
// common.setCreateByName(userName);
// common.setUpdateByName(userName);
common.setCreateTime(new Date());
common.setUpdateTime(new Date());
common.setDelFlag(1);
// common.setCreateBy(userId);
// common.setUpdateBy(userId);
// common.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
// common.setOrganizationId(loginUser.getUserPo().getOrganizationId());
// common.setOrganizationName(loginUser.getUserPo().getOrganizationName());
common.setOperationType(billOperationLogDO.getOperationType());
common.setOperationInfo(billOperationLogDO.getOperationInfo());
List<BillOperationLog> saveList = new ArrayList<>();
for (String billManageId : billOperationLogDO.getBillManageIdSet()) {
BillOperationLog save = new BillOperationLog();
BeanUtils.copyProperties(common, save);
save.setBillManageId(Long.valueOf(billManageId));
saveList.add(save);
}
return billOperationLogService.saveBatch(saveList);
}
/**
* 批量保存数据
@@ -161,4 +201,4 @@ public class BillOperationLogDomainService {
public List<BillOperationLogPO> getDetailsById(Long billManageId) {
return billOperationLogService.getDetailsById(billManageId);
}
}
}
@@ -222,4 +222,7 @@ public class BillingStatement extends BaseVOEntity{
private BigDecimal billingUnitPrice;
@ApiModelProperty("nc科目编码")
private String ncSubjectCode;
@ApiModelProperty("仓储单号")
private String wmsNumber;
}

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