配送系统功能开发

This commit is contained in:
2025-11-25 16:22:27 +08:00
parent 24ca9148dd
commit aa53f26d63
20 changed files with 876 additions and 362 deletions

View File

@@ -290,4 +290,53 @@ public class HttpUtils
return true;
}
}
/**
* 向指定 URL 发送 JSON 格式的 POST 请求
*
* @param url 发送请求的 URL
* @param json JSON 字符串
* @return 响应内容
*/
public static String sendJsonPost(String url, String json) {
PrintWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
log.info("sendJsonPost - {}", url);
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setDoOutput(true);
conn.setDoInput(true);
out = new PrintWriter(conn.getOutputStream());
out.print(json);
out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
log.info("recv - {}", result);
} catch (Exception e) {
log.error("调用 HttpUtils.sendJsonPost 异常 url={}, json={}", url, json, e);
} finally {
try {
if (out != null) out.close();
if (in != null) in.close();
} catch (Exception ex) {
log.error("关闭流异常", ex);
}
}
return result.toString();
}
}

View File

@@ -156,7 +156,7 @@ public class DeliveryAttachmentController extends BaseController
// @Log(title = "配送附件-执行绑定", businessType = BusinessType.INSERT)
@PostMapping("/executeBind")
public AjaxResult executeBind(@Validated @RequestBody DeliveryExecuteBindDTO dto) {
int saved = deliveryAttachmentService.executeBind(dto);
deliveryAttachmentService.executeBind(dto);
return AjaxResult.success()
.put("orderNo", dto.getOrderNo())
.put("scene", dto.getScene());

View File

@@ -3,9 +3,9 @@ package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.domain.dto.DeliveryOrderCreateDTO;
import com.delivery.project.document.domain.dto.DeliveryOrderSaveDTO;
import com.delivery.project.document.domain.vo.DeliveryBillVO;
import com.delivery.project.document.domain.vo.DeliveryOrderGroupVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,7 +42,7 @@ public class DeliveryOrderController extends BaseController
/**
* 查询配送单据主列表
*/
// @PreAuthorize("@ss.hasPermi('document:order:list')")
@PreAuthorize("@ss.hasPermi('document:order:list')")
@GetMapping("/list")
public TableDataInfo list(DeliveryOrder deliveryOrder)
{
@@ -67,7 +67,7 @@ public class DeliveryOrderController extends BaseController
/**
* 获取配送单据主详细信息
*/
// @PreAuthorize("@ss.hasPermi('document:order:query')")
@PreAuthorize("@ss.hasPermi('document:order:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
@@ -112,8 +112,8 @@ public class DeliveryOrderController extends BaseController
* @param dto
* @return
*/
// @PreAuthorize("@ss.hasPermi('document:order:add')")
// @Log(title = "配送单据主-保存(含附件)", businessType = BusinessType.INSERT)
@PreAuthorize("@ss.hasPermi('document:order:add')")
@Log(title = "配送单据主-保存(含附件)", businessType = BusinessType.INSERT)
@PostMapping("/save")
public AjaxResult save(@RequestBody DeliveryOrderSaveDTO dto) {
String username = "大爷的!";
@@ -123,8 +123,8 @@ public class DeliveryOrderController extends BaseController
/** 新增配送单据:同一单号多行写入 */
// @PreAuthorize("@ss.hasPermi('document:order:add')")
// @Log(title = "配送单据", businessType = BusinessType.INSERT)
@PreAuthorize("@ss.hasPermi('document:order:add')")
@Log(title = "配送单据", businessType = BusinessType.INSERT)
@PostMapping("/batch")
public AjaxResult createBatch(@RequestBody DeliveryOrderCreateDTO dto) {
String plateNo = deliveryOrderService.createOrder(dto);
@@ -133,15 +133,15 @@ public class DeliveryOrderController extends BaseController
/** 列表:按单号分组(分页) */
// @PreAuthorize("@ss.hasPermi('document:order:list')")
@GetMapping("/group")
public TableDataInfo listGroup(DeliveryOrder query) {
@PostMapping("/group")
public TableDataInfo listGroup(@RequestBody DeliveryOrder query) {
startPage();
List<DeliveryOrderGroupVO> list = deliveryOrderService.listGroup(query);
return getDataTable(list);
}
/** 详情:按单号查询所有行 */
// @PreAuthorize("@ss.hasPermi('document:order:query')")
@PreAuthorize("@ss.hasPermi('document:order:query')")
@GetMapping("/detail/{orderNo}")
public AjaxResult detail(@PathVariable String orderNo) {
@@ -155,7 +155,8 @@ public class DeliveryOrderController extends BaseController
*/
@GetMapping("/wisdom/rk/list")
public AjaxResult listRkFromWisdom() {
List<RkInfo> list = deliveryOrderService.listWisdomRkForDelivery();
// 这里直接返回一对多结构
List<DeliveryBillVO> list = deliveryOrderService.listWisdomRkForDelivery();
return AjaxResult.success(list);
}
}

View File

@@ -3,7 +3,7 @@ package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.delivery.project.document.service.IVehicleTypeService;
import com.delivery.project.document.domain.RkInfo;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.delivery.framework.aspectj.lang.annotation.Log;
import com.delivery.framework.aspectj.lang.enums.BusinessType;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.service.IRkInfoService;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;

View File

@@ -25,6 +25,10 @@ public class DeliveryOrder extends BaseEntity {
@Excel(name = "配送单据号")
private String orderNo;
/** 出库单据号 */
@Excel(name = "出库单据号")
private String billNoCk;
/** 项目描述 */
@Excel(name = "项目描述")
private String xmMs;
@@ -144,6 +148,8 @@ public class DeliveryOrder extends BaseEntity {
/** 连表查询用:附件列表 */
private List<DeliveryAttachment> attachments;
private List<String> orderStatusList;
// ===================== 费用与里程 =====================
/** 建议费用(按车型单价*里程的推荐值) */
@Excel(name = "建议费用")
@@ -168,7 +174,8 @@ public class DeliveryOrder extends BaseEntity {
public String getOrderNo() { return orderNo; }
public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
public String getBillNoCk() { return billNoCk; }
public void setBillNoCk(String billNoCk) { this.billNoCk = billNoCk; }
public String getXmMs() { return xmMs; }
public void setXmMs(String xmMs) { this.xmMs = xmMs; }
@@ -214,8 +221,8 @@ public class DeliveryOrder extends BaseEntity {
public Date getDeliveryDate() { return deliveryDate; }
public void setDeliveryDate(Date deliveryDate) { this.deliveryDate = deliveryDate; }
public String getplateNo() { return plateNo; }
public void setplateNo(String plateNo) { this.plateNo = plateNo; }
public String getPlateNo() { return plateNo; }
public void setPlateNo(String plateNo) { this.plateNo = plateNo; }
public String getDriverName() { return driverName; }
public void setDriverName(String driverName) { this.driverName = driverName; }
@@ -271,11 +278,20 @@ public class DeliveryOrder extends BaseEntity {
public BigDecimal getTotalKm() { return totalKm; }
public void setTotalKm(BigDecimal totalKm) { this.totalKm = totalKm; }
public List<String> getOrderStatusList() {
return orderStatusList;
}
public void setOrderStatusList(List<String> orderStatusList) {
this.orderStatusList = orderStatusList;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("orderNo", getOrderNo())
.append("billNoCk", getBillNoCk())
.append("xmMs", getXmMs())
.append("xmNo", getXmNo())
.append("wlNo", getWlNo())
@@ -291,7 +307,7 @@ public class DeliveryOrder extends BaseEntity {
.append("destLng", getDestLng())
.append("destLat", getDestLat())
.append("deliveryDate", getDeliveryDate())
.append("plateNo", getplateNo())
.append("plateNo", getPlateNo())
.append("driverName", getDriverName())
.append("driverPhone", getDriverPhone())
.append("shipperName", getShipperName())

View File

@@ -1,28 +1,94 @@
package com.delivery.project.document.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.delivery.framework.aspectj.lang.annotation.Excel;
import com.delivery.framework.web.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 库存单据明细对象 rk_info
* 库存单据对象 rk_info
*
* @author delivery
* @date 2025-10-14
* @author zg
* @date 2025-05-28
*/
public class RkInfo extends BaseEntity {
public class RkInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
// ===================== 基本标识 =====================
/** 模糊搜索关键字(项目号、项目描述、物料号、物料描述、供应商编码、供应商名称,订单编号) */
private String keyword;
/** 主键ID */
private Long id;
/** 单据号(入库/库存单据编号) */
private List<Long> ids;
/** 供应计划ID对应供应计划表主键 */
@Excel(name = "供应计划ID")
private Long gysJhId;
/** 审批人ID非数据库字段 */
private String approverId;
/** 库龄 */
@Excel(name = "库龄")
private Long stockAge;
/** 入库类型 */
private String rkType;
/** 物资类型 */
private String wlType;
/** 所属仓库 */
private String cangku;
/** 多状态查询:是否出库(如 0=入库, 1=出库 等) */
private List<String> isChukuList;
/** 入库类型名称(联查显示用,导出专用) */
@Excel(name = "入库类型名称")
private String rkTypeName;
/** 物资类型名称(联查显示用,导出专用) */
@Excel(name = "物资类型名称")
private String wlTypeName;
/** 所属仓库名称(联查显示用,导出专用) */
@Excel(name = "所属仓库名称")
private String cangkuName;
/** 入库时间(用户操作入库的日期) */
@Excel(name = "入库时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date rkTime;
/** 借用时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "借用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date borrowTime;
/** 归还时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "归还时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date returnTime;
/** 理货员 */
@Excel(name = "理货员")
private String lihuoY;
/** 理货员名称(联查显示用,导出专用) */
private String lihuoYName;
/** 是否已出库0未出库1已出库 */
@Excel(name = "是否已出库", readConverterExp = "0已入库1已出库2待审批3借料出库4入库撤销5出库撤销")
private String isChuku;
/** 单据号 */
@Excel(name = "单据号")
private String billNo;
@@ -30,66 +96,28 @@ public class RkInfo extends BaseEntity {
@Excel(name = "出库单据号")
private String billNoCk;
// ===================== 类型与归属 =====================
/** 入库类型 */
@Excel(name = "入库类型")
private String rkType;
/** 物资类型 */
@Excel(name = "物资类型")
private String wlType;
/** 所属仓库 */
@Excel(name = "所属仓库")
private String cangku;
/** 是否需要配送(0否 1是) */
@Excel(name = "是否需要配送", readConverterExp = "0=否,1=是")
@Excel(name = "是否需要配送", readConverterExp = "0=否,1=是,2=配送中,3=配送完成")
private String isDelivery;
// ===================== 状态与流转 =====================
/** 出入库状态0已入库1已出库2待审批3借料出库4入库撤销5出库撤销 */
@Excel(name = "是否已出库", readConverterExp = "0=已入库,1=已出库,2=待审批,3=借料出库,4=入库撤销,5=出库撤销")
private String isChuku;
/** 审核状态0入库待审核1已通过2已驳回3出库待审核 */
@Excel(name = "审核状态", readConverterExp = "0=入库待审核,1=已通过,2=已驳回,3=出库待审核")
private String status;
/** 是否移库过0否 1是 */
@Excel(name = "是否移库过", readConverterExp = "0=否,1=是")
private String hasMoved;
/** 是否借料0否,1是,2已归还 */
@Excel(name = "是否借料", readConverterExp = "0=否,1=是,2=已归还")
private String isBorrowed;
/** 逻辑删除0 正常1 已删除) */
@Excel(name = "是否删除", readConverterExp = "0=正常,1=已删除")
private String isDelete;
// ===================== 项目信息 =====================
/** 县局 */
@Excel(name = "县局")
private String xj;
/** 项目号(入库/来源项目) */
@Excel(name = "项目号")
/** 项目号 */
@Excel(name = "库存项目号")
private String xmNo;
/** 项目描述(入库/来源项目) */
@Excel(name = "项目描述")
/** 项目描述 */
@Excel(name = "库存项目描述")
private String xmMs;
/** 出库项目号(领取方项目) */
@Excel(name = "出库项目号(领取方项目)")
@Excel(name = "领取方项目号")
private String xmNoCk;
/** 出库项目描述(领取方项目) */
@Excel(name = "出库项目描述(领取方项目)")
@Excel(name = "领取方项目描述")
private String xmMsCk;
// ===================== 物料/供应信息 =====================
/** 物料号 */
@Excel(name = "物料号")
private String wlNo;
@@ -98,7 +126,6 @@ public class RkInfo extends BaseEntity {
@Excel(name = "物料描述")
private String wlMs;
/** 供应商编码 */
@Excel(name = "供应商编码")
private String gysNo;
@@ -107,15 +134,6 @@ public class RkInfo extends BaseEntity {
@Excel(name = "供应商名称")
private String gysMc;
/** SAP订单编号 */
@Excel(name = "SAP订单编号")
private String sapNo;
/** 行号 */
@Excel(name = "行号")
private String xh;
// ===================== 金额/数量 =====================
/** 计划交货金额 */
@Excel(name = "计划交货金额")
private BigDecimal jhAmt;
@@ -124,6 +142,14 @@ public class RkInfo extends BaseEntity {
@Excel(name = "合同单价")
private BigDecimal htDj;
/** SAP订单编号 */
@Excel(name = "SAP订单编号")
private String sapNo;
/** 行号 */
@Excel(name = "行号")
private String xh;
/** 计划交货数量 */
@Excel(name = "计划交货数量")
private Long jhQty;
@@ -140,16 +166,12 @@ public class RkInfo extends BaseEntity {
@Excel(name = "实际入库数量")
private BigDecimal realQty;
// ===================== 库位/托盘/实物 =====================
/** 库位码 */
@Excel(name = "库位码")
private String pcode;
@Excel(name = "出库类型名称")
private String ckTypeName;
/** 库位16进制编码 */
@Excel(name = "库位16进制编码")
/** 库位主键ID */
@Excel(name = "库位主键ID")
private String pcodeId;
/** 托盘码 */
@@ -160,225 +182,373 @@ public class RkInfo extends BaseEntity {
@Excel(name = "实物ID")
private String entityId;
// ===================== 人员/出库信息 =====================
/** 理货员 */
@Excel(name = "理货员")
private String lihuoY;
/** 一货一图 - 货物照片URL */
private String photoUrl;
/** 出库理货员 */
@Excel(name = "出库理货员")
private String ckLihuoY;
/** 施工队 */
@Excel(name = "施工队")
private String teamCode;
/** 出库类型 */
@Excel(name = "出库类型")
private String ckType;
/** 出库备注 */
@Excel(name = "出库备注")
private String ckRemark;
@Excel(name = "出库类型名称")
private String ckTypeName;
// ===================== 关键时间 =====================
/** 入库时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "入库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date rkTime;
private String teamCode;
@Excel(name = "施工队名称")
private String teamName;
/** 领用时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "领用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date lyTime;
/** 借用时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "借用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date borrowTime;
@Excel(name = "出库备注")
private String ckRemark;
/** 归还时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "归还时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date returnTime;
@Excel(name = "出库备注")
private String status;
// ===================== 关联外键 =====================
/** 供应计划ID对应供应计划表主键 */
@Excel(name = "供应计划ID")
private Long gysJhId;
/** 是否移库过0否 1是 */
@Excel(name = "是否移库过")
private String hasMoved;
// ===================== MTD 侧重量/体积 =====================
/** 是否借料0否 1是 */
@Excel(name = "是否借料", readConverterExp = "0=否,1=是,2=已归还")
private String isBorrowed;
/** 签字图片URLimage_type = 0 */
private String signImageUrl;
/** 现场图片URLimage_type = 1 */
private String scenePhotoUrl;
/** 当前审批结果0通过1驳回 */
private String auditResult;
/** 入库开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date startTime;
/** 入库结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
/** 领用开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lyStartTime;
/** 领用结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lyEndTime;
/** 一次封样号 */
@Excel(name = "一次封样号")
private String fycde1;
/** 二次封样号 */
@Excel(name = "二次封样号")
private String fycde2;
/** 是否删除0 表示正常1 表示已删除) */
private String isDelete;
/** 单件重量(kg) */
private BigDecimal weightKg;
/** 单件体积(m³) */
private BigDecimal volumeM3;
// ===================== Getter / Setter =====================
/** 单件体积(立方米) */
private BigDecimal volumeM3;
// Getter 和 Setter 方法
public String getKeyword() { return keyword; }
public void setKeyword(String keyword) { this.keyword = keyword; }
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getBillNo() { return billNo; }
public void setBillNo(String billNo) { this.billNo = billNo; }
public List<Long> getIds() {
return ids;
}
public String getBillNoCk() { return billNoCk; }
public void setBillNoCk(String billNoCk) { this.billNoCk = billNoCk; }
public void setIds(List<Long> ids) {
this.ids = ids;
}
public Long getGysJhId() {
return gysJhId;
}
public void setGysJhId(Long gysJhId) {
this.gysJhId = gysJhId;
}
public String getApproverId() {
return approverId;
}
public void setApproverId(String approverId) {
this.approverId = approverId;
}
public Long getStockAge() { return stockAge; }
public void setStockAge(Long stockAge) { this.stockAge = stockAge; }
public String getRkType() { return rkType; }
public void setRkType(String rkType) { this.rkType = rkType; }
public String getWlType() { return wlType; }
public void setWlType(String wlType) { this.wlType = wlType; }
public String getCangku() { return cangku; }
public void setCangku(String cangku) { this.cangku = cangku; }
public String getRkTypeName() { return rkTypeName; }
public void setRkTypeName(String rkTypeName) { this.rkTypeName = rkTypeName; }
public String getWlTypeName() { return wlTypeName; }
public void setWlTypeName(String wlTypeName) { this.wlTypeName = wlTypeName; }
public String getCangkuName() { return cangkuName; }
public void setCangkuName(String cangkuName) { this.cangkuName = cangkuName; }
public Date getRkTime() { return rkTime; }
public void setRkTime(Date rkTime) { this.rkTime = rkTime; }
public Date getBorrowTime() {
return borrowTime;
}
public void setBorrowTime(Date borrowTime) {
this.borrowTime = borrowTime;
}
public String getIsDelivery() { return isDelivery; }
public void setIsDelivery(String isDelivery) { this.isDelivery = isDelivery; }
public String getIsChuku() { return isChuku; }
public void setIsChuku(String isChuku) { this.isChuku = isChuku; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getHasMoved() { return hasMoved; }
public void setHasMoved(String hasMoved) { this.hasMoved = hasMoved; }
public String getIsBorrowed() { return isBorrowed; }
public void setIsBorrowed(String isBorrowed) { this.isBorrowed = isBorrowed; }
public String getIsDelete() { return isDelete; }
public void setIsDelete(String isDelete) { this.isDelete = isDelete; }
public String getXj() { return xj; }
public void setXj(String xj) { this.xj = xj; }
public String getXmNo() { return xmNo; }
public void setXmNo(String xmNo) { this.xmNo = xmNo; }
public String getXmMs() { return xmMs; }
public void setXmMs(String xmMs) { this.xmMs = xmMs; }
public String getXmNoCk() { return xmNoCk; }
public void setXmNoCk(String xmNoCk) { this.xmNoCk = xmNoCk; }
public String getXmMsCk() { return xmMsCk; }
public void setXmMsCk(String xmMsCk) { this.xmMsCk = xmMsCk; }
public String getWlNo() { return wlNo; }
public void setWlNo(String wlNo) { this.wlNo = wlNo; }
public String getWlMs() { return wlMs; }
public void setWlMs(String wlMs) { this.wlMs = wlMs; }
public String getGysNo() { return gysNo; }
public void setGysNo(String gysNo) { this.gysNo = gysNo; }
public String getGysMc() { return gysMc; }
public void setGysMc(String gysMc) { this.gysMc = gysMc; }
public String getSapNo() { return sapNo; }
public void setSapNo(String sapNo) { this.sapNo = sapNo; }
public String getXh() { return xh; }
public void setXh(String xh) { this.xh = xh; }
public BigDecimal getJhAmt() { return jhAmt; }
public void setJhAmt(BigDecimal jhAmt) { this.jhAmt = jhAmt; }
public BigDecimal getHtDj() { return htDj; }
public void setHtDj(BigDecimal htDj) { this.htDj = htDj; }
public Long getJhQty() { return jhQty; }
public void setJhQty(Long jhQty) { this.jhQty = jhQty; }
public Long getHtQty() { return htQty; }
public void setHtQty(Long htQty) { this.htQty = htQty; }
public String getDw() { return dw; }
public void setDw(String dw) { this.dw = dw; }
public BigDecimal getRealQty() { return realQty; }
public void setRealQty(BigDecimal realQty) { this.realQty = realQty; }
public String getPcode() { return pcode; }
public void setPcode(String pcode) { this.pcode = pcode; }
public String getPcodeId() { return pcodeId; }
public void setPcodeId(String pcodeId) { this.pcodeId = pcodeId; }
public String getTrayCode() { return trayCode; }
public void setTrayCode(String trayCode) { this.trayCode = trayCode; }
public String getEntityId() { return entityId; }
public void setEntityId(String entityId) { this.entityId = entityId; }
public Date getReturnTime() {
return returnTime;
}
public void setReturnTime(Date returnTime) {
this.returnTime = returnTime;
}
public String getLihuoY() { return lihuoY; }
public void setLihuoY(String lihuoY) { this.lihuoY = lihuoY; }
public String getLihuoYName() { return lihuoYName; }
public void setLihuoYName(String lihuoYName) { this.lihuoYName = lihuoYName; }
public List<String> getIsChukuList() {
return isChukuList;
}
public void setIsChukuList(List<String> isChukuList) {
this.isChukuList = isChukuList;
}
public String getIsChuku() { return isChuku; }
public void setIsChuku(String isChuku) { this.isChuku = isChuku; }
public String getBillNo() { return billNo; }
public void setBillNo(String billNo) { this.billNo = billNo; }
public String getBillNoCk() { return billNoCk; }
public void setBillNoCk(String billNoCk) { this.billNoCk = billNoCk; }
public String getXj() { return xj; }
public void setXj(String xj) { this.xj = xj; }
public String getXmNo() { return xmNo; }
public void setXmNo(String xmNo) { this.xmNo = xmNo; }
public String getXmMs() { return xmMs; }
public void setXmMs(String xmMs) { this.xmMs = xmMs; }
public String getWlNo() { return wlNo; }
public void setWlNo(String wlNo) { this.wlNo = wlNo; }
public String getWlMs() { return wlMs; }
public void setWlMs(String wlMs) { this.wlMs = wlMs; }
public String getGysNo() { return gysNo; }
public void setGysNo(String gysNo) { this.gysNo = gysNo; }
public String getGysMc() { return gysMc; }
public void setGysMc(String gysMc) { this.gysMc = gysMc; }
public BigDecimal getJhAmt() { return jhAmt; }
public void setJhAmt(BigDecimal jhAmt) { this.jhAmt = jhAmt; }
public BigDecimal getHtDj() { return htDj; }
public void setHtDj(BigDecimal htDj) { this.htDj = htDj; }
public String getSapNo() { return sapNo; }
public void setSapNo(String sapNo) { this.sapNo = sapNo; }
public String getXh() { return xh; }
public void setXh(String xh) { this.xh = xh; }
public Long getJhQty() { return jhQty; }
public void setJhQty(Long jhQty) { this.jhQty = jhQty; }
public Long getHtQty() { return htQty; }
public void setHtQty(Long htQty) { this.htQty = htQty; }
public String getDw() { return dw; }
public void setDw(String dw) { this.dw = dw; }
public BigDecimal getRealQty() { return realQty; }
public void setRealQty(BigDecimal realQty) { this.realQty = realQty; }
public String getPcode() { return pcode; }
public void setPcode(String pcode) { this.pcode = pcode; }
public String getPcodeId() { return pcodeId; }
public void setPcodeId(String pcodeId) { this.pcodeId = pcodeId; }
public String getTrayCode() { return trayCode; }
public void setTrayCode(String trayCode) { this.trayCode = trayCode; }
public String getEntityId() { return entityId; }
public void setEntityId(String entityId) { this.entityId = entityId; }
public String getPhotoUrl() {
return photoUrl;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
public String getCkLihuoY() { return ckLihuoY; }
public void setCkLihuoY(String ckLihuoY) { this.ckLihuoY = ckLihuoY; }
public String getCkTypeName() { return ckTypeName; }
public void setCkTypeName(String ckTypeName) { this.ckTypeName = ckTypeName; }
public String getTeamCode() { return teamCode; }
public void setTeamCode(String teamCode) { this.teamCode = teamCode; }
public String getCkType() { return ckType; }
public void setCkType(String ckType) { this.ckType = ckType; }
public String getCkRemark() { return ckRemark; }
public void setCkRemark(String ckRemark) { this.ckRemark = ckRemark; }
public Date getRkTime() { return rkTime; }
public void setRkTime(Date rkTime) { this.rkTime = rkTime; }
public String getCkTypeName() { return ckTypeName; }
public void setCkTypeName(String ckTypeName) { this.ckTypeName = ckTypeName; }
public String getTeamCode() { return teamCode; }
public void setTeamCode(String teamCode) { this.teamCode = teamCode; }
public String getTeamName() { return teamName; }
public void setTeamName(String teamName) { this.teamName = teamName; }
public Date getLyTime() { return lyTime; }
public void setLyTime(Date lyTime) { this.lyTime = lyTime; }
public String getCkRemark() { return ckRemark; }
public void setCkRemark(String ckRemark) { this.ckRemark = ckRemark; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getHasMoved() { return hasMoved; }
public void setHasMoved(String hasMoved) { this.hasMoved = hasMoved; }
public String getXmNoCk() {
return xmNoCk;
}
public Date getBorrowTime() { return borrowTime; }
public void setBorrowTime(Date borrowTime) { this.borrowTime = borrowTime; }
public void setXmNoCk(String xmNoCk) {
this.xmNoCk = xmNoCk;
}
public Date getReturnTime() { return returnTime; }
public void setReturnTime(Date returnTime) { this.returnTime = returnTime; }
public String getXmMsCk() {
return xmMsCk;
}
public Long getGysJhId() { return gysJhId; }
public void setGysJhId(Long gysJhId) { this.gysJhId = gysJhId; }
public void setXmMsCk(String xmMsCk) {
this.xmMsCk = xmMsCk;
}
public BigDecimal getWeightKg() { return weightKg; }
public void setWeightKg(BigDecimal weightKg) { this.weightKg = weightKg; }
public BigDecimal getVolumeM3() { return volumeM3; }
public void setVolumeM3(BigDecimal volumeM3) { this.volumeM3 = volumeM3; }
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Date getLyStartTime() {
return lyStartTime;
}
public void setLyStartTime(Date lyStartTime) {
this.lyStartTime = lyStartTime;
}
public Date getLyEndTime() {
return lyEndTime;
}
public void setLyEndTime(Date lyEndTime) {
this.lyEndTime = lyEndTime;
}
public String getIsBorrowed() {
return isBorrowed;
}
public void setIsBorrowed(String isBorrowed) {
this.isBorrowed = isBorrowed;
}
public String getSignImageUrl() {
return signImageUrl;
}
public void setSignImageUrl(String signImageUrl) {
this.signImageUrl = signImageUrl;
}
public String getScenePhotoUrl() {
return scenePhotoUrl;
}
public void setScenePhotoUrl(String scenePhotoUrl) {
this.scenePhotoUrl = scenePhotoUrl;
}
public String getAuditResult() {
return auditResult;
}
public void setAuditResult(String auditResult) {
this.auditResult = auditResult;
}
public String getFycde1() {
return fycde1;
}
public void setFycde1(String fycde1) {
this.fycde1 = fycde1;
}
public String getFycde2() {
return fycde2;
}
public void setFycde2(String fycde2) {
this.fycde2 = fycde2;
}
public String getIsDelete() { return isDelete; }
public void setIsDelete(String isDelete) { this.isDelete = isDelete; }
public String getIsDelivery() {
return isDelivery;
}
public void setIsDelivery(String isDelivery) {
this.isDelivery = isDelivery;
}
public BigDecimal getWeightKg() {
return weightKg;
}
public void setWeightKg(BigDecimal weightKg) {
this.weightKg = weightKg;
}
public BigDecimal getVolumeM3() {
return volumeM3;
}
public void setVolumeM3(BigDecimal volumeM3) {
this.volumeM3 = volumeM3;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("billNo", getBillNo())
.append("billNoCk", getBillNoCk())
.append("gysJhId", getGysJhId())
.append("approverId", getApproverId())
.append("rkType", getRkType())
.append("wlType", getWlType())
.append("cangku", getCangku())
.append("isDelivery", getIsDelivery())
.append("rkTime", getRkTime())
.append("borrowTime", getBorrowTime())
.append("returnTime", getReturnTime())
.append("lihuoY", getLihuoY())
.append("isChuku", getIsChuku())
.append("status", getStatus())
.append("hasMoved", getHasMoved())
.append("isBorrowed", getIsBorrowed())
.append("isDelete", getIsDelete())
.append("billNo", getBillNo())
.append("billNoCk", getBillNoCk())
.append("isDelivery", getIsDelivery())
.append("remark", getRemark())
.append("xj", getXj())
.append("xmNo", getXmNo())
.append("xmMs", getXmMs())
.append("xmNoCk", getXmNoCk())
.append("xmMsCk", getXmMsCk())
.append("wlNo", getWlNo())
.append("wlMs", getWlMs())
.append("gysNo", getGysNo())
.append("gysMc", getGysMc())
.append("sapNo", getSapNo())
.append("xh", getXh())
.append("jhAmt", getJhAmt())
.append("htDj", getHtDj())
.append("sapNo", getSapNo())
.append("xh", getXh())
.append("jhQty", getJhQty())
.append("htQty", getHtQty())
.append("dw", getDw())
@@ -387,22 +557,34 @@ public class RkInfo extends BaseEntity {
.append("pcodeId", getPcodeId())
.append("trayCode", getTrayCode())
.append("entityId", getEntityId())
.append("lihuoY", getLihuoY())
.append("ckLihuoY", getCkLihuoY())
.append("teamCode", getTeamCode())
.append("ckType", getCkType())
.append("ckTypeName", getCkTypeName())
.append("ckRemark", getCkRemark())
.append("rkTime", getRkTime())
.append("lyTime", getLyTime())
.append("borrowTime", getBorrowTime())
.append("returnTime", getReturnTime())
.append("gysJhId", getGysJhId())
.append("remark", getRemark())
.append("photoUrl", getPhotoUrl())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("ckLihuoY", getCkLihuoY())
.append("ckType", getCkType())
.append("ckTypeName", getCkTypeName())
.append("teamCode", getTeamCode())
.append("teamName", getTeamName())
.append("lyTime", getLyTime())
.append("ckRemark", getCkRemark())
.append("status", getStatus())
.append("hasMoved", getHasMoved())
.append("xmNoCk", getXmNoCk())
.append("xmMsCk", getXmMsCk())
.append("startTime", getStartTime())
.append("endTime", getEndTime())
.append("isBorrowed", getIsBorrowed())
.append("signImageUrl", getSignImageUrl())
.append("scenePhotoUrl", getScenePhotoUrl())
.append("auditResult", getAuditResult())
.append("isChukuList", getIsChukuList())
.append("lyStartTime", getLyStartTime())
.append("lyEndTime", getLyEndTime())
.append("fycde1", getFycde1())
.append("fycde2", getFycde2())
.append("isDelete", getIsDelete())
.append("weightKg", getWeightKg())
.append("volumeM3", getVolumeM3())
.toString();

View File

@@ -6,6 +6,7 @@ import java.math.BigDecimal;
@Data
public class DeliveryOrderLineDTO {
private String billNoCk; // 出库单据号
private String xmMs; // 项目描述
private String xmNo; // 项目号
private String wlNo; // 物料号

View File

@@ -0,0 +1,30 @@
package com.delivery.project.document.domain.vo;
import com.delivery.project.document.domain.RkInfo;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 智慧实物-待配送出库单据 VO1 对多)
*/
@Data
public class DeliveryBillVO implements Serializable {
/** 出库单据号bill_no_ck */
private String billNoCk;
/** 出库理货员 */
private String ckLihuoY;
/** 施工队/班组 */
private String teamCode;
/** 领用时间(出库时间) */
private Date lyTime;
/** 该出库单据下的所有货物明细 */
private List<RkInfo> detailList;
}

View File

@@ -26,7 +26,8 @@ public class DeliveryOrderGroupVO {
/** 配送单号 */
private String orderNo;
/** 出库单据号 */
private String billNoCk;
/** 配送日期格式yyyy-MM-dd */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date deliveryDate;

View File

@@ -80,7 +80,7 @@ public interface DeliveryOrderMapper
/**
* 根据单号查询
*
* @param plateNo
* @param
* @return
*/
List<DeliveryOrder> selectByOrderNo(String orderNo);
@@ -91,5 +91,5 @@ public interface DeliveryOrderMapper
* @param orderNo
* @return
*/
DeliveryOrder selectDeliveryOrderByOrderNo(String orderNo);
List<DeliveryOrder> selectDeliveryOrderByOrderNo(String orderNo);
}

View File

@@ -1,8 +1,8 @@
package com.delivery.project.document.mapper;
import java.util.List;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.domain.dto.RkInfoQueryDTO;
import org.apache.ibatis.annotations.Param;
/**
@@ -68,4 +68,6 @@ public interface RkInfoMapper
List<RkInfo> selectGroupedByBill(@Param("q") RkInfo rkInfo);
int updateDeliveryStatus(@Param("billNoCk") String billNoCk,
@Param("isDelivery") Integer isDelivery);
}

View File

@@ -64,7 +64,11 @@ public interface IDeliveryAttachmentService
*/
public int deleteDeliveryAttachmentById(Long id);
/**
* 开始/完成配送
* @param dto
* @return
*/
int executeBind(DeliveryExecuteBindDTO dto);
List<String> upload(MultipartFile[] files, DeliveryAttachUploadDTO dto, HttpServletRequest request);

View File

@@ -2,11 +2,10 @@ package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.DeliveryOrder;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.domain.dto.DeliveryOrderCreateDTO;
import com.delivery.project.document.domain.dto.DeliveryOrderSaveDTO;
import com.delivery.project.document.domain.vo.DeliveryBillVO;
import com.delivery.project.document.domain.vo.DeliveryOrderGroupVO;
import org.springframework.beans.factory.annotation.Value;
/**
* 配送单据主Service接口
@@ -102,6 +101,6 @@ public interface IDeliveryOrderService
*
* @return rk_info 列表
*/
List<RkInfo> listWisdomRkForDelivery();
List<DeliveryBillVO> listWisdomRkForDelivery();
}

View File

@@ -1,8 +1,8 @@
package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.domain.dto.RkInfoQueryDTO;
import java.util.List;
/**
* 库存单据明细Service接口

View File

@@ -8,17 +8,23 @@ import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;
import com.alibaba.fastjson2.JSON;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.DateUtils;
import com.delivery.common.utils.StringUtils;
import com.delivery.common.utils.http.HttpUtils;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.project.document.domain.DeliveryOrder;
import com.delivery.project.document.domain.dto.DeliveryAttachItemDTO;
import com.delivery.project.document.domain.dto.DeliveryAttachUploadDTO;
import com.delivery.project.document.domain.dto.DeliveryExecuteBindDTO;
import com.delivery.project.document.mapper.DeliveryOrderMapper;
import com.delivery.project.document.mapper.RkInfoMapper;
import com.delivery.project.document.service.IDeliveryOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.DeliveryAttachmentMapper;
import com.delivery.project.document.domain.DeliveryAttachment;
@@ -29,6 +35,8 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import static com.delivery.common.utils.SecurityUtils.getUsername;
/**
* 配送附件Service业务层处理
*
@@ -48,6 +56,12 @@ public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
@Autowired
private IDeliveryOrderService deliveryOrderService;
@Value("${wisdom.base-url}")
private String wisdomBaseUrl;
@Autowired
private RkInfoMapper rkInfoMapper;
/**
* 查询配送附件
*
@@ -126,21 +140,31 @@ public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
@Transactional(rollbackFor = Exception.class)
public int executeBind(DeliveryExecuteBindDTO dto) {
// 1) 校验订单存在
DeliveryOrder exist = deliveryOrderMapper.selectDeliveryOrderByOrderNo(dto.getOrderNo());
if (exist == null) {
List<DeliveryOrder> existList = deliveryOrderMapper.selectDeliveryOrderByOrderNo(dto.getOrderNo());
if (existList == null || existList.isEmpty()) {
throw new ServiceException("配送单不存在:" + dto.getOrderNo());
}
String billNoCk = existList.get(0).getBillNoCk();
if (StringUtils.isBlank(billNoCk)) {
throw new ServiceException("配送单未绑定出库单号,无法回写库存状态!");
}
if (dto.getAttachments() == null || dto.getAttachments().isEmpty()) {
throw new ServiceException("附件列表不能为空");
}
// 2) 批量插入附件(只传 URL
List<DeliveryAttachment> list = new ArrayList<>();
// String username = getUsername();
String username = "大爷的!!!";
String username = getUsername();
// String username = "大爷的!!!";
for (DeliveryAttachItemDTO it : dto.getAttachments()) {
if (it == null) continue;
if (it.getScene() == null || it.getBizType() == null || it.getUrl() == null) continue;
if (it == null) {
continue;
}
if (it.getScene() == null || it.getBizType() == null || it.getUrl() == null) {
continue;
}
DeliveryAttachment a = new DeliveryAttachment();
a.setOrderNo(dto.getOrderNo());
@@ -166,15 +190,15 @@ public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
String scene = dto.getScene() == null ? "" : dto.getScene().toUpperCase(Locale.ROOT);
if ("ORIGIN".equals(scene)) {
// 起点:司机信息 + 起点经纬度 + 状态=1
// 起点:司机信息 + 起点经纬度 + 状态=2起运/配送中)
if (dto.getDriverName() != null) patch.setDriverName(dto.getDriverName());
if (dto.getDriverPhone() != null) patch.setDriverPhone(dto.getDriverPhone());
if (dto.getPlateNo() != null) patch.setplateNo(dto.getPlateNo());
if (dto.getLng() != null) patch.setOriginLng(BigDecimal.valueOf(dto.getLng()));
if (dto.getLat() != null) patch.setOriginLat(BigDecimal.valueOf(dto.getLat()));
if (dto.getPlateNo() != null) patch.setPlateNo(dto.getPlateNo());
if (dto.getLng() != null) patch.setOriginLng(BigDecimal.valueOf(dto.getLng()));
if (dto.getLat() != null) patch.setOriginLat(BigDecimal.valueOf(dto.getLat()));
patch.setOrderStatus("2");
} else if ("DEST".equals(scene)) {
// 终点:终点经纬度 + 状态=2
// 终点:终点经纬度 + 费用 + 状态=3已完成
if (dto.getLng() != null) patch.setDestLng(BigDecimal.valueOf(dto.getLng()));
if (dto.getLat() != null) patch.setDestLat(BigDecimal.valueOf(dto.getLat()));
@@ -191,13 +215,70 @@ public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
patch.setTollFee(dto.getTollFee());
}
patch.setOrderStatus("3");
patch.setOrderStatus("3"); // 已完成
}
deliveryOrderMapper.updateDeliveryOrder(patch);
// 4) ⭐ 如果是 DEST 场景,远程调用 WMS把 rk_info.is_delivery 改成 3
if ("DEST".equals(scene)) {
if (StringUtils.isBlank(billNoCk)) {
throw new ServiceException("配送单缺少对应的出库单号 billNoCk无法回写库存状态");
}
// rkInfoMapper.updateDeliveryStatus(billNoCk, 3);
boolean ok = updateWmsIsDelivery(billNoCk, 3);
if (!ok) {
// 让整个事务回滚,附件 + 配送单状态都撤回
throw new ServiceException("回写 WMS 配送状态失败,出库单号:" + billNoCk);
}
}
deliveryOrderService.updateDeliveryOrder(patch);
return list.size();
}
/**
* 远程调用智慧实物管理系统,更新 rk_info.is_delivery 状态
*/
private boolean updateWmsIsDelivery(String billNoCk, int isDelivery) {
String url = wisdomBaseUrl + "/wisdom/stock/updateDeliveryStatus";
Map<String, Object> body = new HashMap<>();
body.put("billNoCk", billNoCk);
body.put("isDelivery", isDelivery);
String json = JSON.toJSONString(body);
try {
// 用你项目里的 HttpUtils 发 JSON POST
String resp = HttpUtils.sendPost(url, json, MediaType.APPLICATION_JSON_VALUE);
if (StringUtils.isBlank(resp)) {
log.error("WMS 更新失败响应为空url={} billNoCk={}", url, billNoCk);
return false;
}
AjaxResult result = JSON.parseObject(resp, AjaxResult.class);
if (result != null && result.isSuccess()) {
return true;
} else {
String msg = (result == null)
? "响应为空"
: String.valueOf(result.get(AjaxResult.MSG_TAG));
log.error("WMS 更新失败billNoCk={},原因={}", billNoCk, msg);
return false;
}
} catch (Exception e) {
log.error("调用 WMS 接口异常billNoCk={}error={}", billNoCk, e.getMessage(), e);
return false;
}
}
// 保存目录 D:\delivery
private static final String BASE_PATH = "D:/delivery";

View File

@@ -1,25 +1,30 @@
package com.delivery.project.document.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.DateUtils;
import com.delivery.common.utils.SecurityUtils;
import com.delivery.common.utils.StringUtils;
import com.delivery.common.utils.http.HttpUtils;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.project.document.domain.DeliveryAttachment;
import com.delivery.project.document.domain.Mtd;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.domain.dto.DeliveryAttachUploadDTO;
import com.delivery.project.document.domain.dto.DeliveryOrderCreateDTO;
import com.delivery.project.document.domain.dto.DeliveryOrderLineDTO;
import com.delivery.project.document.domain.dto.DeliveryOrderSaveDTO;
import com.delivery.project.document.domain.vo.DeliveryBillVO;
import com.delivery.project.document.domain.vo.DeliveryOrderGroupVO;
import com.delivery.project.document.mapper.DeliveryAttachmentMapper;
import com.delivery.project.document.mapper.MtdMapper;
import com.delivery.project.document.mapper.RkInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -29,8 +34,6 @@ import com.delivery.project.document.domain.DeliveryOrder;
import com.delivery.project.document.service.IDeliveryOrderService;
import org.springframework.transaction.annotation.Transactional;
import static com.delivery.common.utils.SecurityUtils.getUsername;
/**
* 配送单据主Service业务层处理
*
@@ -38,6 +41,7 @@ import static com.delivery.common.utils.SecurityUtils.getUsername;
* @date 2025-10-15
*/
@Service
@Slf4j
public class DeliveryOrderServiceImpl implements IDeliveryOrderService
{
@Autowired
@@ -47,6 +51,12 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
@Autowired
private DeliveryAttachmentMapper deliveryAttachmentMapper;
@Autowired
private RkInfoMapper rkInfoMapper;
@Autowired
private MtdMapper mtdMapper;
@Value("${wisdom.base-url}")
private String wisdomBaseUrl;
@@ -174,75 +184,145 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
@Transactional(rollbackFor = Exception.class)
public String createOrder(DeliveryOrderCreateDTO dto) {
// ========== 0. 参数校验 ==========
if (dto == null || dto.getItems() == null || dto.getItems().isEmpty()) {
throw new ServiceException("物料明细不能为空");
}
// 所有明细应是同一出库单据号,这里简单从第一条取出
String billNoCk = dto.getItems().get(0).getBillNoCk();
if (billNoCk == null || billNoCk.trim().isEmpty()) {
throw new ServiceException("明细行缺少出库单据号 billNoCk");
}
// ========== 1. 生成配送单号 ==========
// 如果前端未指定单号则按规则生成一个唯一编号示例DO20251027104532123
String orderNo = (dto.getOrderNo() == null || dto.getOrderNo().trim().isEmpty())
? "DO" + DateUtils.dateTimeNow("yyyyMMddHHmmssSSS")
: dto.getOrderNo().trim();
// 当前时间,用于所有行的 create_time
Date now = DateUtils.getNowDate();
String username = SecurityUtils.getUsername();
// 定义要插入的记录集合
List<DeliveryOrder> rows = new ArrayList<>();
// ========== 2. 遍历每一条物料明细 ==========
for (DeliveryOrderLineDTO it : dto.getItems()) {
// 创建实体对象(每一行对应一条数据库记录)
// 这里如果允许多个出库单合并配送,可以去掉这个校验
if (!billNoCk.equals(it.getBillNoCk())) {
throw new ServiceException("当前接口暂不支持多张出库单合并配送,请确保所有明细 billNoCk 相同");
}
DeliveryOrder row = new DeliveryOrder();
// ========== 2.1 公共头部字段(相同单号下字段一致) ==========
row.setOrderNo(orderNo); // 同单号绑定
row.setOriginName(dto.getOriginName()); // 起点名称
row.setDestName(dto.getDestName()); // 终点名称
row.setDeliveryDate(dto.getDeliveryDate()); // 配送日期
row.setShipperName(dto.getShipperName()); // 发货人姓名
row.setShipperPhone(dto.getShipperPhone()); // 发货人电话
row.setReceiverName(dto.getReceiverName()); // 收货人姓名
row.setReceiverPhone(dto.getReceiverPhone()); // 收货人电话
row.setReceiverOrgName(dto.getReceiverOrgName()); // 收货单位名称
row.setDeliveryTon(dto.getDeliveryTon()); // 配送吨位
row.setGoodsSize(dto.getGoodsSize()); // 货物尺寸
row.setOrderStatus(dto.getOrderStatus() == null ? "1" : dto.getOrderStatus()); // 默认状态:已接单
row.setVehicleTypeId(dto.getVehicleTypeId()); // 车辆类型ID
row.setVehicleTypeName(dto.getVehicleTypeName()); // 车辆类型名称
row.setSuggestFee(dto.getSuggestFee()); // 建议费用
row.setActualFee(dto.getActualFee()); // 实际费用
row.setTollFee(dto.getTollFee()); // 高速费
row.setTotalKm(dto.getTotalKm()); // 总公里数
row.setRemark(dto.getRemark()); // 备注
// 2.1 公共头部字段(整单一致)
row.setOrderNo(orderNo);
row.setOriginName(dto.getOriginName());
row.setOriginLng(dto.getOriginLng());
row.setOriginLat(dto.getOriginLat());
row.setDestName(dto.getDestName());
row.setDestLng(dto.getDestLng());
row.setDestLat(dto.getDestLat());
row.setDeliveryDate(dto.getDeliveryDate());
row.setPlateNo(dto.getPlateNo());
row.setShipperName(dto.getShipperName());
row.setShipperPhone(dto.getShipperPhone());
row.setReceiverName(dto.getReceiverName());
row.setReceiverPhone(dto.getReceiverPhone());
row.setReceiverOrgName(dto.getReceiverOrgName());
row.setDeliveryTon(dto.getDeliveryTon());
row.setGoodsSize(dto.getGoodsSize());
row.setOrderStatus(
StringUtils.isBlank(dto.getOrderStatus()) ? "1" : dto.getOrderStatus().trim()
);
row.setVehicleTypeId(dto.getVehicleTypeId());
row.setVehicleTypeName(dto.getVehicleTypeName());
row.setSuggestFee(dto.getSuggestFee());
row.setActualFee(dto.getActualFee());
row.setTollFee(dto.getTollFee());
row.setTotalKm(dto.getTotalKm());
row.setRemark(dto.getRemark());
// ========== 2.2 明细字段(每行不同) ==========
row.setXmMs(it.getXmMs()); // 项目描述
row.setXmNo(it.getXmNo()); // 项目号
row.setWlNo(it.getWlNo()); // 物料号
row.setWlMs(it.getWlMs()); // 物料描述
row.setRealQty(it.getRealQty()); // 实际入库数量
row.setDw(it.getDw()); // 计量单位
row.setSapNo(it.getSapNo()); // SAP订单号
row.setGysMc(it.getGysMc()); // 供应商名称
// 2.2 明细字段
row.setBillNoCk(it.getBillNoCk());
row.setXmMs(it.getXmMs());
row.setXmNo(it.getXmNo());
row.setWlNo(it.getWlNo());
row.setWlMs(it.getWlMs());
row.setRealQty(it.getRealQty());
row.setDw(it.getDw());
row.setSapNo(it.getSapNo());
row.setGysMc(it.getGysMc());
// ========== 2.3 通用字段 ==========
row.setIsDelete("0"); // 正常状态
row.setCreateTime(now); // 创建时间
row.setCreateBy(getUsername());
// row.setCreateBy("大爷的!");
// 2.3 通用字段
row.setIsDelete("0");
row.setCreateTime(now);
row.setCreateBy(username);
// 添加到批量集合中
rows.add(row);
}
// ========== 3. 批量落库 ==========
if (!rows.isEmpty()) {
// 使用 Mapper.xml 的 <foreach> 一次插入多条记录
deliveryOrderMapper.batchInsert(rows);
}
// ========== 4. 返回单号 ==========
// rkInfoMapper.updateDeliveryStatus(billNoCk, 2);
// ========== 4. 回写 WMSrk_info.is_delivery = 2配送中 ==========
// 按出库单据号整单回写
boolean ok = updateWmsIsDelivery(billNoCk, 2);
if (!ok) {
// 这里直接抛异常让当前事务回滚避免出现“配送单已生成WMS 状态没改”的脏数据
throw new ServiceException("已生成配送单,但回写 WMS 配送状态失败");
}
return orderNo;
}
/**
* 远程调用 WMS按出库单据号修改 rk_info.is_delivery 状态
*
* 请求方式示例:
* POST ${delivery.wms-base-url}/delivery/rkInfo/updateDeliveryStatus
* Body: { "billNoCk": "CK202511200001", "isDelivery": 2 }
*/
private boolean updateWmsIsDelivery(String billNoCk, int isDelivery) {
String url = wisdomBaseUrl + "/wisdom/stock/updateDeliveryStatus";
Map<String, Object> map = new HashMap<>();
map.put("billNoCk", billNoCk);
map.put("isDelivery", isDelivery);
String json = JSON.toJSONString(map);
try {
// 发送 JSON POST你刚加的 sendJsonPost
String resp = HttpUtils.sendJsonPost(url, json);
// 解析为 AjaxResult
AjaxResult result = JSON.parseObject(resp, AjaxResult.class);
if (result != null && result.isSuccess()) {
// code == 200
return true;
} else {
// 取 msg从 Map 里按 key 取
String msg = (result != null)
? String.valueOf(result.get(AjaxResult.MSG_TAG))
: "响应为空";
log.error("WMS 更新失败:{}", msg);
return false;
}
} catch (Exception e) {
log.error("WMS 调用异常 billNoCk={} error={}", billNoCk, e.getMessage(), e);
return false;
}
}
@Override
public List<DeliveryOrderGroupVO> listGroup(DeliveryOrder query) {
return deliveryOrderMapper.selectGroupList(query);
@@ -260,18 +340,23 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
* @return List<RkInfo>
*/
@Override
public List<RkInfo> listWisdomRkForDelivery() {
public List<DeliveryBillVO> listWisdomRkForDelivery() {
// 1. 拼接请求地址
String url = wisdomBaseUrl + "/wisdom/stock/delivery";
// 1. 远程接口地址
String url = wisdomBaseUrl + "/wisdom/stock/delivery/list";
// 2. 发送 GET 请求
String respJson = HttpUtils.sendGet(url);
StringBuilder param = new StringBuilder();
param.append("pageNum=1");
param.append("&pageSize=1000");
param.append("&isChuku=1"); // 已出库
param.append("&isDelivery=1"); // 需要配送
// 2. 调用智慧实物系统
String respJson = HttpUtils.sendGet(url, param.toString());
if (StringUtils.isEmpty(respJson)) {
throw new ServiceException("调用智慧实物接口失败:返回结果为空");
}
// 3. 解析 JSON统一返回结构{ code, msg, data }
JSONObject json = JSON.parseObject(respJson);
if (json == null) {
throw new ServiceException("调用智慧实物接口失败:解析返回结果为空");
@@ -279,30 +364,63 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
Integer code = json.getInteger("code");
if (code == null || code != 200) {
String msg = json.getString("msg");
throw new ServiceException("调用智慧实物接口失败code=" + code + "msg=" + msg);
throw new ServiceException("调用智慧实物接口失败code=" + code
+ "msg=" + json.getString("msg"));
}
Object dataObj = json.get("data");
if (dataObj == null) {
// 没有数据就返回空集合,不算错误
JSONArray data = json.getJSONArray("data");
if (data == null || data.isEmpty()) {
return new ArrayList<>();
}
// data 可能本身就是数组,也可能是单个对象
JSONArray dataArr;
if (dataObj instanceof JSONArray) {
dataArr = (JSONArray) dataObj;
} else {
dataArr = JSON.parseArray(JSON.toJSONString(dataObj));
// 3. 反序列化为一对多结构DeliveryBillVO(detailList 中是 RkInfo)
List<DeliveryBillVO> list = data.toJavaList(DeliveryBillVO.class);
// 4. 收集所有 wlNo
Set<String> wlNoSet = list.stream()
.filter(bill -> bill.getDetailList() != null && !bill.getDetailList().isEmpty())
.flatMap(bill -> bill.getDetailList().stream())
.map(RkInfo::getWlNo)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
if (wlNoSet.isEmpty()) {
return list;
}
if (dataArr == null || dataArr.isEmpty()) {
return new ArrayList<>();
// 5. 一次性查询本地 delivery_mtd
List<Mtd> mtdList = mtdMapper.selectByWlNos(new ArrayList<>(wlNoSet));
if (mtdList == null || mtdList.isEmpty()) {
// 本地没有维护重量体积,也直接返回原始数据
return list;
}
// 4. 转成 List<RkInfo>
return JSON.parseArray(dataArr.toJSONString(), RkInfo.class);
// 6. 转为 Map<wlNo, Mtd>
Map<String, Mtd> mtdMap = mtdList.stream()
.collect(Collectors.toMap(
Mtd::getWlNo,
m -> m,
(a, b) -> a // 同 wlNo 只保留一个
));
// 7. 回填到每一条 RkInfo 上
for (DeliveryBillVO bill : list) {
if (bill.getDetailList() == null) {
continue;
}
for (RkInfo rk : bill.getDetailList()) {
if (rk == null || StringUtils.isBlank(rk.getWlNo())) {
continue;
}
Mtd m = mtdMap.get(rk.getWlNo());
if (m != null) {
rk.setWeightKg(m.getWeightKg());
rk.setVolumeM3(m.getVolumeM3());
}
}
}
return list;
}
}

View File

@@ -2,11 +2,10 @@ package com.delivery.project.document.service.impl;
import java.util.List;
import com.delivery.common.utils.DateUtils;
import com.delivery.project.document.domain.dto.RkInfoQueryDTO;
import com.delivery.project.document.domain.RkInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.RkInfoMapper;
import com.delivery.project.document.domain.RkInfo;
import com.delivery.project.document.service.IRkInfoService;
/**

View File

@@ -61,7 +61,7 @@ spring:
host: 192.168.1.28
port: 6379
database: 0
password:
password: shzg
timeout: 10s
lettuce:
pool:
@@ -116,7 +116,7 @@ gen:
allowOverwrite: false
minio:
endpoint: http://192.168.1.20:9000
endpoint: http://192.168.1.28:9000
accessKey: admin
secretKey: admin123
bucketName: delivery
@@ -124,7 +124,7 @@ minio:
upload:
base-dir: /data/upload/images
base-url: http://192.168.1.20/files
base-url: http://192.168.1.250/files
wisdom:
base-url: http://192.168.1.251:8086

View File

@@ -10,7 +10,7 @@
<id property="id" column="id"/>
<!-- 单号 -->
<result property="orderNo" column="order_no"/>
<result property="billNoCk" column="bill_no_ck"/>
<!-- 基础字段 -->
<result property="xmMs" column="xm_ms"/>
<result property="xmNo" column="xm_no"/>
@@ -228,10 +228,11 @@
resultType="com.delivery.project.document.domain.vo.DeliveryOrderGroupVO">
SELECT
dor.order_no AS orderNo,
MAX(dor.bill_no_ck) AS billNoCk,
MIN(dor.delivery_date) AS deliveryDate,
MAX(dor.origin_name) AS originName,
MAX(dor.dest_name) AS destName,
MAX(dor.plate_no) AS plateNo,
MAX(dor.plate_no) AS plateNo,
MAX(dor.shipper_name) AS shipperName,
MAX(dor.receiver_name) AS receiverName,
COUNT(1) AS itemCount,
@@ -240,9 +241,21 @@
FROM delivery_order dor
<where>
(dor.is_delete = '0' OR dor.is_delete = 0 OR dor.is_delete IS NULL)
<if test="orderStatus != null and orderStatus != ''">
<!-- 优先使用多状态查询 -->
<if test="orderStatusList != null and orderStatusList.size > 0">
AND dor.order_status IN
<foreach collection="orderStatusList" item="st" open="(" separator="," close=")">
#{st}
</foreach>
</if>
<!-- 没有多选时,再走单个状态查询,兼容原有 App 逻辑 -->
<if test="(orderStatusList == null or orderStatusList.size == 0)
and orderStatus != null and orderStatus != ''">
AND dor.order_status = #{orderStatus}
</if>
<if test="plateNo != null and plateNo != ''">
AND dor.plate_no = #{plateNo}
</if>
@@ -263,13 +276,14 @@
</select>
<!-- 单条查询:按单号 -->
<select id="selectDeliveryOrderByOrderNo" parameterType="string"
resultType="com.delivery.project.document.domain.DeliveryOrder">
<select id="selectDeliveryOrderByOrderNo"
parameterType="string"
resultMap="DeliveryOrderResult">
SELECT *
FROM delivery_order
WHERE order_no = #{orderNo,jdbcType=VARCHAR}
AND (is_delete = '0' OR is_delete = 0 OR is_delete IS NULL)
LIMIT 1
ORDER BY id ASC
</select>
<!-- ======================== 插入 ======================== -->
@@ -374,7 +388,8 @@
<!-- 批量插入 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO delivery_order
(order_no, xm_ms, xm_no, wl_no, wl_ms, real_qty, dw, sap_no, gys_mc, remark,
(order_no, bill_no_ck,
xm_ms, xm_no, wl_no, wl_ms, real_qty, dw, sap_no, gys_mc, remark,
origin_name, origin_lng, origin_lat,
dest_name, dest_lng, dest_lat,
delivery_date, plate_no,
@@ -386,20 +401,30 @@
create_by, create_time, update_by, update_time, is_delete)
VALUES
<foreach collection="list" item="it" separator=",">
(#{it.orderNo,jdbcType=VARCHAR}, #{it.xmMs}, #{it.xmNo}, #{it.wlNo}, #{it.wlMs}, #{it.realQty}, #{it.dw},
(
#{it.orderNo},
#{it.billNoCk},
#{it.xmMs}, #{it.xmNo}, #{it.wlNo}, #{it.wlMs}, #{it.realQty}, #{it.dw},
#{it.sapNo}, #{it.gysMc}, #{it.remark},
#{it.originName}, #{it.originLng}, #{it.originLat},
#{it.destName}, #{it.destLng}, #{it.destLat},
#{it.deliveryDate}, #{it.plateNo},
#{it.driverName}, #{it.driverPhone},
#{it.shipperName}, #{it.shipperPhone}, #{it.receiverName}, #{it.receiverPhone}, #{it.receiverOrgName},
#{it.deliveryTon}, #{it.goodsSize}, #{it.orderStatus},
#{it.vehicleTypeId}, #{it.vehicleTypeName},
#{it.suggestFee}, #{it.actualFee}, #{it.tollFee}, #{it.totalKm},
#{it.createBy}, #{it.createTime}, #{it.updateBy}, #{it.updateTime}, #{it.isDelete})
#{it.createBy}, #{it.createTime}, #{it.updateBy}, #{it.updateTime}, #{it.isDelete}
)
</foreach>
</insert>
<!-- ======================== 更新 ======================== -->
<update id="updateDeliveryOrder" parameterType="com.delivery.project.document.domain.DeliveryOrder">
UPDATE delivery_order

View File

@@ -454,6 +454,13 @@
where id = #{id}
</update>
<update id="updateDeliveryStatus">
UPDATE rk_info
SET is_delivery = #{isDelivery}
WHERE bill_no_ck = #{billNoCk}
AND is_delete = '0'
</update>
<delete id="deleteRkInfoById" parameterType="Long">
delete from rk_info where id = #{id}
</delete>