Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/UserServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteUserFeignFallbackFactory.java
This commit is contained in:
秦鸿展
2026-06-05 16:44:23 +08:00
799 changed files with 29955 additions and 3189 deletions
@@ -35,6 +35,13 @@ public interface BmsServiceFeign {
@GetMapping("/settlementCustomersApi/getInfoByCode")
public AjaxResult getCustomersInfoByCode(@RequestParam("settlementCustomersCode")String settlementCustomersCode);
/**
* 按结算主体ID(如货主ID,对应 settlement_customers.settlement_entity_id)查询结算对象
*/
@GetMapping("/settlementCustomersApi/getInfoBySettlementEntityId")
AjaxResult getCustomersInfoBySettlementEntityId(@RequestParam("settlementEntityId") Long settlementEntityId,
@RequestParam(value = "topOrganizationId", required = false) Long topOrganizationId);
/**
* 推送同步业务单据
@@ -8,10 +8,14 @@ import com.mhd.system.api.factory.RemoteOmsFeignFallbackFactory;
import com.mhd.system.api.feign.FeignAutoConfiguration;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
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;
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.4:8017", configuration = FeignAutoConfiguration.class)
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)
public interface OmsServiceFeign {
@@ -33,10 +37,24 @@ public interface OmsServiceFeign {
public AjaxResult pushOutOrderDetail(@RequestBody OutMaterialDetailTZPD outMaterialDetail);
@ApiOperation("编辑物料库存")
@PostMapping("/materialInventoryApi/omsEdit")
public AjaxResult omsEdit(@RequestBody MaterialInventoryOmsParamDO materialInventoryOmsParamDO);
@PostMapping("/reservationMaterialInventoryApi/omsEdit")
@Async
public CompletableFuture<Void> omsEdit(@RequestBody MaterialInventoryOmsParamDO materialInventoryOmsParamDO);
@ApiOperation("库存调整记录插入")
@PostMapping("/reservationInventoryAdjustmentRecordApi/edit")
AjaxResult inventoryAdjustmentRecordInsert(InventoryAdjustmentRecord inventoryAdjustmentRecord);
@ApiOperation("查询企业单位列表-新增物料时显示下拉框数据")
@GetMapping("/erpEnterpriseUnitApi/unitList")
public AjaxResult getUnitList(ErpEnterpriseUnitDTO erpEnterpriseUnitDTO);
//查询企业国别列表-新增物料时显示下拉框数据
@ApiOperation("查询企业国别列表-新增物料时显示下拉框数据")
@GetMapping("/erpCountryApi/countryList")
public AjaxResult getCountryList(ErpCountryDTO erpCountryDTO);
@ApiOperation("保存gwlog")
@PostMapping("/gwLogApi/saveGwLog")
AjaxResult insertGwLog(@RequestBody GwLogDTO gwLogDTO);
@ApiOperation("修改gwlog")
@PostMapping("/gwLogApi/updateGwLog")
AjaxResult updateGwLog(@RequestBody GwLogDTO gwLogDTO);
}
@@ -9,15 +9,19 @@ import com.mhd.common.core.domain.dto.UserDriverDTO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.todo.StatisticalMattersDo;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.system.api.domain.UserDTO;
import com.mhd.system.api.domain.UserShipperQueryDTO;
import com.mhd.system.api.domain.UserUpdateDTO;
import com.mhd.system.api.factory.RemoteUserFeignFallbackFactory;
import com.mhd.system.api.feign.FeignAutoConfiguration;
import com.mhd.system.api.model.LoginUser;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -201,15 +205,16 @@ public interface UserServiceFeign {
@ApiOperation("商业合作伙伴-分页查询托运人列表")
@GetMapping("/userShipperApi/userShipperList")
public AjaxResult<?> userShipperList(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
@RequestParam(value = "userAccount", required = false) String userAccount,
@RequestParam(value = "shipperEnterpriseName", required = false) String shipperEnterpriseName,
@RequestParam(value = "organizationId", required = false) Long organizationId,
@RequestParam(value = "organizationName", required = false) String organizationName,
@RequestParam(value = "createTimeFrom", required = false) String createTimeFrom,
@RequestParam(value = "createTimeTo", required = false) String createTimeTo,
@RequestParam(value = "updateTimeFrom", required = false) String updateTimeFrom,
@RequestParam(value = "updateTimeTo", required = false) String updateTimeTo,
@RequestParam(value = "shipperType", required = false) Integer shipperType);
public TableDataInfo userShipperList(@SpringQueryMap UserShipperQueryDTO userShipperQueryDTO);
@PostMapping("/userShipperApi/updatePushStatus")
public AjaxResult<?> updatePushStatus(@RequestParam(value = "shipperId") Long shipperId,
@RequestParam(value = "pushStatus", required = false) Integer pushStatus,
@RequestParam(value = "pushTime", required = false) String pushTime,
@RequestParam(value = "pushBy", required = false) Long pushBy,
@RequestParam(value = "pushByName", required = false) String pushByName);
@PostMapping("/userShipperApi/getCustomerNcCodeBatch")
AjaxResult getCustomerNcCodeBatch(@RequestBody List<Long> shipperIdList);
}
@@ -26,7 +26,7 @@ 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.5:8014",configuration = FeignAutoConfiguration.class)
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.102.192.30:8014",configuration = FeignAutoConfiguration.class)
public interface WlhyServiceFeign {
/**
@@ -538,4 +538,19 @@ public interface WlhyServiceFeign {
@GetMapping("/feign/order/cancelIssueDocuments")
public AjaxResult cancelIssueDocuments(@RequestParam(name="executeOrderId") String executeOrderId);
@GetMapping(value = "/ntocc/tmsSettlementExchangeRate/queryList")
public AjaxResult<?> queryList(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
@RequestParam(name="pushStatus", required = false) String pushStatus,
@RequestParam(name="organizationId", required = false) String organizationId);
@ApiOperation("汇率-更新推送状态")
@PostMapping("/ntocc/tmsSettlementExchangeRate/updatePushStatus")
void updateExchangeRatePushStatus(@RequestParam("id") String id,
@RequestParam("pushStatus") Integer pushStatus,
@RequestParam(name="pushTime",required = false) String pushTime,
@RequestParam(name="pushBy",required = false) Long pushBy,
@RequestParam(name="pushByName",required = false) String pushByName);
}
@@ -2,6 +2,7 @@ package com.mhd.system.api;
import com.mhd.common.core.constant.ServiceNameConstants;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.system.api.domain.*;
import com.mhd.system.api.factory.RemoteWmsFallbackFactory;
import com.mhd.system.api.feign.FeignAutoConfiguration;
@@ -81,6 +82,13 @@ public interface WmsServiceFeign {
@PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDetail")
public void omsOutOrderAddDetail(@RequestBody List<OutMaterialDetail> outMaterialDetails);
/**
* oms下发单明细保存
*/
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDeliveryDetailsLink")
public void omsOutOrderAddDeliveryDetailsLink(@RequestBody List<DeliveryDetailsLink> deliveryDetailsLinks);
/**
* oms下发单保存
@@ -95,4 +103,16 @@ public interface WmsServiceFeign {
@ApiOperation("oms下发单明细保存")
@PostMapping(value = "/stockInOrderApi/omsInOrderAddDetail")
public void omsInOrderAddDetail(@RequestBody List<InMaterialDetail> inMaterialDetails);
@ApiOperation("oms查询物料列表")
@GetMapping("/materialBaseInfoApi/queryList")
public TableDataInfo getMaterialBaseInfoList(MaterialInfoDTO materialInfoDTO);
@ApiOperation("oms物料列表推送-更新推送信息")
@PostMapping("/materialBaseInfoApi/updatePushStatus")
public AjaxResult<?> updateMaterialPushStatus(@RequestParam("materialBaseInfoId") Long materialBaseInfoId,
@RequestParam("pushStatus") Integer pushStatus,
@RequestParam(value = "pushTime",required = false) String pushTime,
@RequestParam(value = "pushBy",required = false) Long pushBy,
@RequestParam(value = "pushByName",required = false) String pushByName);
}
@@ -0,0 +1,55 @@
package com.mhd.system.api;
import com.mhd.common.core.constant.ServiceNameConstants;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.dto.YmsSysUserDTO;
import com.mhd.system.api.domain.YmsLoginUser;
import com.mhd.system.api.factory.RemoteBmsFeignFallbackFactory;
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,fallbackFactory = RemoteBmsFeignFallbackFactory.class,url = "http://10.102.192.4:8018", configuration = FeignAutoConfiguration.class)
public interface YmsServiceFeign {
/**
* 获取YMS用户基本信息
* @param szwlUserId 数字物流用户ID
* @return YMS登录用户基本信息
*/
@GetMapping("/system/user/inner/getYmsUserInfo/{szwlUserId}")
R<YmsLoginUser> getYmsUserInfo(@PathVariable("szwlUserId") Long szwlUserId);
/**
* 获取用户详细信息
* @param userId 用户ID
* @return 用户信息
*/
@GetMapping("/system/user/inner/info/{userId}")
R<Long> innerGetInfo(@PathVariable("userId") Long userId);
/**
* 新增用户
* @param ymsSysUserDTO 用户信息
* @return 新增结果
*/
@PostMapping("/system/user/inner/add")
R<Object> innerAdd(@RequestBody YmsSysUserDTO ymsSysUserDTO);
/**
* 修改用户
* @param ymsSysUserDTO 用户信息
* @return 修改结果
*/
@PutMapping("/system/user/inner/edit")
R<Object> innerEdit(@RequestBody YmsSysUserDTO ymsSysUserDTO);
/**
* 删除用户
* @param userIds 用户ID数组
* @return 删除结果
*/
@DeleteMapping("/system/user/inner/remove/{userIds}")
R<Object> innerRemove(@PathVariable("userIds") Long[] userIds);
}
@@ -0,0 +1,50 @@
package com.mhd.system.api.domain;
//package com.mhd.wms.domain.deliveryDetailsLink.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class DeliveryDetailsLink extends BaseVOEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty("编号")
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty("oms编号")
private Long omsId;
@ApiModelProperty(value = "业务单id")
private Long orderId;
@ApiModelProperty(value = "业务单号")
private String orderNumber;
@ApiModelProperty(value = "退货入库单号")
private String returnOrderNumber;
@ApiModelProperty(value = "类别")
private String category;
@ApiModelProperty(value = "发票编号")
private String invoiceNumber;
@ApiModelProperty(value = "客户编号")
private String customerNumber;
@ApiModelProperty(value = "配送名称")
private String deliveryName;
@ApiModelProperty(value = "")
private Integer box;
@ApiModelProperty(value = "")
private Integer bag;
@ApiModelProperty(value = "金额")
private BigDecimal amount;
}
@@ -0,0 +1,24 @@
package com.mhd.system.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "企业国别DTO")
public class ErpCountryDTO {
@ApiModelProperty("主键id")
private Long id;
@ApiModelProperty("ERP国别编码")
private String erpCountryCode;
@ApiModelProperty("ERP国别名称")
private String erpCountryName;
@ApiModelProperty("所属组织ID")
private Long organizationId;
}
@@ -0,0 +1,22 @@
package com.mhd.system.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "企业单位DTO")
public class ErpEnterpriseUnitDTO {
@ApiModelProperty("企业单位id")
private Long id;
@ApiModelProperty("企业单位名称")
private String erpName;
@ApiModelProperty("企业单位编码")
private String erpCode;
@ApiModelProperty("组织ID")
private Long organizationId;
}
@@ -0,0 +1,54 @@
package com.mhd.system.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class GwLogDTO {
@ApiModelProperty("日志id")
private Long logId;
@ApiModelProperty("类型")
private String type;
@ApiModelProperty("业务ID")
private Long businessId;
@ApiModelProperty("请求报文")
private String requestBody;
@ApiModelProperty("响应报文")
private String responseBody;
@ApiModelProperty("状态(1-初始,2-成功,3-失败)")
private Integer status;
@ApiModelProperty("错误信息")
private String errorMsg;
@ApiModelProperty("推送时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date sendTime;
@ApiModelProperty("组织ID")
private Long organizationId;
@ApiModelProperty("一级组织ID")
private Long topOrganizationId;
@ApiModelProperty("组织名称")
private String organizationName;
@ApiModelProperty("创建人")
private Long createBy;
@ApiModelProperty("创建时间")
private Date createTime;
}
@@ -3,14 +3,17 @@ 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.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.mhd.common.core.annotation.Excel;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
/**
@@ -368,4 +371,9 @@ public class InMaterialDetail extends BaseVOEntity {
@ApiModelProperty("oms入库单详情id")
@Excel(name = "oms入库单详情id")
private String omsInMaterialDetail;
@ApiModelProperty(value = "饮用时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date drinkDate;
}
@@ -207,6 +207,14 @@ public class MaterialBaseInfoFeign extends BaseVOEntity{
@Excel(name = "是否抄码: 1-是 2-否")
private Integer copyCode;
@ApiModelProperty("货物类型:0-物料 1-半成品 2-成品")
@Excel(name = "货物类型:0-物料 1-半成品 2-成品")
private Integer goodsType;
@ApiModelProperty("毛重(kg")
@Excel(name = "毛重(kg")
private BigDecimal grossWeight;
/**
* 规格型号
*/
@@ -82,12 +82,12 @@ public class MaterialCommonFeign extends BaseVOEntity{
private String dangerLevelName;
@ApiModelProperty("生产日期")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date productionTime;
@ApiModelProperty("失效日期")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "失效日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date expirationTime;
@@ -101,4 +101,4 @@ public class MaterialCommonFeign extends BaseVOEntity{
@ApiModelProperty(name = "权限菜单ID")
private Long permissionMenuId;
}
}
@@ -0,0 +1,57 @@
package com.mhd.system.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "物料信息查询DTO")
public class MaterialInfoDTO {
@ApiModelProperty("物料id")
private Long materialBaseInfoId;
@ApiModelProperty("物料id")
private String materialCode;
@ApiModelProperty("物料名称")
private String materialName;
@ApiModelProperty("货物类型 0-料件 1-半成品 2-成品")
private Integer goodsType;
@ApiModelProperty("组织ID")
private Long organizationId;
@ApiModelProperty("创建时间起")
private String createTimeStart;
@ApiModelProperty("创建时间止")
private String createTimeEnd;
@ApiModelProperty("更新时间起")
private String updateTimeStart;
@ApiModelProperty("更新时间止")
private String updateTimeEnd;
@ApiModelProperty("推送状态")
private Integer pushStatus;
@ApiModelProperty("推送时间起")
private String pushTimeStart;
@ApiModelProperty("推送时间止")
private String pushTimeEnd;
@ApiModelProperty(value = "页码")
private Integer pageNum = 1;
@ApiModelProperty(value = "每页数量")
private Integer pageSize = 10;
}
@@ -76,4 +76,12 @@ public class MaterialInventoryOmsParamDO extends BaseVOEntity {
private LoginUser loginUser;
private String batchNo;
//生产日期
private Date productionDate;
//过期日期
private Date expiryDate;
}
@@ -174,31 +174,31 @@ public class MaterialInventoryPO extends MaterialBasePO {
private String extAttr2;
@ApiModelProperty("生产日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date productionDate;
@ApiModelProperty("过期日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date expiryDate;
@ApiModelProperty("存货日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date inventoryDate;
@ApiModelProperty("ExtAttr3")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date extAttr3;
@ApiModelProperty("ExtAttr4")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date extAttr4;
@@ -362,4 +362,6 @@ public class StockInOrder extends BaseVOEntity {
private String salesmanId;
@ApiModelProperty("业务员名称")
private String salesmanName;
@Excel(name = "附件url")
private String pictureUrl;
}
@@ -71,7 +71,7 @@ public class StockOutOrder extends BaseVOEntity {
private String auditByName;
@ApiModelProperty("出库单审核时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "出库单审核时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date auditTime;
@@ -120,7 +120,7 @@ public class StockOutOrder extends BaseVOEntity {
private String customerName;
@ApiModelProperty("预计出货时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "预计出货时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date expectTime;
@@ -198,7 +198,7 @@ public class StockOutOrder extends BaseVOEntity {
private String cancelByName;
@ApiModelProperty("取消订单时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "取消订单时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date cancelTime;
@@ -219,7 +219,7 @@ public class StockOutOrder extends BaseVOEntity {
private String closeByName;
@ApiModelProperty("关闭订单时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "关闭订单时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date closeTime;
@@ -232,7 +232,7 @@ public class StockOutOrder extends BaseVOEntity {
private Integer checkTaskDistribution;
@ApiModelProperty("复核任务下发时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "复核任务下发时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date checkTaskDistributionTime;
@@ -334,17 +334,17 @@ public class StockOutOrder extends BaseVOEntity {
private String containerNoName;
@ApiModelProperty("出仓日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date outboundDate;
@ApiModelProperty("完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date completeTime;
@ApiModelProperty("orderDate")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date orderDate;
@@ -401,5 +401,8 @@ public class StockOutOrder extends BaseVOEntity {
private String salesmanId;
@ApiModelProperty("业务员名称")
private String salesmanName;
@ApiModelProperty("车次")
@Excel(name = "车次")
private Integer trainNo;
}
@@ -71,7 +71,7 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private String auditByName;
@ApiModelProperty("出库单审核时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "出库单审核时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date auditTime;
@@ -120,7 +120,7 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private String customerName;
@ApiModelProperty("预计出货时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "预计出货时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date expectTime;
@@ -198,7 +198,7 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private String cancelByName;
@ApiModelProperty("取消订单时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "取消订单时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date cancelTime;
@@ -219,7 +219,7 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private String closeByName;
@ApiModelProperty("关闭订单时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "关闭订单时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date closeTime;
@@ -232,7 +232,7 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private Integer checkTaskDistribution;
@ApiModelProperty("复核任务下发时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "复核任务下发时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date checkTaskDistributionTime;
@@ -334,17 +334,17 @@ public class StockOutOrderTZPD extends BaseVOEntity {
private String containerNoName;
@ApiModelProperty("出仓日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date outboundDate;
@ApiModelProperty("完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date completeTime;
@ApiModelProperty("orderDate")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date orderDate;
@@ -34,6 +34,45 @@ public class SysDictType extends BaseEntity
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 组织表ID */
private Long organizationId;
/** 组织名称 */
private String organizationName;
/** 一级组织表ID */
private Long topOrganizationId;
public Long getOrganizationId()
{
return organizationId;
}
public void setOrganizationId(Long organizationId)
{
this.organizationId = organizationId;
}
public String getOrganizationName()
{
return organizationName;
}
public void setOrganizationName(String organizationName)
{
this.organizationName = organizationName;
}
public Long getTopOrganizationId()
{
return topOrganizationId;
}
public void setTopOrganizationId(Long topOrganizationId)
{
this.topOrganizationId = topOrganizationId;
}
public Long getDictId()
{
return dictId;
@@ -86,6 +125,9 @@ public class SysDictType extends BaseEntity
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("organizationId", getOrganizationId())
.append("organizationName", getOrganizationName())
.append("topOrganizationId", getTopOrganizationId())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
@@ -96,7 +96,7 @@ public class SysLogininfor {
/**
* 访问时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date accessTime;
@@ -109,4 +109,4 @@ public class SysLogininfor {
* 响应时间ms
*/
private String responseTime;
}
}
@@ -156,7 +156,7 @@ public class SysOperLog {
/**
* 操作时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operTime;
@@ -176,4 +176,4 @@ public class SysOperLog {
* 端口
*/
private String port;
}
}
@@ -494,4 +494,17 @@ TmsOrderAddDTO implements Serializable {
@ApiModelProperty("当前登录用户")
private LoginUser loginUser;
@ApiModelProperty("发票编号")
@Excel(name = "发票编号")
private String invoiceNumber;
@ApiModelProperty("订单号")
@Excel(name = "订单号")
private String goodsNumber;
@ApiModelProperty("业务主单")
@Excel(name = "业务主单")
private String businessMainOrder;
}
@@ -0,0 +1,52 @@
package com.mhd.system.api.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class UserShipperQueryDTO {
@ApiModelProperty(value = "页码")
private Integer pageNum = 1;
@ApiModelProperty(value = "每页数量")
private Integer pageSize = 10;
@ApiModelProperty(value = "登录账号")
private String userAccount;
@ApiModelProperty(value = "企业名称")
private String shipperEnterpriseName;
@ApiModelProperty(value = "组织ID")
private String organizationId;
@ApiModelProperty(value = "组织名称")
private String organizationName;
@ApiModelProperty(value = "创建时间起")
private String createTimeFrom;
@ApiModelProperty(value = "创建时间止")
private String createTimeTo;
@ApiModelProperty(value = "更新时间起")
private String updateTimeFrom;
@ApiModelProperty(value = "更新时间止")
private String updateTimeTo;
@ApiModelProperty(value = "货主类型")
private String shipperType;
@ApiModelProperty(value = "推送状态")
private Integer pushStatus;
@ApiModelProperty(value = "推送时间起")
private String pushTimeFrom;
@ApiModelProperty(value = "推送时间止")
private String pushTimeTo;
}
@@ -42,10 +42,10 @@ public class UserUpdateDTO extends BaseVOEntity {
private String userIdcardNumber;
@ApiModelProperty(name = "身份证号加密")
private String userIdcardNumberDes;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(name = "身份证有效期自")
private Date userIdcardDateFrom;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(name = "身份证有效期至")
private Date userIdcardDateTo;
@ApiModelProperty(name = "身份证是否长期:0-无状态,1-是,2-否")
@@ -76,7 +76,7 @@ public class UserUpdateDTO extends BaseVOEntity {
private String userWechatSessionKey;
@ApiModelProperty(name = "密码登录错误次数")
private Integer passwordWrongTimes;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty(name = "最近一次登录时间")
private Date lastLoginTime;
@ApiModelProperty(name = "最近一次登录IP")
@@ -89,15 +89,15 @@ public class UserUpdateDTO extends BaseVOEntity {
private int userAuthStatus;
@ApiModelProperty(name = "用户审核人用户姓名")
private String userAuthByUsername;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(name = "用户审核时间")
private Date userAuthTime;
@ApiModelProperty(name = "加入黑名单备注(解除时需要清空)")
private String userStatusRemark;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(name = "用户状态更新时间")
private Date userStatusTime;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@ApiModelProperty(name = "用户生日")
private Date userBirthday;
@ApiModelProperty(name = "用户住址信息")
@@ -122,4 +122,4 @@ public class UserUpdateDTO extends BaseVOEntity {
@ApiModelProperty(name = "请求域名")
private String tenantsDomainName;
}
}
@@ -0,0 +1,63 @@
package com.mhd.system.api.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* YMS登录用户信息
* @author AI
* @date 2026/05/13
*/
@Data
public class YmsLoginUser {
//登录人id
private Long id;
//登录人账号
private String username;
//登录人名字
private String nickName;
//登录人密码
private String password;
//当前登录部门code
private String orgCode;
//头像
private String avatar;
//性别(0男 1女 2未知)
private String sex;
//电子邮件
private String email;
//电话
private String phonenumber;
//状态(0正常 1停用)
private String status;
//删除标志(0代表存在 2代表删除)
private String delFlag;
//最后登录IP
private String loginIp;
//最后登录时间
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date loginDate;
//创建时间
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
//数字物流用户ID
private Long szwlUserId;
//一级组织表ID
private Long topOrganizationId;
//组织表ID
private Long organizationId;
//角色code集合
private String roleCodes;
//角色名称集合
private String roleNames;
//推广码
private String promoCode;
//账号类型 1.普通账号,2.组织账号,3.一级账号,4.平台员工,5.企业员工,6.合作商
private Integer userAccountType;
}
@@ -42,6 +42,11 @@ public class RemoteBmsFeignFallbackFactory implements FallbackFactory<BmsService
return AjaxResult.error(throwable.getMessage());
}
@Override
public AjaxResult getCustomersInfoBySettlementEntityId(Long settlementEntityId, Long topOrganizationId) {
return AjaxResult.error(throwable.getMessage());
}
@Override
public AjaxResult pushSyncData(BusinessDataPushDTO businessDataPushDTO) {
return AjaxResult.error(throwable.getMessage());
@@ -11,6 +11,7 @@ import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
@@ -50,12 +51,32 @@ public class RemoteOmsFeignFallbackFactory implements FallbackFactory<OmsService
}
@Override
public AjaxResult omsEdit(MaterialInventoryOmsParamDO materialInventoryOmsParamDO) {
public CompletableFuture<Void> omsEdit(MaterialInventoryOmsParamDO materialInventoryOmsParamDO) {
return null;
}
// @Override
// public AjaxResult inventoryAdjustmentRecordInsert(InventoryAdjustmentRecord inventoryAdjustmentRecord) {
// return null;
// }
@Override
public AjaxResult getUnitList(ErpEnterpriseUnitDTO erpEnterpriseUnitDTO) {
return null;
}
@Override
public AjaxResult inventoryAdjustmentRecordInsert(InventoryAdjustmentRecord inventoryAdjustmentRecord) {
public AjaxResult getCountryList(ErpCountryDTO erpCountryDTO) {
return null;
}
@Override
public AjaxResult insertGwLog(GwLogDTO gwLogDTO) {
return null;
}
@Override
public AjaxResult updateGwLog(GwLogDTO gwLogDTO) {
return null;
}
};
@@ -289,6 +289,11 @@ public class RemoteSystemFeignFallbackFactory implements FallbackFactory<SystemS
return AjaxResult.error("查询失败");
}
@Override
public AjaxResult getInfoByCustomerAndOrganizationId(String settlementCustomersCode, Integer contractType, Long topOrganizationId, Long organizationId) {
return null;
}
@Override
public AjaxResult queryList() {
return AjaxResult.error("查询失败");
@@ -5,8 +5,10 @@ import com.mhd.common.core.domain.dto.StatisticalMattersDTO;
import com.mhd.common.core.domain.dto.UserDataPermissionQueryDTO;
import com.mhd.common.core.domain.dto.UserDriverDTO;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.system.api.domain.UserDTO;
import com.mhd.system.api.domain.UserShipperQueryDTO;
import com.mhd.system.api.domain.UserUpdateDTO;
import com.mhd.system.api.model.LoginUser;
import com.mhd.common.core.domain.entity.R;
@@ -19,6 +21,8 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -183,13 +187,29 @@ public class RemoteUserFeignFallbackFactory implements FallbackFactory<UserServi
}
@Override
public AjaxResult<?> userShipperList(Integer pageNum, Integer pageSize, String userAccount, String shipperEnterpriseName, Long organizationId, String organizationName, String createTimeFrom, String createTimeTo, String updateTimeFrom, String updateTimeTo, Integer shipperType) {
return AjaxResult.error("查询失败" + throwable.getMessage());
public AjaxResult updateLineManagement(UserDTO userDTO) {
return AjaxResult.error("失败" + throwable.getMessage());
}
@Override
public AjaxResult updateLineManagement(UserDTO userDTO) {
return AjaxResult.error("失败" + throwable.getMessage());
public TableDataInfo userShipperList(UserShipperQueryDTO userShipperQueryDTO) {
TableDataInfo tableDataInfo = new TableDataInfo();
tableDataInfo.setData(new ArrayList<>());
tableDataInfo.setTotal(0);
tableDataInfo.setCode(500);
tableDataInfo.setMsg("查询失败:" + throwable.getMessage());
return tableDataInfo;
}
@Override
public AjaxResult<?> updatePushStatus(Long shipperId, Integer pushStatus, String pushTime, Long pushBy, String pushByName) {
return AjaxResult.error("更新失败" + throwable.getMessage());
}
@Override
public AjaxResult getCustomerNcCodeBatch(List<Long> shipperIdList) {
return AjaxResult.error("更新失败" + throwable.getMessage());
}
};
}
@@ -550,6 +550,16 @@ public class RemoteWlhyFallbackFactory implements FallbackFactory<WlhyServiceFei
public AjaxResult cancelIssueDocuments(String executeOrderId) {
return AjaxResult.error(cause.getMessage());
}
@Override
public AjaxResult<?> queryList(Integer pageNo, Integer pageSize, String pushStatus, String organizationId) {
return AjaxResult.error(cause.getMessage());
}
@Override
public void updateExchangeRatePushStatus(String id, Integer pushStatus, String pushTime, Long pushBy, String pushByName) {
}
};
}
}
@@ -2,6 +2,7 @@ package com.mhd.system.api.factory;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.system.api.WlhyServiceFeign;
import com.mhd.system.api.WmsServiceFeign;
import com.mhd.system.api.domain.*;
@@ -11,6 +12,7 @@ import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -62,6 +64,11 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
public void omsOutOrderAddDetail(List<OutMaterialDetail> outMaterialDetails) {
}
@Override
public void omsOutOrderAddDeliveryDetailsLink(List<DeliveryDetailsLink> deliveryDetailsLinks) {
}
@Override
public void omsInOrderAdd(StockInOrder stockInOrder) {
}
@@ -69,6 +76,20 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
@Override
public void omsInOrderAddDetail(List<InMaterialDetail> inMaterialDetails) {
}
@Override
public TableDataInfo getMaterialBaseInfoList(MaterialInfoDTO materialInfoDTO) {
TableDataInfo tableDataInfo = new TableDataInfo();
tableDataInfo.setData(new ArrayList<>());
tableDataInfo.setTotal(0);
tableDataInfo.setCode(500);
return tableDataInfo;
}
@Override
public AjaxResult<?> updateMaterialPushStatus(Long materialBaseInfoId, Integer pushStatus, String pushTime, Long pushBy, String pushByName) {
return AjaxResult.error(cause.getMessage());
}
};
}
}
@@ -11,6 +11,7 @@ import com.mhd.system.api.domain.MallOAuthToken;
import com.mhd.system.api.domain.mall.BaseUser;
import com.mhd.system.api.domain.SysUser;
import com.mhd.system.api.domain.WlhyLoginUser;
import com.mhd.system.api.domain.YmsLoginUser;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -87,6 +88,11 @@ public class LoginUser implements Serializable
*/
private WlhyLoginUser wlhyLoginUser;
/**
* YMS用户信息
*/
private YmsLoginUser ymsLoginUser;
/**
* websocket地址
*/
@@ -26,6 +26,7 @@ import com.mhd.common.log.service.AsyncLogService;
import com.mhd.common.redis.service.RedisService;
import com.mhd.system.api.*;
import com.mhd.system.api.domain.*;
import com.mhd.system.api.domain.YmsLoginUser;
import com.mhd.system.api.domain.mall.SysTenant;
import com.mhd.system.api.domain.mall.UserInfo;
import com.mhd.system.api.domain.mall.UserInfoLoginDTO;
@@ -70,6 +71,8 @@ public class SysLoginService {
private UserServiceFeign userServiceFeign;
@Resource
private WlhyServiceFeign wlhyServiceFeign;
@Resource
private YmsServiceFeign ymsServiceFeign;
@Resource
private RedisService redisService;
@@ -459,6 +462,17 @@ public class SysLoginService {
userInfo.setWlhyLoginUser(wlhyLoginUserR.getData());
}
}
// 获取YMS登录用户基本信息
try {
R<YmsLoginUser> ymsLoginUserR = ymsServiceFeign.getYmsUserInfo(userInfo.getUserPo().getUserId());
if (ymsLoginUserR.getCode() == R.SUCCESS && ymsLoginUserR.getData() != null) {
userInfo.setYmsLoginUser(ymsLoginUserR.getData());
log.info("获取YMS用户信息成功,userId: {}", userInfo.getUserPo().getUserId());
}
} catch (Exception e) {
// 获取YMS用户信息失败时,记录日志但不影响登录
log.warn("获取YMS用户信息失败,但不影响登录: {}", e.getMessage());
}
if(mallFlag == 1){
/*单点登录,获取商城鉴权
* 根据用户角色判断需要鉴权的服务,
+9 -7
View File
@@ -12,21 +12,23 @@ spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
# server-addr: 10.102.192.5:6848
username: nacos
password: manhuoda@2023
server-addr: 10.33.0.129:6010
# username: nacos
# password: manhuoda@2023
#线上正式环境
# server-addr: 10.102.192.5: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.5:6848
username: nacos
password: manhuoda@2023
# username: nacos
# password: manhuoda@2023
#线上正式环境
group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置
file-extension: yml #默认properties
+17
View File
@@ -0,0 +1,17 @@
# 基础镜像
FROM arm64v8/openjdk:8
# author
MAINTAINER manhuoda
#指定东八区时区
ENV TZ Asia/Shanghai
#指定utf-8编码格
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
#将当前jar 复制到容器根目录下
ADD target/mhd-bi.jar mhd-bi.jar
#暴露容器端口 Docker镜像告知Docker宿主机应用监听了端口
EXPOSE 9200
# 运行jar包
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Xms1000m", "-Xmx1500m","-jar","/mhd-bi.jar"]
+180
View File
@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mhd</artifactId>
<groupId>com.mhd</groupId>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mhd-bi</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--添加web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加feign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--nacos 服务注册客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Sentinel⽀持采⽤ Nacos 作为规则配置数据源,引⼊该适配依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--sentinel 核⼼环境 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--链路追踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Alibaba Fastjson -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!--spring cloud stream 依赖(rabbit-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<!-- Mhd Common Core-->
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-common-core</artifactId>
</dependency>
<!-- Mhd Common Redis-->
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-common-redis</artifactId>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.1.193</version>
</dependency>
<!--import mybatis plus 它会自动引入mybatis及mybatis spring切勿重复引用以免冲突-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--添加druid连接池 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<!--链路追踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<!-- Mhd Common Security-->
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-common-security</artifactId>
</dependency>
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-api-system</artifactId>
</dependency>
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-common-log</artifactId>
</dependency>
<!-- net.sf.json -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.mhd</groupId>
<artifactId>mhd-common-datasource</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>mhd-bi</id>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+44
View File
@@ -0,0 +1,44 @@
-- =============================================================================
-- 达梦 DM8:综合态势(单表,可重复执行)
-- 接口:GET /biReport/comprehensive
-- 执行顺序:删除历史多表/旧快照 → 建 BI_COMPREHENSIVE_SNAPSHOT → 示例 INSERT
-- PAYLOAD_JSON 与 ComprehensiveSituationVO 字段名一致;接口取 DEL_FLAG=1 且 CREATE_TIME 最新一条。
-- =============================================================================
-- 子表优先
DROP TABLE IF EXISTS
BI_COMPREHENSIVE_INCOME_TREND;
DROP TABLE IF EXISTS
BI_COMPREHENSIVE_METRIC;
DROP TABLE IF EXISTS
BI_COMPREHENSIVE_SNAPSHOT;
CREATE TABLE
BI_COMPREHENSIVE_SNAPSHOT (
ID BIGINT IDENTITY(1,1) NOT NULL,
PAYLOAD_JSON CLOB NOT NULL,
CREATE_TIME DATETIME DEFAULT NULL,
UPDATE_TIME DATETIME DEFAULT NULL,
REMARK VARCHAR(500) DEFAULT NULL,
DEL_FLAG NUMBER(1) DEFAULT 1 NOT NULL,
PRIMARY KEY (ID)
);
CREATE INDEX IDX_BI_COMP_SNAP_DEL_CR ON
BI_COMPREHENSIVE_SNAPSHOT(DEL_FLAG, CREATE_TIME);
CREATE INDEX IDX_BI_COMP_SNAP_UPD ON
BI_COMPREHENSIVE_SNAPSHOT(UPDATE_TIME);
COMMENT ON TABLE
BI_COMPREHENSIVE_SNAPSHOT IS '综合态势-整包 JSON 快照';
COMMENT ON COLUMN
BI_COMPREHENSIVE_SNAPSHOT.DEL_FLAG IS '0无状态 1正常 2已删除';
INSERT INTO
BI_COMPREHENSIVE_SNAPSHOT (PAYLOAD_JSON, CREATE_TIME, UPDATE_TIME, DEL_FLAG)
VALUES (
'{"valueAddedServiceIncome":5330000,"inventoryTurnover":25,"orderCount":42300,"vehicleUtilizationRate":97.4,"fuelConsumptionPerHundredKm":15,"incomeTrend":[280,210,260,310,470,390]}',
SYSDATE,
SYSDATE,
1
);
COMMIT;
@@ -0,0 +1,53 @@
-- =============================================================================
-- 达梦 DM8:月台监测(单表,可重复执行)
-- 接口:GET /biReport/platformSurveillance
-- 执行顺序:删除历史多表/旧快照 → 建 BI_PLATFORM_SURVEILLANCE_SNAPSHOT → 示例 INSERT
-- PAYLOAD_JSON 与 PlatformSurveillanceVO 一致;接口取 DEL_FLAG=1 且 CREATE_TIME 最新一条。
-- =============================================================================
DROP TABLE IF EXISTS
BI_PS_ALARM_DIST;
DROP TABLE IF EXISTS
BI_PS_TASK_TYPE;
DROP TABLE IF EXISTS
BI_PS_ALARM_TREND;
DROP TABLE IF EXISTS
BI_PS_TASK_LOAD;
DROP TABLE IF EXISTS
BI_PS_AVG_DURATION_TREND;
DROP TABLE IF EXISTS
BI_PS_VEHICLE;
DROP TABLE IF EXISTS
BI_PLATFORM_SURVEILLANCE_METRIC;
DROP TABLE IF EXISTS
BI_PLATFORM_SURVEILLANCE_SNAPSHOT;
CREATE TABLE
BI_PLATFORM_SURVEILLANCE_SNAPSHOT (
ID BIGINT IDENTITY(1,1) NOT NULL,
PAYLOAD_JSON CLOB NOT NULL,
CREATE_TIME DATETIME DEFAULT NULL,
UPDATE_TIME DATETIME DEFAULT NULL,
REMARK VARCHAR(500) DEFAULT NULL,
DEL_FLAG NUMBER(1) DEFAULT 1 NOT NULL,
PRIMARY KEY (ID)
);
CREATE INDEX IDX_BI_PS_SNAP_DEL_CR ON
BI_PLATFORM_SURVEILLANCE_SNAPSHOT(DEL_FLAG, CREATE_TIME);
CREATE INDEX IDX_BI_PS_SNAP_UPD ON
BI_PLATFORM_SURVEILLANCE_SNAPSHOT(UPDATE_TIME);
COMMENT ON TABLE
BI_PLATFORM_SURVEILLANCE_SNAPSHOT IS '月台监测-整包 JSON 快照';
COMMENT ON COLUMN
BI_PLATFORM_SURVEILLANCE_SNAPSHOT.DEL_FLAG IS '0无状态 1正常 2已删除';
INSERT INTO
BI_PLATFORM_SURVEILLANCE_SNAPSHOT (PAYLOAD_JSON, CREATE_TIME, UPDATE_TIME, DEL_FLAG)
VALUES (
'{"vehicles":[{"plateNumber":"粤CFR1958","status":"作业中","platformId":"#48","platformDuration":265},{"plateNumber":"粤CFR1958","status":"已离园","platformId":"#48","platformDuration":265},{"plateNumber":"粤CFR1958","status":"作业中","platformId":"#48","platformDuration":265},{"plateNumber":"粤CFR1958","status":"作业中","platformId":"#48","platformDuration":265},{"plateNumber":"粤CFR1958","status":"作业中","platformId":"#48","platformDuration":265},{"plateNumber":"粤CFR1958","status":"作业中","platformId":"#48","platformDuration":265}],"efficiencyStatistics":{"entryOvertimeRate":60,"overtimeCount":45,"platformOnTimeRate":92,"avgPlatformDuration":4.5,"yardOnTimeRate":88,"avgYardDuration":4.5},"platformOverview":{"totalPlatforms":43,"currentOccupancyRate":50,"operatingPlatforms":23,"todayTasks":324},"vehicleStatus":{"todayReservedVehicles":3000,"notCheckedIn":1500,"operatingVehicles":1000,"completedVehicles":1000},"avgOperationDurationTrend":[{"month":"11月","yardDuration":10,"platformDuration":23},{"month":"12月","yardDuration":14,"platformDuration":15},{"month":"1月","yardDuration":23.5,"platformDuration":20},{"month":"2月","yardDuration":22,"platformDuration":17},{"month":"3月","yardDuration":13,"platformDuration":14},{"month":"4月","yardDuration":17,"platformDuration":10}],"monthlyTaskStatistics":{"taskTotal":1455,"taskTotalYoY":5,"avgTaskDuration":4.5,"avgDurationYoY":-5,"taskCompletionRate":95,"completionRateYoY":5},"taskLoadStatistics":[{"time":"15时","taskCount":100},{"time":"16时","taskCount":110},{"time":"17时","taskCount":115},{"time":"18时","taskCount":80},{"time":"19时","taskCount":60},{"time":"20时","taskCount":40},{"time":"21时","taskCount":40},{"time":"22时","taskCount":40},{"time":"23时","taskCount":30},{"time":"0时","taskCount":10},{"time":"1时","taskCount":10},{"time":"2时","taskCount":10},{"time":"3时","taskCount":10},{"time":"4时","taskCount":10},{"time":"5时","taskCount":10},{"time":"6时","taskCount":20},{"time":"7时","taskCount":30},{"time":"8时","taskCount":70},{"time":"9时","taskCount":95},{"time":"10时","taskCount":110},{"time":"11时","taskCount":120},{"time":"12时","taskCount":130},{"time":"13时","taskCount":130}],"platformAlarmTrend":[{"date":"11日","alarmCount":10},{"date":"12日","alarmCount":14},{"date":"13日","alarmCount":23},{"date":"14日","alarmCount":22},{"date":"15日","alarmCount":13},{"date":"16日","alarmCount":17},{"date":"17日","alarmCount":8}],"taskTypeStatistics":{"totalTasks":4325,"taskTypes":[{"type":"类型1","count":2400},{"type":"类型2","count":2300},{"type":"类型3","count":2300},{"type":"类型4","count":2300}]},"platformAlarmStatistics":{"todayAlarmTotal":13,"handled":12,"unhandled":1},"platformAlarmDistribution":[{"type":"类型1","count":300},{"type":"类型2","count":245},{"type":"类型3","count":280},{"type":"类型4","count":340},{"type":"类型5","count":455},{"type":"类型6","count":400},{"type":"类型7","count":300}]}',
SYSDATE,
SYSDATE,
1
);
COMMIT;
@@ -0,0 +1,45 @@
-- =============================================================================
-- 达梦 DM8:仓储运输(单表,可重复执行)
-- 接口:GET /biReport/warehouseTransport
-- 执行顺序:删除历史多表/旧快照 → 建 BI_WAREHOUSE_TRANSPORT_SNAPSHOT → 示例 INSERT
-- PAYLOAD_JSON 与 WarehouseTransportSituationVO 字段名一致;接口取 DEL_FLAG=1 且 CREATE_TIME 最新一条。
-- =============================================================================
DROP TABLE IF EXISTS
BI_WTS_CUSTOMER_RANK;
DROP TABLE IF EXISTS
BI_WTS_TIME_SERIES;
DROP TABLE IF EXISTS
BI_WAREHOUSE_TRANSPORT_METRIC;
DROP TABLE IF EXISTS
BI_WAREHOUSE_TRANSPORT_SNAPSHOT;
CREATE TABLE
BI_WAREHOUSE_TRANSPORT_SNAPSHOT (
ID BIGINT IDENTITY(1,1) NOT NULL,
PAYLOAD_JSON CLOB NOT NULL,
CREATE_TIME DATETIME DEFAULT NULL,
UPDATE_TIME DATETIME DEFAULT NULL,
REMARK VARCHAR(500) DEFAULT NULL,
DEL_FLAG NUMBER(1) DEFAULT 1 NOT NULL,
PRIMARY KEY (ID)
);
CREATE INDEX IDX_BI_WTS_SNAP_DEL_CR ON
BI_WAREHOUSE_TRANSPORT_SNAPSHOT(DEL_FLAG, CREATE_TIME);
CREATE INDEX IDX_BI_WTS_SNAP_UPD ON
BI_WAREHOUSE_TRANSPORT_SNAPSHOT(UPDATE_TIME);
COMMENT ON TABLE
BI_WAREHOUSE_TRANSPORT_SNAPSHOT IS '仓储运输-整包 JSON 快照';
COMMENT ON COLUMN
BI_WAREHOUSE_TRANSPORT_SNAPSHOT.DEL_FLAG IS '0无状态 1正常 2已删除';
INSERT INTO
BI_WAREHOUSE_TRANSPORT_SNAPSHOT (PAYLOAD_JSON, CREATE_TIME, UPDATE_TIME, DEL_FLAG)
VALUES (
'{"warehouseDistributionOnTimeRate":99.2,"currentYearOrders":525440,"currentQuarterOrders":225120,"currentMonthOrders":23560,"warehouseOrderTrend":[100,93,85,70,98,88],"throughput":[10,14,23,10,13,19],"currentMonthTurnoverRate":3,"currentYearTurnoverRate":4,"inventoryTurnoverTrend":[10,14,23,22,13,17],"totalTransportIncome":5850,"orderCount":856,"transportTrips":533,"annualTransportVolume":15,"transportOrderTotal":4325,"crossBorderTransportOrder":2400,"domesticTransportOrder":2300,"transportTripsTrend":[100,140,230,100,130,192],"vehicleUtilizationRate":[600,460,350,470,450,620],"warehouseDockSyncRate":[100,98,87,78,97,86],"customerContributionRank":{"customerName":["客户A","客户B","客户C","客户D","客户E"],"customerAmount":[147,150,170,160,180]}}',
SYSDATE,
SYSDATE,
1
);
COMMIT;
+15
View File
@@ -0,0 +1,15 @@
ALTER TABLE BI_COMPREHENSIVE_SNAPSHOT
ADD (DEL_FLAG TINYINT DEFAULT 1);
COMMENT ON COLUMN BI_COMPREHENSIVE_SNAPSHOT.DEL_FLAG IS '删除标志:0-无状态, 1-正常, 2-已删除';
ALTER TABLE BI_PLATFORM_SURVEILLANCE_SNAPSHOT
ADD (DEL_FLAG TINYINT DEFAULT 1);
COMMENT ON COLUMN BI_PLATFORM_SURVEILLANCE_SNAPSHOT.DEL_FLAG IS '删除标志:0-无状态, 1-正常, 2-已删除';
ALTER TABLE BI_WAREHOUSE_TRANSPORT_SNAPSHOT
ADD (DEL_FLAG TINYINT DEFAULT 1);
COMMENT ON COLUMN BI_WAREHOUSE_TRANSPORT_SNAPSHOT.DEL_FLAG IS '删除标志:0-无状态, 1-正常, 2-已删除';
@@ -0,0 +1,236 @@
package com.mhd.bi;
import com.mhd.common.core.annotation.fieldsetvalue.CommonService;
import com.mhd.common.core.annotation.fieldsetvalue.SetFeildValueAspect;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication(scanBasePackages = {"com.mhd", "com.mhd.bi"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.mhd","com.mhd.bi.infrastructure.feign"})
@MapperScan("com.mhd.bi.domain.**.mapper")
@Import({SetFeildValueAspect.class, CommonService.class})
@EnableAsync
@EnableScheduling
public class BiApplication {
public static void main(String[] args) {
SpringApplication.run(BiApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 可视化页面模块启动成功 ლ(´ڡ`ლ)゙ " +
"# _oo0oo_\n" +
"# o8888888o\n" +
"# 88\" . \"88\n" +
"# (| -_- |)\n" +
"# 0\\ = /0\n" +
"# ___/`---'\\___\n" +
"# .' \\\\| |// '.\n" +
"# / \\\\||| : |||// \\\n" +
"# / _||||| -:- |||||- \\\n" +
"# | | \\\\\\ - /// | |\n" +
"# | \\_| ''\\---/'' |_/ |\n" +
"# \\ .-\\__ '-' ___/-. /\n" +
"# ___'. .' /--.--\\ `. .'___\n" +
"# .\"\" '< `.___\\_<|>_/___.' >' \"\".\n" +
"# | | : `- \\`.;`\\ _ /`;.`/ - ` : | |\n" +
"# \\ \\ `_. \\_ __\\ /__ _/ .-` / /\n" +
"# =====`-.____`.___ \\_____/___.-`___.-'=====\n" +
"# `=---='\n" +
"#\n" +
"#\n" +
"# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
"#\n" +
"# 佛祖保佑 永无BUG\n" +
"#\n" +
"#    ┏┓   ┏┓\n" +
"#   ┏┛┻━━━┛┻┓\n" +
"#   ┃       \n" +
"#   ┃   ━   \n" +
"#   ┃ ┳┛ ┗┳ ┃\n" +
"#   ┃       \n" +
"#   ┃   ┻   \n" +
"#   ┃       \n" +
"#   ┗━┓   ┏━┛Codes are far away from bugs with the animal protecting\n" +
"#     ┃   ┃ 神兽保佑,代码无bug\n" +
"#     ┃   ┃\n" +
"#     ┃   ┗━━━┓\n" +
"#     ┃      ┣┓\n" +
"#     ┃     ┏┛\n" +
"#     ┗┓┓┏━┳┓┏┛\n" +
"#      ┃┫┫ ┃┫┫\n" +
"#      ┗┻┛ ┗┻┛\n" +
"#\n" +
"#    ┏┓   ┏┓\n" +
"#   ┏┛┻━━━┛┻┓\n" +
"#   ┃        \n" +
"#   ┃   ━   \n" +
"#   ┃    <┃\n" +
"#   ┃       \n" +
"#   ┃ . ⌒ ..┃\n" +
"#   ┃       \n" +
"#   ┗━┓   ┏━┛\n" +
"#     ┃   ┃ Codes are far away from bugs with the animal protecting       \n" +
"#     ┃   ┃ 神兽保佑,代码无bug\n" +
"#     ┃   ┃           \n" +
"#     ┃   ┃       \n" +
"#     ┃   ┃\n" +
"#     ┃   ┃           \n" +
"#     ┃   ┗━━━┓\n" +
"#     ┃       ┣┓\n" +
"#     ┃       ┏┛\n" +
"#     ┗┓┓┏━┳┓┏┛\n" +
"#      ┃┫┫ ┃┫┫\n" +
"#      ┗┻┛ ┗┻┛\n" +
"# ┏┓   ┏┓+ +\n" +
"#   ┏┛┻━━━┛┻┓ + +\n" +
"#   ┃       ┃  \n" +
"#   ┃   ━   ┃ ++ + + +\n" +
"#   ████━████ ┃+\n" +
"#   ┃       ┃ +\n" +
"#   ┃   ┻   ┃\n" +
"#   ┃       ┃ + +\n" +
"#   ┗━┓   ┏━┛\n" +
"#     ┃   ┃           \n" +
"#     ┃   ┃ + + + +\n" +
"#     ┃   ┃    Codes are far away from bugs with the animal protecting   \n" +
"#     ┃   ┃ +     神兽保佑,代码无bug  \n" +
"#     ┃   ┃\n" +
"#     ┃   ┃  +         \n" +
"#     ┃    ┗━━━┓ + +\n" +
"#     ┃        ┣┓\n" +
"#     ┃        ┏┛\n" +
"#     ┗┓┓┏━┳┓┏┛ + + + +\n" +
"#      ┃┫┫ ┃┫┫\n" +
"#      ┗┻┛ ┗┻┛+ + + +\n" +
"# d*##$.\n" +
"# zP\"\"\"\"\"$e. $\" $o\n" +
"#4$ '$ $\" $\n" +
"#'$ '$ J$ $F\n" +
"# 'b $k $> $\n" +
"# $k $r J$ d$\n" +
"# '$ $ $\" $~\n" +
"# '$ \"$ '$E $\n" +
"# $ $L $\" $F ...\n" +
"# $. 4B $ $$$*\"\"\"*b\n" +
"# '$ $. $$ $$ $F\n" +
"# \"$ R$ $F $\" $\n" +
"# $k ?$ u* dF .$\n" +
"# ^$. $$\" z$ u$$$$e\n" +
"# #$b $E.dW@e$\" ?$\n" +
"# #$ .o$$# d$$$$c ?F\n" +
"# $ .d$$#\" . zo$> #$r .uF\n" +
"# $L .u$*\" $&$$$k .$$d$$F\n" +
"# $$\" \"\"^\"$$$P\"$P9$\n" +
"# JP .o$$$$u:$P $$\n" +
"# $ ..ue$\" \"\" $\"\n" +
"# d$ $F $\n" +
"# $$ ....udE 4B\n" +
"# #$ \"\"\"\"` $r @$\n" +
"# ^$L '$ $F\n" +
"# RN 4N $\n" +
"# *$b d$\n" +
"# $$k $F\n" +
"# $$b $F\n" +
"# $\"\" $F\n" +
"# '$ $\n" +
"# $L $\n" +
"# '$ $\n" +
"# $ $\n" +
"#\n" +
"#\n" +
"# ┌─┐ ┌─┐\n" +
"# ┌──┘ ┴───────┘ ┴──┐\n" +
"# │ │\n" +
"# │ ─── │\n" +
"# │ ─┬┘ └┬─ │\n" +
"# │ │\n" +
"# │ ─┴─ │\n" +
"# │ │\n" +
"# └───┐ ┌───┘\n" +
"# │ │\n" +
"# │ │\n" +
"# │ │\n" +
"# │ └──────────────┐\n" +
"# │ │\n" +
"# │ ├─┐\n" +
"# │ ┌─┘\n" +
"# │ │\n" +
"# └─┐ ┐ ┌───────┬──┐ ┌──┘\n" +
"# │ ─┤ ─┤ │ ─┤ ─┤\n" +
"# └──┴──┘ └──┴──┘\n" +
"# 神兽保佑\n" +
"# 代码无BUG!\n" +
"#\n" +
"# ___====-_ _-====___\n" +
"# _--^^^#####// \\\\#####^^^--_\n" +
"# _-^##########// ( ) \\\\##########^-_\n" +
"# -############// |\\^^/| \\\\############-\n" +
"# _/############// (@::@) \\\\############\\_\n" +
"# /#############(( \\\\// ))#############\\\n" +
"# -###############\\\\ (oo) //###############-\n" +
"# -#################\\\\ / VV \\ //#################-\n" +
"# -###################\\\\/ \\//###################-\n" +
"# _#/|##########/\\######( /\\ )######/\\##########|\\#_\n" +
"# |/ |#/\\#/\\#/\\/ \\#/\\##\\ | | /##/\\#/ \\/\\#/\\#/\\#| \\|\n" +
"# ` |/ V V ` V \\#\\| | | |/#/ V ' V V \\| '\n" +
"# ` ` ` ` / | | | | \\ ' ' ' '\n" +
"# ( | | | | )\n" +
"# __\\ | | | | /__\n" +
"# (vvv(VVV)(VVV)vvv)\n" +
"# 神兽保佑\n" +
"# 代码无BUG!\n" +
"# __----~~~~~~~~~~~------___\n" +
"# . . ~~//====...... __--~ ~~\n" +
"# -. \\_|// |||\\\\ ~~~~~~::::... /~\n" +
"# ___-==_ _-~o~ \\/ ||| \\\\ _/~~-\n" +
"# __---~~~.==~||\\=_ -_--~/_-~|- |\\\\ \\\\ _/~\n" +
"# _-~~ .=~ | \\\\-_ '-~7 /- / || \\ /\n" +
"# .~ .~ | \\\\ -_ / /- / || \\ /\n" +
"# / ____ / | \\\\ ~-_/ /|- _/ .|| \\ /\n" +
"# |~~ ~~|--~~~~--_ \\ ~==-/ | \\~--===~~ .\\\n" +
"# ' ~-| /| |-~\\~~ __--~~\n" +
"# |-~~-_/ | | ~\\_ _-~ /\\\n" +
"# / \\ \\__ \\/~ \\__\n" +
"# _--~ _/ | .-~~____--~-/ ~~==.\n" +
"# ((->/~ '.|||' -_| ~~-/ , . _||\n" +
"# -_ ~\\ ~~---l__i__i__i--~~_/\n" +
"# _-~-__ ~) \\--______________--~~\n" +
"# //.-~~~-~_--~- |-------~~~~~~~~\n" +
"# //.-~~~--\\\n" +
"# 神兽保佑\n" +
"# 代码无BUG!\n" +
"# ,----------------, ,---------,\n" +
"# ,-----------------------, ,\" ,\"|\n" +
"# ,\" ,\"| ,\" ,\" |\n" +
"# +-----------------------+ | ,\" ,\" |\n" +
"# | .-----------------. | | +---------+ |\n" +
"# | | | | | | -==----'| |\n" +
"# | | I LOVE DOS! | | | | | |\n" +
"# | | Bad command or | | |/----|`---= | |\n" +
"# | | C:\\>_ | | | ,/|==== ooo | ;\n" +
"# | | | | | // |(((( [33]| ,\"\n" +
"# | `-----------------' |,\" .;'| |(((( | ,\"\n" +
"# +-----------------------+ ;; | | |,\"\n" +
"# /_)______________(_/ //' | +---------+\n" +
"# ___________________________/___ `,\n" +
"# / oooooooooooooooo .o. oooo /, \\,\"-----------\n" +
"# / ==ooooooooooooooo==.o. ooo= // ,`\\--{)B ,\"\n" +
"# /_==__==========__==_ooo__ooo=_/' /___________,\"\n" +
"#\n" +
"# .-~~~~~~~~~-._ _.-~~~~~~~~~-.\n" +
"# __.' ~. .~ `.__\n" +
"# .'// \\./ \\\\`.\n" +
"# .'// | \\\\`.\n" +
"# .'// .-~\"\"\"\"\"\"\"~~~~-._ | _,-~~~~\"\"\"\"\"\"\"~-. \\\\`.\n" +
"# .'//.-\" `-. | .-' \"-.\\\\`.\n" +
"# .'//______.============-.. \\ | / ..-============.______\\\\`.\n" +
"# .'______________________________\\|/______________________________`.");
}
}
@@ -0,0 +1,18 @@
package com.mhd.bi.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* BI 开放接口访问控制请求头 {@code X-BI-Access-Token}
* <p>配置了 {@code accessToken} 时必须与请求头完全一致未配置时仅校验请求头非空</p>
*/
@Data
@ConfigurationProperties(prefix = "mhd.bi")
public class BiAccessProperties {
/**
* X-BI-Access-Token 比对的密钥为空则只要请求头非空即可
*/
private String accessToken = "";
}
@@ -0,0 +1,25 @@
package com.mhd.bi.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
/**
* 注册 /biReport 路径的访问令牌校验
*/
@Configuration
@EnableConfigurationProperties(BiAccessProperties.class)
public class BiReportAccessConfiguration {
@Bean
public FilterRegistrationBean<BiReportAccessTokenFilter> biReportAccessTokenFilter(BiAccessProperties properties) {
FilterRegistrationBean<BiReportAccessTokenFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new BiReportAccessTokenFilter(properties));
registration.addUrlPatterns("/biReport/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 100);
registration.setName("biReportAccessTokenFilter");
return registration;
}
}
@@ -0,0 +1,60 @@
package com.mhd.bi.config;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 限制 /biReport 下接口必须携带 {@code X-BI-Access-Token}否则 401
*/
public class BiReportAccessTokenFilter extends OncePerRequestFilter {
private static final String UNAUTHORIZED_MSG = "未认证,请提供有效的访问Token";
public static final String HEADER_X_BI_ACCESS_TOKEN = "X-BI-Access-Token";
private final BiAccessProperties accessProperties;
public BiReportAccessTokenFilter(BiAccessProperties accessProperties) {
this.accessProperties = accessProperties;
}
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
filterChain.doFilter(request, response);
return;
}
String presented = request.getHeader(HEADER_X_BI_ACCESS_TOKEN);
if (!StringUtils.hasText(presented)) {
writeUnauthorized(response);
return;
}
String expected = accessProperties.getAccessToken();
if (StringUtils.hasText(expected) && !expected.equals(presented)) {
writeUnauthorized(response);
return;
}
filterChain.doFilter(request, response);
}
private static void writeUnauthorized(HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setContentType("application/json;charset=UTF-8");
String body = "{\"code\":401,\"msg\":\"" + UNAUTHORIZED_MSG.replace("\"", "\\\"") + "\"}";
response.getOutputStream().write(body.getBytes(StandardCharsets.UTF_8));
}
}
@@ -0,0 +1,23 @@
package com.mhd.bi.domain.biComprehensive.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
/**
* 综合态势SQL BiComprehensiveReportMapper.xml取数与组装均在 Mapper 层完成
*/
public interface BiComprehensiveReportMapper {
String selectLatestPayloadJson();
/**
* 最新快照 VO内部调用 {@link #selectLatestPayloadJson()}
*/
default ComprehensiveSituationVO loadLatestComprehensive() {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(),
ComprehensiveSituationVO.class,
BiReportSnapshotMapperSupport::emptyComprehensiveSituation,
"综合态势");
}
}
@@ -0,0 +1,21 @@
package com.mhd.bi.domain.biComprehensive.service;
import com.mhd.bi.domain.biComprehensive.repository.mapper.BiComprehensiveReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 综合态势数据访问仅经 Mapper XML SQL Mapper 默认方法组装
*/
@Service
public class BiComprehensiveReportService {
@Resource
private BiComprehensiveReportMapper biComprehensiveReportMapper;
public ComprehensiveSituationVO loadLatestComprehensive() {
return biComprehensiveReportMapper.loadLatestComprehensive();
}
}
@@ -0,0 +1,20 @@
package com.mhd.bi.domain.biHkMacaoServiceZone.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone.HkMacaoServiceZoneVO;
/**
* 港澳服务专区 NGWL_TEST_BI.BI_HK_MACAO_SERVICE_ZONE_SNAPSHOT 最新 PAYLOAD_JSON 并解析
*/
public interface BiHkMacaoServiceZoneReportMapper {
String selectLatestPayloadJson();
default HkMacaoServiceZoneVO loadLatestHkMacaoServiceZone() {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(),
HkMacaoServiceZoneVO.class,
BiReportSnapshotMapperSupport::emptyHkMacaoServiceZone,
"港澳服务专区");
}
}
@@ -0,0 +1,21 @@
package com.mhd.bi.domain.biHkMacaoServiceZone.service;
import com.mhd.bi.domain.biHkMacaoServiceZone.repository.mapper.BiHkMacaoServiceZoneReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone.HkMacaoServiceZoneVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 港澳服务专区
*/
@Service
public class BiHkMacaoServiceZoneReportService {
@Resource
private BiHkMacaoServiceZoneReportMapper biHkMacaoServiceZoneReportMapper;
public HkMacaoServiceZoneVO loadLatestHkMacaoServiceZone() {
return biHkMacaoServiceZoneReportMapper.loadLatestHkMacaoServiceZone();
}
}
@@ -0,0 +1,150 @@
package com.mhd.bi.domain.biHkMacaoServiceZone.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone.*;
import java.util.Arrays;
import java.util.List;
/**
* 港澳服务专区快照演示数据对齐大屏示例 JSON后续可改为真实聚合
*/
public final class HkMacaoServiceZoneDemoData {
private HkMacaoServiceZoneDemoData() {
}
public static HkMacaoServiceZoneVO build() {
HkOrderStatsVO orderStats = HkOrderStatsVO.builder()
.totalOrders(4361L)
.unit("")
.momGrowth("+12.5%")
.trend("up")
.build();
List<HkPercentageDetailVO> goodsDetails = Arrays.asList(
HkPercentageDetailVO.builder().name("广东").percentage("25%").build(),
HkPercentageDetailVO.builder().name("澳门").percentage("25%").build(),
HkPercentageDetailVO.builder().name("广西").percentage("50%").build()
);
List<HkPercentageDetailVO> crossBorderDetails = Arrays.asList(
HkPercentageDetailVO.builder().name("出口订单").percentage("25.8%").build(),
HkPercentageDetailVO.builder().name("进口订单").percentage("16.8%").build()
);
List<HkOrderTrendMonthVO> warehouseOrderTrend = Arrays.asList(
HkOrderTrendMonthVO.builder().month("1月").orderRatio(150).orderCount(400).build(),
HkOrderTrendMonthVO.builder().month("2月").orderRatio(200).orderCount(250).build(),
HkOrderTrendMonthVO.builder().month("3月").orderRatio(250).orderCount(300).build(),
HkOrderTrendMonthVO.builder().month("4月").orderRatio(200).orderCount(280).build(),
HkOrderTrendMonthVO.builder().month("5月").orderRatio(280).orderCount(320).build(),
HkOrderTrendMonthVO.builder().month("6月").orderRatio(220).orderCount(310).build(),
HkOrderTrendMonthVO.builder().month("7月").orderRatio(260).orderCount(330).build()
);
List<HkMonthRatePointVO> turnoverData = Arrays.asList(
HkMonthRatePointVO.builder().month("11月").rate(10).build(),
HkMonthRatePointVO.builder().month("12月").rate(15).build(),
HkMonthRatePointVO.builder().month("1月").rate(22).build(),
HkMonthRatePointVO.builder().month("2月").rate(20).build(),
HkMonthRatePointVO.builder().month("3月").rate(12).build(),
HkMonthRatePointVO.builder().month("4月").rate(16).build()
);
List<HkMonthValuePointVO> cargoVolumeTrend = Arrays.asList(
HkMonthValuePointVO.builder().month("1月").value(80).build(),
HkMonthValuePointVO.builder().month("2月").value(85).build(),
HkMonthValuePointVO.builder().month("3月").value(90).build(),
HkMonthValuePointVO.builder().month("4月").value(70).build(),
HkMonthValuePointVO.builder().month("5月").value(95).build(),
HkMonthValuePointVO.builder().month("6月").value(88).build()
);
List<HkOrderTrendMonthVO> transportOrderTrend = Arrays.asList(
HkOrderTrendMonthVO.builder().month("1月").orderRatio(150).orderCount(400).build(),
HkOrderTrendMonthVO.builder().month("2月").orderRatio(200).orderCount(250).build(),
HkOrderTrendMonthVO.builder().month("3月").orderRatio(250).orderCount(300).build(),
HkOrderTrendMonthVO.builder().month("4月").orderRatio(200).orderCount(280).build(),
HkOrderTrendMonthVO.builder().month("5月").orderRatio(280).orderCount(320).build(),
HkOrderTrendMonthVO.builder().month("6月").orderRatio(220).orderCount(310).build(),
HkOrderTrendMonthVO.builder().month("7月").orderRatio(260).orderCount(330).build()
);
List<HkMonthRatePointVO> onTimeDeliveryRate = Arrays.asList(
HkMonthRatePointVO.builder().month("1月").rate(90).build(),
HkMonthRatePointVO.builder().month("2月").rate(92).build(),
HkMonthRatePointVO.builder().month("3月").rate(88).build(),
HkMonthRatePointVO.builder().month("4月").rate(85).build(),
HkMonthRatePointVO.builder().month("5月").rate(95).build(),
HkMonthRatePointVO.builder().month("6月").rate(93).build()
);
List<HkMapPointVO> mapPoints = Arrays.asList(
HkMapPointVO.builder()
.id("wh_001")
.type("warehouse")
.name("通宇保税仓")
.status("normal")
.location(HkMapLocationVO.builder().lat(22.2800).lng(113.5600).build())
.metrics(HkWarehouseMetricsVO.builder()
.inboundOperations(1)
.outboundOperations(1)
.build())
.build(),
HkMapPointVO.builder()
.id("vehicle_88888")
.type("vehicle")
.name("粤A88888")
.status("in_transit")
.location(HkMapLocationVO.builder().lat(22.2500).lng(113.5500).build())
.details(HkVehicleDetailsVO.builder()
.warehouseName("通宇")
.licensePlate("粤A88888")
.loadingAddress("珠海")
.destinationAddress("澳门")
.currentLocation("珠海市")
.updateTime("2026年4月15日 17:52")
.build())
.build()
);
return HkMacaoServiceZoneVO.builder()
.warehouseOrderStats(orderStats)
.clientServiceStats(HkClientServiceStatsVO.builder()
.hkMacaoClients(26)
.clientRatio("10.5%")
.warehouseUsageArea("1688m2")
.areaRatio("1.5%")
.build())
.goodsSourceStats(HkRingChartStatsVO.builder()
.totalOrders(1000)
.details(goodsDetails)
.build())
.crossBorderOrderStats(HkRingChartStatsVO.builder()
.totalOrders(400)
.details(crossBorderDetails)
.build())
.warehouseOrderTrend(warehouseOrderTrend)
.inventoryTurnoverTrend(HkInventoryTurnoverTrendVO.builder()
.currentMonthRate("3次")
.annualRate("4次")
.unit("")
.data(turnoverData)
.build())
.transportOrderStats(orderStats)
.doorToDoorEfficiency(HkDoorToDoorEfficiencyVO.builder()
.averageTime("28.6分")
.fastestTime("13.2分")
.momGrowth("+30%")
.build())
.crossBorderTransportStats(HkRingChartStatsVO.builder()
.totalOrders(400)
.details(crossBorderDetails)
.build())
.cargoVolumeTrend(cargoVolumeTrend)
.transportOrderTrend(transportOrderTrend)
.onTimeDeliveryRate(onTimeDeliveryRate)
.mapData(HkMapDataVO.builder().points(mapPoints).build())
.build();
}
}
@@ -0,0 +1,23 @@
package com.mhd.bi.domain.biOverallOperation.repository.mapper;
import com.mhd.bi.domain.biOverallOperation.support.OverallOperationPayloadNormalizer;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
/**
* 总体运营态势SQL BiOverallOperationReportMapper.xml取数与组装均在 Mapper 层完成
*/
public interface BiOverallOperationReportMapper {
String selectLatestPayloadJson();
default OverallOperationSituationVO loadLatestOverallOperation() {
String json = OverallOperationPayloadNormalizer.normalizeJson(selectLatestPayloadJson());
OverallOperationSituationVO vo = BiReportSnapshotMapperSupport.parsePayload(
json,
OverallOperationSituationVO.class,
BiReportSnapshotMapperSupport::emptyOverallOperationSituation,
"总体运营态势");
return OverallOperationPayloadNormalizer.ensureDefaults(vo);
}
}
@@ -0,0 +1,21 @@
package com.mhd.bi.domain.biOverallOperation.service;
import com.mhd.bi.domain.biOverallOperation.repository.mapper.BiOverallOperationReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 南光物流业务经营分析 · 总体运营态势大图1
*/
@Service
public class BiOverallOperationReportService {
@Resource
private BiOverallOperationReportMapper biOverallOperationReportMapper;
public OverallOperationSituationVO loadLatestOverallOperation() {
return biOverallOperationReportMapper.loadLatestOverallOperation();
}
}
@@ -0,0 +1,95 @@
package com.mhd.bi.domain.biOverallOperation.support;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mhd.bi.domain.biReport.support.BiInventoryTurnoverTrendSupport;
import com.mhd.bi.domain.biReport.support.BiOnTimeDeliveryRateChartSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallTransportOperationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallWarehouseOperationVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/**
* 总体运营态势左侧 warehouse.turnover_rate_trend右下角 transport.on_time_rate
*/
@Slf4j
public final class OverallOperationPayloadNormalizer {
private static final ObjectMapper MAPPER = new ObjectMapper();
private OverallOperationPayloadNormalizer() {
}
public static String normalizeJson(String json) {
if (StringUtils.isBlank(json)) {
return json;
}
try {
JsonNode root = MAPPER.readTree(json.trim());
boolean changed = false;
ObjectNode rootObj = (ObjectNode) root;
JsonNode warehouse = root.path("warehouse");
if (warehouse.isObject()) {
ObjectNode warehouseObj = (ObjectNode) warehouse;
if (warehouseObj.has("map") && !rootObj.has("map")) {
rootObj.set("map", warehouseObj.remove("map"));
changed = true;
}
if (warehouseObj.has("transport") && !rootObj.has("transport")) {
rootObj.set("transport", warehouseObj.remove("transport"));
changed = true;
}
if (warehouseObj.has("capabilityRanking")) {
warehouseObj.remove("capabilityRanking");
changed = true;
}
if (warehouseObj.has("on_time_rate")) {
warehouseObj.remove("on_time_rate");
changed = true;
}
if (!warehouseObj.has("turnover_rate_trend")) {
warehouseObj.set("turnover_rate_trend",
MAPPER.valueToTree(BiInventoryTurnoverTrendSupport.defaultTrend()));
changed = true;
}
}
JsonNode transport = root.path("transport");
if (transport.isObject()) {
ObjectNode transportObj = (ObjectNode) transport;
if (transportObj.has("enterpriseRanking")) {
transportObj.remove("enterpriseRanking");
changed = true;
}
if (!transportObj.has("on_time_rate")) {
transportObj.set("on_time_rate",
MAPPER.valueToTree(BiOnTimeDeliveryRateChartSupport.defaultChart()));
changed = true;
}
}
return changed ? MAPPER.writeValueAsString(root) : json;
} catch (Exception e) {
log.warn("总体运营态势 PAYLOAD_JSON 规范化失败,按原 JSON 解析", e);
return json;
}
}
public static OverallOperationSituationVO ensureDefaults(OverallOperationSituationVO vo) {
if (vo == null) {
return null;
}
OverallWarehouseOperationVO warehouse = vo.getWarehouse();
if (warehouse != null && BiInventoryTurnoverTrendSupport.isEmpty(warehouse.getTurnoverRateTrend())) {
warehouse.setTurnoverRateTrend(BiInventoryTurnoverTrendSupport.defaultTrend());
}
OverallTransportOperationVO transport = vo.getTransport();
if (transport != null && BiOnTimeDeliveryRateChartSupport.isChartEmpty(transport.getOnTimeRate())) {
transport.setOnTimeRate(BiOnTimeDeliveryRateChartSupport.defaultChart());
}
return vo;
}
}
@@ -0,0 +1,20 @@
package com.mhd.bi.domain.biPlatformSurveillance.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
/**
* 月台监测SQL BiPlatformSurveillanceReportMapper.xml取数与组装均在 Mapper 层完成
*/
public interface BiPlatformSurveillanceReportMapper {
String selectLatestPayloadJson();
default PlatformSurveillanceVO loadLatestPlatformSurveillance() {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(),
PlatformSurveillanceVO.class,
BiReportSnapshotMapperSupport::emptyPlatformSurveillance,
"月台监测");
}
}
@@ -0,0 +1,18 @@
package com.mhd.bi.domain.biPlatformSurveillance.service;
import com.mhd.bi.domain.biPlatformSurveillance.repository.mapper.BiPlatformSurveillanceReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class BiPlatformSurveillanceReportService {
@Resource
private BiPlatformSurveillanceReportMapper biPlatformSurveillanceReportMapper;
public PlatformSurveillanceVO loadLatestPlatformSurveillance() {
return biPlatformSurveillanceReportMapper.loadLatestPlatformSurveillance();
}
}
@@ -0,0 +1,42 @@
package com.mhd.bi.domain.biReport.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WhMonthRatePointVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WhTurnoverRateTrendVO;
import java.util.Arrays;
/**
* 总体运营态势左侧库存周转率趋势默认数据与仓储运营专区 turnover_rate_trend 结构一致
*/
public final class BiInventoryTurnoverTrendSupport {
private BiInventoryTurnoverTrendSupport() {
}
public static WhTurnoverRateTrendVO defaultTrend() {
return WhTurnoverRateTrendVO.builder()
.currentMonth("3次")
.annual("4次")
.data(Arrays.asList(
WhMonthRatePointVO.builder().month("11月").rate(10).build(),
WhMonthRatePointVO.builder().month("12月").rate(15).build(),
WhMonthRatePointVO.builder().month("1月").rate(22).build(),
WhMonthRatePointVO.builder().month("2月").rate(20).build(),
WhMonthRatePointVO.builder().month("3月").rate(12).build(),
WhMonthRatePointVO.builder().month("4月").rate(16).build()
))
.build();
}
public static boolean isEmpty(WhTurnoverRateTrendVO trend) {
return trend == null || trend.getData() == null || trend.getData().isEmpty();
}
public static WhTurnoverRateTrendVO emptyShell() {
return WhTurnoverRateTrendVO.builder()
.currentMonth("")
.annual("")
.data(java.util.Collections.emptyList())
.build();
}
}
@@ -0,0 +1,50 @@
package com.mhd.bi.domain.biReport.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TrMonthValuePointVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TrTypedChartVO;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 准时配送率折线图总体运营 transport.on_time_rate运输运营专区 on_time_rate 共用
*/
public final class BiOnTimeDeliveryRateChartSupport {
private BiOnTimeDeliveryRateChartSupport() {
}
public static TrTypedChartVO defaultChart() {
return TrTypedChartVO.builder()
.title("准时配送率")
.type("line")
.unit("%")
.data(defaultMonthPoints())
.build();
}
public static List<TrMonthValuePointVO> defaultMonthPoints() {
return Arrays.asList(
TrMonthValuePointVO.builder().month("1月").value(98).build(),
TrMonthValuePointVO.builder().month("2月").value(96).build(),
TrMonthValuePointVO.builder().month("3月").value(85).build(),
TrMonthValuePointVO.builder().month("4月").value(70).build(),
TrMonthValuePointVO.builder().month("5月").value(92).build(),
TrMonthValuePointVO.builder().month("6月").value(90).build()
);
}
public static boolean isChartEmpty(TrTypedChartVO chart) {
return chart == null || chart.getData() == null || chart.getData().isEmpty();
}
public static TrTypedChartVO emptyChartShell() {
return TrTypedChartVO.builder()
.title("")
.type("")
.unit("")
.data(Collections.emptyList())
.build();
}
}
@@ -0,0 +1,276 @@
package com.mhd.bi.domain.biReport.support;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.CustomerContributionRankVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TrTypedChartVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.function.Supplier;
/**
* Mapper 层使用的快照 JSON 解析与空态SQL 仅定义在对应 Mapper.xml查询条件见各 XMLDEL_FLAG=1 CREATE_TIME 取最新
*/
@Slf4j
public final class BiReportSnapshotMapperSupport {
private static final ObjectMapper MAPPER = new ObjectMapper();
private BiReportSnapshotMapperSupport() {
}
public static <T> T parsePayload(String json, Class<T> type, Supplier<T> empty, String logLabel) {
if (StringUtils.isBlank(json)) {
return empty.get();
}
try {
return MAPPER.readValue(json.trim(), type);
} catch (Exception e) {
log.warn("{} PAYLOAD_JSON 解析失败,返回空态", logLabel, e);
return empty.get();
}
}
public static ComprehensiveSituationVO emptyComprehensiveSituation() {
return ComprehensiveSituationVO.builder()
.valueAddedServiceIncome(0L)
.inventoryTurnover(0)
.orderCount(0)
.vehicleUtilizationRate(0d)
.fuelConsumptionPerHundredKm(0)
.incomeTrend(Collections.emptyList())
.build();
}
public static WarehouseTransportSituationVO emptyWarehouseTransportSituation() {
return WarehouseTransportSituationVO.builder()
.warehouseDistributionOnTimeRate(0d)
.currentYearOrders(0L)
.currentQuarterOrders(0)
.currentMonthOrders(0)
.warehouseOrderTrend(Collections.emptyList())
.throughput(Collections.emptyList())
.currentMonthTurnoverRate(0)
.currentYearTurnoverRate(0)
.inventoryTurnoverTrend(Collections.emptyList())
.totalTransportIncome(0)
.orderCount(0)
.transportTrips(0)
.annualTransportVolume(0)
.transportOrderTotal(0)
.crossBorderTransportOrder(0)
.domesticTransportOrder(0)
.transportTripsTrend(Collections.emptyList())
.vehicleUtilizationRate(Collections.emptyList())
.warehouseDockSyncRate(Collections.emptyList())
.customerContributionRank(CustomerContributionRankVO.builder()
.customerName(Collections.emptyList())
.customerAmount(Collections.emptyList())
.build())
.build();
}
public static PlatformSurveillanceVO emptyPlatformSurveillance() {
return PlatformSurveillanceVO.builder()
.vehicles(Collections.emptyList())
.efficiencyStatistics(EfficiencyStatisticsVO.builder()
.entryOvertimeRate(0).overtimeCount(0).platformOnTimeRate(0)
.avgPlatformDuration(0d).yardOnTimeRate(0).avgYardDuration(0d).build())
.platformOverview(PlatformOverviewVO.builder()
.totalPlatforms(0).currentOccupancyRate(0).operatingPlatforms(0).todayTasks(0).build())
.vehicleStatus(VehicleStatusVO.builder()
.todayReservedVehicles(0).notCheckedIn(0).operatingVehicles(0).completedVehicles(0).build())
.avgOperationDurationTrend(Collections.emptyList())
.monthlyTaskStatistics(MonthlyTaskStatisticsVO.builder()
.taskTotal(0).taskTotalYoY(0).avgTaskDuration(0d).avgDurationYoY(0)
.taskCompletionRate(0).completionRateYoY(0).build())
.taskLoadStatistics(Collections.emptyList())
.platformAlarmTrend(Collections.emptyList())
.taskTypeStatistics(TaskTypeStatisticsVO.builder()
.totalTasks(0).taskTypes(Collections.emptyList()).build())
.platformAlarmStatistics(PlatformAlarmStatisticsVO.builder()
.todayAlarmTotal(0).handled(0).unhandled(0).build())
.platformAlarmDistribution(Collections.emptyList())
.build();
}
public static OverallOperationSituationVO emptyOverallOperationSituation() {
return OverallOperationSituationVO.builder()
.updateTime("")
.warehouse(OverallWarehouseOperationVO.builder()
.orderStatistics(OverallWarehouseOrderStatisticVO.builder()
.processedOrderCount(0L).changePercent(0d).build())
.coreCapability(OverallWarehouseCoreCapabilityVO.builder()
.totalWarehouses(0).selfOperatedCount(0).outsourcedCount(0)
.operatingArea(0).areaUnit("")
.build())
.orderTrendByMonth(Collections.emptyList())
.throughputTrendByMonth(Collections.emptyList())
.bizStatistics(OverallWarehouseBizStatisticVO.builder()
.customerCount(0L).coverageArea("")
.annualThroughput(0).throughputUnit("").throughputGrowth(0d)
.build())
.turnoverRateTrend(BiInventoryTurnoverTrendSupport.defaultTrend())
.build())
.map(OverallMapSectionVO.builder().nodes(Collections.emptyList()).build())
.transport(OverallTransportOperationVO.builder()
.orderSummary(OverallTransportOrderSummaryVO.builder()
.processedOrderCount(0L).changePercent(0d)
.annualFreight(0d).freightUnit("").freightGrowth(0d)
.build())
.capacityStatistics(OverallTransportCapacityVO.builder()
.totalVehicles(0).ownedVehicles(0).socialVehicles(0)
.totalDrivers(0).ownedDrivers(0).socialDrivers(0)
.build())
.orderTrendByMonth(Collections.emptyList())
.freightTrendByMonth(Collections.emptyList())
.orderDistribution(OverallTransportModeDistributionVO.builder()
.crossBorder(0L).domestic(0L).build())
.onTimeRate(BiOnTimeDeliveryRateChartSupport.emptyChartShell())
.build())
.build();
}
public static WarehouseOperationZoneVO emptyWarehouseOperationZone() {
WhColdStorageMetricVO emptyColdMetric = WhColdStorageMetricVO.builder().value("").trend("").build();
return WarehouseOperationZoneVO.builder()
.warehouseName("")
.updateTime("")
.orderSummary(WhOrderSummaryVO.builder()
.totalCount("")
.inboundOrders(WhOrderSummaryCountItemVO.builder().label("").value(0).build())
.outboundOrders(WhOrderSummaryCountItemVO.builder().label("").value(0).build())
.operationOrders(WhOrderSummaryCountItemVO.builder().label("").value(0).build())
.build())
.coldStorageStats(WhColdStorageStatsVO.builder()
.revenueShare(emptyColdMetric)
.utilizationRate(emptyColdMetric)
.damageRate(emptyColdMetric)
.build())
.temperatureExceptions(Collections.emptyList())
.storageOverview(WhStorageOverviewVO.builder()
.title("").value(0).unit("").subText("").build())
.operationStats(WhOperationStatsVO.builder()
.title("").value(0).unit("").growthRate("").trend("").build())
.businessPlanning(WhBusinessPlanningVO.builder()
.generalWarehouse(0).coldStorage(0).foodProcessing(0).automatedStorage(0).build())
.throughputTrend(Collections.emptyList())
.areaDistribution(WhAreaDistributionVO.builder()
.utilizationRate("").details(Collections.emptyList()).build())
.capacityUtilizationTrend(WhCapacityUtilizationTrendVO.builder()
.peakLabel("").data(Collections.emptyList()).build())
.orderStatistics(WhOrderStatisticsVO.builder()
.annualOrders(0L).quarterlyOrders(0L).monthlyOrders(0L).build())
.serviceStatistics(WhServiceStatisticsVO.builder()
.clients(0).coverage("").onTimeRate("").rateChange("").build())
.orderTrend(Collections.emptyList())
.turnoverRateTrend(WhTurnoverRateTrendVO.builder()
.currentMonth("").annual("").data(Collections.emptyList()).build())
.serviceCapacity(Collections.emptyList())
.realTimeAnalysis(WhRealTimeAnalysisVO.builder()
.utilizationRate(WhRealTimeGaugeVO.builder().value("").comparison("").trend("").build())
.rentalRate(WhRealTimeGaugeVO.builder().value("").comparison("").trend("").build())
.build())
.map(WhWarehouseMapVO.builder()
.legend("")
.nodes(Collections.emptyList())
.build())
.build();
}
public static TransportOperationZoneVO emptyTransportOperationZone() {
TrCapacityCountVO emptyCount = TrCapacityCountVO.builder()
.total(0).todayNew(0).yesterdayNew(0).build();
return TransportOperationZoneVO.builder()
.updateTime("")
.dashboardTitle("")
.activeTab("")
.orderStatistics(TrOrderStatisticsVO.builder().title("").total(0L).trend("").build())
.transportStats(TrTransportStatsVO.builder()
.title("").tripCount(0).volume(0d).volumeUnit("").build())
.orderTypeChart(TrOrderTypeChartVO.builder()
.title("").type("").data(Collections.emptyList()).build())
.tripCountTrend(TrTypedChartVO.builder()
.title("").type("").unit(null).data(Collections.emptyList()).build())
.orderTrend(TrTypedChartVO.builder()
.title("").type("").unit("").data(Collections.emptyList()).build())
.volumeTrend(TrTypedChartVO.builder()
.title("").type("").unit("").data(Collections.emptyList()).build())
.map(TrVehicleMapVO.builder()
.title("")
.legend(TrMapLegendVO.builder().idle(0).working(0).build())
.nodes(Collections.emptyList())
.build())
.enterpriseOperation(TrEnterpriseOperationVO.builder()
.title("").columns(Collections.emptyList()).list(Collections.emptyList()).build())
.capacityStatus(TrCapacityStatusVO.builder()
.title("").staff(emptyCount).vehicles(emptyCount).build())
.cargoCategory(TrCargoCategoryVO.builder()
.title("").totalOrders("").data(Collections.emptyList()).build())
.onTimeRate(TrTypedChartVO.builder()
.title("").type("").unit("").data(Collections.emptyList()).build())
.vehicleUtilization(TrBarChartVO.builder()
.title("").unit("").data(Collections.emptyList()).build())
.transportSummary(TrTransportSummaryVO.builder()
.title("").safeMileage("").avgDeliveryTime("").build())
.capacityStats(TrCapacityStatsVO.builder()
.vehicles(emptyCapacityStatItem())
.drivers(emptyCapacityStatItem())
.escorts(emptyCapacityStatItem())
.build())
.cargoTypeDistribution(TrCargoTypeDistributionVO.builder()
.title("").totalOrders(0).totalUnit("").details(Collections.emptyList()).build())
.freshOrderStats(emptyBrandOrderStats())
.vitasoyOrderStats(emptyBrandOrderStats())
.build();
}
private static TrBrandOrderStatsVO emptyBrandOrderStats() {
return TrBrandOrderStatsVO.builder()
.plannedDelivery(TrOrderStatMetricVO.builder().value(0).unit("").label("").build())
.orderQuantity(TrOrderStatMetricVO.builder().value(0).unit("").label("").build())
.vehiclesInTransit(TrOrderStatMetricVO.builder().value(0).unit("").label("").build())
.completedDelivery(TrOrderStatTextMetricVO.builder().value("").unit("").label("").build())
.overtimeDelivery(TrOrderStatMetricVO.builder().value(0).unit("").label("").build())
.onTimeRate(TrOrderStatRateMetricVO.builder().value("").trend("").label("").build())
.build();
}
private static TrCapacityStatItemVO emptyCapacityStatItem() {
return TrCapacityStatItemVO.builder().value(0).unit("").label("").build();
}
public static HkMacaoServiceZoneVO emptyHkMacaoServiceZone() {
HkOrderStatsVO emptyOrderStats = HkOrderStatsVO.builder()
.totalOrders(0L).unit("").momGrowth("").trend("").build();
return HkMacaoServiceZoneVO.builder()
.warehouseOrderStats(emptyOrderStats)
.clientServiceStats(HkClientServiceStatsVO.builder()
.hkMacaoClients(0).clientRatio("").warehouseUsageArea("").areaRatio("").build())
.goodsSourceStats(HkRingChartStatsVO.builder()
.totalOrders(0).details(Collections.emptyList()).build())
.crossBorderOrderStats(HkRingChartStatsVO.builder()
.totalOrders(0).details(Collections.emptyList()).build())
.warehouseOrderTrend(Collections.emptyList())
.inventoryTurnoverTrend(HkInventoryTurnoverTrendVO.builder()
.currentMonthRate("").annualRate("").unit("").data(Collections.emptyList()).build())
.transportOrderStats(emptyOrderStats)
.doorToDoorEfficiency(HkDoorToDoorEfficiencyVO.builder()
.averageTime("").fastestTime("").momGrowth("").build())
.crossBorderTransportStats(HkRingChartStatsVO.builder()
.totalOrders(0).details(Collections.emptyList()).build())
.cargoVolumeTrend(Collections.emptyList())
.transportOrderTrend(Collections.emptyList())
.onTimeDeliveryRate(Collections.emptyList())
.mapData(HkMapDataVO.builder().points(Collections.emptyList()).build())
.build();
}
}
@@ -0,0 +1,18 @@
package com.mhd.bi.domain.biReport.support;
/**
* BI 快照表 {@code DEL_FLAG} 取值三张 *\_SNAPSHOT 表一致
* <p>查询接口仅返回 {@link #NORMAL}</p>
*/
public final class BiSnapshotDelFlag {
/** 无状态 */
public static final int NONE = 0;
/** 正常(接口查询可见) */
public static final int NORMAL = 1;
/** 已删除(逻辑删除,接口不返回) */
public static final int DELETED = 2;
private BiSnapshotDelFlag() {
}
}
@@ -0,0 +1,23 @@
package com.mhd.bi.domain.biSnapshotSync.repository.mapper;
import org.apache.ibatis.annotations.Param;
/**
* BI 快照表写入定时同步任务使用
*/
public interface BiSnapshotWriteMapper {
int insertComprehensiveSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertWarehouseTransportSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertPlatformSurveillanceSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertOverallOperationSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertWarehouseOperationZoneSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertTransportOperationZoneSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertHkMacaoServiceZoneSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
}
@@ -0,0 +1,28 @@
package com.mhd.bi.domain.biSnapshotSync.scheduler;
import com.mhd.bi.domain.biSnapshotSync.service.BiReportSnapshotSyncService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 定时将业务快照写入 BI_COMPREHENSIVE_SNAPSHOT / BI_WAREHOUSE_TRANSPORT_SNAPSHOT / BI_PLATFORM_SURVEILLANCE_SNAPSHOT / BI_OVERALL_OPERATION_SNAPSHOT / BI_WAREHOUSE_OPERATION_ZONE_SNAPSHOT / BI_TRANSPORT_OPERATION_ZONE_SNAPSHOT
* <p>默认关闭需在配置中设置 {@code mhd.bi.snapshot-sync.enabled=true}</p>
*/
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "mhd.bi.snapshot-sync", name = "enabled", havingValue = "true")
public class BiReportSnapshotSyncScheduler {
private final BiReportSnapshotSyncService biReportSnapshotSyncService;
@Scheduled(cron = "${mhd.bi.snapshot-sync.cron:0 0 2 * * ?}")
public void runSnapshotSync() {
log.info("BI 报表快照定时同步开始");
biReportSnapshotSyncService.syncAllSnapshots();
log.info("BI 报表快照定时同步结束");
}
}
@@ -0,0 +1,193 @@
package com.mhd.bi.domain.biSnapshotSync.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mhd.bi.domain.biSnapshotSync.repository.mapper.BiSnapshotWriteMapper;
import com.mhd.bi.domain.biSnapshotSync.support.BiSnapshotWeeklyRandomDataBuilder;
import com.mhd.bi.domain.biHkMacaoServiceZone.support.HkMacaoServiceZoneDemoData;
import com.mhd.bi.domain.biTransportOperationZone.support.TransportOperationZoneDemoData;
import com.mhd.bi.domain.biWarehouseOperationZone.support.WarehouseOperationZoneDemoData;
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.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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Random;
/**
* BI 快照表定时同步综合态势 / 仓储运输 / 月台监测 / 总体运营态势 / 仓储运营专区 / 运输运营专区 / 港澳服务专区
* <p><b>当前临时</b>{@code build*} 使用 {@link BiSnapshotWeeklyRandomDataBuilder}每次执行使用新的 {@link Random}
* <b>同一天多次手动触发以及每次定时任务执行</b>生成的模拟数据均<b>不相同</b>仍在基准 ±20% </p>
* <p><b>后续改造</b>在各 {@code build*} 中改为查库/Feign 聚合真实业务并组装 VO</p>
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class BiReportSnapshotSyncService {
private static final String REMARK_SYNC = "scheduled snapshot-sync";
private final BiSnapshotWriteMapper biSnapshotWriteMapper;
private final ObjectMapper objectMapper;
/**
* 依次同步各快照表单表失败不影响其它表只记日志
*/
public void syncAllSnapshots() {
syncComprehensiveSnapshot();
syncWarehouseTransportSnapshot();
syncPlatformSurveillanceSnapshot();
syncOverallOperationSnapshot();
syncWarehouseOperationZoneSnapshot();
syncTransportOperationZoneSnapshot();
syncHkMacaoServiceZoneSnapshot();
}
public void syncComprehensiveSnapshot() {
try {
ComprehensiveSituationVO vo = buildComprehensiveSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertComprehensiveSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 综合态势快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_COMPREHENSIVE_SNAPSHOT 权限及库是否一致", rows);
}
log.info("BI 综合态势快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 综合态势快照同步失败", e);
}
}
public void syncWarehouseTransportSnapshot() {
try {
WarehouseTransportSituationVO vo = buildWarehouseTransportSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertWarehouseTransportSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 仓储运输快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_WAREHOUSE_TRANSPORT_SNAPSHOT", rows);
}
log.info("BI 仓储运输快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 仓储运输快照同步失败", e);
}
}
public void syncPlatformSurveillanceSnapshot() {
try {
PlatformSurveillanceVO vo = buildPlatformSurveillanceSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertPlatformSurveillanceSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 月台监测快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_PLATFORM_SURVEILLANCE_SNAPSHOT", rows);
}
log.info("BI 月台监测快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 月台监测快照同步失败", e);
}
}
public void syncOverallOperationSnapshot() {
try {
OverallOperationSituationVO vo = buildOverallOperationSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertOverallOperationSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 总体运营态势快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_OVERALL_OPERATION_SNAPSHOT", rows);
}
log.info("BI 总体运营态势快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 总体运营态势快照同步失败", e);
}
}
public void syncWarehouseOperationZoneSnapshot() {
try {
WarehouseOperationZoneVO vo = buildWarehouseOperationZoneSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertWarehouseOperationZoneSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 仓储运营专区快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_WAREHOUSE_OPERATION_ZONE_SNAPSHOT", rows);
}
log.info("BI 仓储运营专区快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 仓储运营专区快照同步失败", e);
}
}
/**
* TODO 业务落地改为查询真实数据组装 VO临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#overallOperation(Random)}
*/
protected OverallOperationSituationVO buildOverallOperationSnapshot() {
return BiSnapshotWeeklyRandomDataBuilder.overallOperation(new Random());
}
/**
* TODO 业务落地改为查询真实数据组装 VO临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#comprehensive(Random)}
*/
protected ComprehensiveSituationVO buildComprehensiveSnapshot() {
return BiSnapshotWeeklyRandomDataBuilder.comprehensive(new Random());
}
/** TODO 业务落地:改为查询真实数据。临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#warehouseTransport(Random)}。 */
protected WarehouseTransportSituationVO buildWarehouseTransportSnapshot() {
return BiSnapshotWeeklyRandomDataBuilder.warehouseTransport(new Random());
}
/** TODO 业务落地:改为查询真实数据。临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#platformSurveillance(Random)}。 */
protected PlatformSurveillanceVO buildPlatformSurveillanceSnapshot() {
return BiSnapshotWeeklyRandomDataBuilder.platformSurveillance(new Random());
}
/**
* TODO 业务落地改为查询真实数据组装 VO当前为 {@link WarehouseOperationZoneDemoData} 静态示例
*/
protected WarehouseOperationZoneVO buildWarehouseOperationZoneSnapshot() {
return WarehouseOperationZoneDemoData.build();
}
public void syncTransportOperationZoneSnapshot() {
try {
TransportOperationZoneVO vo = buildTransportOperationZoneSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertTransportOperationZoneSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 运输运营专区快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_TRANSPORT_OPERATION_ZONE_SNAPSHOT", rows);
}
log.info("BI 运输运营专区快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 运输运营专区快照同步失败", e);
}
}
/**
* TODO 业务落地改为查询真实数据组装 VO当前为 {@link TransportOperationZoneDemoData} 静态示例
*/
protected TransportOperationZoneVO buildTransportOperationZoneSnapshot() {
return TransportOperationZoneDemoData.build();
}
public void syncHkMacaoServiceZoneSnapshot() {
try {
HkMacaoServiceZoneVO vo = buildHkMacaoServiceZoneSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertHkMacaoServiceZoneSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 港澳服务专区快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_HK_MACAO_SERVICE_ZONE_SNAPSHOT", rows);
}
log.info("BI 港澳服务专区快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 港澳服务专区快照同步失败", e);
}
}
/**
* TODO 业务落地改为查询真实数据组装 VO当前为 {@link HkMacaoServiceZoneDemoData} 静态示例
*/
protected HkMacaoServiceZoneVO buildHkMacaoServiceZoneSnapshot() {
return HkMacaoServiceZoneDemoData.build();
}
}
@@ -0,0 +1,437 @@
package com.mhd.bi.domain.biSnapshotSync.support;
import com.mhd.bi.domain.biReport.support.BiOnTimeDeliveryRateChartSupport;
import com.mhd.bi.domain.biReport.support.BiInventoryTurnoverTrendSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.CustomerContributionRankVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
* <b>临时</b>在基准 ±20% 内生成模拟快照基准对齐 insert_bi_snapshots_alternate_row_dm
* 调用 {@link #comprehensive(Random)} 等时须传入 {@link Random}<b>每次 {@code new Random()} 则每次结果不同</b>
* 若需可重复如单测可传入 {@link #randomForDate(java.time.LocalDate, long)} 等有固定种子的实例
*/
public final class BiSnapshotWeeklyRandomDataBuilder {
private BiSnapshotWeeklyRandomDataBuilder() {
}
/**
* 固定种子如同日多次一致适用于单元测试等生产模拟同步请使用 {@code new Random()}
*/
public static Random randomForDate(LocalDate date, long salt) {
long epochDay = date.toEpochDay();
salt = salt % 1000000007L;
return new Random(epochDay * 1_000_003L + salt * 7919L);
}
/**
* @deprecated 请使用 {@link #randomForDate(LocalDate, long)}历史方法名保留兼容现已按自然日而非 ISO
*/
@Deprecated
public static Random randomForWeekOf(LocalDate date, long salt) {
return randomForDate(date, salt);
}
@Deprecated
public static Random randomForWeekOf(LocalDate date) {
return randomForDate(date, 0L);
}
private static double jitterFactor(Random r) {
return 0.8 + r.nextDouble() * 0.4;
}
static int jitterInt(int base, Random r) {
return (int) Math.round(base * jitterFactor(r));
}
static long jitterLong(long base, Random r) {
return Math.round(base * jitterFactor(r));
}
static double jitterDouble(double base, Random r) {
return Math.round(base * jitterFactor(r) * 10.0) / 10.0;
}
static int jitterPercentInt(int base, Random r) {
return Math.min(100, Math.max(0, jitterInt(base, r)));
}
private static double jitterPercentDouble(double base, Random r) {
double v = base * jitterFactor(r);
return Math.min(100.0, Math.max(0.0, Math.round(v * 10.0) / 10.0));
}
private static List<Integer> jitterIntArray(int[] arr, Random r) {
return Arrays.stream(arr).map(v -> jitterInt(v, r)).boxed().collect(Collectors.toList());
}
public static ComprehensiveSituationVO comprehensive(Random r) {
return ComprehensiveSituationVO.builder()
.valueAddedServiceIncome(jitterLong(Baseline.COMP_INCOME, r))
.inventoryTurnover(Math.max(1, jitterInt(Baseline.COMP_TURNOVER, r)))
.orderCount(Math.max(0, jitterInt(Baseline.COMP_ORDERS, r)))
.vehicleUtilizationRate(jitterPercentDouble(Baseline.COMP_VEHICLE_PCT, r))
.fuelConsumptionPerHundredKm(Math.max(1, jitterInt(Baseline.COMP_FUEL, r)))
.incomeTrend(jitterIntArray(Baseline.COMP_INCOME_TREND, r))
.build();
}
public static WarehouseTransportSituationVO warehouseTransport(Random r) {
List<Integer> dock = new ArrayList<>();
for (int v : Baseline.W_DOCK) {
dock.add(jitterPercentInt(v, r));
}
List<Integer> custAmt = new ArrayList<>();
for (int v : Baseline.W_CUST_AMT) {
custAmt.add(jitterInt(v, r));
}
return WarehouseTransportSituationVO.builder()
.warehouseDistributionOnTimeRate(jitterPercentDouble(Baseline.W_WH_RATE, r))
.currentYearOrders(jitterLong(Baseline.W_YEAR_ORD, r))
.currentQuarterOrders(Math.max(0, jitterInt(Baseline.W_Q_ORD, r)))
.currentMonthOrders(Math.max(0, jitterInt(Baseline.W_M_ORD, r)))
.warehouseOrderTrend(jitterIntArray(Baseline.W_WH_TREND, r))
.throughput(jitterIntArray(Baseline.W_THROUGH, r))
.currentMonthTurnoverRate(Math.max(1, jitterInt(Baseline.W_M_TOR, r)))
.currentYearTurnoverRate(Math.max(1, jitterInt(Baseline.W_Y_TOR, r)))
.inventoryTurnoverTrend(jitterIntArray(Baseline.W_INV_TR, r))
.totalTransportIncome(Math.max(0, jitterInt(Baseline.W_INCOME, r)))
.orderCount(Math.max(0, jitterInt(Baseline.W_ORD, r)))
.transportTrips(Math.max(0, jitterInt(Baseline.W_TRIPS, r)))
.annualTransportVolume(Math.max(0, jitterInt(Baseline.W_VOL, r)))
.transportOrderTotal(Math.max(0, jitterInt(Baseline.W_TOT, r)))
.crossBorderTransportOrder(Math.max(0, jitterInt(Baseline.W_CB, r)))
.domesticTransportOrder(Math.max(0, jitterInt(Baseline.W_DM, r)))
.transportTripsTrend(jitterIntArray(Baseline.W_TRIP_TR, r))
.vehicleUtilizationRate(jitterIntArray(Baseline.W_VEH_UT, r))
.warehouseDockSyncRate(dock)
.customerContributionRank(CustomerContributionRankVO.builder()
.customerName(Arrays.asList(Baseline.W_CUST_NAMES))
.customerAmount(custAmt)
.build())
.build();
}
public static PlatformSurveillanceVO platformSurveillance(Random r) {
List<PlatformVehicleItemVO> vehicles = new ArrayList<>();
for (String[] row : Baseline.P_PLATES) {
int dur = jitterInt(Integer.parseInt(row[3]), r);
vehicles.add(PlatformVehicleItemVO.builder()
.plateNumber(row[0])
.status(row[1])
.platformId(row[2])
.platformDuration(Math.max(1, dur))
.build());
}
EfficiencyStatisticsVO eff = EfficiencyStatisticsVO.builder()
.entryOvertimeRate(jitterPercentInt(Baseline.P_ENT_OT, r))
.overtimeCount(Math.max(0, jitterInt(Baseline.P_OT_CNT, r)))
.platformOnTimeRate(jitterPercentInt(Baseline.P_PL_OT, r))
.avgPlatformDuration(Math.max(0.1, jitterDouble(Baseline.P_AVG_PL, r)))
.yardOnTimeRate(jitterPercentInt(Baseline.P_YD_OT, r))
.avgYardDuration(Math.max(0.1, jitterDouble(Baseline.P_AVG_YD, r)))
.build();
PlatformOverviewVO overview = PlatformOverviewVO.builder()
.totalPlatforms(Math.max(1, jitterInt(Baseline.P_TOT_PL, r)))
.currentOccupancyRate(jitterPercentInt(Baseline.P_OCC, r))
.operatingPlatforms(Math.max(0, jitterInt(Baseline.P_OP, r)))
.todayTasks(Math.max(0, jitterInt(Baseline.P_TASKS, r)))
.build();
VehicleStatusVO vs = VehicleStatusVO.builder()
.todayReservedVehicles(Math.max(0, jitterInt(Baseline.P_RESV, r)))
.notCheckedIn(Math.max(0, jitterInt(Baseline.P_NC, r)))
.operatingVehicles(Math.max(0, jitterInt(Baseline.P_OPV, r)))
.completedVehicles(Math.max(0, jitterInt(Baseline.P_DONE, r)))
.build();
List<AvgOperationDurationTrendItemVO> avgTrend = new ArrayList<>();
for (int i = 0; i < Baseline.P_MO_LABELS.length; i++) {
avgTrend.add(AvgOperationDurationTrendItemVO.builder()
.month(Baseline.P_MO_LABELS[i])
.yardDuration(Math.max(0.0, jitterDouble(Baseline.P_YD_D[i], r)))
.platformDuration(Math.max(0.0, jitterDouble(Baseline.P_PL_D[i], r)))
.build());
}
MonthlyTaskStatisticsVO monthly = MonthlyTaskStatisticsVO.builder()
.taskTotal(Math.max(0, jitterInt(Baseline.P_MT_TOT, r)))
.taskTotalYoY(jitterInt(Baseline.P_MT_YOY, r))
.avgTaskDuration(Math.max(0.1, jitterDouble(Baseline.P_MT_AVG, r)))
.avgDurationYoY(jitterInt(Baseline.P_MT_AVG_YOY, r))
.taskCompletionRate(jitterPercentInt(Baseline.P_MT_CR, r))
.completionRateYoY(jitterInt(Baseline.P_MT_CR_YOY, r))
.build();
List<TaskLoadItemVO> load = new ArrayList<>();
for (int i = 0; i < Baseline.P_LOAD_T.length; i++) {
load.add(TaskLoadItemVO.builder()
.time(Baseline.P_LOAD_T[i])
.taskCount(Math.max(0, jitterInt(Baseline.P_LOAD_C[i], r)))
.build());
}
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++) {
typeCounts.add(TaskTypeCountItemVO.builder()
.type(Baseline.P_TT_TYPES[i])
.count(Math.max(0, jitterInt(Baseline.P_TT_CNT[i], r)))
.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);
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)
.efficiencyStatistics(eff)
.platformOverview(overview)
.vehicleStatus(vs)
.avgOperationDurationTrend(avgTrend)
.monthlyTaskStatistics(monthly)
.taskLoadStatistics(load)
.platformAlarmTrend(alarmTrend)
.taskTypeStatistics(TaskTypeStatisticsVO.builder()
.totalTasks(Math.max(0, jitterInt(Baseline.P_TT_TOT, r)))
.taskTypes(typeCounts)
.build())
.platformAlarmStatistics(PlatformAlarmStatisticsVO.builder()
.todayAlarmTotal(todayAl)
.handled(handled)
.unhandled(unhandled)
.build())
.platformAlarmDistribution(dist)
.build();
}
/**
* 总体运营态势 {@code create_bi_overall_operation_dm.sql} 内置 PAYLOAD_JSON 一致不随 Random 抖动
*/
public static OverallOperationSituationVO overallOperation(Random r) {
return overallReferenceDashboard();
}
/**
* 与产品约定返回值示例一致供快照同步与联调
* 左侧 {@code warehouse.turnover_rate_trend} 库存周转率趋势右下角 {@code transport.on_time_rate} 准时配送率
*/
public static OverallOperationSituationVO overallReferenceDashboard() {
return OverallOperationSituationVO.builder()
.updateTime("2026-05-11 10:55:00")
.warehouse(OverallWarehouseOperationVO.builder()
.orderStatistics(OverallWarehouseOrderStatisticVO.builder()
.processedOrderCount(6767L)
.changePercent(5.4)
.build())
.coreCapability(OverallWarehouseCoreCapabilityVO.builder()
.totalWarehouses(10)
.selfOperatedCount(4)
.outsourcedCount(6)
.operatingArea(28)
.areaUnit("万m²")
.build())
.orderTrendByMonth(Arrays.asList(
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("1月").inboundOrders(700L).outboundOrders(450L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("2月").inboundOrders(900L).outboundOrders(550L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("3月").inboundOrders(800L).outboundOrders(480L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("4月").inboundOrders(550L).outboundOrders(300L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("5月").inboundOrders(750L).outboundOrders(350L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("6月").inboundOrders(580L).outboundOrders(320L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("7月").inboundOrders(780L).outboundOrders(400L).build()
))
.throughputTrendByMonth(Arrays.asList(
OverallThroughputTrendMonthVO.builder().monthLabel("11月").throughput(10).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("12月").throughput(14).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("1月").throughput(23).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("2月").throughput(22).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("3月").throughput(17).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("4月").throughput(18).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("5月").throughput(9).build()
))
.bizStatistics(OverallWarehouseBizStatisticVO.builder()
.customerCount(582L)
.coverageArea("覆盖港珠澳")
.annualThroughput(26)
.throughputUnit("万吨")
.throughputGrowth(8.5)
.build())
.turnoverRateTrend(BiInventoryTurnoverTrendSupport.defaultTrend())
.build())
.map(OverallMapSectionVO.builder()
.nodes(Arrays.asList(
OverallMapNodeVO.builder()
.type("headquarters")
.name("总部")
.location(Arrays.asList(113.55, 22.25, 0.0))
.build(),
OverallMapNodeVO.builder()
.type("businessUnit")
.name("业务单元")
.location(Arrays.asList(113.55, 22.20, 0.0))
.tooltip(OverallMapTooltipVO.builder()
.title("通宇业务情况分析")
.data(Arrays.asList(
OverallMapTooltipDataItemVO.builder().label("在途车辆").value(3).build(),
OverallMapTooltipDataItemVO.builder().label("在途订单").value(11).build()
))
.build())
.build(),
OverallMapNodeVO.builder()
.type("warehouse")
.name("通宇保税仓")
.location(Arrays.asList(114.16, 22.28, 0.0))
.tooltip(OverallMapTooltipVO.builder()
.title("通宇保税仓情况分析")
.data(Arrays.asList(
OverallMapTooltipDataItemVO.builder().label("入库作业").value(1).build(),
OverallMapTooltipDataItemVO.builder().label("出库作业").value(1).build()
))
.build())
.build()
))
.build())
.transport(OverallTransportOperationVO.builder()
.orderSummary(OverallTransportOrderSummaryVO.builder()
.processedOrderCount(5240L)
.changePercent(6.2)
.annualFreight(2.6)
.freightUnit("万吨")
.freightGrowth(8.5)
.build())
.capacityStatistics(OverallTransportCapacityVO.builder()
.totalVehicles(320)
.ownedVehicles(100)
.socialVehicles(220)
.totalDrivers(400)
.ownedDrivers(160)
.socialDrivers(240)
.build())
.orderTrendByMonth(Arrays.asList(
OverallTransportOrderTrendMonthVO.builder().monthLabel("1月").count(100L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("2月").count(120L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("3月").count(230L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("4月").count(110L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("5月").count(150L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("6月").count(200L).build()
))
.freightTrendByMonth(Arrays.asList(
OverallTransportFreightTrendMonthVO.builder().monthLabel("1月").freight(80).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("2月").freight(110).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("3月").freight(240).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("4月").freight(100).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("5月").freight(140).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("6月").freight(190).build()
))
.orderDistribution(OverallTransportModeDistributionVO.builder()
.crossBorder(2400L)
.domestic(2300L)
.build())
.onTimeRate(BiOnTimeDeliveryRateChartSupport.defaultChart())
.build())
.build();
}
/**
* 基准与 SQL 脚本 alternate sample 一致
*/
private static final class Baseline {
static final long COMP_INCOME = 6_185_000L;
static final int COMP_TURNOVER = 18;
static final int COMP_ORDERS = 50_120;
static final double COMP_VEHICLE_PCT = 93.2;
static final int COMP_FUEL = 12;
static final int[] COMP_INCOME_TREND = {195, 248, 302, 415, 366, 488};
static final double W_WH_RATE = 96.8;
static final long W_YEAR_ORD = 612_800L;
static final int W_Q_ORD = 198_600;
static final int W_M_ORD = 28_440;
static final int[] W_WH_TREND = {82, 91, 77, 68, 103, 89};
static final int[] W_THROUGH = {18, 11, 26, 15, 9, 21};
static final int W_M_TOR = 4;
static final int W_Y_TOR = 5;
static final int[] W_INV_TR = {16, 19, 11, 24, 18, 14};
static final int W_INCOME = 7_230;
static final int W_ORD = 912;
static final int W_TRIPS = 601;
static final int W_VOL = 22;
static final int W_TOT = 5_100;
static final int W_CB = 2_680;
static final int W_DM = 2_420;
static final int[] W_TRIP_TR = {120, 95, 210, 155, 88, 175};
static final int[] W_VEH_UT = {520, 410, 380, 500, 590, 480};
static final int[] W_DOCK = {96, 91, 82, 75, 99, 88};
static final String[] W_CUST_NAMES = {"华东冷链", "华南汽配", "西南快消", "华北家电", "跨境达"};
static final int[] W_CUST_AMT = {198, 172, 205, 189, 221};
static final String[][] P_PLATES = {
{"粤A12345", "待入场", "#12", "88"},
{"闽D99887", "作业中", "#07", "142"},
{"粤B66220", "已离园", "#29", "201"}
};
static final int P_ENT_OT = 42;
static final int P_OT_CNT = 28;
static final int P_PL_OT = 88;
static final double P_AVG_PL = 3.8;
static final int P_YD_OT = 91;
static final double P_AVG_YD = 5.2;
static final int P_TOT_PL = 58;
static final int P_OCC = 62;
static final int P_OP = 31;
static final int P_TASKS = 418;
static final int P_RESV = 2_850;
static final int P_NC = 920;
static final int P_OPV = 1_180;
static final int P_DONE = 1_420;
static final String[] P_MO_LABELS = {"5月", "6月", "7月"};
static final double[] P_YD_D = {12, 16, 19};
static final double[] P_PL_D = {19, 21, 18};
static final int P_MT_TOT = 1_820;
static final int P_MT_YOY = 8;
static final double P_MT_AVG = 5.1;
static final int P_MT_AVG_YOY = -3;
static final int P_MT_CR = 97;
static final int P_MT_CR_YOY = 2;
static final String[] P_LOAD_T = {"8时", "10时", "14时"};
static final int[] P_LOAD_C = {45, 120, 156};
static final String[] P_AL_D = {"1日", "2日", "3日"};
static final int[] P_AL_C = {6, 9, 4};
static final int P_TT_TOT = 5_100;
static final String[] P_TT_TYPES = {"干线发车", "城配到仓", "跨境保税"};
static final int[] P_TT_CNT = {2_100, 1_800, 1_200};
static final int P_AL_TOT = 9;
static final int P_AL_H = 8;
static final String[] P_DIST_T = {"仓储-温湿度", "月台-停留超时", "园区-证件异常"};
static final int[] P_DIST_C = {120, 95, 77};
}
}
@@ -0,0 +1,21 @@
package com.mhd.bi.domain.biTransportOperationZone.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TransportOperationZoneVO;
import org.apache.ibatis.annotations.Param;
/**
* 运输运营专区 NGWL_TEST_BI.BI_TRANSPORT_OPERATION_ZONE_SNAPSHOT 最新 PAYLOAD_JSON 并解析
*/
public interface BiTransportOperationZoneReportMapper {
String selectLatestPayloadJson(@Param("organizationName") String organizationName);
default TransportOperationZoneVO loadTransportOperationZone(String organizationName) {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(organizationName),
TransportOperationZoneVO.class,
BiReportSnapshotMapperSupport::emptyTransportOperationZone,
"运输运营专区");
}
}
@@ -0,0 +1,25 @@
package com.mhd.bi.domain.biTransportOperationZone.service;
import com.mhd.bi.domain.biTransportOperationZone.repository.mapper.BiTransportOperationZoneReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.TransportOperationZoneVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 南光物流业务经营分析 · 运输运营专区
*/
@Service
public class BiTransportOperationZoneReportService {
@Resource
private BiTransportOperationZoneReportMapper biTransportOperationZoneReportMapper;
/**
* @param organizationName 企业运营/组织名称模糊匹配为空时取全表最新一条
*/
public TransportOperationZoneVO loadTransportOperationZone(String organizationName) {
return biTransportOperationZoneReportMapper.loadTransportOperationZone(StringUtils.trimToNull(organizationName));
}
}
@@ -0,0 +1,204 @@
package com.mhd.bi.domain.biTransportOperationZone.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.transportZone.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 运输运营专区快照演示数据对齐大屏示例 JSON后续可改为真实聚合
*/
public final class TransportOperationZoneDemoData {
private static final DateTimeFormatter UPDATE_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private TransportOperationZoneDemoData() {
}
public static TransportOperationZoneVO build() {
List<TrOrderTypeMonthItemVO> orderTypeData = Arrays.asList(
TrOrderTypeMonthItemVO.builder().month("1月").crossBorder(30).domestic(25).build(),
TrOrderTypeMonthItemVO.builder().month("2月").crossBorder(40).domestic(35).build(),
TrOrderTypeMonthItemVO.builder().month("3月").crossBorder(20).domestic(30).build(),
TrOrderTypeMonthItemVO.builder().month("4月").crossBorder(35).domestic(40).build(),
TrOrderTypeMonthItemVO.builder().month("5月").crossBorder(50).domestic(45).build(),
TrOrderTypeMonthItemVO.builder().month("6月").crossBorder(60).domestic(55).build(),
TrOrderTypeMonthItemVO.builder().month("7月").crossBorder(70).domestic(65).build()
);
List<TrMonthValuePointVO> tripTrend = Arrays.asList(
point("1月", 120), point("2月", 150), point("3月", 220),
point("4月", 100), point("5月", 140), point("6月", 180)
);
List<TrMonthValuePointVO> orderTrend = Arrays.asList(
point("1月", 100), point("2月", 140), point("3月", 230),
point("4月", 100), point("5月", 140), point("6月", 190)
);
List<TrMonthValuePointVO> volumeTrend = Arrays.asList(
point("1月", 95), point("2月", 90), point("3月", 80),
point("4月", 65), point("5月", 92), point("6月", 88)
);
List<TrMonthValuePointVO> onTimeRate = Arrays.asList(
point("1月", 98), point("2月", 96), point("3月", 85),
point("4月", 70), point("5月", 92), point("6月", 90)
);
List<TrMonthValuePointVO> vehicleUtil = Arrays.asList(
point("1月", 600), point("2月", 460), point("3月", 390),
point("4月", 470), point("5月", 450), point("6月", 620)
);
List<TrEnterpriseRowVO> enterpriseList = Arrays.asList(
row("NO.1", "通宇", "268.25万", "2400单", 95),
row("NO.2", "南岐", "258.15万", "1800单", 98),
row("NO.3", "谷丰", "242.32万", "1200单", 13),
row("NO.4", "仓码", "231.54万", "800单", 12),
row("NO.5", "横琴", "220.90万", "567单", 15)
);
List<TrCargoCategoryItemVO> cargoItems = Arrays.asList(
TrCargoCategoryItemVO.builder().name("危化").value(25).color("green").build(),
TrCargoCategoryItemVO.builder().name("普货").value(25).color("blue").build(),
TrCargoCategoryItemVO.builder().name("冻品").value(50).color("orange").build()
);
List<TrCargoTypeDetailVO> cargoTypeDetails = Arrays.asList(
TrCargoTypeDetailVO.builder().typeCode("2").name("第2类 气体").percentage("65%").color("#1890FF").build(),
TrCargoTypeDetailVO.builder().typeCode("3").name("第3类 易燃液体").percentage("25%").color("#52C41A").build(),
TrCargoTypeDetailVO.builder().typeCode("8").name("第8类 腐蚀性物质").percentage("15%").color("#FAAD14").build()
);
TrMapNodeVO mapNode = TrMapNodeVO.builder()
.id(1L)
.name("通宇作业车辆")
.location(Arrays.asList(113.55, 22.25))
.status("working")
.detail(TrMapNodeDetailVO.builder()
.title("作业详情")
.licensePlate("粤A88888")
.businessUnit("通宇")
.loadingPlace("珠海")
.destination("澳门")
.currentLocation("珠海市")
.updateTime("2026年4月15日 17:52")
.build())
.build();
return TransportOperationZoneVO.builder()
.updateTime(LocalDateTime.now().format(UPDATE_TIME_FMT))
.dashboardTitle("南光物流业务经营分析")
.activeTab("运输运营专区")
.orderStatistics(TrOrderStatisticsVO.builder()
.title("订单统计")
.total(4361L)
.trend("+12.5%")
.build())
.transportStats(TrTransportStatsVO.builder()
.title("运输统计")
.tripCount(240)
.volume(2.6)
.volumeUnit("万吨")
.build())
.orderTypeChart(TrOrderTypeChartVO.builder()
.title("订单类型")
.type("area")
.data(orderTypeData)
.build())
.tripCountTrend(chart("车次趋势", "line", null, tripTrend))
.orderTrend(chart("订单趋势", "area", "", orderTrend))
.volumeTrend(chart("货量趋势", "area", "%", volumeTrend))
.map(TrVehicleMapVO.builder()
.title("车辆实时监控")
.legend(TrMapLegendVO.builder().idle(80).working(200).build())
.nodes(Collections.singletonList(mapNode))
.build())
.enterpriseOperation(TrEnterpriseOperationVO.builder()
.title("企业运营")
.columns(Arrays.asList("序号", "企业名称", "货运量", "处理单量", "准时配送率"))
.list(enterpriseList)
.build())
.capacityStatus(TrCapacityStatusVO.builder()
.title("运力情况")
.staff(capacityCount(718, 0, 0))
.vehicles(capacityCount(507, 0, 0))
.build())
.cargoCategory(TrCargoCategoryVO.builder()
.title("货物品类")
.totalOrders("1000单")
.data(cargoItems)
.build())
.onTimeRate(chart("准时配送率", "line", "%", onTimeRate))
.vehicleUtilization(TrBarChartVO.builder()
.title("出车利用率")
.unit("车次/辆")
.data(vehicleUtil)
.build())
.transportSummary(TrTransportSummaryVO.builder()
.title("运输统计")
.safeMileage("240万公里")
.avgDeliveryTime("平均4小时送达")
.build())
.capacityStats(TrCapacityStatsVO.builder()
.vehicles(capacityStatItem(280, "", "车辆"))
.drivers(capacityStatItem(360, "", "驾驶员"))
.escorts(capacityStatItem(56, "", "押运员"))
.build())
.cargoTypeDistribution(TrCargoTypeDistributionVO.builder()
.title("货物类型分布")
.totalOrders(1000)
.totalUnit("")
.details(cargoTypeDetails)
.build())
.freshOrderStats(sampleBrandOrderStats())
.vitasoyOrderStats(sampleBrandOrderStats())
.build();
}
private static TrBrandOrderStatsVO sampleBrandOrderStats() {
return TrBrandOrderStatsVO.builder()
.plannedDelivery(orderStatMetric(2135, "", "计划配送"))
.orderQuantity(orderStatMetric(228, "万吨", "订单数量"))
.vehiclesInTransit(orderStatMetric(84, "", "在途车辆"))
.completedDelivery(TrOrderStatTextMetricVO.builder()
.value("22.8%").unit("").label("完成配送").build())
.overtimeDelivery(orderStatMetric(228, "", "超时配送"))
.onTimeRate(TrOrderStatRateMetricVO.builder()
.value("85%").trend("+30%").label("准时配送率").build())
.build();
}
private static TrOrderStatMetricVO orderStatMetric(int value, String unit, String label) {
return TrOrderStatMetricVO.builder().value(value).unit(unit).label(label).build();
}
private static TrCapacityStatItemVO capacityStatItem(int value, String unit, String label) {
return TrCapacityStatItemVO.builder().value(value).unit(unit).label(label).build();
}
private static TrMonthValuePointVO point(String month, int value) {
return TrMonthValuePointVO.builder().month(month).value(value).build();
}
private static TrTypedChartVO chart(String title, String type, String unit, List<TrMonthValuePointVO> data) {
return TrTypedChartVO.builder().title(title).type(type).unit(unit).data(data).build();
}
private static TrCapacityCountVO capacityCount(int total, int todayNew, int yesterdayNew) {
return TrCapacityCountVO.builder()
.total(total).todayNew(todayNew).yesterdayNew(yesterdayNew).build();
}
private static TrEnterpriseRowVO row(String rank, String name, String volume,
String processedOrders, int onTimeRate) {
return TrEnterpriseRowVO.builder()
.rank(rank).name(name).volume(volume)
.processedOrders(processedOrders).onTimeRate(onTimeRate)
.build();
}
}
@@ -0,0 +1,21 @@
package com.mhd.bi.domain.biWarehouseOperationZone.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WarehouseOperationZoneVO;
import org.apache.ibatis.annotations.Param;
/**
* 仓储运营专区 NGWL_TEST_BI.BI_WAREHOUSE_OPERATION_ZONE_SNAPSHOT 最新 PAYLOAD_JSON 并解析
*/
public interface BiWarehouseOperationZoneReportMapper {
String selectLatestPayloadJson(@Param("organizationName") String organizationName);
default WarehouseOperationZoneVO loadWarehouseOperationZone(String organizationName) {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(organizationName),
WarehouseOperationZoneVO.class,
BiReportSnapshotMapperSupport::emptyWarehouseOperationZone,
"仓储运营专区");
}
}
@@ -0,0 +1,25 @@
package com.mhd.bi.domain.biWarehouseOperationZone.service;
import com.mhd.bi.domain.biWarehouseOperationZone.repository.mapper.BiWarehouseOperationZoneReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.WarehouseOperationZoneVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 南光物流业务经营分析 · 仓储运营专区
*/
@Service
public class BiWarehouseOperationZoneReportService {
@Resource
private BiWarehouseOperationZoneReportMapper biWarehouseOperationZoneReportMapper;
/**
* @param organizationName 企业运营/组织名称模糊匹配为空时取全表最新一条
*/
public WarehouseOperationZoneVO loadWarehouseOperationZone(String organizationName) {
return biWarehouseOperationZoneReportMapper.loadWarehouseOperationZone(StringUtils.trimToNull(organizationName));
}
}
@@ -0,0 +1,210 @@
package com.mhd.bi.domain.biWarehouseOperationZone.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.warehouseZone.*;
import java.util.Arrays;
import java.util.List;
/**
* 仓储运营专区快照演示数据对齐大屏示例 JSON后续可改为真实聚合
*/
public final class WarehouseOperationZoneDemoData {
private WarehouseOperationZoneDemoData() {
}
public static WarehouseOperationZoneVO build() {
List<WhThroughputMonthItemVO> throughputTrend = Arrays.asList(
WhThroughputMonthItemVO.builder().month("11月").value(10).build(),
WhThroughputMonthItemVO.builder().month("12月").value(14).build(),
WhThroughputMonthItemVO.builder().month("1月").value(22).build(),
WhThroughputMonthItemVO.builder().month("2月").value(21).build(),
WhThroughputMonthItemVO.builder().month("3月").value(13).build(),
WhThroughputMonthItemVO.builder().month("4月").value(16).build(),
WhThroughputMonthItemVO.builder().month("5月").value(8).build()
);
List<WhAreaDistributionDetailVO> areaDetails = Arrays.asList(
WhAreaDistributionDetailVO.builder().name("普通仓出租面积").value(9400).unit("").build(),
WhAreaDistributionDetailVO.builder().name("自动化立库出租面积").value(9400).unit("").build(),
WhAreaDistributionDetailVO.builder().name("闲置面积").value(9400).unit("").build(),
WhAreaDistributionDetailVO.builder().name("冷冻仓出租面积").value(9400).unit("").build()
);
List<WhMonthRatePointVO> capTrendData = Arrays.asList(
WhMonthRatePointVO.builder().month("1月").rate(20).build(),
WhMonthRatePointVO.builder().month("2月").rate(30).build(),
WhMonthRatePointVO.builder().month("3月").rate(55).build(),
WhMonthRatePointVO.builder().month("4月").rate(40).build(),
WhMonthRatePointVO.builder().month("5月").rate(45).build(),
WhMonthRatePointVO.builder().month("6月").rate(60).build(),
WhMonthRatePointVO.builder().month("7月").rate(50).build()
);
List<WhMonthRatePointVO> orderTrend = Arrays.asList(
WhMonthRatePointVO.builder().month("1月").rate(100).build(),
WhMonthRatePointVO.builder().month("2月").rate(90).build(),
WhMonthRatePointVO.builder().month("3月").rate(75).build(),
WhMonthRatePointVO.builder().month("4月").rate(70).build(),
WhMonthRatePointVO.builder().month("5月").rate(95).build(),
WhMonthRatePointVO.builder().month("6月").rate(85).build()
);
List<WhMonthRatePointVO> turnoverData = Arrays.asList(
WhMonthRatePointVO.builder().month("11月").rate(10).build(),
WhMonthRatePointVO.builder().month("12月").rate(15).build(),
WhMonthRatePointVO.builder().month("1月").rate(22).build(),
WhMonthRatePointVO.builder().month("2月").rate(20).build(),
WhMonthRatePointVO.builder().month("3月").rate(12).build(),
WhMonthRatePointVO.builder().month("4月").rate(16).build()
);
List<WhServiceCapacityRowVO> serviceCapacity = Arrays.asList(
WhServiceCapacityRowVO.builder().rank(1).name("君华仓").totalArea("1.2万m²").processed("2,400单").throughput("2.2万吨").build(),
WhServiceCapacityRowVO.builder().rank(2).name("通宇仓").totalArea("1.2万m²").processed("1,800单").throughput("1.1万吨").build(),
WhServiceCapacityRowVO.builder().rank(3).name("横琴仓").totalArea("1.2万m²").processed("1,200单").throughput("1.5万吨").build(),
WhServiceCapacityRowVO.builder().rank(4).name("新南仓").totalArea("1.2万m²").processed("800单").throughput("2.1万吨").build(),
WhServiceCapacityRowVO.builder().rank(5).name("谷丰仓").totalArea("1.2万m²").processed("567单").throughput("1.8万吨").build()
);
return WarehouseOperationZoneVO.builder()
.warehouseName("新南仓")
.updateTime("2026-04-16 18:41:00")
.orderSummary(WhOrderSummaryVO.builder()
.totalCount("03600")
.inboundOrders(orderSummaryItem("入库单", 2298))
.outboundOrders(orderSummaryItem("出库单", 1129))
.operationOrders(orderSummaryItem("作业单", 345))
.build())
.coldStorageStats(WhColdStorageStatsVO.builder()
.revenueShare(coldMetric("64.8%", "+30%"))
.utilizationRate(coldMetric("28.6%", "+30%"))
.damageRate(coldMetric("1.6%", "+30%"))
.build())
.temperatureExceptions(sampleTemperatureExceptions())
.storageOverview(WhStorageOverviewVO.builder()
.title("仓储面积")
.value(10)
.unit("万m²")
.subText("覆盖仓库数8个")
.build())
.operationStats(WhOperationStatsVO.builder()
.title("年吞吐量")
.value(26)
.unit("万吨")
.growthRate("8.5%")
.trend("up")
.build())
.businessPlanning(WhBusinessPlanningVO.builder()
.generalWarehouse(43000)
.coldStorage(15000)
.foodProcessing(11000)
.automatedStorage(5200)
.build())
.throughputTrend(throughputTrend)
.areaDistribution(WhAreaDistributionVO.builder()
.utilizationRate("85%")
.details(areaDetails)
.build())
.capacityUtilizationTrend(WhCapacityUtilizationTrendVO.builder()
.peakLabel("60%")
.data(capTrendData)
.build())
.orderStatistics(WhOrderStatisticsVO.builder()
.annualOrders(525440L)
.quarterlyOrders(225120L)
.monthlyOrders(23560L)
.build())
.serviceStatistics(WhServiceStatisticsVO.builder()
.clients(582)
.coverage("覆盖港珠澳")
.onTimeRate("98.2%")
.rateChange("0.4%")
.build())
.orderTrend(orderTrend)
.turnoverRateTrend(WhTurnoverRateTrendVO.builder()
.currentMonth("3次")
.annual("4次")
.data(turnoverData)
.build())
.serviceCapacity(serviceCapacity)
.realTimeAnalysis(WhRealTimeAnalysisVO.builder()
.utilizationRate(WhRealTimeGaugeVO.builder()
.value("50.8%")
.comparison("3.4%")
.trend("up")
.build())
.rentalRate(WhRealTimeGaugeVO.builder()
.value("70.8%")
.comparison("3.4%")
.trend("up")
.build())
.build())
.map(WhWarehouseMapVO.builder()
.legend("仓库")
.nodes(Arrays.asList(
mapNode(1L, "君华仓", 113.52, 22.30,
"君华保税仓", "12000m²", 520, 2400, "82%", "36.5%"),
mapNode(2L, "通宇仓", 113.55, 22.25,
"通宇保税仓", "2000m²", 668, 237, "85%", "37.1%"),
mapNode(3L, "横琴仓", 113.54, 22.12,
"横琴保税仓", "3500m²", 445, 1200, "78%", "42.0%"),
mapNode(4L, "新南仓", 113.58, 22.20,
"新南保税仓", "2800m²", 390, 800, "80%", "35.8%"),
mapNode(5L, "谷丰仓", 113.48, 22.22,
"谷丰保税仓", "4500m²", 512, 567, "76%", "33.2%")
))
.build())
.build();
}
private static WhOrderSummaryCountItemVO orderSummaryItem(String label, int value) {
return WhOrderSummaryCountItemVO.builder().label(label).value(value).build();
}
private static WhColdStorageMetricVO coldMetric(String value, String trend) {
return WhColdStorageMetricVO.builder().value(value).trend(trend).build();
}
private static List<WhTemperatureExceptionVO> sampleTemperatureExceptions() {
return Arrays.asList(
tempException(1, "I级"),
tempException(2, "II级"),
tempException(3, "II级"),
tempException(4, "II级"),
tempException(5, "IV级"),
tempException(6, "IV级"),
tempException(7, "IV级")
);
}
private static WhTemperatureExceptionVO tempException(int rank, String level) {
return WhTemperatureExceptionVO.builder()
.rank(rank)
.level(level)
.area("A1区")
.deviceId("01020304")
.temperature("-4°C")
.duration("持续0小时12分钟")
.occurTime("04-16 18:41")
.build();
}
private static WhMapNodeVO mapNode(long id, String name, double lng, double lat,
String warehouseName, String totalArea, int totalSku,
int todayOrders, String utilizationRate, String rentalRate) {
return WhMapNodeVO.builder()
.id(id)
.name(name)
.location(Arrays.asList(lng, lat))
.detail(WhMapPopupVO.builder()
.warehouseName(warehouseName)
.totalArea(totalArea)
.totalSku(totalSku)
.todayOrders(todayOrders)
.utilizationRate(utilizationRate)
.rentalRate(rentalRate)
.build())
.build();
}
}
@@ -0,0 +1,20 @@
package com.mhd.bi.domain.biWarehouseTransport.repository.mapper;
import com.mhd.bi.domain.biReport.support.BiReportSnapshotMapperSupport;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
/**
* 仓储运输SQL BiWarehouseTransportReportMapper.xml取数与组装均在 Mapper 层完成
*/
public interface BiWarehouseTransportReportMapper {
String selectLatestPayloadJson();
default WarehouseTransportSituationVO loadLatestWarehouseTransport() {
return BiReportSnapshotMapperSupport.parsePayload(
selectLatestPayloadJson(),
WarehouseTransportSituationVO.class,
BiReportSnapshotMapperSupport::emptyWarehouseTransportSituation,
"仓储运输");
}
}
@@ -0,0 +1,18 @@
package com.mhd.bi.domain.biWarehouseTransport.service;
import com.mhd.bi.domain.biWarehouseTransport.repository.mapper.BiWarehouseTransportReportMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class BiWarehouseTransportReportService {
@Resource
private BiWarehouseTransportReportMapper biWarehouseTransportReportMapper;
public WarehouseTransportSituationVO loadLatestWarehouseTransport() {
return biWarehouseTransportReportMapper.loadLatestWarehouseTransport();
}
}
@@ -0,0 +1,28 @@
package com.mhd.bi.domain.testTable.entity;
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 org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class TestTable implements Serializable {
private static final long serialVersionUID = 1L;
/** 车队id */
@ApiModelProperty("车队id")
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty(name = "txt")
private String txt;
}
@@ -0,0 +1,8 @@
package com.mhd.bi.domain.testTable.repository.facade;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mhd.bi.domain.testTable.entity.TestTable;
public interface TestTableService extends IService<TestTable>
{
}
@@ -0,0 +1,16 @@
package com.mhd.bi.domain.testTable.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mhd.bi.domain.testTable.entity.TestTable;
import java.util.List;
/**
* 车队Mapper接口
*
* @author zihao
* @date 2023-05-24
*/
public interface TestTableMapper extends BaseMapper<TestTable>
{
}
@@ -0,0 +1,15 @@
package com.mhd.bi.domain.testTable.repository.persistence;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mhd.bi.domain.testTable.entity.TestTable;
import com.mhd.bi.domain.testTable.repository.facade.TestTableService;
import com.mhd.bi.domain.testTable.repository.mapper.TestTableMapper;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class TestTableServiceImpl extends ServiceImpl<TestTableMapper, TestTable> implements TestTableService {
}
@@ -0,0 +1,147 @@
package com.mhd.bi.interfaces.facadeApi.biReport;
import com.mhd.bi.domain.biSnapshotSync.service.BiReportSnapshotSyncService;
import com.mhd.bi.domain.biComprehensive.service.BiComprehensiveReportService;
import com.mhd.bi.domain.biPlatformSurveillance.service.BiPlatformSurveillanceReportService;
import com.mhd.bi.domain.biOverallOperation.service.BiOverallOperationReportService;
import com.mhd.bi.domain.biHkMacaoServiceZone.service.BiHkMacaoServiceZoneReportService;
import com.mhd.bi.domain.biTransportOperationZone.service.BiTransportOperationZoneReportService;
import com.mhd.bi.domain.biWarehouseOperationZone.service.BiWarehouseOperationZoneReportService;
import com.mhd.bi.domain.biWarehouseTransport.service.BiWarehouseTransportReportService;
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.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.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* BI 报表接口
*/
@Api(tags = "BI报表", description = "须在请求头携带 X-BI-Access-Token,与配置 mhd.bi.access-token 一致")
@Slf4j
@RestController
@RequestMapping("/biReport")
@CrossOrigin
public class BiReportApi extends BaseController {
@Autowired
private BiComprehensiveReportService biComprehensiveReportService;
@Autowired
private BiWarehouseTransportReportService biWarehouseTransportReportService;
@Autowired
private BiPlatformSurveillanceReportService biPlatformSurveillanceReportService;
@Autowired
private BiOverallOperationReportService biOverallOperationReportService;
@Autowired
private BiWarehouseOperationZoneReportService biWarehouseOperationZoneReportService;
@Autowired
private BiTransportOperationZoneReportService biTransportOperationZoneReportService;
@Autowired
private BiHkMacaoServiceZoneReportService biHkMacaoServiceZoneReportService;
@Autowired
private BiReportSnapshotSyncService biReportSnapshotSyncService;
@ApiOperation(value = "手动触发快照同步", notes = "立即写入各 BI 快照表(综合、仓储运输、月台监测、总体运营、仓储运营专区、运输运营专区、港澳服务专区);须带 X-BI-Access-Token")
@PostMapping("/snapshotSync/run")
public BiApiResult<Void> runSnapshotSyncOnce() {
biReportSnapshotSyncService.syncAllSnapshots();
return BiApiResult.ok(null);
}
/**
* 综合态势指标查询按照 del_flag=1 create_time 最新一条
*/
@ApiOperation(value = "综合态势指标查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条")
@GetMapping("/comprehensive")
public BiApiResult<ComprehensiveSituationVO> comprehensive() {
ComprehensiveSituationVO data = biComprehensiveReportService.loadLatestComprehensive();
return BiApiResult.ok(data);
}
/**
* 仓储运输指标查询按照 del_flag=1 create_time 最新一条
*/
@ApiOperation(value = "仓储运输指标查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条")
@GetMapping("/warehouseTransport")
public BiApiResult<WarehouseTransportSituationVO> warehouseTransport() {
WarehouseTransportSituationVO data = biWarehouseTransportReportService.loadLatestWarehouseTransport();
return BiApiResult.ok(data);
}
/**
* 月台监测指标查询按照 del_flag=1 create_time 最新一条
*/
@ApiOperation(value = "月台监测指标查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条快照")
@GetMapping("/platformSurveillance")
public BiApiResult<PlatformSurveillanceVO> platformSurveillance() {
PlatformSurveillanceVO data = biPlatformSurveillanceReportService.loadLatestPlatformSurveillance();
return BiApiResult.ok(data);
}
//园区物流大屏接口----------------------------------------------------------------------
/**
* 总体运营态势
*/
@ApiOperation(value = "总体运营态势查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条整包 JSON 解析结果")
@GetMapping("/overallOperation")
public BiApiResult<OverallOperationSituationVO> overallOperation() {
OverallOperationSituationVO data = biOverallOperationReportService.loadLatestOverallOperation();
return BiApiResult.ok(data);
}
/**
* 仓储运营专区大屏仓储运营专区Tab
*/
@ApiOperation(value = "仓储运营专区查询", notes = "未传 organizationName 时返回全表最新一条;")
@GetMapping("/warehouseOperationZone")
public BiApiResult<WarehouseOperationZoneVO> warehouseOperationZone(
@ApiParam(value = "企业运营/组织名称")
@RequestParam(value = "organizationName", required = false) String organizationName) {
WarehouseOperationZoneVO data = biWarehouseOperationZoneReportService.loadWarehouseOperationZone(organizationName);
return BiApiResult.ok(data);
}
/**
* 运输运营专区大屏运输运营专区Tab
*/
@ApiOperation(value = "运输运营专区查询", notes = "未传 organizationName 时返回全表最新一条;传入时双向模糊匹配 ORGANIZATION_NAME(库名包含关键词,或关键词包含库名)")
@GetMapping("/transportOperationZone")
public BiApiResult<TransportOperationZoneVO> transportOperationZone(
@ApiParam(value = "企业运营/组织名称,与快照表 ORGANIZATION_NAME 双向模糊匹配")
@RequestParam(value = "organizationName", required = false) String organizationName) {
TransportOperationZoneVO data = biTransportOperationZoneReportService.loadTransportOperationZone(organizationName);
return BiApiResult.ok(data);
}
/**
* 港澳服务专区大屏港澳服务专区
*/
@ApiOperation(value = "港澳服务专区查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条整包 JSON 解析结果")
@GetMapping("/hkMacaoServiceZone")
public BiApiResult<HkMacaoServiceZoneVO> hkMacaoServiceZone() {
HkMacaoServiceZoneVO data = biHkMacaoServiceZoneReportService.loadLatestHkMacaoServiceZone();
return BiApiResult.ok(data);
}
}
@@ -0,0 +1,24 @@
package com.mhd.bi.interfaces.facadeApi.biReport.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* BI 接口统一响应与前端示例code + msg + data
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BiApiResult<T> {
private int code = 200;
private String message = "操作成功";
private T data;
public static <T> BiApiResult<T> ok(T data) {
return new BiApiResult<>(200, "操作成功", data);
}
}
@@ -0,0 +1,39 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 综合态势指标
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("综合态势指标")
public class ComprehensiveSituationVO {
@ApiModelProperty("增值服务收入,单位:元人民币")
private Long valueAddedServiceIncome;
@ApiModelProperty("库存周转率,单位:次")
private Integer inventoryTurnover;
@ApiModelProperty("运输订单量,单位:单")
private Integer orderCount;
@ApiModelProperty("车辆利用率,单位:%")
private Double vehicleUtilizationRate;
@ApiModelProperty("百公里油耗,单位:升")
private Integer fuelConsumptionPerHundredKm;
@ApiModelProperty("运输收入趋势,单位:万元(近半年,按月正序)")
private List<Integer> incomeTrend;
}
@@ -0,0 +1,24 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("客户贡献排名(前5")
public class CustomerContributionRankVO {
@ApiModelProperty("客户名称")
private List<String> customerName;
@ApiModelProperty("客户金额,单位:万元")
private List<Integer> customerAmount;
}
@@ -0,0 +1,78 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("仓储运输指标")
public class WarehouseTransportSituationVO {
@ApiModelProperty("仓配衔接准时率,单位:%")
private Double warehouseDistributionOnTimeRate;
@ApiModelProperty("本年度订单,单位:单")
private Long currentYearOrders;
@ApiModelProperty("本季度订单,单位:单")
private Integer currentQuarterOrders;
@ApiModelProperty("本月度订单,单位:单")
private Integer currentMonthOrders;
@ApiModelProperty("仓库订单趋势,单位:单(近半年,按月正序)")
private List<Integer> warehouseOrderTrend;
@ApiModelProperty("吞吐量统计,单位:吨(近半年,按月正序)")
private List<Integer> throughput;
@ApiModelProperty("本月周转率,单位:次")
private Integer currentMonthTurnoverRate;
@ApiModelProperty("本年周转率,单位:次")
private Integer currentYearTurnoverRate;
@ApiModelProperty("库存周转率趋势,单位:次(近半年,按月正序)")
private List<Integer> inventoryTurnoverTrend;
@ApiModelProperty("总收入,单位:万元")
private Integer totalTransportIncome;
@ApiModelProperty("订单数量,单位:单")
private Integer orderCount;
@ApiModelProperty("运输车次,单位:次")
private Integer transportTrips;
@ApiModelProperty("运输货量,单位:万吨")
private Integer annualTransportVolume;
@ApiModelProperty("运输订单总数,单位:单")
private Integer transportOrderTotal;
@ApiModelProperty("跨境订单,单位:单")
private Integer crossBorderTransportOrder;
@ApiModelProperty("国内订单,单位:单")
private Integer domesticTransportOrder;
@ApiModelProperty("运输车次趋势(近半年,按月正序)")
private List<Integer> transportTripsTrend;
@ApiModelProperty("出车利用率,单位:车次(近半年,按月正序)")
private List<Integer> vehicleUtilizationRate;
@ApiModelProperty("仓配衔接准时率(近半年,按月正序),单位:%")
private List<Integer> warehouseDockSyncRate;
@ApiModelProperty("客户贡献排名")
private CustomerContributionRankVO customerContributionRank;
}
@@ -0,0 +1,33 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-服务客户统计")
public class HkClientServiceStatsVO {
@JsonProperty("hk_macao_clients")
@ApiModelProperty("港澳客户数")
private Integer hkMacaoClients;
@JsonProperty("client_ratio")
@ApiModelProperty("客户占比")
private String clientRatio;
@JsonProperty("warehouse_usage_area")
@ApiModelProperty("仓库使用面积")
private String warehouseUsageArea;
@JsonProperty("area_ratio")
@ApiModelProperty("面积占比")
private String areaRatio;
}
@@ -0,0 +1,29 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-门到门时效")
public class HkDoorToDoorEfficiencyVO {
@JsonProperty("average_time")
@ApiModelProperty("平均时效")
private String averageTime;
@JsonProperty("fastest_time")
@ApiModelProperty("最快时效")
private String fastestTime;
@JsonProperty("mom_growth")
@ApiModelProperty("环比增幅")
private String momGrowth;
}
@@ -0,0 +1,33 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-库存周转率趋势")
public class HkInventoryTurnoverTrendVO {
@JsonProperty("current_month_rate")
@ApiModelProperty("本月周转率")
private String currentMonthRate;
@JsonProperty("annual_rate")
@ApiModelProperty("年度周转率")
private String annualRate;
@ApiModelProperty("单位")
private String unit;
@ApiModelProperty("按月序列")
private List<HkMonthRatePointVO> data;
}
@@ -0,0 +1,74 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 港澳服务专区整包 data 与快照 PAYLOAD_JSON 一致
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区")
public class HkMacaoServiceZoneVO {
@JsonProperty("warehouse_order_stats")
@ApiModelProperty("仓库订单统计")
private HkOrderStatsVO warehouseOrderStats;
@JsonProperty("client_service_stats")
@ApiModelProperty("服务客户统计")
private HkClientServiceStatsVO clientServiceStats;
@JsonProperty("goods_source_stats")
@ApiModelProperty("货物品类来源")
private HkRingChartStatsVO goodsSourceStats;
@JsonProperty("cross_border_order_stats")
@ApiModelProperty("跨境订单统计")
private HkRingChartStatsVO crossBorderOrderStats;
@JsonProperty("warehouse_order_trend")
@ApiModelProperty("仓库订单趋势")
private List<HkOrderTrendMonthVO> warehouseOrderTrend;
@JsonProperty("inventory_turnover_trend")
@ApiModelProperty("库存周转率趋势")
private HkInventoryTurnoverTrendVO inventoryTurnoverTrend;
@JsonProperty("transport_order_stats")
@ApiModelProperty("运输订单统计")
private HkOrderStatsVO transportOrderStats;
@JsonProperty("door_to_door_efficiency")
@ApiModelProperty("门到门时效")
private HkDoorToDoorEfficiencyVO doorToDoorEfficiency;
@JsonProperty("cross_border_transport_stats")
@ApiModelProperty("跨境运输订单")
private HkRingChartStatsVO crossBorderTransportStats;
@JsonProperty("cargo_volume_trend")
@ApiModelProperty("货量趋势")
private List<HkMonthValuePointVO> cargoVolumeTrend;
@JsonProperty("transport_order_trend")
@ApiModelProperty("运输订单趋势")
private List<HkOrderTrendMonthVO> transportOrderTrend;
@JsonProperty("on_time_delivery_rate")
@ApiModelProperty("准时交付率")
private List<HkMonthRatePointVO> onTimeDeliveryRate;
@JsonProperty("map_data")
@ApiModelProperty("地图点位")
private HkMapDataVO mapData;
}
@@ -0,0 +1,21 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-地图数据")
public class HkMapDataVO {
@ApiModelProperty("点位列表")
private List<HkMapPointVO> points;
}
@@ -0,0 +1,22 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-地图坐标")
public class HkMapLocationVO {
@ApiModelProperty("纬度")
private Double lat;
@ApiModelProperty("经度")
private Double lng;
}
@@ -0,0 +1,37 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-地图点位")
public class HkMapPointVO {
@ApiModelProperty("点位ID")
private String id;
@ApiModelProperty("类型 warehouse/vehicle")
private String type;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("坐标")
private HkMapLocationVO location;
@ApiModelProperty("仓库指标(type=warehouse")
private HkWarehouseMetricsVO metrics;
@ApiModelProperty("车辆详情(type=vehicle")
private HkVehicleDetailsVO details;
}
@@ -0,0 +1,22 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-月份比率点")
public class HkMonthRatePointVO {
@ApiModelProperty("月份")
private String month;
@ApiModelProperty("比率或趋势值")
private Integer rate;
}
@@ -0,0 +1,22 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-月度数值点")
public class HkMonthValuePointVO {
@ApiModelProperty("月份")
private String month;
@ApiModelProperty("数值")
private Integer value;
}
@@ -0,0 +1,31 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-订单统计")
public class HkOrderStatsVO {
@JsonProperty("total_orders")
@ApiModelProperty("订单总量")
private Long totalOrders;
@ApiModelProperty("单位")
private String unit;
@JsonProperty("mom_growth")
@ApiModelProperty("环比增幅")
private String momGrowth;
@ApiModelProperty("趋势 up/down")
private String trend;
}
@@ -0,0 +1,28 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-订单趋势月度点")
public class HkOrderTrendMonthVO {
@ApiModelProperty("月份")
private String month;
@JsonProperty("order_ratio")
@ApiModelProperty("订单比率/柱值")
private Integer orderRatio;
@JsonProperty("order_count")
@ApiModelProperty("订单数")
private Integer orderCount;
}
@@ -0,0 +1,22 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-占比明细")
public class HkPercentageDetailVO {
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("占比")
private String percentage;
}
@@ -0,0 +1,26 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-环形图统计")
public class HkRingChartStatsVO {
@JsonProperty("total_orders")
@ApiModelProperty("订单/统计总量")
private Integer totalOrders;
@ApiModelProperty("明细")
private List<HkPercentageDetailVO> details;
}
@@ -0,0 +1,41 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-车辆详情")
public class HkVehicleDetailsVO {
@JsonProperty("warehouse_name")
@ApiModelProperty("关联仓库")
private String warehouseName;
@JsonProperty("license_plate")
@ApiModelProperty("车牌号")
private String licensePlate;
@JsonProperty("loading_address")
@ApiModelProperty("装货地址")
private String loadingAddress;
@JsonProperty("destination_address")
@ApiModelProperty("目的地")
private String destinationAddress;
@JsonProperty("current_location")
@ApiModelProperty("当前位置")
private String currentLocation;
@JsonProperty("update_time")
@ApiModelProperty("更新时间")
private String updateTime;
}
@@ -0,0 +1,25 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.hkMacaoZone;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-港澳服务专区-仓库运营指标")
public class HkWarehouseMetricsVO {
@JsonProperty("inbound_operations")
@ApiModelProperty("入库作业数")
private Integer inboundOperations;
@JsonProperty("outbound_operations")
@ApiModelProperty("出库作业数")
private Integer outboundOperations;
}
@@ -0,0 +1,30 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.overall;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("总体运营态势-地图节点")
public class OverallMapNodeVO {
@ApiModelProperty("类型:headquarters / businessUnit / warehouse")
private String type;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("坐标 [经度, 纬度]")
private List<Double> location;
@ApiModelProperty("悬停信息")
private OverallMapTooltipVO tooltip;
}
@@ -0,0 +1,21 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.overall;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("总体运营态势-地图")
public class OverallMapSectionVO {
@ApiModelProperty("地图节点")
private List<OverallMapNodeVO> nodes;
}
@@ -0,0 +1,22 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.overall;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("地图气泡-指标项")
public class OverallMapTooltipDataItemVO {
@ApiModelProperty("标签")
private String label;
@ApiModelProperty("数值")
private Integer value;
}
@@ -0,0 +1,24 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.overall;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("总体运营态势-地图气泡")
public class OverallMapTooltipVO {
@ApiModelProperty("标题")
private String title;
@ApiModelProperty("指标行")
private List<OverallMapTooltipDataItemVO> data;
}
@@ -0,0 +1,31 @@
package com.mhd.bi.interfaces.facadeApi.biReport.vo.overall;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 总体运营态势 PAYLOAD_JSON接口 data 字段结构一致
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("BI-总体运营态势")
public class OverallOperationSituationVO {
@ApiModelProperty("快照时间展示")
private String updateTime;
@ApiModelProperty("仓储运营")
private OverallWarehouseOperationVO warehouse;
@ApiModelProperty("地图")
private OverallMapSectionVO map;
@ApiModelProperty("运输运营")
private OverallTransportOperationVO transport;
}

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