This commit is contained in:
2025-11-21 10:53:04 +08:00
parent e24d6ef0b4
commit 24ca9148dd
61 changed files with 4918 additions and 582 deletions

View File

@@ -0,0 +1,15 @@
package com.delivery.framework.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/** 配送定位上报规则配置 */
@Data
@Component("locationReportProperties")
@ConfigurationProperties(prefix = "delivery.location")
public class LocationReportProperties {
private long minPersistIntervalMs;
private long stateTtlHours;
private long lockSeconds;
}

View File

@@ -32,6 +32,10 @@ public class ResourcesConfig implements WebMvcConfigurer
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + DeliveryConfig.getProfile() + "/");
/** D:\delivery 的静态映射 */
registry.addResourceHandler("/delivery/**")
.addResourceLocations("file:D:/delivery/");
/** swagger配置 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")

View File

@@ -114,7 +114,14 @@ public class SecurityConfig
requests.antMatchers(
"/login",
"/register",
"/app/**",
"/delivery/**",
"/document/vehicle/**",
"/document/type/**",
"/document/location/**",
"/document/mtd/**",
"/document/info/**",
"/delivery/location/**",
"/document/attachment/**",
"/document/order/**",
// "/document/info/bill/groups",

View File

@@ -173,4 +173,28 @@ public class SysLoginService
{
userService.updateLoginInfo(userId, IpUtils.getIpAddr(), DateUtils.getNowDate());
}
public LoginUser loginWithoutCaptcha(String username, String password) {
loginPreCheck(username, password);
Authentication authentication;
try {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(token);
authentication = authenticationManager.authenticate(token);
}catch (Exception e){
throw new ServiceException("登录失败");
}finally {
AuthenticationContextHolder.clearContext();
}
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
return loginUser;
}
}

View File

@@ -1,15 +1,15 @@
package com.delivery.project.document.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.MinioUtil;
import com.delivery.common.utils.uuid.IdUtils;
import com.delivery.project.document.domain.dto.DeliveryAttachUploadDTO;
import com.delivery.project.document.domain.dto.DeliveryExecuteBindDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@@ -32,6 +32,7 @@ import org.springframework.web.multipart.MultipartFile;
* @date 2025-10-15
*/
@RestController
@Slf4j
@RequestMapping("/document/attachment")
public class DeliveryAttachmentController extends BaseController
{
@@ -45,6 +46,7 @@ public class DeliveryAttachmentController extends BaseController
@Value("${minio.bucketName}")
private String bucketName;
/**
* 查询配送附件列表
*/
@@ -118,8 +120,8 @@ public class DeliveryAttachmentController extends BaseController
*/
// @PreAuthorize("@ss.hasPermi('document:attachment:add')")
// @Log(title = "配送附件-上传(仅MinIO)", businessType = BusinessType.OTHER)
@PostMapping(value = "/upload", consumes = {"multipart/form-data"})
public AjaxResult upload(@RequestPart("files") MultipartFile[] files,
@PostMapping(value = "/uploads", consumes = {"multipart/form-data"})
public AjaxResult uploads(@RequestPart("files") MultipartFile[] files,
@Validated @ModelAttribute DeliveryAttachUploadDTO dto) {
try {
// 用 scene + bizType 自动当作子目录(可空)
@@ -133,7 +135,7 @@ public class DeliveryAttachmentController extends BaseController
List<String> urls = minioUtil.uploadBatch(
files,
bucketName,
minioUtil.buildDateFolder("delivery", sub) // delivery/yyyy-MM-dd[/scene/bizType]
minioUtil.buildDateFolder("delivery", sub)
);
return AjaxResult.success("urls", urls);
} catch (ServiceException se) {
@@ -142,4 +144,36 @@ public class DeliveryAttachmentController extends BaseController
return AjaxResult.error("上传失败:" + e.getMessage());
}
}
/**
* 开始配送
* @param dto
* @return
*/
// @PreAuthorize("@ss.hasPermi('document:attachment:add')")
// @Log(title = "配送附件-执行绑定", businessType = BusinessType.INSERT)
@PostMapping("/executeBind")
public AjaxResult executeBind(@Validated @RequestBody DeliveryExecuteBindDTO dto) {
int saved = deliveryAttachmentService.executeBind(dto);
return AjaxResult.success()
.put("orderNo", dto.getOrderNo())
.put("scene", dto.getScene());
}
@Log(title = "配送附件上传", businessType = BusinessType.OTHER)
@PostMapping(value = "/upload", consumes = "multipart/form-data")
public AjaxResult upload(@RequestPart("files") MultipartFile[] files,
@Validated @ModelAttribute DeliveryAttachUploadDTO dto,
HttpServletRequest request) {
try {
List<String> urls = deliveryAttachmentService.upload(files, dto, request);
return AjaxResult.success("上传成功", urls);
} catch (Exception e) {
log.error("【附件上传失败】{}", e.getMessage(), e);
return AjaxResult.error("上传失败:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,118 @@
package com.delivery.project.document.controller;
import com.delivery.common.utils.poi.ExcelUtil;
import com.delivery.framework.aspectj.lang.annotation.Log;
import com.delivery.framework.aspectj.lang.enums.BusinessType;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.framework.web.page.TableDataInfo;
import com.delivery.project.document.domain.DeliveryLocationRecord;
import com.delivery.project.document.domain.dto.DeliverySimpleLocationDTO;
import com.delivery.project.document.domain.dto.LocationReportDTO;
import com.delivery.project.document.service.ILocationReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 配送定位上报 Controller仅打印经纬度
*
* @author delivery
* @date 2025-10-20
*/
@Slf4j
@RestController
@RequestMapping("/delivery/location")
public class DeliveryLocationController extends BaseController {
@Autowired
private ILocationReportService deliveryLocationRecordService;
@PostMapping("/report")
public AjaxResult report(@Validated @RequestBody LocationReportDTO dto) {
String username = getUsername();
return AjaxResult.success(deliveryLocationRecordService.report(dto, username));
}
/**
* 查询配送定位记录(车牌+单号维度)列表
*/
@PreAuthorize("@ss.hasPermi('document:record:list')")
@GetMapping("/list")
public TableDataInfo list(DeliveryLocationRecord deliveryLocationRecord)
{
startPage();
List<DeliveryLocationRecord> list = deliveryLocationRecordService.selectDeliveryLocationRecordList(deliveryLocationRecord);
return getDataTable(list);
}
/**
* 导出配送定位记录(车牌+单号维度)列表
*/
@PreAuthorize("@ss.hasPermi('document:record:export')")
@Log(title = "配送定位记录(车牌+单号维度)", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DeliveryLocationRecord deliveryLocationRecord)
{
List<DeliveryLocationRecord> list = deliveryLocationRecordService.selectDeliveryLocationRecordList(deliveryLocationRecord);
ExcelUtil<DeliveryLocationRecord> util = new ExcelUtil<DeliveryLocationRecord>(DeliveryLocationRecord.class);
util.exportExcel(response, list, "配送定位记录(车牌+单号维度)数据");
}
/**
* 获取配送定位记录(车牌+单号维度)详细信息
*/
@PreAuthorize("@ss.hasPermi('document:record:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(deliveryLocationRecordService.selectDeliveryLocationRecordById(id));
}
/**
* 新增配送定位记录(车牌+单号维度)
*/
@PreAuthorize("@ss.hasPermi('document:record:add')")
@Log(title = "配送定位记录(车牌+单号维度)", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeliveryLocationRecord deliveryLocationRecord)
{
return toAjax(deliveryLocationRecordService.insertDeliveryLocationRecord(deliveryLocationRecord));
}
/**
* 修改配送定位记录(车牌+单号维度)
*/
@PreAuthorize("@ss.hasPermi('document:record:edit')")
@Log(title = "配送定位记录(车牌+单号维度)", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeliveryLocationRecord deliveryLocationRecord)
{
return toAjax(deliveryLocationRecordService.updateDeliveryLocationRecord(deliveryLocationRecord));
}
/**
* 删除配送定位记录(车牌+单号维度)
*/
@PreAuthorize("@ss.hasPermi('document:record:remove')")
@Log(title = "配送定位记录(车牌+单号维度)", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(deliveryLocationRecordService.deleteDeliveryLocationRecordByIds(ids));
}
// @PreAuthorize("@ss.hasPermi('document:record:track')")
@GetMapping("/track")
public AjaxResult track(@RequestParam("orderNo") String orderNo,
@RequestParam("plateNo") String plateNo) {
List<DeliverySimpleLocationDTO> points =
deliveryLocationRecordService.selectTrackPoints(orderNo, plateNo);
return AjaxResult.success(points);
}
}

View File

@@ -3,7 +3,10 @@ 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.DeliveryOrderGroupVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -88,8 +91,7 @@ public class DeliveryOrderController extends BaseController
@PreAuthorize("@ss.hasPermi('document:order:edit')")
@Log(title = "配送单据主", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeliveryOrder deliveryOrder)
{
public AjaxResult edit(@RequestBody DeliveryOrder deliveryOrder) {
return toAjax(deliveryOrderService.updateDeliveryOrder(deliveryOrder));
}
@@ -119,4 +121,41 @@ public class DeliveryOrderController extends BaseController
return toAjax(rows);
}
/** 新增配送单据:同一单号多行写入 */
// @PreAuthorize("@ss.hasPermi('document:order:add')")
// @Log(title = "配送单据", businessType = BusinessType.INSERT)
@PostMapping("/batch")
public AjaxResult createBatch(@RequestBody DeliveryOrderCreateDTO dto) {
String plateNo = deliveryOrderService.createOrder(dto);
return success("创建成功,单号:" + plateNo);
}
/** 列表:按单号分组(分页) */
// @PreAuthorize("@ss.hasPermi('document:order:list')")
@GetMapping("/group")
public TableDataInfo listGroup(DeliveryOrder query) {
startPage();
List<DeliveryOrderGroupVO> list = deliveryOrderService.listGroup(query);
return getDataTable(list);
}
/** 详情:按单号查询所有行 */
// @PreAuthorize("@ss.hasPermi('document:order:query')")
@GetMapping("/detail/{orderNo}")
public AjaxResult detail(@PathVariable String orderNo) {
return success(deliveryOrderService.listByOrderNo(orderNo));
}
/**
* 从智慧实物系统拉取待配送出库单据列表
*/
@GetMapping("/wisdom/rk/list")
public AjaxResult listRkFromWisdom() {
List<RkInfo> list = deliveryOrderService.listWisdomRkForDelivery();
return AjaxResult.success(list);
}
}

View File

@@ -0,0 +1,29 @@
package com.delivery.project.document.controller;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.project.document.domain.dto.LocationReportDTO;
import com.delivery.project.document.service.ILocationReportService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
///** 配送定位上报 Controller车牌+单号维度) */
//@RestController
//@RequestMapping("/document/location")
//public class LocationController extends BaseController {
//
// @Resource
// private ILocationReportService locationReportService;
//
// /** APP 上报定位(车牌号 + 配送单号 + 经纬度) */
//// @PreAuthorize("@ss.hasPermi('document:location:report')")
// @PostMapping("/report")
// public AjaxResult report(@Validated @RequestBody LocationReportDTO dto) {
//// String username = getUsername();
// System.out.println("1`1111111111111111111111111111");
// String username = "大爷的!!!";
// return AjaxResult.success(locationReportService.report(dto, username));
// }
//}

View File

@@ -0,0 +1,128 @@
package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.delivery.project.document.domain.dto.CalcTotalWvDTO;
import com.delivery.project.document.domain.vo.TotalWvVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.delivery.framework.aspectj.lang.annotation.Log;
import com.delivery.framework.aspectj.lang.enums.BusinessType;
import com.delivery.project.document.domain.Mtd;
import com.delivery.project.document.service.IMtdService;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.common.utils.poi.ExcelUtil;
import com.delivery.framework.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 物料字典Controller
*
* @author delivery
* @date 2025-10-23
*/
@RestController
@RequestMapping("/document/mtd")
public class MtdController extends BaseController
{
@Autowired
private IMtdService mtdService;
/**
* 查询物料字典列表
*/
@PreAuthorize("@ss.hasPermi('document:mtd:list')")
@GetMapping("/list")
public TableDataInfo list(Mtd mtd)
{
startPage();
List<Mtd> list = mtdService.selectMtdList(mtd);
return getDataTable(list);
}
/**
* 导出物料字典列表
*/
@PreAuthorize("@ss.hasPermi('document:mtd:export')")
@Log(title = "物料字典", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, Mtd mtd)
{
List<Mtd> list = mtdService.selectMtdList(mtd);
ExcelUtil<Mtd> util = new ExcelUtil<Mtd>(Mtd.class);
util.exportExcel(response, list, "物料字典数据");
}
/**
* Excel 导入物料字典(同 wlNo 则更新,不存在则新增)
*/
@PreAuthorize("@ss.hasPermi('document:mtd:import')")
@Log(title = "物料字典", businessType = BusinessType.IMPORT)
@PostMapping("/importData")
public AjaxResult importData(@RequestParam("file") MultipartFile file) throws Exception
{
if (file == null || file.isEmpty()) {
return AjaxResult.error("导入文件不能为空");
}
ExcelUtil<Mtd> util = new ExcelUtil<>(Mtd.class);
List<Mtd> list = util.importExcel(file.getInputStream());
int handled = mtdService.importMtd(list, getUsername());
return success("导入成功,共处理 " + handled + "");
}
/**
* 获取物料字典详细信息
*/
@PreAuthorize("@ss.hasPermi('document:mtd:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(mtdService.selectMtdById(id));
}
/**
* 新增物料字典
*/
@PreAuthorize("@ss.hasPermi('document:mtd:add')")
@Log(title = "物料字典", businessType = BusinessType.INSERT)
@PostMapping()
public AjaxResult add(@RequestBody Mtd mtd)
{
return toAjax(mtdService.insertMtd(mtd));
}
/**
* 修改物料字典
*/
@PreAuthorize("@ss.hasPermi('document:mtd:edit')")
@Log(title = "物料字典", businessType = BusinessType.UPDATE)
@PutMapping()
public AjaxResult edit(@RequestBody Mtd mtd)
{
return toAjax(mtdService.updateMtd(mtd));
}
/**
* 删除物料字典
*/
@PreAuthorize("@ss.hasPermi('document:mtd:remove')")
@Log(title = "物料字典", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(mtdService.deleteMtdByIds(ids));
}
/**
* 计算货物的总体积和重量
*/
// @PreAuthorize("@ss.hasPermi('document:mtd:calc')")
@PostMapping("/calcTotalWv")
public AjaxResult calcTotalWv(@RequestBody CalcTotalWvDTO dto) {
TotalWvVO vo = mtdService.calcTotalWv(dto);
return AjaxResult.success(vo);
}
}

View File

@@ -3,9 +3,7 @@ package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.delivery.project.document.domain.dto.RkInfoQueryDTO;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.ApiOperation;
import com.delivery.project.document.service.IVehicleTypeService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -42,9 +40,13 @@ public class RkInfoController extends BaseController
* 查询库存单据明细列表
*/
@GetMapping("/list")
public TableDataInfo list(RkInfo rkInfo) {
public TableDataInfo list(RkInfo rkInfo)
{
List<RkInfo> list = rkInfoService.selectRkInfoList(rkInfo);
// 封装分页返回
return getDataTable(list);
}
/**
* 导出库存单据明细列表
@@ -62,7 +64,7 @@ public class RkInfoController extends BaseController
/**
* 获取库存单据明细详细信息
*/
@PreAuthorize("@ss.hasPermi('document:info:query')")
// @PreAuthorize("@ss.hasPermi('document:info:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
@@ -114,4 +116,15 @@ public class RkInfoController extends BaseController
return getDataTable(rows);
}
@GetMapping("/page")
public TableDataInfo page(RkInfo rkInfo)
{
// 开启分页
startPage();
List<RkInfo> list = rkInfoService.selectRkInfoList(rkInfo);
// 封装分页返回
return getDataTable(list);
}
}

View File

@@ -0,0 +1,104 @@
package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.delivery.framework.aspectj.lang.annotation.Log;
import com.delivery.framework.aspectj.lang.enums.BusinessType;
import com.delivery.project.document.domain.Vehicle;
import com.delivery.project.document.service.IVehicleService;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.common.utils.poi.ExcelUtil;
import com.delivery.framework.web.page.TableDataInfo;
/**
* 车辆档案Controller
*
* @author delivery
* @date 2025-10-23
*/
@RestController
@RequestMapping("/document/vehicle")
public class VehicleController extends BaseController
{
@Autowired
private IVehicleService vehicleService;
/**
* 查询车辆档案列表
*/
// @PreAuthorize("@ss.hasPermi('document:vehicle:list')")
@GetMapping("/list")
public TableDataInfo list(Vehicle vehicle)
{
startPage();
List<Vehicle> list = vehicleService.selectVehicleList(vehicle);
return getDataTable(list);
}
/**
* 导出车辆档案列表
*/
@PreAuthorize("@ss.hasPermi('document:vehicle:export')")
@Log(title = "车辆档案", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, Vehicle vehicle)
{
List<Vehicle> list = vehicleService.selectVehicleList(vehicle);
ExcelUtil<Vehicle> util = new ExcelUtil<Vehicle>(Vehicle.class);
util.exportExcel(response, list, "车辆档案数据");
}
/**
* 获取车辆档案详细信息
*/
@PreAuthorize("@ss.hasPermi('document:vehicle:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(vehicleService.selectVehicleById(id));
}
/**
* 新增车辆档案
*/
@PreAuthorize("@ss.hasPermi('document:vehicle:add')")
@Log(title = "车辆档案", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody Vehicle vehicle)
{
return toAjax(vehicleService.insertVehicle(vehicle));
}
/**
* 修改车辆档案
*/
@PreAuthorize("@ss.hasPermi('document:vehicle:edit')")
@Log(title = "车辆档案", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody Vehicle vehicle)
{
return toAjax(vehicleService.updateVehicle(vehicle));
}
/**
* 删除车辆档案
*/
@PreAuthorize("@ss.hasPermi('document:vehicle:remove')")
@Log(title = "车辆档案", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(vehicleService.deleteVehicleByIds(ids));
}
}

View File

@@ -0,0 +1,127 @@
package com.delivery.project.document.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.delivery.project.document.domain.dto.CalcSuggestFeeDTO;
import com.delivery.project.document.domain.vo.CalcSuggestFeeVO;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.delivery.framework.aspectj.lang.annotation.Log;
import com.delivery.framework.aspectj.lang.enums.BusinessType;
import com.delivery.project.document.domain.VehicleType;
import com.delivery.project.document.service.IVehicleTypeService;
import com.delivery.framework.web.controller.BaseController;
import com.delivery.framework.web.domain.AjaxResult;
import com.delivery.common.utils.poi.ExcelUtil;
import com.delivery.framework.web.page.TableDataInfo;
/**
* 车型定义Controller
*
* @author delivery
* @date 2025-10-23
*/
@RestController
@RequestMapping("/document/type")
public class VehicleTypeController extends BaseController
{
@Autowired
private IVehicleTypeService vehicleTypeService;
/**
* 查询车型定义列表
*/
// @PreAuthorize("@ss.hasPermi('document:type:list')")
@GetMapping("/list")
public TableDataInfo list(VehicleType vehicleType)
{
startPage();
List<VehicleType> list = vehicleTypeService.selectVehicleTypeList(vehicleType);
return getDataTable(list);
}
/**
* 导出车型定义列表
*/
@PreAuthorize("@ss.hasPermi('document:type:export')")
@Log(title = "车型定义", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, VehicleType vehicleType)
{
List<VehicleType> list = vehicleTypeService.selectVehicleTypeList(vehicleType);
ExcelUtil<VehicleType> util = new ExcelUtil<VehicleType>(VehicleType.class);
util.exportExcel(response, list, "车型定义数据");
}
/**
* 获取车型定义详细信息
*/
@PreAuthorize("@ss.hasPermi('document:type:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(vehicleTypeService.selectVehicleTypeById(id));
}
/**
* 新增车型定义
*/
@PreAuthorize("@ss.hasPermi('document:type:add')")
@Log(title = "车型定义", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody VehicleType vehicleType)
{
return toAjax(vehicleTypeService.insertVehicleType(vehicleType));
}
/**
* 修改车型定义
*/
@PreAuthorize("@ss.hasPermi('document:type:edit')")
@Log(title = "车型定义", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody VehicleType vehicleType)
{
return toAjax(vehicleTypeService.updateVehicleType(vehicleType));
}
/**
* 删除车型定义
*/
@PreAuthorize("@ss.hasPermi('document:type:remove')")
@Log(title = "车型定义", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(vehicleTypeService.deleteVehicleTypeByIds(ids));
}
/** 计算建议费用(支持前端指定车型重算) */
@PostMapping("/fee")
public AjaxResult calcSuggestFee(@RequestBody CalcSuggestFeeDTO dto) {
CalcSuggestFeeVO vo = vehicleTypeService.calcSuggestFee(dto);
return success(vo);
}
/**
* 查看全部车型
* @param vehicleType
* @return
*/
@GetMapping("/page")
public TableDataInfo page(VehicleType vehicleType)
{
List<VehicleType> list = vehicleTypeService.selectVehicleTypeList(vehicleType);
return getDataTable(list);
}
}

View File

@@ -0,0 +1,49 @@
package com.delivery.project.document.controller.app;
import com.delivery.framework.security.LoginBody;
import com.delivery.framework.security.LoginUser;
import com.delivery.framework.security.service.SysLoginService;
import com.delivery.framework.security.service.TokenService;
import com.delivery.framework.web.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/app")
public class LoginController {
@Autowired
private SysLoginService loginService;
@Autowired
private TokenService tokenService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody) {
String username = loginBody.getUsername();
String password = loginBody.getPassword();
LoginUser loginUser = loginService.loginWithoutCaptcha(username, password);
String token = tokenService.createToken(loginUser);
Map<String, Object> data = new HashMap<>();
data.put("token", token);
data.put("user", loginUser.getUser());
return AjaxResult.success(data);
}
}

View File

@@ -20,7 +20,7 @@ public class DeliveryAttachment extends BaseEntity
/** 关联的配送单ID */
@Excel(name = "关联的配送单ID")
private Long orderId;
private String orderNo;
/** 场景ORIGIN起点、DEST终点 */
@@ -57,14 +57,14 @@ public class DeliveryAttachment extends BaseEntity
return id;
}
public void setOrderId(Long orderId)
public void setOrderNo(String orderNo)
{
this.orderId = orderId;
this.orderNo = orderNo;
}
public Long getOrderId()
public String getOrderNo()
{
return orderId;
return orderNo;
}
public void setScene(String scene)
@@ -131,7 +131,7 @@ public class DeliveryAttachment extends BaseEntity
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("orderId", getOrderId())
.append("orderNo", getOrderNo())
.append("scene", getScene())
.append("bizType", getBizType())
.append("url", getUrl())

View File

@@ -0,0 +1,39 @@
package com.delivery.project.document.domain;
import com.delivery.framework.web.domain.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/** 配送定位落库记录实体(车牌+单号维度) */
@Data
public class DeliveryLocationRecord extends BaseEntity {
/** 主键ID */
private Long id;
/** 车牌号(上报维度之一) */
private String plateNo;
/** 配送单号(上报维度之一,必填) */
private String orderNo;
/** 经度保留6位小数 */
private BigDecimal lng;
/** 纬度保留6位小数 */
private BigDecimal lat;
/** 服务端接收并确认落库时间 */
private Date reportedAt;
/** 来源app等 */
private String source;
/** 触发原因3_same/15s_tick等 */
private String remark;
/** 是否删除0正常1删除 */
private String isDelete;
}

View File

@@ -12,17 +12,19 @@ import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 配送单据主对象 delivery_order
*
* @author delivery
* @date 2025-10-15
*/
public class DeliveryOrder extends BaseEntity
{
public class DeliveryOrder extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 配送单据号 */
@Excel(name = "配送单据号")
private String orderNo;
/** 项目描述 */
@Excel(name = "项目描述")
private String xmMs;
@@ -86,7 +88,15 @@ public class DeliveryOrder extends BaseEntity
/** 配送车牌 */
@Excel(name = "配送车牌")
private String vehiclePlate;
private String plateNo;
/** 司机姓名 */
@Excel(name = "司机姓名")
private String driverName;
/** 司机联系方式 */
@Excel(name = "司机联系方式")
private String driverPhone;
/** 发货人姓名 */
@Excel(name = "发货人姓名")
@@ -112,6 +122,21 @@ public class DeliveryOrder extends BaseEntity
@Excel(name = "配送吨位")
private BigDecimal deliveryTon;
/** 货物尺寸(㎡),占地面积 */
@Excel(name = "货物尺寸(㎡)")
private BigDecimal goodsSize;
/** 配送状态0待接单1已接单2配送中3已签收 */
@Excel(name = "配送状态", readConverterExp = "0=待接单,1=已接单,2=配送中,3=已签收")
private String orderStatus;
/** 车辆类型ID */
private Long vehicleTypeId;
/** 车辆类型名称 */
@Excel(name = "车辆类型名称")
private String vehicleTypeName;
/** 是否删除0正常 1已删除 */
@Excel(name = "是否删除", readConverterExp = "0=正常,1=已删除")
private String isDelete;
@@ -119,253 +144,138 @@ public class DeliveryOrder extends BaseEntity
/** 连表查询用:附件列表 */
private List<DeliveryAttachment> attachments;
// ===================== 费用与里程 =====================
/** 建议费用(按车型单价*里程的推荐值) */
@Excel(name = "建议费用")
private BigDecimal suggestFee;
/** 实际费用(最终确认费用) */
@Excel(name = "实际费用")
private BigDecimal actualFee;
/** 高速费用 */
@Excel(name = "高速费用")
private BigDecimal tollFee;
/** 总公里数(行驶里程) */
@Excel(name = "总公里数")
private BigDecimal totalKm;
// ===================== Getter & Setter =====================
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getOrderNo() { return orderNo; }
public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
public String getXmMs() { return xmMs; }
public void setXmMs(String xmMs) { this.xmMs = xmMs; }
public String getXmNo() { return xmNo; }
public void setXmNo(String xmNo) { this.xmNo = xmNo; }
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 BigDecimal getRealQty() { return realQty; }
public void setRealQty(BigDecimal realQty) { this.realQty = realQty; }
public String getDw() { return dw; }
public void setDw(String dw) { this.dw = dw; }
public String getSapNo() { return sapNo; }
public void setSapNo(String sapNo) { this.sapNo = sapNo; }
public String getGysMc() { return gysMc; }
public void setGysMc(String gysMc) { this.gysMc = gysMc; }
public String getOriginName() { return originName; }
public void setOriginName(String originName) { this.originName = originName; }
public BigDecimal getOriginLng() { return originLng; }
public void setOriginLng(BigDecimal originLng) { this.originLng = originLng; }
public BigDecimal getOriginLat() { return originLat; }
public void setOriginLat(BigDecimal originLat) { this.originLat = originLat; }
public String getDestName() { return destName; }
public void setDestName(String destName) { this.destName = destName; }
public BigDecimal getDestLng() { return destLng; }
public void setDestLng(BigDecimal destLng) { this.destLng = destLng; }
public BigDecimal getDestLat() { return destLat; }
public void setDestLat(BigDecimal destLat) { this.destLat = destLat; }
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 getDriverName() { return driverName; }
public void setDriverName(String driverName) { this.driverName = driverName; }
public String getDriverPhone() { return driverPhone; }
public void setDriverPhone(String driverPhone) { this.driverPhone = driverPhone; }
public String getShipperName() { return shipperName; }
public void setShipperName(String shipperName) { this.shipperName = shipperName; }
public String getShipperPhone() { return shipperPhone; }
public void setShipperPhone(String shipperPhone) { this.shipperPhone = shipperPhone; }
public String getReceiverName() { return receiverName; }
public void setReceiverName(String receiverName) { this.receiverName = receiverName; }
public String getReceiverPhone() { return receiverPhone; }
public void setReceiverPhone(String receiverPhone) { this.receiverPhone = receiverPhone; }
public String getReceiverOrgName() { return receiverOrgName; }
public void setReceiverOrgName(String receiverOrgName) { this.receiverOrgName = receiverOrgName; }
public BigDecimal getDeliveryTon() { return deliveryTon; }
public void setDeliveryTon(BigDecimal deliveryTon) { this.deliveryTon = deliveryTon; }
public BigDecimal getGoodsSize() { return goodsSize; }
public void setGoodsSize(BigDecimal goodsSize) { this.goodsSize = goodsSize; }
public String getOrderStatus() { return orderStatus; }
public void setOrderStatus(String orderStatus) { this.orderStatus = orderStatus; }
public Long getVehicleTypeId() { return vehicleTypeId; }
public void setVehicleTypeId(Long vehicleTypeId) { this.vehicleTypeId = vehicleTypeId; }
public String getVehicleTypeName() { return vehicleTypeName; }
public void setVehicleTypeName(String vehicleTypeName) { this.vehicleTypeName = vehicleTypeName; }
public String getIsDelete() { return isDelete; }
public void setIsDelete(String isDelete) { this.isDelete = isDelete; }
public List<DeliveryAttachment> getAttachments() { return attachments; }
public void setAttachments(List<DeliveryAttachment> attachments) { this.attachments = attachments; }
public void setId(Long id)
{
this.id = id;
}
public BigDecimal getSuggestFee() { return suggestFee; }
public void setSuggestFee(BigDecimal suggestFee) { this.suggestFee = suggestFee; }
public Long getId()
{
return id;
}
public BigDecimal getActualFee() { return actualFee; }
public void setActualFee(BigDecimal actualFee) { this.actualFee = actualFee; }
public void setXmMs(String xmMs)
{
this.xmMs = xmMs;
}
public BigDecimal getTollFee() { return tollFee; }
public void setTollFee(BigDecimal tollFee) { this.tollFee = tollFee; }
public String getXmMs()
{
return xmMs;
}
public void setXmNo(String xmNo)
{
this.xmNo = xmNo;
}
public String getXmNo()
{
return xmNo;
}
public void setWlNo(String wlNo)
{
this.wlNo = wlNo;
}
public String getWlNo()
{
return wlNo;
}
public void setWlMs(String wlMs)
{
this.wlMs = wlMs;
}
public String getWlMs()
{
return wlMs;
}
public void setRealQty(BigDecimal realQty)
{
this.realQty = realQty;
}
public BigDecimal getRealQty()
{
return realQty;
}
public void setDw(String dw)
{
this.dw = dw;
}
public String getDw()
{
return dw;
}
public void setSapNo(String sapNo)
{
this.sapNo = sapNo;
}
public String getSapNo()
{
return sapNo;
}
public void setGysMc(String gysMc)
{
this.gysMc = gysMc;
}
public String getGysMc()
{
return gysMc;
}
public void setOriginName(String originName)
{
this.originName = originName;
}
public String getOriginName()
{
return originName;
}
public void setOriginLng(BigDecimal originLng)
{
this.originLng = originLng;
}
public BigDecimal getOriginLng()
{
return originLng;
}
public void setOriginLat(BigDecimal originLat)
{
this.originLat = originLat;
}
public BigDecimal getOriginLat()
{
return originLat;
}
public void setDestName(String destName)
{
this.destName = destName;
}
public String getDestName()
{
return destName;
}
public void setDestLng(BigDecimal destLng)
{
this.destLng = destLng;
}
public BigDecimal getDestLng()
{
return destLng;
}
public void setDestLat(BigDecimal destLat)
{
this.destLat = destLat;
}
public BigDecimal getDestLat()
{
return destLat;
}
public void setDeliveryDate(Date deliveryDate)
{
this.deliveryDate = deliveryDate;
}
public Date getDeliveryDate()
{
return deliveryDate;
}
public void setVehiclePlate(String vehiclePlate)
{
this.vehiclePlate = vehiclePlate;
}
public String getVehiclePlate()
{
return vehiclePlate;
}
public void setShipperName(String shipperName)
{
this.shipperName = shipperName;
}
public String getShipperName()
{
return shipperName;
}
public void setShipperPhone(String shipperPhone)
{
this.shipperPhone = shipperPhone;
}
public String getShipperPhone()
{
return shipperPhone;
}
public void setReceiverName(String receiverName)
{
this.receiverName = receiverName;
}
public String getReceiverName()
{
return receiverName;
}
public void setReceiverPhone(String receiverPhone)
{
this.receiverPhone = receiverPhone;
}
public String getReceiverPhone()
{
return receiverPhone;
}
public void setReceiverOrgName(String receiverOrgName)
{
this.receiverOrgName = receiverOrgName;
}
public String getReceiverOrgName()
{
return receiverOrgName;
}
public void setDeliveryTon(BigDecimal deliveryTon)
{
this.deliveryTon = deliveryTon;
}
public BigDecimal getDeliveryTon()
{
return deliveryTon;
}
public void setIsDelete(String isDelete)
{
this.isDelete = isDelete;
}
public String getIsDelete()
{
return isDelete;
}
public BigDecimal getTotalKm() { return totalKm; }
public void setTotalKm(BigDecimal totalKm) { this.totalKm = totalKm; }
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("orderNo", getOrderNo())
.append("xmMs", getXmMs())
.append("xmNo", getXmNo())
.append("wlNo", getWlNo())
@@ -374,7 +284,6 @@ public class DeliveryOrder extends BaseEntity
.append("dw", getDw())
.append("sapNo", getSapNo())
.append("gysMc", getGysMc())
.append("remark", getRemark())
.append("originName", getOriginName())
.append("originLng", getOriginLng())
.append("originLat", getOriginLat())
@@ -382,13 +291,23 @@ public class DeliveryOrder extends BaseEntity
.append("destLng", getDestLng())
.append("destLat", getDestLat())
.append("deliveryDate", getDeliveryDate())
.append("vehiclePlate", getVehiclePlate())
.append("plateNo", getplateNo())
.append("driverName", getDriverName())
.append("driverPhone", getDriverPhone())
.append("shipperName", getShipperName())
.append("shipperPhone", getShipperPhone())
.append("receiverName", getReceiverName())
.append("receiverPhone", getReceiverPhone())
.append("receiverOrgName", getReceiverOrgName())
.append("deliveryTon", getDeliveryTon())
.append("goodsSize", getGoodsSize())
.append("orderStatus", getOrderStatus())
.append("suggestFee", getSuggestFee())
.append("actualFee", getActualFee())
.append("tollFee", getTollFee())
.append("totalKm", getTotalKm())
.append("vehicleTypeId", getVehicleTypeId())
.append("vehicleTypeName", getVehicleTypeName())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())

View File

@@ -0,0 +1,25 @@
package com.delivery.project.document.domain;
import lombok.Data;
import java.math.BigDecimal;
/** 按单号部分字段更新动态UPDATE覆盖该单号下所有行 */
@Data
public class DeliveryOrderPatch {
private String plateNo;
// 地理位置
private BigDecimal originLng;
private BigDecimal originLat;
private BigDecimal destLng;
private BigDecimal destLat;
// 状态 & 费用
private String orderStatus; // "2" 配送中 / "3" 已签收
private BigDecimal actualFee;
private BigDecimal totalKm;
private BigDecimal tollFee;
// 元数据
private String updateBy;
}

View File

@@ -0,0 +1,132 @@
package com.delivery.project.document.domain;
import java.math.BigDecimal;
import com.delivery.framework.aspectj.lang.annotation.Excel;
import com.delivery.framework.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 物料字典对象 mtd
*
* @author delivery
* @date 2025-10-23
*/
public class Mtd extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 物料编号 */
@Excel(name = "物料编号")
private String wlNo;
/** 物料描述 */
@Excel(name = "物料描述")
private String wlMs;
/** 计量单位 */
@Excel(name = "计量单位")
private String dw;
/** 单件重量(kg) */
@Excel(name = "单件重量(kg)")
private BigDecimal weightKg;
/** 单件体积(立方米) */
@Excel(name = "单件体积(立方米)")
private BigDecimal volumeM3;
/** 是否删除(0正常 1删除) */
@Excel(name = "是否删除(0正常 1删除)")
private String isDelete;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setWlNo(String wlNo)
{
this.wlNo = wlNo;
}
public String getWlNo()
{
return wlNo;
}
public void setWlMs(String wlMs)
{
this.wlMs = wlMs;
}
public String getWlMs()
{
return wlMs;
}
public void setDw(String dw)
{
this.dw = dw;
}
public String getDw()
{
return dw;
}
public void setWeightKg(BigDecimal weightKg)
{
this.weightKg = weightKg;
}
public BigDecimal getWeightKg()
{
return weightKg;
}
public void setVolumeM3(BigDecimal volumeM3)
{
this.volumeM3 = volumeM3;
}
public BigDecimal getVolumeM3()
{
return volumeM3;
}
public void setIsDelete(String isDelete)
{
this.isDelete = isDelete;
}
public String getIsDelete()
{
return isDelete;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("wlNo", getWlNo())
.append("wlMs", getWlMs())
.append("dw", getDw())
.append("weightKg", getWeightKg())
.append("volumeM3", getVolumeM3())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("isDelete", getIsDelete())
.toString();
}
}

View File

@@ -145,6 +145,9 @@ public class RkInfo extends BaseEntity {
@Excel(name = "库位码")
private String pcode;
@Excel(name = "出库类型名称")
private String ckTypeName;
/** 库位16进制编码 */
@Excel(name = "库位16进制编码")
private String pcodeId;
@@ -204,6 +207,12 @@ public class RkInfo extends BaseEntity {
@Excel(name = "供应计划ID")
private Long gysJhId;
// ===================== MTD 侧重量/体积 =====================
/** 单件重量(kg) */
private BigDecimal weightKg;
/** 单件体积(m³) */
private BigDecimal volumeM3;
// ===================== Getter / Setter =====================
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
@@ -310,6 +319,9 @@ public class RkInfo extends BaseEntity {
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; }
@@ -334,6 +346,11 @@ public class RkInfo extends BaseEntity {
public Long getGysJhId() { return gysJhId; }
public void setGysJhId(Long gysJhId) { this.gysJhId = gysJhId; }
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)
@@ -374,6 +391,7 @@ public class RkInfo extends BaseEntity {
.append("ckLihuoY", getCkLihuoY())
.append("teamCode", getTeamCode())
.append("ckType", getCkType())
.append("ckTypeName", getCkTypeName())
.append("ckRemark", getCkRemark())
.append("rkTime", getRkTime())
.append("lyTime", getLyTime())
@@ -385,6 +403,8 @@ public class RkInfo extends BaseEntity {
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("weightKg", getWeightKg())
.append("volumeM3", getVolumeM3())
.toString();
}
}

View File

@@ -0,0 +1,258 @@
package com.delivery.project.document.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.delivery.framework.web.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.delivery.framework.aspectj.lang.annotation.Excel;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 车辆档案对象 vehicle
*
* @author delivery
* @date 2025-10-23
*/
public class Vehicle extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 车牌号(唯一) */
@Excel(name = "车牌号", readConverterExp = "唯=一")
private String plateNo;
/** VIN/车架号 */
@Excel(name = "VIN/车架号")
private String vin;
/** 车型IDvehicle_type.id */
@Excel(name = "车型ID", readConverterExp = "v=ehicle_type.id")
private Long vehicleTypeId;
/** 申报承重(吨) */
@Excel(name = "申报承重(吨)")
private BigDecimal declaredWeightTon;
/** 申报载方(立方米) */
@Excel(name = "申报载方(立方米)")
private BigDecimal declaredVolumeM3;
/** 司机姓名 */
@Excel(name = "司机姓名")
private String driverName;
/** 司机手机号 */
@Excel(name = "司机手机号")
private String driverPhone;
/** 司机身份证号(可选) */
@Excel(name = "司机身份证号(可选)")
private String driverIdNo;
/** 驾驶证号(可选) */
@Excel(name = "驾驶证号(可选)")
private String driverLicenseNo;
/** 准驾车型(可选) */
@Excel(name = "准驾车型(可选)")
private String driverLicenseLevel;
/** 年检到期日 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "年检到期日", width = 30, dateFormat = "yyyy-MM-dd")
private Date inspectionExpireDate;
/** 保险到期日 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "保险到期日", width = 30, dateFormat = "yyyy-MM-dd")
private Date insuranceExpireDate;
/** 状态(0启用 1停用 2维修) */
@Excel(name = "状态(0启用 1停用 2维修)")
private String status;
/** 是否删除(0正常 1删除) */
@Excel(name = "是否删除(0正常 1删除)")
private String isDelete;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setPlateNo(String plateNo)
{
this.plateNo = plateNo;
}
public String getPlateNo()
{
return plateNo;
}
public void setVin(String vin)
{
this.vin = vin;
}
public String getVin()
{
return vin;
}
public void setVehicleTypeId(Long vehicleTypeId)
{
this.vehicleTypeId = vehicleTypeId;
}
public Long getVehicleTypeId()
{
return vehicleTypeId;
}
public void setDeclaredWeightTon(BigDecimal declaredWeightTon)
{
this.declaredWeightTon = declaredWeightTon;
}
public BigDecimal getDeclaredWeightTon()
{
return declaredWeightTon;
}
public void setDeclaredVolumeM3(BigDecimal declaredVolumeM3)
{
this.declaredVolumeM3 = declaredVolumeM3;
}
public BigDecimal getDeclaredVolumeM3()
{
return declaredVolumeM3;
}
public void setDriverName(String driverName)
{
this.driverName = driverName;
}
public String getDriverName()
{
return driverName;
}
public void setDriverPhone(String driverPhone)
{
this.driverPhone = driverPhone;
}
public String getDriverPhone()
{
return driverPhone;
}
public void setDriverIdNo(String driverIdNo)
{
this.driverIdNo = driverIdNo;
}
public String getDriverIdNo()
{
return driverIdNo;
}
public void setDriverLicenseNo(String driverLicenseNo)
{
this.driverLicenseNo = driverLicenseNo;
}
public String getDriverLicenseNo()
{
return driverLicenseNo;
}
public void setDriverLicenseLevel(String driverLicenseLevel)
{
this.driverLicenseLevel = driverLicenseLevel;
}
public String getDriverLicenseLevel()
{
return driverLicenseLevel;
}
public void setInspectionExpireDate(Date inspectionExpireDate)
{
this.inspectionExpireDate = inspectionExpireDate;
}
public Date getInspectionExpireDate()
{
return inspectionExpireDate;
}
public void setInsuranceExpireDate(Date insuranceExpireDate)
{
this.insuranceExpireDate = insuranceExpireDate;
}
public Date getInsuranceExpireDate()
{
return insuranceExpireDate;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setIsDelete(String isDelete)
{
this.isDelete = isDelete;
}
public String getIsDelete()
{
return isDelete;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("plateNo", getPlateNo())
.append("vin", getVin())
.append("vehicleTypeId", getVehicleTypeId())
.append("declaredWeightTon", getDeclaredWeightTon())
.append("declaredVolumeM3", getDeclaredVolumeM3())
.append("driverName", getDriverName())
.append("driverPhone", getDriverPhone())
.append("driverIdNo", getDriverIdNo())
.append("driverLicenseNo", getDriverLicenseNo())
.append("driverLicenseLevel", getDriverLicenseLevel())
.append("inspectionExpireDate", getInspectionExpireDate())
.append("insuranceExpireDate", getInsuranceExpireDate())
.append("status", getStatus())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("isDelete", getIsDelete())
.toString();
}
}

View File

@@ -0,0 +1,178 @@
package com.delivery.project.document.domain;
import java.math.BigDecimal;
import com.delivery.framework.aspectj.lang.annotation.Excel;
import com.delivery.framework.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 车型定义对象 vehicle_type
*
* @author delivery
* @date 2025-10-23
*/
public class VehicleType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 车型编码(唯一) */
@Excel(name = "车型编码", readConverterExp = "唯=一")
private String typeCode;
/** 车型名称(如:微面/小面/3米8/5米2/6米8/7米6/9米6/13米/17米5 */
@Excel(name = "车型名称", readConverterExp = "如=:微面/小面/3米8/5米2/6米8/7米6/9米6/13米/17米5")
private String typeName;
/** 承重下限(吨, 含) */
@Excel(name = "承重下限(吨, 含)")
private BigDecimal weightMinTon;
/** 承重上限(吨, 含) */
@Excel(name = "承重上限(吨, 含)")
private BigDecimal weightMaxTon;
/** 载方下限(立方米, 含) */
@Excel(name = "载方下限(立方米, 含)")
private BigDecimal volumeMinM3;
/** 载方上限(立方米, 含) */
@Excel(name = "载方上限(立方米, 含)")
private BigDecimal volumeMaxM3;
/** 每公里单价(元/km) */
@Excel(name = "每公里单价(元/km)")
private BigDecimal unitPricePerKm;
/** 状态(0启用 1停用) */
@Excel(name = "状态(0启用 1停用)")
private String status;
/** 是否删除(0正常 1删除) */
@Excel(name = "是否删除(0正常 1删除)")
private String isDelete;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setTypeCode(String typeCode)
{
this.typeCode = typeCode;
}
public String getTypeCode()
{
return typeCode;
}
public void setTypeName(String typeName)
{
this.typeName = typeName;
}
public String getTypeName()
{
return typeName;
}
public void setWeightMinTon(BigDecimal weightMinTon)
{
this.weightMinTon = weightMinTon;
}
public BigDecimal getWeightMinTon()
{
return weightMinTon;
}
public void setWeightMaxTon(BigDecimal weightMaxTon)
{
this.weightMaxTon = weightMaxTon;
}
public BigDecimal getWeightMaxTon()
{
return weightMaxTon;
}
public void setVolumeMinM3(BigDecimal volumeMinM3)
{
this.volumeMinM3 = volumeMinM3;
}
public BigDecimal getVolumeMinM3()
{
return volumeMinM3;
}
public void setVolumeMaxM3(BigDecimal volumeMaxM3)
{
this.volumeMaxM3 = volumeMaxM3;
}
public BigDecimal getVolumeMaxM3()
{
return volumeMaxM3;
}
public void setUnitPricePerKm(BigDecimal unitPricePerKm)
{
this.unitPricePerKm = unitPricePerKm;
}
public BigDecimal getUnitPricePerKm()
{
return unitPricePerKm;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setIsDelete(String isDelete)
{
this.isDelete = isDelete;
}
public String getIsDelete()
{
return isDelete;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("typeCode", getTypeCode())
.append("typeName", getTypeName())
.append("weightMinTon", getWeightMinTon())
.append("weightMaxTon", getWeightMaxTon())
.append("volumeMinM3", getVolumeMinM3())
.append("volumeMaxM3", getVolumeMaxM3())
.append("unitPricePerKm", getUnitPricePerKm())
.append("status", getStatus())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("isDelete", getIsDelete())
.toString();
}
}

View File

@@ -0,0 +1,24 @@
// src/main/java/com/delivery/project/document/domain/dto/CalcSuggestFeeDTO.java
package com.delivery.project.document.domain.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
* 计算建议费用 - 请求体 DTO
* 前端传入:货物重量、体积、行程公里数;若前端手动选择车型则传 vehicleTypeId。
*/
@Data
public class CalcSuggestFeeDTO {
/** 货物重量(单位:吨) */
private BigDecimal weightTon;
/** 货物体积(单位:立方米) */
private BigDecimal volumeM3;
/** 行程距离(单位:公里) */
private BigDecimal distanceKm;
/** 指定车型ID可选传入则按该车型计算建议费用 */
private Long vehicleTypeId;
}

View File

@@ -0,0 +1,28 @@
// CalcTotalWvDTO.java
package com.delivery.project.document.domain.dto;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 计算总重量/总体积 请求DTO
* - 支持仅传 wlNos每个物料默认1件重复出现按数量累加
* - 也支持 itemswlNo + qty若两者同时传以 items 为准
*/
@Data
public class CalcTotalWvDTO {
/** 物料号列表(可重复;每次出现视作数量+1 */
private List<String> wlNos;
/** 物料+数量(更精确的传法) */
private List<Item> items;
@Data
public static class Item {
/** 物料号 */
private String wlNo;
/** 数量可空默认1<=0 会按1处理 */
private BigDecimal qty;
}
}

View File

@@ -0,0 +1,19 @@
package com.delivery.project.document.domain.dto;
import lombok.Data;
/** 已上传图片条目只传URL */
@Data
public class DeliveryAttachItemDTO {
/** 场景ORIGIN / DEST必填 */
private String scene;
/** 类型SIGN_DRIVER / SIGN_COURIER / SIGN_RECEIVER / PHOTO_SITE / PHOTO_BILL必填 */
private String bizType;
/** 图片URL必填 */
private String url;
/** 排序(可选) */
private Long sortNo;
/** 备注(可选) */
private String remark;
}

View File

@@ -0,0 +1,37 @@
package com.delivery.project.document.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/** 执行配送单据绑定URL + 回写经纬度/司机/状态) */
@Data
public class DeliveryExecuteBindDTO {
/** 配送单据号delivery_order.order_no */
@NotNull
private String orderNo;
/** 当前执行场景ORIGIN / DEST */
@NotNull
private String scene;
/** 司机信息ORIGIN 场景带上DEST 可补齐) */
private String driverName;
private String driverPhone;
private String plateNo;//配送车牌
/** APP 当前定位 */
private Double lng;
private Double lat;
/** 费用(仅在 DEST 时会回写,可选) */
private BigDecimal actualFee; // 实际费用
private BigDecimal tollFee; // 高速费用
/** 本次执行的附件条目URL 列表) */
@NotNull
private List<DeliveryAttachItemDTO> attachments;
}

View File

@@ -0,0 +1,105 @@
package com.delivery.project.document.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 配送单据创建入参对象(头 + 行)
* 说明:用于前端创建配送单时提交数据,后端写入 delivery_order 表
*
* @author delivery
* @date 2025-10-28
*/
@Data
public class DeliveryOrderCreateDTO {
/**
* 配送单据号,可传可不传;
* 不传时由后端自动生成(格式如 DO202510280001
*/
private String orderNo;
// ==================== 头部信息(整单通用) ====================
/** 起始地点名称 */
private String originName;
/** 起始地点经度 */
private BigDecimal originLng;
/** 起始地点纬度 */
private BigDecimal originLat;
/** 目的地点名称 */
private String destName;
/** 目的地点经度 */
private BigDecimal destLng;
/** 目的地点纬度 */
private BigDecimal destLat;
/** 配送日期yyyy-MM-dd 格式) */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date deliveryDate;
/** 配送车辆车牌号 */
private String plateNo;
/** 发货人姓名 */
private String shipperName;
/** 发货人联系电话 */
private String shipperPhone;
/** 收货人姓名 */
private String receiverName;
/** 收货人联系电话 */
private String receiverPhone;
/** 收货单位名称 */
private String receiverOrgName;
/** 配送吨位(单位:吨) */
private BigDecimal deliveryTon;
/** 货物体积(单位:立方米) */
private BigDecimal goodsSize;
/** 单据状态(默认 0待发货1起运2送达 */
private String orderStatus;
/** 车辆类型ID外键对应 vehicle_type 表主键) */
private Long vehicleTypeId;
/** 车辆类型名称小型面包车、9.6米货车等) */
private String vehicleTypeName;
/** 系统建议运费(根据车型和里程计算) */
private BigDecimal suggestFee;
/** 实际运费(人工调整或司机确认后) */
private BigDecimal actualFee;
/** 过路费(收费站、高速费等额外费用) */
private BigDecimal tollFee;
/** 配送总里程(单位:公里) */
private BigDecimal totalKm;
/** 备注说明(可填写其他补充信息) */
private String remark;
// ==================== 行明细(多物料行) ====================
/**
* 物料明细项列表(同一单号下多条记录)
* 每条记录包含项目、物料、数量、单位等信息
*/
private List<DeliveryOrderLineDTO> items;
}

View File

@@ -0,0 +1,17 @@
package com.delivery.project.document.domain.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class DeliveryOrderLineDTO {
private String xmMs; // 项目描述
private String xmNo; // 项目号
private String wlNo; // 物料号
private String wlMs; // 物料描述
private BigDecimal realQty; // 实际入库数量
private String dw; // 计量单位
private String sapNo; // SAP订单编号
private String gysMc; // 供应商名称
}

View File

@@ -6,31 +6,114 @@ import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 配送单据(创建入参)
* 说明:前端提交新建配送单据时使用
*/
@Data
public class DeliveryOrderSaveDTO {
// ===================== 项目信息 =====================
/** 项目描述(来源项目/业务项目名称) */
private String xmMs;
/** 项目号(来源项目编号) */
private String xmNo;
// ===================== 物料信息 =====================
/** 物料号 */
private String wlNo;
/** 物料描述 */
private String wlMs;
/** 实际入库数量(与配送关联的数量) */
private BigDecimal realQty;
/** 计量单位(如:个、米、吨等) */
private String dw;
/** SAP 订单编号(便于对账/追踪) */
private String sapNo;
/** 供应商名称 */
private String gysMc;
// ===================== 起止地点 =====================
/** 起始地点名称 */
private String originName;
/** 起始地点经度WGS84一般为经度小数度 */
private BigDecimal originLng;
/** 起始地点纬度WGS84一般为纬度小数度 */
private BigDecimal originLat;
/** 目的地点名称 */
private String destName;
/** 目的地点经度WGS84 */
private BigDecimal destLng;
/** 目的地点纬度WGS84 */
private BigDecimal destLat;
// ===================== 配送信息 =====================
/** 配送日期(计划/实际发车日期) */
private Date deliveryDate;
private String vehiclePlate;
/** 配送车牌 */
private String plateNo;
/** 发货人姓名 */
private String shipperName;
/** 发货人联系方式 */
private String shipperPhone;
/** 接收人姓名 */
private String receiverName;
/** 接收人联系方式 */
private String receiverPhone;
/** 接收单位名称 */
private String receiverOrgName;
/** 配送吨位(货重,单位:吨) */
private BigDecimal deliveryTon;
/** 附件列表前端从上传接口获取的URL传入 */
/** 货物尺寸(㎡),即占地面积 */
private BigDecimal goodsSize;
// ===================== 车型(新增) =====================
/** 车辆类型ID关联 vehicle_type 表主键) */
private Long vehicleTypeId;
/** 车辆类型名称(冗余存储,便于展示与历史追溯) */
private String vehicleTypeName;
// ===================== 费用与里程(新增) =====================
/** 建议费用(按车型单价与里程计算的推荐值) */
private BigDecimal suggestFee;
/** 实际费用(最终确认费用) */
private BigDecimal actualFee;
/** 高速费用(本次运输产生的过路/高速费) */
private BigDecimal tollFee;
/** 总公里数(本次运输的行驶里程,单位:公里) */
private BigDecimal totalKm;
// ===================== 附件 =====================
/** 附件列表(前端从上传接口获取的 URL 传入) */
private List<DeliveryAttachUploadDTO> attachments;
}

View File

@@ -0,0 +1,13 @@
package com.delivery.project.document.domain.dto;
import lombok.Data;
@Data
public class DeliverySimpleLocationDTO {
/** 经度 */
private Double lng;
/** 纬度 */
private Double lat;
}

View File

@@ -0,0 +1,31 @@
package com.delivery.project.document.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/** APP 上报定位请求体 */
@Data
public class LocationReportDTO {
/** 车牌号(维度之一) */
@NotBlank(message = "车牌号不能为空")
private String plateNo;
/** 配送单号(维度之一,必填) */
@NotBlank(message = "配送单号不能为空")
private String orderNo;
/** 经度保留6位小数 */
@NotNull(message = "经度不能为空")
private BigDecimal lng;
/** 纬度保留6位小数 */
@NotNull(message = "纬度不能为空")
private BigDecimal lat;
/** 客户端时间戳(可选) */
private Long clientTs;
}

View File

@@ -0,0 +1,57 @@
// src/main/java/com/delivery/project/document/domain/vo/CalcSuggestFeeVO.java
package com.delivery.project.document.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 计算建议费用 - 响应体 VO
* 返回推荐/选定的车型、单价、建议费用,以及候选车型列表。
*/
@Data
public class CalcSuggestFeeVO {
/** 选定/推荐车型ID */
private Long vehicleTypeId;
/** 选定/推荐车型名称 */
private String vehicleTypeName;
/** 每公里单价(单位:元/公里) */
private BigDecimal unitPricePerKm;
/** 建议费用单位四舍五入保留2位小数 */
private BigDecimal suggestFee;
/** 候选车型列表(按价格/容量排序) */
private List<VehicleTypeOptionVO> candidates;
/**
* 候选车型项 VO
* 表示一条可选车型的基本信息。
*/
@Data
public static class VehicleTypeOptionVO {
/** 车型ID */
private Long id;
/** 车型名称 */
private String name;
/** 每公里单价(单位:元/公里) */
private BigDecimal unitPricePerKm;
/** 承重下限(单位:吨,含) */
private BigDecimal weightMinTon;
/** 承重上限(单位:吨,含) */
private BigDecimal weightMaxTon;
/** 载方下限(单位:立方米,含) */
private BigDecimal volumeMinM3;
/** 载方上限(单位:立方米,含) */
private BigDecimal volumeMaxM3;
}
}

View File

@@ -0,0 +1,57 @@
package com.delivery.project.document.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 配送单据汇总视图对象
*
* 用途:
* - 用于列表页或统计页面展示配送单的核心概要信息;
* - 不含附件、物料明细,只反映每张单据的基础汇总信息。
*
* @author delivery
* @date 2025-10-29
*/
@Data
public class DeliveryOrderGroupVO {
/** 配送单号 */
private String orderNo;
/** 配送日期格式yyyy-MM-dd */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date deliveryDate;
/** 起始地点名称(发货点) */
private String originName;
/** 目的地点名称(收货点) */
private String destName;
/** 车辆车牌号 */
private String plateNo;
/** 配送单状态 */
private String orderStatus;
/** 发货人姓名 */
private String shipperName;
/** 收货人姓名 */
private String receiverName;
/** 物料行数(明细数量,用于显示一单包含多少种货物) */
private Integer itemCount;
/** 数量合计(汇总所有明细的总数量,可为空) */
private BigDecimal totalQty;
}

View File

@@ -0,0 +1,16 @@
// TotalWvVO.java
package com.delivery.project.document.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
* 仅返回总重量与总体积
*/
@Data
public class TotalWvVO {
/** 总重量kg */
private BigDecimal totalWeightKg;
/** 总体积 */
private BigDecimal totalVolumeM3;
}

View File

@@ -58,4 +58,10 @@ public interface DeliveryAttachmentMapper
* @return 结果
*/
public int deleteDeliveryAttachmentByIds(Long[] ids);
/**
* 批量插入
* @param list
*/
void batchInsert(List<DeliveryAttachment> list);
}

View File

@@ -0,0 +1,74 @@
package com.delivery.project.document.mapper;
import com.delivery.project.document.domain.DeliveryLocationRecord;
import com.delivery.project.document.domain.dto.DeliverySimpleLocationDTO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface DeliveryLocationRecordMapper {
/** 插入一条定位记录 */
int insert(DeliveryLocationRecord record);
/** 批量插入定位记录 */
int insertBatch(List<DeliveryLocationRecord> batch);
/**
* 查询配送定位记录(车牌+单号维度)
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 配送定位记录(车牌+单号维度)
*/
public DeliveryLocationRecord selectDeliveryLocationRecordById(Long id);
/**
* 查询配送定位记录(车牌+单号维度)列表
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 配送定位记录(车牌+单号维度)集合
*/
public List<DeliveryLocationRecord> selectDeliveryLocationRecordList(DeliveryLocationRecord deliveryLocationRecord);
/**
* 新增配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
public int insertDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord);
/**
* 修改配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
public int updateDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord);
/**
* 删除配送定位记录(车牌+单号维度)
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 结果
*/
public int deleteDeliveryLocationRecordById(Long id);
/**
* 批量删除配送定位记录(车牌+单号维度)
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteDeliveryLocationRecordByIds(Long[] ids);
/**
* 查询车辆轨迹点
*
* @param plateNo 订单编号
* @param plateNo 车牌号
* @return 轨迹点
*/
List<DeliverySimpleLocationDTO> selectTrackPoints(String orderNo, String plateNo);
}

View File

@@ -2,6 +2,8 @@ package com.delivery.project.document.mapper;
import java.util.List;
import com.delivery.project.document.domain.DeliveryOrder;
import com.delivery.project.document.domain.vo.DeliveryOrderGroupVO;
import org.apache.ibatis.annotations.Param;
/**
* 配送单据主Mapper接口
@@ -58,4 +60,36 @@ public interface DeliveryOrderMapper
* @return 结果
*/
public int deleteDeliveryOrderByIds(Long[] ids);
/**
* 批量插入
*
* @param rows
* @return
*/
int batchInsert(@Param("list") List<DeliveryOrder> rows);
/**
* 分组查询
*
* @param query
* @return
*/
List<DeliveryOrderGroupVO> selectGroupList(DeliveryOrder query);
/**
* 根据单号查询
*
* @param plateNo
* @return
*/
List<DeliveryOrder> selectByOrderNo(String orderNo);
/**
* 根据单号查询
*
* @param orderNo
* @return
*/
DeliveryOrder selectDeliveryOrderByOrderNo(String orderNo);
}

View File

@@ -0,0 +1,73 @@
package com.delivery.project.document.mapper;
import java.util.List;
import com.delivery.project.document.domain.Mtd;
import org.apache.ibatis.annotations.Param;
/**
* 物料字典Mapper接口
*
* @author delivery
* @date 2025-10-23
*/
public interface MtdMapper
{
/**
* 查询物料字典
*
* @param id 物料字典主键
* @return 物料字典
*/
public Mtd selectMtdById(Long id);
/**
* 查询物料字典列表
*
* @param mtd 物料字典
* @return 物料字典集合
*/
public List<Mtd> selectMtdList(Mtd mtd);
/**
* 新增物料字典
*
* @param mtd 物料字典
* @return 结果
*/
public int insertMtd(Mtd mtd);
/**
* 修改物料字典
*
* @param mtd 物料字典
* @return 结果
*/
public int updateMtd(Mtd mtd);
/**
* 删除物料字典
*
* @param id 物料字典主键
* @return 结果
*/
public int deleteMtdById(Long id);
/**
* 批量删除物料字典
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteMtdByIds(Long[] ids);
/**
* 批量 UPSERT同 wlNo 更新,不存在则新增)
* 依赖 wl_no 唯一索引
*/
int batchUpsertMtd(List<Mtd> list);
/**
* 根据多个物料编号查询物料信息
*/
List<Mtd> selectByWlNos(@Param("wlNos") List<String> wlNos);
}

View File

@@ -66,4 +66,6 @@ public interface RkInfoMapper
* 不新增 resultMap / VO直接用 RkInfoResult 映射需要的字段
*/
List<RkInfo> selectGroupedByBill(@Param("q") RkInfo rkInfo);
}

View File

@@ -0,0 +1,61 @@
package com.delivery.project.document.mapper;
import java.util.List;
import com.delivery.project.document.domain.Vehicle;
/**
* 车辆档案Mapper接口
*
* @author delivery
* @date 2025-10-23
*/
public interface VehicleMapper
{
/**
* 查询车辆档案
*
* @param id 车辆档案主键
* @return 车辆档案
*/
public Vehicle selectVehicleById(Long id);
/**
* 查询车辆档案列表
*
* @param vehicle 车辆档案
* @return 车辆档案集合
*/
public List<Vehicle> selectVehicleList(Vehicle vehicle);
/**
* 新增车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
public int insertVehicle(Vehicle vehicle);
/**
* 修改车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
public int updateVehicle(Vehicle vehicle);
/**
* 删除车辆档案
*
* @param id 车辆档案主键
* @return 结果
*/
public int deleteVehicleById(Long id);
/**
* 批量删除车辆档案
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteVehicleByIds(Long[] ids);
}

View File

@@ -0,0 +1,80 @@
package com.delivery.project.document.mapper;
import java.math.BigDecimal;
import java.util.List;
import com.delivery.project.document.domain.VehicleType;
/**
* 车型定义Mapper接口
*
* @author delivery
* @date 2025-10-23
*/
public interface VehicleTypeMapper
{
/**
* 查询车型定义
*
* @param id 车型定义主键
* @return 车型定义
*/
public VehicleType selectVehicleTypeById(Long id);
/**
* 查询车型定义列表
*
* @param vehicleType 车型定义
* @return 车型定义集合
*/
public List<VehicleType> selectVehicleTypeList(VehicleType vehicleType);
/**
* 新增车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
public int insertVehicleType(VehicleType vehicleType);
/**
* 修改车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
public int updateVehicleType(VehicleType vehicleType);
/**
* 删除车型定义
*
* @param id 车型定义主键
* @return 结果
*/
public int deleteVehicleTypeById(Long id);
/**
* 批量删除车型定义
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteVehicleTypeByIds(Long[] ids);
/**
* 批量查询车型定义
*
* @param w 宽
* @param v 高
* @return 批量结果
*/
List<VehicleType> selectMatchTypes(BigDecimal w, Comparable<BigDecimal> v);
/**
* 批量查询车型定义
*
* @param w 宽
* @param v 高
* @return 批量结果
*/
List<VehicleType> selectFallbackTypes(BigDecimal w, BigDecimal v);
}

View File

@@ -2,8 +2,12 @@ package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.DeliveryAttachment;
import com.delivery.project.document.domain.dto.DeliveryAttachUploadDTO;
import com.delivery.project.document.domain.dto.DeliveryExecuteBindDTO;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
/**
* 配送附件Service接口
*
@@ -60,4 +64,9 @@ public interface IDeliveryAttachmentService
*/
public int deleteDeliveryAttachmentById(Long id);
int executeBind(DeliveryExecuteBindDTO dto);
List<String> upload(MultipartFile[] files, DeliveryAttachUploadDTO dto, HttpServletRequest request);
}

View File

@@ -2,7 +2,11 @@ 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.DeliveryOrderGroupVO;
import org.springframework.beans.factory.annotation.Value;
/**
* 配送单据主Service接口
@@ -68,4 +72,36 @@ public interface IDeliveryOrderService
* @return
*/
int saveOrderWithAttachments(DeliveryOrderSaveDTO dto, String username);
/**
* 新建配送单据:同一单号多行写入
* @param dto
* @return
*/
String createOrder(DeliveryOrderCreateDTO dto);
/**
* 列表:按单号分组(分页)
* @param query
* @return
*/
List<DeliveryOrderGroupVO> listGroup(DeliveryOrder query);
/**
* 详情:按单号查询所有行
* @param plateNo
* @return
*/
/** 详情:按单号查行 */
List<DeliveryOrder> listByOrderNo(String orderNo);
/**
* 从智慧实物系统查询待配送出库单据
*
* @return rk_info 列表
*/
List<RkInfo> listWisdomRkForDelivery();
}

View File

@@ -0,0 +1,75 @@
package com.delivery.project.document.service;
import com.delivery.project.document.domain.DeliveryLocationRecord;
import com.delivery.project.document.domain.dto.DeliverySimpleLocationDTO;
import com.delivery.project.document.domain.dto.LocationReportDTO;
import java.util.List;
import java.util.Map;
/** 定位上报服务接口(实现层由 Impl 提供) */
public interface ILocationReportService {
/**
* APP 上报定位
* @param dto 上报体
* @param username 当前操作人(由 Controller 使用 BaseController.getUsername() 传入)
* @return 处理结果
*/
Map<String, Object> report(LocationReportDTO dto, String username);
/**
* 查询配送定位记录(车牌+单号维度)
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 配送定位记录(车牌+单号维度)
*/
public DeliveryLocationRecord selectDeliveryLocationRecordById(Long id);
/**
* 查询配送定位记录(车牌+单号维度)列表
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 配送定位记录(车牌+单号维度)集合
*/
public List<DeliveryLocationRecord> selectDeliveryLocationRecordList(DeliveryLocationRecord deliveryLocationRecord);
/**
* 新增配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
public int insertDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord);
/**
* 修改配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
public int updateDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord);
/**
* 批量删除配送定位记录(车牌+单号维度)
*
* @param ids 需要删除的配送定位记录(车牌+单号维度)主键集合
* @return 结果
*/
public int deleteDeliveryLocationRecordByIds(Long[] ids);
/**
* 删除配送定位记录(车牌+单号维度)信息
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 结果
*/
public int deleteDeliveryLocationRecordById(Long id);
/**
* 查询轨迹点
* @param plateNo 订单号
* @param plateNo 车牌号
* @return 轨迹点
*/
List<DeliverySimpleLocationDTO> selectTrackPoints(String orderNo, String plateNo);
}

View File

@@ -0,0 +1,80 @@
package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.Mtd;
import com.delivery.project.document.domain.dto.CalcTotalWvDTO;
import com.delivery.project.document.domain.vo.TotalWvVO;
/**
* 物料字典Service接口
*
* @author delivery
* @date 2025-10-23
*/
public interface IMtdService
{
/**
* 查询物料字典
*
* @param id 物料字典主键
* @return 物料字典
*/
public Mtd selectMtdById(Long id);
/**
* 查询物料字典列表
*
* @param mtd 物料字典
* @return 物料字典集合
*/
public List<Mtd> selectMtdList(Mtd mtd);
/**
* 新增物料字典
*
* @param mtd 物料字典
* @return 结果
*/
public int insertMtd(Mtd mtd);
/**
* 修改物料字典
*
* @param mtd 物料字典
* @return 结果
*/
public int updateMtd(Mtd mtd);
/**
* 批量删除物料字典
*
* @param ids 需要删除的物料字典主键集合
* @return 结果
*/
public int deleteMtdByIds(Long[] ids);
/**
* 删除物料字典信息
*
* @param id 物料字典主键
* @return 结果
*/
public int deleteMtdById(Long id);
/**
* 导入物料字典数据
*
* @param list 物料字典数据列表
* @param username 更新者
* @return 结果
*/
int importMtd(List<Mtd> list, String username);
/**
* 计算总重量和体积
*
* @param dto 计算参数
* @return 结果
*/
TotalWvVO calcTotalWv(CalcTotalWvDTO dto);
}

View File

@@ -0,0 +1,61 @@
package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.Vehicle;
/**
* 车辆档案Service接口
*
* @author delivery
* @date 2025-10-23
*/
public interface IVehicleService
{
/**
* 查询车辆档案
*
* @param id 车辆档案主键
* @return 车辆档案
*/
public Vehicle selectVehicleById(Long id);
/**
* 查询车辆档案列表
*
* @param vehicle 车辆档案
* @return 车辆档案集合
*/
public List<Vehicle> selectVehicleList(Vehicle vehicle);
/**
* 新增车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
public int insertVehicle(Vehicle vehicle);
/**
* 修改车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
public int updateVehicle(Vehicle vehicle);
/**
* 批量删除车辆档案
*
* @param ids 需要删除的车辆档案主键集合
* @return 结果
*/
public int deleteVehicleByIds(Long[] ids);
/**
* 删除车辆档案信息
*
* @param id 车辆档案主键
* @return 结果
*/
public int deleteVehicleById(Long id);
}

View File

@@ -0,0 +1,70 @@
package com.delivery.project.document.service;
import java.util.List;
import com.delivery.project.document.domain.VehicleType;
import com.delivery.project.document.domain.dto.CalcSuggestFeeDTO;
import com.delivery.project.document.domain.vo.CalcSuggestFeeVO;
/**
* 车型定义Service接口
*
* @author delivery
* @date 2025-10-23
*/
public interface IVehicleTypeService
{
/**
* 查询车型定义
*
* @param id 车型定义主键
* @return 车型定义
*/
public VehicleType selectVehicleTypeById(Long id);
/**
* 查询车型定义列表
*
* @param vehicleType 车型定义
* @return 车型定义集合
*/
public List<VehicleType> selectVehicleTypeList(VehicleType vehicleType);
/**
* 新增车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
public int insertVehicleType(VehicleType vehicleType);
/**
* 修改车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
public int updateVehicleType(VehicleType vehicleType);
/**
* 批量删除车型定义
*
* @param ids 需要删除的车型定义主键集合
* @return 结果
*/
public int deleteVehicleTypeByIds(Long[] ids);
/**
* 删除车型定义信息
*
* @param id 车型定义主键
* @return 结果
*/
public int deleteVehicleTypeById(Long id);
/**
* 计算建议运费
* @param dto
* @return
*/
CalcSuggestFeeVO calcSuggestFee(CalcSuggestFeeDTO dto);
}

View File

@@ -0,0 +1,161 @@
package com.delivery.project.document.service;
import com.delivery.framework.config.LocationReportProperties;
import com.delivery.project.document.domain.DeliveryLocationRecord;
import com.delivery.project.document.mapper.DeliveryLocationRecordMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
/**
* 定位数据批量落库任务
* ---------------------------------------------
* 功能说明:
* 每隔固定时间默认15秒执行一次将 Redis 中缓存的定位数据批量写入数据库。
*
* 核心逻辑:
* 1. 每辆车(车牌 + 订单号)对应一个独立的 Redis ZSET
* 2. ZSET 内部保存该车在 15 秒窗口内的唯一经纬度坐标;
* 3. 定时任务遍历所有活跃 ZSET
* - 取出所有在窗口时间内的坐标;
* - 对比上次已落库坐标(跨窗口去重);
* - 批量插入数据库;
* - 清理已处理坐标;
* - 更新“最后一次落库坐标”;
*
* 优点:
* ✅ ZSET 天然去重(同一经纬度不会重复插入);
* ✅ 批量落库,减轻数据库压力;
* ✅ 支持数千辆车同时上报;
* ✅ 可水平扩展。
*/
@Slf4j
@Component
@EnableScheduling
@RequiredArgsConstructor
public class LocationBatchFlusher {
/** Redis 客户端 */
private final StringRedisTemplate redis;
/** 业务配置项(包含定时间隔、缓存时间等) */
private final LocationReportProperties props;
/** MyBatis Mapper用于批量插入数据库 */
private final DeliveryLocationRecordMapper mapper;
/** 活跃车辆集合Set 结构保存所有存在ZSET的key */
private static final String KEY_INDEX = "delivery:loc:index";
/** 状态存储Hash 结构,保存每个车的最后一次写库坐标) */
private static final String KEY_STATE_PREFIX = "delivery:loc:state:";
/**
* 定时任务每隔固定时间如15秒执行一次
* fixedDelay 表示“上一次任务执行完毕后延迟多少毫秒再执行下一次”
* 取值来自配置类 LocationReportProperties.minPersistIntervalMs
*/
@Scheduled(fixedDelayString = "#{@locationReportProperties.minPersistIntervalMs}")
public void flushWindow() {
// 获取所有活跃ZSET的key每辆车对应一个
Set<String> keys = redis.opsForSet().members(KEY_INDEX);
if (keys == null || keys.isEmpty()) return;
long now = System.currentTimeMillis(); // 当前时间戳
List<DeliveryLocationRecord> batch = new ArrayList<>(); // 批量写入列表
// 遍历每一辆车的ZSET
for (String zsetKey : keys) {
String plate = parsePlate(zsetKey); // 提取车牌号
String order = parseOrder(zsetKey); // 提取订单号
String stateKey = KEY_STATE_PREFIX + plate + ":" + order; // 每辆车的状态key
// ✅ 从ZSET中获取当前时间之前的所有坐标
Set<ZSetOperations.TypedTuple<String>> tuples =
redis.opsForZSet().rangeByScoreWithScores(zsetKey, 0, now);
if (tuples == null || tuples.isEmpty()) continue;
// 读取“上次已落库的最后一条坐标”,用于跨窗口去重
String lastWritten = (String) redis.opsForHash().get(stateKey, "lastWritten");
// 临时变量记录这次批量中最后插入的member
String lastInsertedMember = lastWritten;
// 遍历ZSET中的坐标数据
for (ZSetOperations.TypedTuple<String> t : tuples) {
String member = t.getValue(); // 坐标字符串,如 "120.125600,30.276800"
Double score = t.getScore(); // ZSET中存储的时间戳首次上报时间
if (member == null || score == null) continue;
// ❗跨窗口去重逻辑:如果当前坐标与上次写库坐标完全一致,则跳过
if (member.equals(lastWritten)) continue;
// 拆分经纬度
String[] arr = member.split(",");
if (arr.length != 2) continue;
// 构造数据库实体对象
DeliveryLocationRecord r = new DeliveryLocationRecord();
r.setPlateNo(plate);
r.setOrderNo(order);
r.setLng(new BigDecimal(arr[0]));
r.setLat(new BigDecimal(arr[1]));
r.setReportedAt(new Date(score.longValue())); // 上报时间取ZSET中的分数
r.setSource("app");
r.setRemark("tick_" + props.getMinPersistIntervalMs());
r.setCreateBy("");
r.setIsDelete("0");
batch.add(r);
// 记录这次批量最后插入的坐标用于更新lastWritten
lastInsertedMember = member;
}
// 清理:删除本窗口内已处理的坐标数据
redis.opsForZSet().removeRangeByScore(zsetKey, 0, now);
// 记录最新写库坐标,用于下一轮去重
if (lastInsertedMember != null) {
redis.opsForHash().put(stateKey, "lastWritten", lastInsertedMember);
redis.expire(stateKey, props.getStateTtlHours(), java.util.concurrent.TimeUnit.HOURS);
}
}
// 若本轮有新数据,则批量插入数据库
if (!batch.isEmpty()) {
int n = mapper.insertBatch(batch);
log.info("[location-flush] 本轮批量落库完成:插入 {} 条定位记录,共处理 {} 个ZSET", n, keys.size());
}
}
/**
* 从ZSET的key中解析出车牌号
* 例如delivery:loc:buf:浙A88888:D202511030001 → 返回“浙A88888”
*/
private String parsePlate(String zsetKey) {
String prefix = "delivery:loc:buf:";
if (!zsetKey.startsWith(prefix)) return "";
String tail = zsetKey.substring(prefix.length());
int i = tail.indexOf(':');
return i < 0 ? tail : tail.substring(0, i);
}
/**
* 从ZSET的key中解析出订单号
* 例如delivery:loc:buf:浙A88888:D202511030001 → 返回“D202511030001”
*/
private String parseOrder(String zsetKey) {
int p = zsetKey.lastIndexOf(':');
return p < 0 ? "" : zsetKey.substring(p + 1);
}
}

View File

@@ -1,19 +1,33 @@
package com.delivery.project.document.service.impl;
import java.util.List;
import java.util.Locale;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.DateUtils;
import com.delivery.common.utils.MinioUtil;
import com.delivery.common.utils.StringUtils;
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.service.IDeliveryOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.DeliveryAttachmentMapper;
import com.delivery.project.document.domain.DeliveryAttachment;
import com.delivery.project.document.service.IDeliveryAttachmentService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
/**
* 配送附件Service业务层处理
@@ -22,11 +36,18 @@ import org.springframework.web.multipart.MultipartFile;
* @date 2025-10-15
*/
@Service
@Slf4j
public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
{
@Autowired
private DeliveryAttachmentMapper deliveryAttachmentMapper;
@Autowired
private DeliveryOrderMapper deliveryOrderMapper;
@Autowired
private IDeliveryOrderService deliveryOrderService;
/**
* 查询配送附件
*
@@ -101,5 +122,133 @@ public class DeliveryAttachmentServiceImpl implements IDeliveryAttachmentService
return deliveryAttachmentMapper.deleteDeliveryAttachmentById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int executeBind(DeliveryExecuteBindDTO dto) {
// 1) 校验订单存在
DeliveryOrder exist = deliveryOrderMapper.selectDeliveryOrderByOrderNo(dto.getOrderNo());
if (exist == null) {
throw new ServiceException("配送单不存在:" + dto.getOrderNo());
}
if (dto.getAttachments() == null || dto.getAttachments().isEmpty()) {
throw new ServiceException("附件列表不能为空");
}
// 2) 批量插入附件(只传 URL
List<DeliveryAttachment> list = new ArrayList<>();
// 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;
DeliveryAttachment a = new DeliveryAttachment();
a.setOrderNo(dto.getOrderNo());
a.setScene(it.getScene());
a.setBizType(it.getBizType());
a.setUrl(it.getUrl());
a.setSortNo(it.getSortNo());
a.setRemark(it.getRemark());
a.setStatus("1"); // 已绑定
a.setIsDelete("0");
a.setCreateBy(username);
a.setCreateTime(DateUtils.getNowDate());
list.add(a);
}
if (list.isEmpty()) {
throw new ServiceException("有效附件条目为空");
}
deliveryAttachmentMapper.batchInsert(list);
// 3) 回写配送单(仅填需要更新的字段),交给已有 updateDeliveryOrder(按 order_no 更新)
DeliveryOrder patch = new DeliveryOrder();
patch.setOrderNo(dto.getOrderNo());
String scene = dto.getScene() == null ? "" : dto.getScene().toUpperCase(Locale.ROOT);
if ("ORIGIN".equals(scene)) {
// 起点:司机信息 + 起点经纬度 + 状态=1
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()));
patch.setOrderStatus("2");
} else if ("DEST".equals(scene)) {
// 终点:终点经纬度 + 状态=2
if (dto.getLng() != null) patch.setDestLng(BigDecimal.valueOf(dto.getLng()));
if (dto.getLat() != null) patch.setDestLat(BigDecimal.valueOf(dto.getLat()));
if (dto.getActualFee() != null) {
if (dto.getActualFee().compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("实际费用不能为负数");
}
patch.setActualFee(dto.getActualFee());
}
if (dto.getTollFee() != null) {
if (dto.getTollFee().compareTo(BigDecimal.ZERO) < 0) {
throw new ServiceException("高速费用不能为负数");
}
patch.setTollFee(dto.getTollFee());
}
patch.setOrderStatus("3");
}
deliveryOrderService.updateDeliveryOrder(patch);
return list.size();
}
// 保存目录 D:\delivery
private static final String BASE_PATH = "D:/delivery";
@Override
public List<String> upload(MultipartFile[] files, DeliveryAttachUploadDTO dto, HttpServletRequest request) {
if (files == null || files.length == 0) {
throw new ServiceException("上传文件不能为空");
}
if (dto == null || StringUtils.isBlank(dto.getScene()) || StringUtils.isBlank(dto.getBizType())) {
throw new ServiceException("scene 和 bizType 不能为空");
}
String scene = dto.getScene().trim().toLowerCase(Locale.ROOT);
String bizType = dto.getBizType().trim().toLowerCase(Locale.ROOT);
String dateFolder = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
Path targetDir = Paths.get(BASE_PATH, dateFolder, scene, bizType);
try {
Files.createDirectories(targetDir);
List<String> urls = new ArrayList<>();
for (MultipartFile file : files) {
if (file.isEmpty()) continue;
String original = file.getOriginalFilename();
String ext = "";
if (original != null && original.contains(".")) {
ext = original.substring(original.lastIndexOf("."));
}
String newName = UUID.randomUUID().toString().replace("-", "") + ext;
Path targetFile = targetDir.resolve(newName);
Files.copy(file.getInputStream(), targetFile, StandardCopyOption.REPLACE_EXISTING);
// 自动识别访问前缀http://ip:port
String baseUrl = ServletUriComponentsBuilder.fromRequestUri(request)
.replacePath(null)
.build()
.toUriString();
// 返回完整URL
String url = baseUrl + "/delivery/" + dateFolder + "/" + scene + "/" + bizType + "/" + newName;
urls.add(url);
}
log.info("【附件上传成功】{}", urls);
return urls;
} catch (Exception e) {
log.error("文件保存失败", e);
throw new ServiceException("文件保存失败:" + e.getMessage());
}
}
}

View File

@@ -1,22 +1,36 @@
package com.delivery.project.document.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
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.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.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.DeliveryOrderGroupVO;
import com.delivery.project.document.mapper.DeliveryAttachmentMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.DeliveryOrderMapper;
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业务层处理
*
@@ -33,6 +47,9 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
@Autowired
private DeliveryAttachmentMapper deliveryAttachmentMapper;
@Value("${wisdom.base-url}")
private String wisdomBaseUrl;
/**
* 查询配送单据主
*
@@ -77,8 +94,10 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
* @return 结果
*/
@Override
public int updateDeliveryOrder(DeliveryOrder deliveryOrder)
{
public int updateDeliveryOrder(DeliveryOrder deliveryOrder) {
if (deliveryOrder.getOrderNo() == null) {
throw new ServiceException("orderNo 不能为空");
}
deliveryOrder.setUpdateTime(DateUtils.getNowDate());
return deliveryOrderMapper.updateDeliveryOrder(deliveryOrder);
}
@@ -118,7 +137,7 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
order.setCreateTime(DateUtils.getNowDate());
deliveryOrderMapper.insertDeliveryOrder(order);
Long orderId = order.getId();
String orderNo = order.getOrderNo();
int affected = 1;
// 2. 保存附件
@@ -131,7 +150,7 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
}
DeliveryAttachment att = new DeliveryAttachment();
att.setOrderId(orderId);
att.setOrderNo(orderNo);
att.setScene(item.getScene());
att.setBizType(item.getBizType());
att.setUrl(item.getUrl());
@@ -150,4 +169,140 @@ public class DeliveryOrderServiceImpl implements IDeliveryOrderService
return affected;
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createOrder(DeliveryOrderCreateDTO dto) {
// ========== 1. 生成配送单号 ==========
// 如果前端未指定单号则按规则生成一个唯一编号示例DO20251027104532123
String orderNo = (dto.getOrderNo() == null || dto.getOrderNo().trim().isEmpty())
? "DO" + DateUtils.dateTimeNow("yyyyMMddHHmmssSSS")
: dto.getOrderNo().trim();
// 当前时间,用于所有行的 create_time
Date now = DateUtils.getNowDate();
// 定义要插入的记录集合
List<DeliveryOrder> rows = new ArrayList<>();
// ========== 2. 遍历每一条物料明细 ==========
for (DeliveryOrderLineDTO it : dto.getItems()) {
// 创建实体对象(每一行对应一条数据库记录)
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.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.3 通用字段 ==========
row.setIsDelete("0"); // 正常状态
row.setCreateTime(now); // 创建时间
row.setCreateBy(getUsername());
// row.setCreateBy("大爷的!");
// 添加到批量集合中
rows.add(row);
}
// ========== 3. 批量落库 ==========
if (!rows.isEmpty()) {
// 使用 Mapper.xml 的 <foreach> 一次插入多条记录
deliveryOrderMapper.batchInsert(rows);
}
// ========== 4. 返回单号 ==========
return orderNo;
}
@Override
public List<DeliveryOrderGroupVO> listGroup(DeliveryOrder query) {
return deliveryOrderMapper.selectGroupList(query);
}
@Override
public List<DeliveryOrder> listByOrderNo(String orderNo) {
return deliveryOrderMapper.selectByOrderNo(orderNo);
}
/**
* 从【智慧实物管理系统】查询“待配送的出库单据”
* 对应智慧实物接口GET /wisdom/stock/delivery
*
* @return List<RkInfo>
*/
@Override
public List<RkInfo> listWisdomRkForDelivery() {
// 1. 拼接请求地址
String url = wisdomBaseUrl + "/wisdom/stock/delivery";
// 2. 发送 GET 请求
String respJson = HttpUtils.sendGet(url);
if (StringUtils.isEmpty(respJson)) {
throw new ServiceException("调用智慧实物接口失败:返回结果为空");
}
// 3. 解析 JSON统一返回结构{ code, msg, data }
JSONObject json = JSON.parseObject(respJson);
if (json == null) {
throw new ServiceException("调用智慧实物接口失败:解析返回结果为空");
}
Integer code = json.getInteger("code");
if (code == null || code != 200) {
String msg = json.getString("msg");
throw new ServiceException("调用智慧实物接口失败code=" + code + "msg=" + msg);
}
Object dataObj = json.get("data");
if (dataObj == null) {
// 没有数据就返回空集合,不算错误
return new ArrayList<>();
}
// data 可能本身就是数组,也可能是单个对象
JSONArray dataArr;
if (dataObj instanceof JSONArray) {
dataArr = (JSONArray) dataObj;
} else {
dataArr = JSON.parseArray(JSON.toJSONString(dataObj));
}
if (dataArr == null || dataArr.isEmpty()) {
return new ArrayList<>();
}
// 4. 转成 List<RkInfo>
return JSON.parseArray(dataArr.toJSONString(), RkInfo.class);
}
}

View File

@@ -0,0 +1,185 @@
package com.delivery.project.document.service.impl;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.DateUtils;
import com.delivery.framework.config.LocationReportProperties;
import com.delivery.project.document.domain.DeliveryLocationRecord;
import com.delivery.project.document.domain.dto.DeliverySimpleLocationDTO;
import com.delivery.project.document.domain.dto.LocationReportDTO;
import com.delivery.project.document.mapper.DeliveryLocationRecordMapper;
import com.delivery.project.document.service.ILocationReportService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 定位上报:仅写 ZSET 缓冲member=lng,latscore=ts按 15s 周期由定时任务批量入库
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class LocationReportServiceImpl implements ILocationReportService {
@Autowired
private DeliveryLocationRecordMapper deliveryLocationRecordMapper;
private final StringRedisTemplate redis;
private final LocationReportProperties props;
private static final String KEY_BUF_PREFIX = "delivery:loc:buf:"; // delivery:loc:buf:{plate}:{order}
private static final String KEY_INDEX = "delivery:loc:index"; // 活跃 ZSET 索引Set
/**
* 上报车辆位置信息。
*
* @param dto 包含车辆位置相关信息的数据传输对象,必须包含车牌号、订单号、经纬度等字段
* @param username 当前操作用户标识(可用于日志或权限校验,当前未使用)
* @return 返回一个Map结构的结果包含是否成功缓冲、原因、车牌号、订单号及时间戳等信息
*/
@Override
public Map<String, Object> report(LocationReportDTO dto, String username) {
final String plate = dto.getPlateNo().trim();
final String orderNo = dto.getOrderNo().trim();
final String zsetKey = KEY_BUF_PREFIX + plate + ":" + orderNo;
final String lockKey = "delivery:loc:lock:" + plate + ":" + orderNo;
// 使用 Redis 分布式锁防止并发写入同一辆车的位置数据
Boolean locked = redis.opsForValue().setIfAbsent(lockKey, "1", props.getLockSeconds(), TimeUnit.SECONDS);
if (locked == null || !locked) {
return resp(false, "concurrent_skip", plate, orderNo, 0);
}
try {
BigDecimal lng = dto.getLng().setScale(6, RoundingMode.HALF_UP);
BigDecimal lat = dto.getLat().setScale(6, RoundingMode.HALF_UP);
long now = System.currentTimeMillis();
String member = lng.toPlainString() + "," + lat.toPlainString();
// ✅ 去重缓存:只在不存在时写入(等价 ZADD NX
redis.opsForZSet().addIfAbsent(zsetKey, member, now);
// 设置过期时间并记录该key为活跃key
redis.expire(zsetKey, props.getStateTtlHours(), TimeUnit.HOURS);
redis.opsForSet().add(KEY_INDEX, zsetKey);
return resp(true, "buffered", plate, orderNo, now);
} catch (Exception e) {
throw new ServiceException("定位上报处理失败:" + e.getMessage());
} finally {
// 释放分布式锁
redis.delete(lockKey);
}
}
/**
* 构造响应结果。
*
* @param ok 是否处理成功
* @param reason 处理结果的原因描述
* @param plate 车牌号码
* @param orderNo 订单编号
* @param ts 时间戳
* @return 封装后的响应Map对象
*/
private Map<String, Object> resp(boolean ok, String reason, String plate, String orderNo, long ts) {
Map<String, Object> m = new HashMap<>();
m.put("buffered", ok);
m.put("reason", reason);
m.put("plateNo", plate);
m.put("orderNo", orderNo);
m.put("ts", ts);
return m;
}
/**
* 查询配送定位记录(车牌+单号维度)
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 配送定位记录(车牌+单号维度)
*/
@Override
public DeliveryLocationRecord selectDeliveryLocationRecordById(Long id)
{
return deliveryLocationRecordMapper.selectDeliveryLocationRecordById(id);
}
/**
* 查询配送定位记录(车牌+单号维度)列表
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 配送定位记录(车牌+单号维度)
*/
@Override
public List<DeliveryLocationRecord> selectDeliveryLocationRecordList(DeliveryLocationRecord deliveryLocationRecord)
{
return deliveryLocationRecordMapper.selectDeliveryLocationRecordList(deliveryLocationRecord);
}
/**
* 新增配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
@Override
public int insertDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord)
{
deliveryLocationRecord.setCreateTime(DateUtils.getNowDate());
return deliveryLocationRecordMapper.insertDeliveryLocationRecord(deliveryLocationRecord);
}
/**
* 修改配送定位记录(车牌+单号维度)
*
* @param deliveryLocationRecord 配送定位记录(车牌+单号维度)
* @return 结果
*/
@Override
public int updateDeliveryLocationRecord(DeliveryLocationRecord deliveryLocationRecord)
{
deliveryLocationRecord.setUpdateTime(DateUtils.getNowDate());
return deliveryLocationRecordMapper.updateDeliveryLocationRecord(deliveryLocationRecord);
}
/**
* 批量删除配送定位记录(车牌+单号维度)
*
* @param ids 需要删除的配送定位记录(车牌+单号维度)主键
* @return 结果
*/
@Override
public int deleteDeliveryLocationRecordByIds(Long[] ids)
{
return deliveryLocationRecordMapper.deleteDeliveryLocationRecordByIds(ids);
}
/**
* 删除配送定位记录(车牌+单号维度)信息
*
* @param id 配送定位记录(车牌+单号维度)主键
* @return 结果
*/
@Override
public int deleteDeliveryLocationRecordById(Long id)
{
return deliveryLocationRecordMapper.deleteDeliveryLocationRecordById(id);
}
@Override
public List<DeliverySimpleLocationDTO> selectTrackPoints(String orderNo, String plateNo) {
return deliveryLocationRecordMapper.selectTrackPoints(orderNo, plateNo);
}
}

View File

@@ -0,0 +1,172 @@
package com.delivery.project.document.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.delivery.common.exception.ServiceException;
import com.delivery.common.utils.DateUtils;
import com.delivery.project.document.domain.dto.CalcTotalWvDTO;
import com.delivery.project.document.domain.vo.TotalWvVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.MtdMapper;
import com.delivery.project.document.domain.Mtd;
import com.delivery.project.document.service.IMtdService;
import static com.delivery.common.utils.StringUtils.nvl;
/**
* 物料字典Service业务层处理
*
* @author delivery
* @date 2025-10-23
*/
@Service
public class MtdServiceImpl implements IMtdService
{
@Autowired
private MtdMapper mtdMapper;
/**
* 查询物料字典
*
* @param id 物料字典主键
* @return 物料字典
*/
@Override
public Mtd selectMtdById(Long id)
{
return mtdMapper.selectMtdById(id);
}
/**
* 查询物料字典列表
*
* @param mtd 物料字典
* @return 物料字典
*/
@Override
public List<Mtd> selectMtdList(Mtd mtd)
{
return mtdMapper.selectMtdList(mtd);
}
/**
* 新增物料字典
*
* @param mtd 物料字典
* @return 结果
*/
@Override
public int insertMtd(Mtd mtd)
{
mtd.setCreateTime(DateUtils.getNowDate());
return mtdMapper.insertMtd(mtd);
}
/**
* 修改物料字典
*
* @param mtd 物料字典
* @return 结果
*/
@Override
public int updateMtd(Mtd mtd)
{
mtd.setUpdateTime(DateUtils.getNowDate());
return mtdMapper.updateMtd(mtd);
}
/**
* 批量删除物料字典
*
* @param ids 需要删除的物料字典主键
* @return 结果
*/
@Override
public int deleteMtdByIds(Long[] ids)
{
return mtdMapper.deleteMtdByIds(ids);
}
/**
* 删除物料字典信息
*
* @param id 物料字典主键
* @return 结果
*/
@Override
public int deleteMtdById(Long id)
{
return mtdMapper.deleteMtdById(id);
}
// MtdServiceImpl.java 追加实现
@Override
public int importMtd(List<Mtd> list, String operator)
{
if (list == null || list.isEmpty()) {
throw new ServiceException("导入数据为空");
}
// 清洗与校验
List<Mtd> clean = new ArrayList<>(list.size());
for (Mtd m : list) {
if (m == null) continue;
if (m.getWlNo() == null || m.getWlNo().trim().isEmpty()) {
// wlNo 必填
continue;
}
m.setWlNo(m.getWlNo().trim());
if (m.getIsDelete() == null) m.setIsDelete("0");
// 写入操作人与时间
m.setUpdateBy(operator);
m.setUpdateTime(DateUtils.getNowDate());
// 如果是新增场景create_by/create_time 也一起填上ON DUPLICATE 不会覆盖 create_*
if (m.getCreateBy() == null) m.setCreateBy(operator);
if (m.getCreateTime() == null) m.setCreateTime(DateUtils.getNowDate());
clean.add(m);
}
if (clean.isEmpty()) {
throw new ServiceException("有效导入数据为空(缺少 wlNo");
}
// 批量 UPSERT依赖 mtd.wl_no 唯一索引)
return mtdMapper.batchUpsertMtd(clean);
}
@Override
public TotalWvVO calcTotalWv(CalcTotalWvDTO dto) {
if (dto == null || dto.getWlNos() == null || dto.getWlNos().isEmpty()) {
TotalWvVO empty = new TotalWvVO();
empty.setTotalWeightKg(BigDecimal.ZERO);
empty.setTotalVolumeM3(BigDecimal.ZERO);
return empty;
}
// 查询数据库中所有匹配的物料信息
List<Mtd> list = mtdMapper.selectByWlNos(dto.getWlNos());
BigDecimal totalWeight = BigDecimal.ZERO;
BigDecimal totalVolume = BigDecimal.ZERO;
for (Mtd m : list) {
BigDecimal w = m.getWeightKg() == null ? BigDecimal.ZERO : m.getWeightKg();
BigDecimal v = m.getVolumeM3() == null ? BigDecimal.ZERO : m.getVolumeM3();
totalWeight = totalWeight.add(w);
totalVolume = totalVolume.add(v);
}
TotalWvVO vo = new TotalWvVO();
vo.setTotalWeightKg(totalWeight);
vo.setTotalVolumeM3(totalVolume);
return vo;
}
}

View File

@@ -0,0 +1,96 @@
package com.delivery.project.document.service.impl;
import java.util.List;
import com.delivery.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.VehicleMapper;
import com.delivery.project.document.domain.Vehicle;
import com.delivery.project.document.service.IVehicleService;
/**
* 车辆档案Service业务层处理
*
* @author delivery
* @date 2025-10-23
*/
@Service
public class VehicleServiceImpl implements IVehicleService
{
@Autowired
private VehicleMapper vehicleMapper;
/**
* 查询车辆档案
*
* @param id 车辆档案主键
* @return 车辆档案
*/
@Override
public Vehicle selectVehicleById(Long id)
{
return vehicleMapper.selectVehicleById(id);
}
/**
* 查询车辆档案列表
*
* @param vehicle 车辆档案
* @return 车辆档案
*/
@Override
public List<Vehicle> selectVehicleList(Vehicle vehicle)
{
return vehicleMapper.selectVehicleList(vehicle);
}
/**
* 新增车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
@Override
public int insertVehicle(Vehicle vehicle)
{
vehicle.setCreateTime(DateUtils.getNowDate());
return vehicleMapper.insertVehicle(vehicle);
}
/**
* 修改车辆档案
*
* @param vehicle 车辆档案
* @return 结果
*/
@Override
public int updateVehicle(Vehicle vehicle)
{
vehicle.setUpdateTime(DateUtils.getNowDate());
return vehicleMapper.updateVehicle(vehicle);
}
/**
* 批量删除车辆档案
*
* @param ids 需要删除的车辆档案主键
* @return 结果
*/
@Override
public int deleteVehicleByIds(Long[] ids)
{
return vehicleMapper.deleteVehicleByIds(ids);
}
/**
* 删除车辆档案信息
*
* @param id 车辆档案主键
* @return 结果
*/
@Override
public int deleteVehicleById(Long id)
{
return vehicleMapper.deleteVehicleById(id);
}
}

View File

@@ -0,0 +1,177 @@
package com.delivery.project.document.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import com.delivery.common.utils.DateUtils;
import com.delivery.project.document.domain.dto.CalcSuggestFeeDTO;
import com.delivery.project.document.domain.vo.CalcSuggestFeeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.delivery.project.document.mapper.VehicleTypeMapper;
import com.delivery.project.document.domain.VehicleType;
import com.delivery.project.document.service.IVehicleTypeService;
/**
* 车型定义Service业务层处理
*
* @author delivery
* @date 2025-10-23
*/
@Service
public class VehicleTypeServiceImpl implements IVehicleTypeService
{
@Autowired
private VehicleTypeMapper vehicleTypeMapper;
/**
* 查询车型定义
*
* @param id 车型定义主键
* @return 车型定义
*/
@Override
public VehicleType selectVehicleTypeById(Long id)
{
return vehicleTypeMapper.selectVehicleTypeById(id);
}
/**
* 查询车型定义列表
*
* @param vehicleType 车型定义
* @return 车型定义
*/
@Override
public List<VehicleType> selectVehicleTypeList(VehicleType vehicleType)
{
return vehicleTypeMapper.selectVehicleTypeList(vehicleType);
}
/**
* 新增车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
@Override
public int insertVehicleType(VehicleType vehicleType)
{
vehicleType.setCreateTime(DateUtils.getNowDate());
return vehicleTypeMapper.insertVehicleType(vehicleType);
}
/**
* 修改车型定义
*
* @param vehicleType 车型定义
* @return 结果
*/
@Override
public int updateVehicleType(VehicleType vehicleType)
{
vehicleType.setUpdateTime(DateUtils.getNowDate());
return vehicleTypeMapper.updateVehicleType(vehicleType);
}
/**
* 批量删除车型定义
*
* @param ids 需要删除的车型定义主键
* @return 结果
*/
@Override
public int deleteVehicleTypeByIds(Long[] ids)
{
return vehicleTypeMapper.deleteVehicleTypeByIds(ids);
}
/**
* 删除车型定义信息
*
* @param id 车型定义主键
* @return 结果
*/
@Override
public int deleteVehicleTypeById(Long id)
{
return vehicleTypeMapper.deleteVehicleTypeById(id);
}
@Override
public CalcSuggestFeeVO calcSuggestFee(CalcSuggestFeeDTO dto)
{
// ========== 0) 入参兜底 ==========
BigDecimal w = nvl(dto.getWeightTon()); // 货物重量(吨)
BigDecimal v = nvl(dto.getVolumeM3()); // 货物体积(立方米)
BigDecimal km = nvl(dto.getDistanceKm()); // 行程公里数(公里)
// ========== 1) 候选车型:严格匹配,若无则兜底匹配 ==========
List<VehicleType> candidates = vehicleTypeMapper.selectMatchTypes(w, v);
if (candidates == null || candidates.isEmpty()) {
candidates = vehicleTypeMapper.selectFallbackTypes(w, v);
}
if (candidates == null || candidates.isEmpty()) {
throw new RuntimeException("未找到适配车型,请检查车型配置或输入参数。");
}
// 稳定排序:单价升序 -> 承重上限升序 -> 载方上限升序 -> id 升序(数据库已排序,这里再兜一层)
candidates.sort(Comparator
.comparing(VehicleType::getUnitPricePerKm, Comparator.nullsLast(BigDecimal::compareTo))
.thenComparing(VehicleType::getWeightMaxTon, Comparator.nullsLast(BigDecimal::compareTo))
.thenComparing(VehicleType::getVolumeMaxM3, Comparator.nullsLast(BigDecimal::compareTo))
.thenComparing(VehicleType::getId, Comparator.nullsLast(Long::compareTo)));
// ========== 2) 选定车型:前端指定 or 系统推荐 ==========
VehicleType chosen;
if (dto.getVehicleTypeId() != null) {
// 前端点名车型:优先在候选中找,找不到则直接按主键查
chosen = candidates.stream()
.filter(t -> dto.getVehicleTypeId().equals(t.getId()))
.findFirst()
.orElseGet(() -> vehicleTypeMapper.selectVehicleTypeById(dto.getVehicleTypeId()));
if (chosen == null) {
throw new RuntimeException("指定车型不存在或已被禁用id=" + dto.getVehicleTypeId());
}
} else {
chosen = candidates.get(0);
}
// ========== 3) 计算建议费用:单价 × 公里数保留2位 ==========
BigDecimal price = chosen.getUnitPricePerKm();
if (price == null) {
throw new RuntimeException("车型【" + chosen.getTypeName() + "】未配置每公里单价unit_price_per_km 为空)");
}
BigDecimal fee = price.multiply(km).setScale(2, RoundingMode.HALF_UP);
// ========== 4) 组装返回 ==========
CalcSuggestFeeVO vo = new CalcSuggestFeeVO();
vo.setVehicleTypeId(chosen.getId());
vo.setVehicleTypeName(chosen.getTypeName());
vo.setUnitPricePerKm(price);
vo.setSuggestFee(fee);
// 候选项
List<CalcSuggestFeeVO.VehicleTypeOptionVO> list = new ArrayList<>(candidates.size());
for (VehicleType t : candidates) {
CalcSuggestFeeVO.VehicleTypeOptionVO o = new CalcSuggestFeeVO.VehicleTypeOptionVO();
o.setId(t.getId());
o.setName(t.getTypeName());
o.setUnitPricePerKm(t.getUnitPricePerKm());
o.setWeightMinTon(t.getWeightMinTon());
o.setWeightMaxTon(t.getWeightMaxTon());
o.setVolumeMinM3(t.getVolumeMinM3());
o.setVolumeMaxM3(t.getVolumeMaxM3());
list.add(o);
}
vo.setCandidates(list);
return vo;
}
private static BigDecimal nvl(BigDecimal x) {
return x == null ? BigDecimal.ZERO : x;
}
}

View File

@@ -12,6 +12,13 @@ delivery:
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 图片上传地址
upload-path: D:/delivery
location:
min-persist-interval-ms: 15000 # 批量入库的周期(毫秒)
state-ttl-hours: 2 # ZSET 缓冲键 TTL小时
lock-seconds: 2 # 并发短锁(同车+单)秒数
# 开发环境配置
server:
@@ -109,7 +116,7 @@ gen:
allowOverwrite: false
minio:
endpoint: http://192.168.1.28:9000
endpoint: http://192.168.1.20:9000
accessKey: admin
secretKey: admin123
bucketName: delivery
@@ -117,4 +124,7 @@ minio:
upload:
base-dir: /data/upload/images
base-url: http://192.168.1.28/files
base-url: http://192.168.1.20/files
wisdom:
base-url: http://192.168.1.251:8086

View File

@@ -1,51 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.DeliveryAttachmentMapper">
<resultMap type="DeliveryAttachment" id="DeliveryAttachmentResult">
<result property="id" column="id" />
<result property="orderId" column="order_id" />
<result property="scene" column="scene" />
<result property="bizType" column="biz_type" />
<result property="url" column="url" />
<result property="status" column="status" />
<result property="sortNo" column="sort_no" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="isDelete" column="is_delete" />
<!-- 建议使用全限定名;如果你项目里配了 typeAliases也可保持短名 -->
<resultMap type="com.delivery.project.document.domain.DeliveryAttachment" id="DeliveryAttachmentResult">
<result property="id" column="id"/>
<!-- 这里改成 orderNo <-> order_no -->
<result property="orderNo" column="order_no"/>
<result property="scene" column="scene"/>
<result property="bizType" column="biz_type"/>
<result property="url" column="url"/>
<result property="status" column="status"/>
<result property="sortNo" column="sort_no"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="isDelete" column="is_delete"/>
</resultMap>
<!-- 同步把列清单里的 order_id 改为 order_no -->
<sql id="selectDeliveryAttachmentVo">
select id, order_id, scene, biz_type, url, status, sort_no, remark, create_by, create_time, update_by, update_time, is_delete from delivery_attachment
SELECT id, order_no, scene, biz_type, url, status, sort_no, remark,
create_by, create_time, update_by, update_time, is_delete
FROM delivery_attachment
</sql>
<select id="selectDeliveryAttachmentList" parameterType="DeliveryAttachment" resultMap="DeliveryAttachmentResult">
<select id="selectDeliveryAttachmentList"
parameterType="com.delivery.project.document.domain.DeliveryAttachment"
resultMap="DeliveryAttachmentResult">
<include refid="selectDeliveryAttachmentVo"/>
<where>
<if test="orderId != null "> and order_id = #{orderId}</if>
<if test="scene != null and scene != ''"> and scene = #{scene}</if>
<if test="bizType != null and bizType != ''"> and biz_type = #{bizType}</if>
<if test="url != null and url != ''"> and url = #{url}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="sortNo != null "> and sort_no = #{sortNo}</if>
<if test="isDelete != null and isDelete != ''"> and is_delete = #{isDelete}</if>
<!-- 这里用 orderNo -->
<if test="orderNo != null"> AND order_no = #{orderNo}</if>
<if test="scene != null and scene != ''"> AND scene = #{scene}</if>
<if test="bizType != null and bizType != ''"> AND biz_type = #{bizType}</if>
<if test="url != null and url != ''"> AND url = #{url}</if>
<if test="status != null and status != ''"> AND status = #{status}</if>
<if test="sortNo != null"> AND sort_no = #{sortNo}</if>
<if test="isDelete != null and isDelete != ''"> AND is_delete = #{isDelete}</if>
</where>
</select>
<select id="selectDeliveryAttachmentById" parameterType="Long" resultMap="DeliveryAttachmentResult">
<select id="selectDeliveryAttachmentById" parameterType="long" resultMap="DeliveryAttachmentResult">
<include refid="selectDeliveryAttachmentVo"/>
where id = #{id}
WHERE id = #{id}
</select>
<insert id="insertDeliveryAttachment" parameterType="DeliveryAttachment" useGeneratedKeys="true" keyProperty="id">
insert into delivery_attachment
<!-- 新增(单条): order_no -->
<insert id="insertDeliveryAttachment"
parameterType="com.delivery.project.document.domain.DeliveryAttachment"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO delivery_attachment
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="orderId != null">order_id,</if>
<if test="orderNo != null">order_no,</if>
<if test="scene != null">scene,</if>
<if test="bizType != null">biz_type,</if>
<if test="url != null">url,</if>
@@ -58,8 +69,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateTime != null">update_time,</if>
<if test="isDelete != null">is_delete,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderId != null">#{orderId},</if>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="orderNo != null">#{orderNo},</if>
<if test="scene != null">#{scene},</if>
<if test="bizType != null">#{bizType},</if>
<if test="url != null">#{url},</if>
@@ -74,10 +85,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<update id="updateDeliveryAttachment" parameterType="DeliveryAttachment">
update delivery_attachment
<!-- 批量新增(可选,便于一次性插多条) -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO delivery_attachment
(order_no, scene, biz_type, url, status, sort_no, remark,
create_by, create_time, is_delete)
VALUES
<foreach collection="list" item="it" separator=",">
(#{it.orderNo}, #{it.scene}, #{it.bizType}, #{it.url}, #{it.status},
#{it.sortNo}, #{it.remark}, #{it.createBy}, #{it.createTime}, #{it.isDelete})
</foreach>
</insert>
<!-- 更新:把 order_id 改为 order_no -->
<update id="updateDeliveryAttachment"
parameterType="com.delivery.project.document.domain.DeliveryAttachment">
UPDATE delivery_attachment
<trim prefix="SET" suffixOverrides=",">
<if test="orderId != null">order_id = #{orderId},</if>
<if test="orderNo != null">order_no = #{orderNo},</if>
<if test="scene != null">scene = #{scene},</if>
<if test="bizType != null">biz_type = #{bizType},</if>
<if test="url != null">url = #{url},</if>
@@ -90,17 +115,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="isDelete != null">is_delete = #{isDelete},</if>
</trim>
where id = #{id}
WHERE id = #{id}
</update>
<delete id="deleteDeliveryAttachmentById" parameterType="Long">
delete from delivery_attachment where id = #{id}
<delete id="deleteDeliveryAttachmentById" parameterType="long">
DELETE FROM delivery_attachment WHERE id = #{id}
</delete>
<delete id="deleteDeliveryAttachmentByIds" parameterType="String">
delete from delivery_attachment where id in
<delete id="deleteDeliveryAttachmentByIds" parameterType="string">
DELETE FROM delivery_attachment WHERE id IN
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.DeliveryLocationRecordMapper">
<!-- ✅ 统一一个 ResultMap使用全限定名避免别名不生效 -->
<resultMap id="DeliveryLocationRecordResult"
type="com.delivery.project.document.domain.DeliveryLocationRecord">
<id column="id" property="id"/>
<result column="plate_no" property="plateNo"/>
<result column="order_no" property="orderNo"/>
<result column="lng" property="lng"/>
<result column="lat" property="lat"/>
<result column="reported_at" property="reportedAt"/>
<result column="source" property="source"/>
<result column="remark" property="remark"/>
<result column="create_by" property="createBy"/>
<result column="create_time" property="createTime"/>
<result column="update_by" property="updateBy"/>
<result column="update_time" property="updateTime"/>
<result column="is_delete" property="isDelete"/>
</resultMap>
<sql id="baseSelect">
SELECT id, plate_no, order_no, lng, lat, reported_at, source, remark,
create_by, create_time, update_by, update_time, is_delete
FROM delivery_location_record
</sql>
<!-- 列表查询:默认 is_delete='0' -->
<select id="selectDeliveryLocationRecordList"
parameterType="com.delivery.project.document.domain.DeliveryLocationRecord"
resultMap="DeliveryLocationRecordResult">
<include refid="baseSelect"/>
<where>
AND is_delete = '0'
<if test="plateNo != null and plateNo != ''"> AND plate_no = #{plateNo}</if>
<if test="orderNo != null and orderNo != ''"> AND order_no = #{orderNo}</if>
<if test="lng != null"> AND lng = #{lng}</if>
<if test="lat != null"> AND lat = #{lat}</if>
<if test="reportedAt != null"> AND reported_at = #{reportedAt}</if>
<if test="source != null and source != ''"> AND source = #{source}</if>
<!-- 若你需要带 isDelete 条件可再加,但默认已固定为 0 -->
</where>
ORDER BY reported_at ASC, id ASC
</select>
<select id="selectDeliveryLocationRecordById" parameterType="long"
resultMap="DeliveryLocationRecordResult">
<include refid="baseSelect"/>
WHERE id = #{id}
</select>
<insert id="insertDeliveryLocationRecord"
parameterType="com.delivery.project.document.domain.DeliveryLocationRecord"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO delivery_location_record
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">plate_no,</if>
<if test="orderNo != null and orderNo != ''">order_no,</if>
<if test="lng != null">lng,</if>
<if test="lat != null">lat,</if>
<if test="reportedAt != null">reported_at,</if>
<if test="source != null">source,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
create_time,
is_delete
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">#{plateNo},</if>
<if test="orderNo != null and orderNo != ''">#{orderNo},</if>
<if test="lng != null">#{lng},</if>
<if test="lat != null">#{lat},</if>
<if test="reportedAt != null">#{reportedAt},</if>
<if test="source != null">#{source},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
NOW(),
'0'
</trim>
</insert>
<update id="updateDeliveryLocationRecord"
parameterType="com.delivery.project.document.domain.DeliveryLocationRecord">
UPDATE delivery_location_record
<trim prefix="SET" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">plate_no = #{plateNo},</if>
<if test="orderNo != null and orderNo != ''">order_no = #{orderNo},</if>
<if test="lng != null">lng = #{lng},</if>
<if test="lat != null">lat = #{lat},</if>
<if test="reportedAt != null">reported_at = #{reportedAt},</if>
<if test="source != null">source = #{source},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
update_time = NOW(),
<if test="isDelete != null and isDelete != ''">is_delete = #{isDelete},</if>
</trim>
WHERE id = #{id}
</update>
<delete id="deleteDeliveryLocationRecordById" parameterType="long">
DELETE FROM delivery_location_record WHERE id = #{id}
</delete>
<delete id="deleteDeliveryLocationRecordByIds">
DELETE FROM delivery_location_record WHERE id IN
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- ✅ 轨迹点查询(简化 DTOlng, lat, reportedAt -->
<select id="selectTrackPoints" resultType="com.delivery.project.document.domain.dto.DeliverySimpleLocationDTO">
SELECT
lng,
lat,
reported_at AS reportedAt
FROM delivery_location_record
WHERE is_delete = '0'
AND order_no = #{orderNo}
AND plate_no = #{plateNo}
ORDER BY reported_at ASC, id ASC
</select>
<insert id="insert"
parameterType="com.delivery.project.document.domain.DeliveryLocationRecord"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO delivery_location_record
(plate_no, order_no, lng, lat, reported_at, source, remark, create_by, create_time, is_delete)
VALUES
(#{plateNo}, #{orderNo}, #{lng}, #{lat}, #{reportedAt}, #{source}, #{remark},
#{createBy}, NOW(), '0')
</insert>
<insert id="insertBatch">
INSERT INTO delivery_location_record
(plate_no, order_no, lng, lat, reported_at, source, remark, create_by, create_time, is_delete)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.plateNo}, #{r.orderNo}, #{r.lng}, #{r.lat}, #{r.reportedAt},
#{r.source}, #{r.remark}, #{r.createBy}, NOW(), '0')
</foreach>
</insert>
</mapper>

View File

@@ -1,12 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.DeliveryOrderMapper">
<!-- ======================== 基础 ResultMap ======================== -->
<resultMap type="com.delivery.project.document.domain.DeliveryOrder" id="DeliveryOrderResult">
<!-- 用 <id> 保证连表折叠 -->
<!-- 主键 -->
<id property="id" column="id"/>
<!-- 单号 -->
<result property="orderNo" column="order_no"/>
<!-- 基础字段 -->
<result property="xmMs" column="xm_ms"/>
<result property="xmNo" column="xm_no"/>
<result property="wlNo" column="wl_no"/>
@@ -18,15 +23,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="remark" column="remark"/>
<result property="originName" column="origin_name"/>
<result property="originLng" column="origin_lng"/>
<result property="originLat" column="origin_lat"/>
<result property="originLng" column="origin_lng" jdbcType="DECIMAL"/>
<result property="originLat" column="origin_lat" jdbcType="DECIMAL"/>
<result property="destName" column="dest_name"/>
<result property="destLng" column="dest_lng"/>
<result property="destLat" column="dest_lat"/>
<result property="destLng" column="dest_lng" jdbcType="DECIMAL"/>
<result property="destLat" column="dest_lat" jdbcType="DECIMAL"/>
<result property="deliveryDate" column="delivery_date"/>
<result property="vehiclePlate" column="vehicle_plate"/>
<result property="plateNo" column="plate_no"/>
<!-- 司机 -->
<result property="driverName" column="driver_name"/>
<result property="driverPhone" column="driver_phone"/>
<result property="shipperName" column="shipper_name"/>
<result property="shipperPhone" column="shipper_phone"/>
@@ -36,6 +45,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="receiverOrgName" column="receiver_org_name"/>
<result property="deliveryTon" column="delivery_ton"/>
<!-- 货物尺寸(㎡) -->
<result property="goodsSize" column="goods_size" jdbcType="DECIMAL"/>
<result property="orderStatus" column="order_status"/>
<!-- 车型外键与名称 -->
<result property="vehicleTypeId" column="vehicle_type_id"/>
<result property="vehicleTypeName" column="vehicle_type_name"/>
<!-- 费用/里程 -->
<result property="suggestFee" column="suggest_fee"/>
<result property="actualFee" column="actual_fee"/>
<result property="tollFee" column="toll_fee"/>
<result property="totalKm" column="total_km"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
@@ -44,11 +67,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="isDelete" column="is_delete"/>
</resultMap>
<!-- 附件行(按你给的 DeliveryAttachment 字段) -->
<!-- ======================== 附件内联 ResultMap ======================== -->
<resultMap id="DeliveryAttachmentInlineResult"
type="com.delivery.project.document.domain.DeliveryAttachment">
<id property="id" column="att_id"/>
<result property="orderId" column="att_order_id"/>
<result property="orderNo" column="att_order_no"/>
<result property="scene" column="att_scene"/>
<result property="bizType" column="att_biz_type"/>
<result property="url" column="att_url"/>
@@ -62,7 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="isDelete" column="att_is_delete"/>
</resultMap>
<!-- 主实体 + 附件集合 -->
<!-- ======================== 主实体 + 附件集合 ======================== -->
<resultMap id="DeliveryOrderWithAttachResult"
type="com.delivery.project.document.domain.DeliveryOrder"
extends="DeliveryOrderResult">
@@ -70,83 +93,192 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
resultMap="DeliveryAttachmentInlineResult"/>
</resultMap>
<!-- ======================== 带附件的查询列(别名统一 dor ======================== -->
<sql id="selectDeliveryOrderVoWithAttach">
select
do.id, do.xm_ms, do.xm_no, do.wl_no, do.wl_ms, do.real_qty, do.dw, do.sap_no, do.gys_mc,
do.remark, do.origin_name, do.origin_lng, do.origin_lat,
do.dest_name, do.dest_lng, do.dest_lat,
do.delivery_date, do.vehicle_plate,
do.shipper_name, do.shipper_phone,
do.receiver_name, do.receiver_phone, do.receiver_org_name,
do.delivery_ton, do.create_by, do.create_time, do.update_by, do.update_time, do.is_delete,
dor.id, dor.order_no,
dor.xm_ms, dor.xm_no, dor.wl_no, dor.wl_ms, dor.real_qty, dor.dw, dor.sap_no, dor.gys_mc,
dor.remark, dor.origin_name, dor.origin_lng, dor.origin_lat,
dor.dest_name, dor.dest_lng, dor.dest_lat,
dor.delivery_date, dor.plate_no, dor.order_status,
dor.driver_name, dor.driver_phone,
dor.shipper_name, dor.shipper_phone,
dor.receiver_name, dor.receiver_phone, dor.receiver_org_name,
dor.delivery_ton,
dor.goods_size,
-- 车型外键与名称
dor.vehicle_type_id, dor.vehicle_type_name,
-- 费用/里程
dor.suggest_fee, dor.actual_fee, dor.toll_fee, dor.total_km,
dor.create_by, dor.create_time, dor.update_by, dor.update_time, dor.is_delete,
-- 附件列att_ 前缀)
da.id as att_id,
da.order_id as att_order_id,
da.scene as att_scene,
da.biz_type as att_biz_type,
da.url as att_url,
da.status as att_status,
da.sort_no as att_sort_no,
da.remark as att_remark,
da.create_by as att_create_by,
da.create_time as att_create_time,
da.update_by as att_update_by,
da.update_time as att_update_time,
da.is_delete as att_is_delete
da.id AS att_id,
da.order_no AS att_order_no,
da.scene AS att_scene,
da.biz_type AS att_biz_type,
da.url AS att_url,
da.status AS att_status,
da.sort_no AS att_sort_no,
da.remark AS att_remark,
da.create_by AS att_create_by,
da.create_time AS att_create_time,
da.update_by AS att_update_by,
da.update_time AS att_update_time,
da.is_delete AS att_is_delete
from delivery_order do
from delivery_order dor
left join delivery_attachment da
on da.order_id = do.id
on da.order_no = dor.order_no
and da.is_delete = '0'
</sql>
<!-- ======================== 不带附件的查询列 ======================== -->
<sql id="selectDeliveryOrderVo">
select id, 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, vehicle_plate, shipper_name, shipper_phone, receiver_name, receiver_phone, receiver_org_name, delivery_ton, create_by, create_time, update_by, update_time, is_delete from delivery_order
select id, order_no, 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,
-- 司机
driver_name, driver_phone,
shipper_name, shipper_phone, receiver_name,
receiver_phone, receiver_org_name, delivery_ton, goods_size, order_status,
-- 车型外键与名称
vehicle_type_id, vehicle_type_name,
-- 费用/里程
suggest_fee, actual_fee, toll_fee, total_km,
create_by, create_time, update_by, update_time, is_delete
from delivery_order
</sql>
<!-- ======================== 列表查询(使用 dor 别名) ======================== -->
<select id="selectDeliveryOrderList"
parameterType="com.delivery.project.document.domain.DeliveryOrder"
resultMap="DeliveryOrderWithAttachResult">
<include refid="selectDeliveryOrderVoWithAttach"/>
<where>
<if test="xmMs != null and xmMs != ''"> and do.xm_ms = #{xmMs}</if>
<if test="xmNo != null and xmNo != ''"> and do.xm_no = #{xmNo}</if>
<if test="wlNo != null and wlNo != ''"> and do.wl_no = #{wlNo}</if>
<if test="wlMs != null and wlMs != ''"> and do.wl_ms = #{wlMs}</if>
<if test="realQty != null "> and do.real_qty = #{realQty}</if>
<if test="dw != null and dw != ''"> and do.dw = #{dw}</if>
<if test="sapNo != null and sapNo != ''"> and do.sap_no = #{sapNo}</if>
<if test="gysMc != null and gysMc != ''"> and do.gys_mc = #{gysMc}</if>
<if test="originName != null and originName != ''"> and do.origin_name like concat('%', #{originName}, '%')</if>
<if test="originLng != null "> and do.origin_lng = #{originLng}</if>
<if test="originLat != null "> and do.origin_lat = #{originLat}</if>
<if test="destName != null and destName != ''"> and do.dest_name like concat('%', #{destName}, '%')</if>
<if test="destLng != null "> and do.dest_lng = #{destLng}</if>
<if test="destLat != null "> and do.dest_lat = #{destLat}</if>
<if test="deliveryDate != null "> and do.delivery_date = #{deliveryDate}</if>
<if test="vehiclePlate != null and vehiclePlate != ''"> and do.vehicle_plate = #{vehiclePlate}</if>
<if test="shipperName != null and shipperName != ''"> and do.shipper_name like concat('%', #{shipperName}, '%')</if>
<if test="shipperPhone != null and shipperPhone != ''"> and do.shipper_phone = #{shipperPhone}</if>
<if test="receiverName != null and receiverName != ''"> and do.receiver_name like concat('%', #{receiverName}, '%')</if>
<if test="receiverPhone != null and receiverPhone != ''"> and do.receiver_phone = #{receiverPhone}</if>
<if test="receiverOrgName != null and receiverOrgName != ''"> and do.receiver_org_name like concat('%', #{receiverOrgName}, '%')</if>
<if test="deliveryTon != null "> and do.delivery_ton = #{deliveryTon}</if>
<if test="isDelete != null and isDelete != ''"> and do.is_delete = #{isDelete}</if>
<choose>
<when test="isDelete != null and isDelete != ''">
and dor.is_delete = #{isDelete}
</when>
<otherwise>
and dor.is_delete = '0'
</otherwise>
</choose>
<if test="xmMs != null and xmMs != ''"> and dor.xm_ms = #{xmMs}</if>
<if test="xmNo != null and xmNo != ''"> and dor.xm_no = #{xmNo}</if>
<if test="wlNo != null and wlNo != ''"> and dor.wl_no = #{wlNo}</if>
<if test="wlMs != null and wlMs != ''"> and dor.wl_ms = #{wlMs}</if>
<if test="realQty != null "> and dor.real_qty = #{realQty}</if>
<if test="dw != null and dw != ''"> and dor.dw = #{dw}</if>
<if test="sapNo != null and sapNo != ''"> and dor.sap_no = #{sapNo}</if>
<if test="gysMc != null and gysMc != ''"> and dor.gys_mc = #{gysMc}</if>
<if test="originName != null and originName != ''"> and dor.origin_name like concat('%', #{originName}, '%')</if>
<if test="originLng != null "> and dor.origin_lng = #{originLng}</if>
<if test="originLat != null "> and dor.origin_lat = #{originLat}</if>
<if test="destName != null and destName != ''"> and dor.dest_name like concat('%', #{destName}, '%')</if>
<if test="destLng != null "> and dor.dest_lng = #{destLng}</if>
<if test="destLat != null "> and dor.dest_lat = #{destLat}</if>
<if test="deliveryDate != null "> and dor.delivery_date = #{deliveryDate}</if>
<if test="plateNo != null and plateNo != ''"> and dor.plate_no = #{plateNo}</if>
<!-- 司机筛选 -->
<if test="driverName != null and driverName != ''"> and dor.driver_name like concat('%', #{driverName}, '%')</if>
<if test="driverPhone != null and driverPhone != ''"> and dor.driver_phone = #{driverPhone}</if>
<if test="shipperName != null and shipperName != ''"> and dor.shipper_name like concat('%', #{shipperName}, '%')</if>
<if test="shipperPhone != null and shipperPhone != ''"> and dor.shipper_phone = #{shipperPhone}</if>
<if test="receiverName != null and receiverName != ''"> and dor.receiver_name like concat('%', #{receiverName}, '%')</if>
<if test="receiverPhone != null and receiverPhone != ''"> and dor.receiver_phone = #{receiverPhone}</if>
<if test="receiverOrgName != null and receiverOrgName != ''"> and dor.receiver_org_name like concat('%', #{receiverOrgName}, '%')</if>
<if test="deliveryTon != null "> and dor.delivery_ton = #{deliveryTon}</if>
<if test="goodsSize != null"> and dor.goods_size = #{goodsSize}</if>
<if test="orderStatus != null and orderStatus != ''"> and dor.order_status = #{orderStatus}</if>
<!-- 车型筛选 -->
<if test="vehicleTypeId != null"> and dor.vehicle_type_id = #{vehicleTypeId}</if>
<if test="vehicleTypeName != null and vehicleTypeName != ''">
and dor.vehicle_type_name like concat('%', #{vehicleTypeName}, '%')
</if>
<!-- 费用/里程筛选 -->
<if test="suggestFee != null"> and dor.suggest_fee = #{suggestFee}</if>
<if test="actualFee != null"> and dor.actual_fee = #{actualFee}</if>
<if test="tollFee != null"> and dor.toll_fee = #{tollFee}</if>
<if test="totalKm != null"> and dor.total_km = #{totalKm}</if>
</where>
</select>
<!-- 主键查询(别名 dor -->
<select id="selectDeliveryOrderById"
parameterType="long"
resultMap="DeliveryOrderWithAttachResult">
<include refid="selectDeliveryOrderVoWithAttach"/>
where do.id = #{id}
where dor.id = #{id}
limit 1
</select>
<!-- 列表:按单号分组 -->
<select id="selectGroupList"
parameterType="com.delivery.project.document.domain.DeliveryOrder"
resultType="com.delivery.project.document.domain.vo.DeliveryOrderGroupVO">
SELECT
dor.order_no AS orderNo,
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.shipper_name) AS shipperName,
MAX(dor.receiver_name) AS receiverName,
COUNT(1) AS itemCount,
SUM(dor.real_qty) AS totalQty,
MAX(dor.order_status) AS orderStatus
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 != ''">
AND dor.order_status = #{orderStatus}
</if>
<if test="plateNo != null and plateNo != ''">
AND dor.plate_no = #{plateNo}
</if>
<if test="deliveryDate != null">
AND DATE(dor.delivery_date) = DATE(#{deliveryDate})
</if>
</where>
GROUP BY dor.order_no
ORDER BY MAX(dor.create_time) DESC
</select>
<!-- 详情:同单号所有行 -->
<select id="selectByOrderNo" 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)
ORDER BY id
</select>
<!-- 单条查询:按单号 -->
<select id="selectDeliveryOrderByOrderNo" parameterType="string"
resultType="com.delivery.project.document.domain.DeliveryOrder">
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
</select>
<!-- ======================== 插入 ======================== -->
<!-- 单条插入 -->
<insert id="insertDeliveryOrder" parameterType="DeliveryOrder" useGeneratedKeys="true" keyProperty="id">
insert into delivery_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="orderNo != null">order_no,</if>
<if test="xmMs != null">xm_ms,</if>
<if test="xmNo != null">xm_no,</if>
<if test="wlNo != null">wl_no,</if>
@@ -163,13 +295,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="destLng != null">dest_lng,</if>
<if test="destLat != null">dest_lat,</if>
<if test="deliveryDate != null">delivery_date,</if>
<if test="vehiclePlate != null">vehicle_plate,</if>
<if test="plateNo != null">plate_no,</if>
<if test="driverName != null">driver_name,</if>
<if test="driverPhone != null">driver_phone,</if>
<if test="shipperName != null">shipper_name,</if>
<if test="shipperPhone != null">shipper_phone,</if>
<if test="receiverName != null">receiver_name,</if>
<if test="receiverPhone != null">receiver_phone,</if>
<if test="receiverOrgName != null">receiver_org_name,</if>
<if test="deliveryTon != null">delivery_ton,</if>
<if test="goodsSize != null">goods_size,</if>
<if test="orderStatus != null">order_status,</if>
<if test="vehicleTypeId != null">vehicle_type_id,</if>
<if test="vehicleTypeName != null">vehicle_type_name,</if>
<if test="suggestFee != null">suggest_fee,</if>
<if test="actualFee != null">actual_fee,</if>
<if test="tollFee != null">toll_fee,</if>
<if test="totalKm != null">total_km,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
@@ -177,6 +324,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="isDelete != null">is_delete,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="orderNo != null">#{orderNo,jdbcType=VARCHAR},</if>
<if test="xmMs != null">#{xmMs},</if>
<if test="xmNo != null">#{xmNo},</if>
<if test="wlNo != null">#{wlNo},</if>
@@ -193,13 +341,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="destLng != null">#{destLng},</if>
<if test="destLat != null">#{destLat},</if>
<if test="deliveryDate != null">#{deliveryDate},</if>
<if test="vehiclePlate != null">#{vehiclePlate},</if>
<if test="plateNo != null">#{plateNo},</if>
<if test="driverName != null">#{driverName},</if>
<if test="driverPhone != null">#{driverPhone},</if>
<if test="shipperName != null">#{shipperName},</if>
<if test="shipperPhone != null">#{shipperPhone},</if>
<if test="receiverName != null">#{receiverName},</if>
<if test="receiverPhone != null">#{receiverPhone},</if>
<if test="receiverOrgName != null">#{receiverOrgName},</if>
<if test="deliveryTon != null">#{deliveryTon},</if>
<if test="goodsSize != null">#{goodsSize},</if>
<if test="orderStatus != null">#{orderStatus},</if>
<if test="vehicleTypeId != null">#{vehicleTypeId},</if>
<if test="vehicleTypeName != null">#{vehicleTypeName},</if>
<if test="suggestFee != null">#{suggestFee},</if>
<if test="actualFee != null">#{actualFee},</if>
<if test="tollFee != null">#{tollFee},</if>
<if test="totalKm != null">#{totalKm},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
@@ -208,8 +371,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<update id="updateDeliveryOrder" parameterType="DeliveryOrder">
update delivery_order
<!-- 批量插入 -->
<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,
origin_name, origin_lng, origin_lat,
dest_name, dest_lng, dest_lat,
delivery_date, plate_no,
driver_name, driver_phone,
shipper_name, shipper_phone, receiver_name, receiver_phone, receiver_org_name,
delivery_ton, goods_size, order_status,
vehicle_type_id, vehicle_type_name,
suggest_fee, actual_fee, toll_fee, total_km,
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.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})
</foreach>
</insert>
<!-- ======================== 更新 ======================== -->
<update id="updateDeliveryOrder" parameterType="com.delivery.project.document.domain.DeliveryOrder">
UPDATE delivery_order
<trim prefix="SET" suffixOverrides=",">
<if test="xmMs != null">xm_ms = #{xmMs},</if>
<if test="xmNo != null">xm_no = #{xmNo},</if>
@@ -220,29 +413,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="sapNo != null">sap_no = #{sapNo},</if>
<if test="gysMc != null">gys_mc = #{gysMc},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="originName != null">origin_name = #{originName},</if>
<if test="originLng != null">origin_lng = #{originLng},</if>
<if test="originLat != null">origin_lat = #{originLat},</if>
<if test="destName != null">dest_name = #{destName},</if>
<if test="destLng != null">dest_lng = #{destLng},</if>
<if test="destLat != null">dest_lat = #{destLat},</if>
<if test="deliveryDate != null">delivery_date = #{deliveryDate},</if>
<if test="vehiclePlate != null">vehicle_plate = #{vehiclePlate},</if>
<if test="plateNo != null">plate_no = #{plateNo},</if>
<if test="driverName != null">driver_name = #{driverName},</if>
<if test="driverPhone != null">driver_phone = #{driverPhone},</if>
<if test="shipperName != null">shipper_name = #{shipperName},</if>
<if test="shipperPhone != null">shipper_phone = #{shipperPhone},</if>
<if test="receiverName != null">receiver_name = #{receiverName},</if>
<if test="receiverPhone != null">receiver_phone = #{receiverPhone},</if>
<if test="receiverOrgName != null">receiver_org_name = #{receiverOrgName},</if>
<if test="deliveryTon != null">delivery_ton = #{deliveryTon},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="goodsSize != null">goods_size = #{goodsSize},</if>
<if test="orderStatus != null">order_status = #{orderStatus},</if>
<if test="vehicleTypeId != null">vehicle_type_id = #{vehicleTypeId},</if>
<if test="vehicleTypeName != null">vehicle_type_name = #{vehicleTypeName},</if>
<if test="suggestFee != null">suggest_fee = #{suggestFee},</if>
<if test="actualFee != null">actual_fee = #{actualFee},</if>
<if test="tollFee != null">toll_fee = #{tollFee},</if>
<if test="totalKm != null">total_km = #{totalKm},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="isDelete != null">is_delete = #{isDelete},</if>
</trim>
where id = #{id}
WHERE order_no = #{orderNo}
</update>
<!-- ======================== 删除 ======================== -->
<delete id="deleteDeliveryOrderById" parameterType="Long">
delete from delivery_order where id = #{id}
</delete>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.MtdMapper">
<!-- 用全限定名IDE 即刻消红 -->
<resultMap id="MtdResult" type="com.delivery.project.document.domain.Mtd">
<id property="id" column="id"/>
<result property="wlNo" column="wl_no"/>
<result property="wlMs" column="wl_ms"/>
<result property="dw" column="dw"/>
<result property="weightKg" column="weight_kg"/>
<result property="volumeM3" column="volume_m3"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="isDelete" column="is_delete"/>
</resultMap>
<sql id="selectMtdVo">
SELECT id, wl_no, wl_ms, dw, weight_kg, volume_m3,
create_by, create_time, update_by, update_time, is_delete
FROM delivery_mtd
</sql>
<select id="selectMtdList"
parameterType="com.delivery.project.document.domain.Mtd"
resultMap="MtdResult">
<include refid="selectMtdVo"/>
<where>
<if test="wlNo != null and wlNo != ''"> AND wl_no = #{wlNo}</if>
<if test="wlMs != null and wlMs != ''"> AND wl_ms = #{wlMs}</if>
<if test="dw != null and dw != ''"> AND dw = #{dw}</if>
<if test="weightKg != null"> AND weight_kg = #{weightKg}</if>
<if test="volumeM3 != null"> AND volume_m3 = #{volumeM3}</if>
<if test="isDelete != null and isDelete != ''"> AND is_delete = #{isDelete}</if>
</where>
</select>
<select id="selectMtdById" parameterType="java.lang.Long" resultMap="MtdResult">
<include refid="selectMtdVo"/>
WHERE id = #{id}
</select>
<select id="selectByWlNos" parameterType="list" resultMap="MtdResult">
SELECT id, wl_no, wl_ms, dw, weight_kg, volume_m3, is_delete
FROM delivery_mtd
WHERE (is_delete = '0' OR is_delete IS NULL)
AND wl_no IN
<foreach collection="wlNos" item="wlNo" open="(" separator="," close=")">
#{wlNo}
</foreach>
</select>
<insert id="insertMtd"
parameterType="com.delivery.project.document.domain.Mtd"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO delivery_mtd
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="wlNo != null and wlNo != ''">wl_no,</if>
<if test="wlMs != null">wl_ms,</if>
<if test="dw != null">dw,</if>
<if test="weightKg != null">weight_kg,</if>
<if test="volumeM3 != null">volume_m3,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime!= null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime!= null">update_time,</if>
<if test="isDelete != null">is_delete,</if>
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="wlNo != null and wlNo != ''">#{wlNo},</if>
<if test="wlMs != null">#{wlMs},</if>
<if test="dw != null">#{dw},</if>
<if test="weightKg != null">#{weightKg},</if>
<if test="volumeM3 != null">#{volumeM3},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime!= null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime!= null">#{updateTime},</if>
<if test="isDelete != null">#{isDelete},</if>
</trim>
</insert>
<update id="updateMtd" parameterType="com.delivery.project.document.domain.Mtd">
UPDATE delivery_mtd
<trim prefix="SET" suffixOverrides=",">
<if test="wlNo != null and wlNo != ''">wl_no = #{wlNo},</if>
<if test="wlMs != null">wl_ms = #{wlMs},</if>
<if test="dw != null">dw = #{dw},</if>
<if test="weightKg != null">weight_kg = #{weightKg},</if>
<if test="volumeM3 != null">volume_m3 = #{volumeM3},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime!= null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime!= null">update_time = #{updateTime},</if>
<if test="isDelete != null">is_delete = #{isDelete},</if>
</trim>
WHERE id = #{id}
</update>
<delete id="deleteMtdById" parameterType="java.lang.Long">
DELETE FROM delivery_mtd WHERE id = #{id}
</delete>
<delete id="deleteMtdByIds" parameterType="long">
DELETE FROM delivery_mtd WHERE id IN
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<insert id="batchUpsertMtd" parameterType="java.util.List">
INSERT INTO delivery_mtd
(wl_no, wl_ms, dw, weight_kg, volume_m3, create_by, create_time, update_by, update_time, is_delete)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.wlNo}, #{item.wlMs}, #{item.dw}, #{item.weightKg}, #{item.volumeM3},
#{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.isDelete})
</foreach>
ON DUPLICATE KEY UPDATE
wl_ms = VALUES(wl_ms),
dw = VALUES(dw),
weight_kg = VALUES(weight_kg),
volume_m3 = VALUES(volume_m3),
update_by = VALUES(update_by),
update_time = VALUES(update_time),
is_delete = VALUES(is_delete)
</insert>
</mapper>

View File

@@ -1,124 +1,147 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.RkInfoMapper">
<resultMap type="RkInfo" id="RkInfoResult">
<result property="id" column="id" />
<result property="rkType" column="rk_type" />
<result property="wlType" column="wl_type" />
<result property="cangku" column="cangku" />
<result property="rkTime" column="rk_time" />
<result property="lihuoY" column="lihuo_y" />
<result property="isChuku" column="is_chuku" />
<result property="status" column="status" />
<result property="remark" column="remark" />
<result property="billNo" column="bill_no" />
<result property="isDelivery" column="is_delivery" />
<result property="xj" column="xj" />
<result property="xmNo" column="xm_no" />
<result property="xmMs" column="xm_ms" />
<result property="xmNoCk" column="xm_no_ck" />
<result property="xmMsCk" column="xm_ms_ck" />
<result property="wlNo" column="wl_no" />
<result property="wlMs" column="wl_ms" />
<result property="gysNo" column="gys_no" />
<result property="gysMc" column="gys_mc" />
<result property="jhAmt" column="jh_amt" />
<result property="htDj" column="ht_dj" />
<result property="sapNo" column="sap_no" />
<result property="xh" column="xh" />
<result property="jhQty" column="jh_qty" />
<result property="htQty" column="ht_qty" />
<result property="dw" column="dw" />
<result property="realQty" column="real_qty" />
<result property="pcode" column="pcode" />
<result property="pcodeId" column="pcode_id" />
<result property="trayCode" column="tray_code" />
<result property="entityId" column="entity_id" />
<result property="ckLihuoY" column="ck_lihuo_y" />
<result property="teamCode" column="team_code" />
<result property="ckType" column="ck_type" />
<result property="ckRemark" column="ck_remark" />
<result property="lyTime" column="ly_time" />
<result property="billNoCk" column="bill_no_ck" />
<result property="borrowTime" column="borrow_time" />
<result property="returnTime" column="return_time" />
<result property="hasMoved" column="has_moved" />
<result property="isBorrowed" column="is_borrowed" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="isDelete" column="is_delete" />
<result property="gysJhId" column="gys_jh_id" />
<result property="id" column="id"/>
<result property="rkType" column="rk_type"/>
<result property="wlType" column="wl_type"/>
<result property="cangku" column="cangku"/>
<result property="rkTime" column="rk_time"/>
<result property="lihuoY" column="lihuo_y"/>
<result property="isChuku" column="is_chuku"/>
<result property="status" column="status"/>
<result property="remark" column="remark"/>
<result property="billNo" column="bill_no"/>
<result property="isDelivery" column="is_delivery"/>
<result property="xj" column="xj"/>
<result property="xmNo" column="xm_no"/>
<result property="xmMs" column="xm_ms"/>
<result property="xmNoCk" column="xm_no_ck"/>
<result property="xmMsCk" column="xm_ms_ck"/>
<result property="wlNo" column="wl_no"/>
<result property="wlMs" column="wl_ms"/>
<result property="gysNo" column="gys_no"/>
<result property="gysMc" column="gys_mc"/>
<result property="jhAmt" column="jh_amt"/>
<result property="htDj" column="ht_dj"/>
<result property="sapNo" column="sap_no"/>
<result property="xh" column="xh"/>
<result property="jhQty" column="jh_qty"/>
<result property="htQty" column="ht_qty"/>
<result property="dw" column="dw"/>
<result property="realQty" column="real_qty"/>
<result property="pcode" column="pcode"/>
<result property="pcodeId" column="pcode_id"/>
<result property="trayCode" column="tray_code"/>
<result property="entityId" column="entity_id"/>
<result property="ckLihuoY" column="ck_lihuo_y"/>
<result property="teamCode" column="team_code"/>
<result property="ckType" column="ck_type"/>
<result property="ckRemark" column="ck_remark"/>
<result property="lyTime" column="ly_time"/>
<result property="billNoCk" column="bill_no_ck"/>
<result property="borrowTime" column="borrow_time"/>
<result property="returnTime" column="return_time"/>
<result property="hasMoved" column="has_moved"/>
<result property="isBorrowed" column="is_borrowed"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="isDelete" column="is_delete"/>
<result property="gysJhId" column="gys_jh_id"/>
<!-- 新增:来自 mtd 的两列 -->
<result property="weightKg" column="weight_kg"/>
<result property="volumeM3" column="volume_m3"/>
</resultMap>
<sql id="selectRkInfoVo">
select id, rk_type, wl_type, cangku, rk_time, lihuo_y, is_chuku, status, remark, bill_no, is_delivery, xj, xm_no, xm_ms, xm_no_ck, xm_ms_ck, wl_no, wl_ms, gys_no, gys_mc, jh_amt, ht_dj, sap_no, xh, jh_qty, ht_qty, dw, real_qty, pcode, pcode_id, tray_code, entity_id, ck_lihuo_y, team_code, ck_type, ck_remark, ly_time, bill_no_ck, borrow_time, return_time, has_moved, is_borrowed, create_by, create_time, update_by, update_time, is_delete, gys_jh_id from rk_info
<!-- 统一的字段清单(带 ri. 别名) -->
<sql id="rkInfoColumns">
ri.id, ri.rk_type, ri.wl_type, ri.cangku, ri.rk_time, ri.lihuo_y, ri.is_chuku, ri.status, ri.remark,
ri.bill_no, ri.is_delivery, ri.xj, ri.xm_no, ri.xm_ms, ri.xm_no_ck, ri.xm_ms_ck, ri.wl_no, ri.wl_ms,
ri.gys_no, ri.gys_mc, ri.jh_amt, ri.ht_dj, ri.sap_no, ri.xh, ri.jh_qty, ri.ht_qty, ri.dw, ri.real_qty,
ri.pcode, ri.pcode_id, ri.tray_code, ri.entity_id, ri.ck_lihuo_y, ri.team_code, ri.ck_type, ri.ck_remark,
ri.ly_time, ri.bill_no_ck, ri.borrow_time, ri.return_time, ri.has_moved, ri.is_borrowed,
ri.create_by, ri.create_time, ri.update_by, ri.update_time, ri.is_delete, ri.gys_jh_id
</sql>
<!-- 统一的 FROM + JOIN 片段 -->
<sql id="rkInfoFromJoinMtd">
FROM rk_info ri
LEFT JOIN delivery_mtd m
ON m.wl_no = ri.wl_no
AND (m.is_delete = '0' OR m.is_delete = 0 OR m.is_delete IS NULL)
</sql>
<!-- 列表查询(分页场景) -->
<select id="selectRkInfoList" parameterType="RkInfo" resultMap="RkInfoResult">
<include refid="selectRkInfoVo"/>
SELECT
<include refid="rkInfoColumns"/>,
m.weight_kg,
m.volume_m3
<include refid="rkInfoFromJoinMtd"/>
<where>
<if test="rkType != null and rkType != ''"> and rk_type = #{rkType}</if>
<if test="wlType != null and wlType != ''"> and wl_type = #{wlType}</if>
<if test="cangku != null and cangku != ''"> and cangku = #{cangku}</if>
<if test="rkTime != null "> and rk_time = #{rkTime}</if>
<if test="lihuoY != null and lihuoY != ''"> and lihuo_y = #{lihuoY}</if>
<if test="isChuku != null and isChuku != ''"> and is_chuku = #{isChuku}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="billNo != null and billNo != ''"> and bill_no = #{billNo}</if>
<if test="isDelivery != null and isDelivery != ''"> and is_delivery = #{isDelivery}</if>
<if test="xj != null and xj != ''"> and xj = #{xj}</if>
<if test="xmNo != null and xmNo != ''"> and xm_no = #{xmNo}</if>
<if test="xmMs != null and xmMs != ''"> and xm_ms = #{xmMs}</if>
<if test="xmNoCk != null and xmNoCk != ''"> and xm_no_ck = #{xmNoCk}</if>
<if test="xmMsCk != null and xmMsCk != ''"> and xm_ms_ck = #{xmMsCk}</if>
<if test="wlNo != null and wlNo != ''"> and wl_no = #{wlNo}</if>
<if test="wlMs != null and wlMs != ''"> and wl_ms = #{wlMs}</if>
<if test="gysNo != null and gysNo != ''"> and gys_no = #{gysNo}</if>
<if test="gysMc != null and gysMc != ''"> and gys_mc = #{gysMc}</if>
<if test="jhAmt != null "> and jh_amt = #{jhAmt}</if>
<if test="htDj != null "> and ht_dj = #{htDj}</if>
<if test="sapNo != null and sapNo != ''"> and sap_no = #{sapNo}</if>
<if test="xh != null and xh != ''"> and xh = #{xh}</if>
<if test="jhQty != null "> and jh_qty = #{jhQty}</if>
<if test="htQty != null "> and ht_qty = #{htQty}</if>
<if test="dw != null and dw != ''"> and dw = #{dw}</if>
<if test="realQty != null "> and real_qty = #{realQty}</if>
<if test="pcode != null and pcode != ''"> and pcode = #{pcode}</if>
<if test="pcodeId != null and pcodeId != ''"> and pcode_id = #{pcodeId}</if>
<if test="trayCode != null and trayCode != ''"> and tray_code = #{trayCode}</if>
<if test="entityId != null and entityId != ''"> and entity_id = #{entityId}</if>
<if test="ckLihuoY != null and ckLihuoY != ''"> and ck_lihuo_y = #{ckLihuoY}</if>
<if test="teamCode != null and teamCode != ''"> and team_code = #{teamCode}</if>
<if test="ckType != null and ckType != ''"> and ck_type = #{ckType}</if>
<if test="ckRemark != null and ckRemark != ''"> and ck_remark = #{ckRemark}</if>
<if test="lyTime != null "> and ly_time = #{lyTime}</if>
<if test="billNoCk != null and billNoCk != ''"> and bill_no_ck = #{billNoCk}</if>
<if test="borrowTime != null "> and borrow_time = #{borrowTime}</if>
<if test="returnTime != null "> and return_time = #{returnTime}</if>
<if test="hasMoved != null and hasMoved != ''"> and has_moved = #{hasMoved}</if>
<if test="isBorrowed != null and isBorrowed != ''"> and is_borrowed = #{isBorrowed}</if>
<if test="isDelete != null and isDelete != ''"> and is_delete = #{isDelete}</if>
<if test="gysJhId != null "> and gys_jh_id = #{gysJhId}</if>
(ri.is_delete = '0' OR ri.is_delete = 0 OR ri.is_delete IS NULL)
<if test="rkType != null and rkType != ''"> and ri.rk_type = #{rkType}</if>
<if test="wlType != null and wlType != ''"> and ri.wl_type = #{wlType}</if>
<if test="cangku != null and cangku != ''"> and ri.cangku = #{cangku}</if>
<if test="rkTime != null "> and ri.rk_time = #{rkTime}</if>
<if test="lihuoY != null and lihuoY != ''"> and ri.lihuo_y = #{lihuoY}</if>
<if test="isChuku != null and isChuku != ''"> and ri.is_chuku = #{isChuku}</if>
<if test="status != null and status != ''"> and ri.status = #{status}</if>
<if test="billNo != null and billNo != ''"> and ri.bill_no = #{billNo}</if>
<if test="isDelivery != null and isDelivery != ''"> and ri.is_delivery = #{isDelivery}</if>
<if test="xj != null and xj != ''"> and ri.xj = #{xj}</if>
<if test="xmNo != null and xmNo != ''"> and ri.xm_no = #{xmNo}</if>
<if test="xmMs != null and xmMs != ''"> and ri.xm_ms = #{xmMs}</if>
<if test="xmNoCk != null and xmNoCk != ''"> and ri.xm_no_ck = #{xmNoCk}</if>
<if test="xmMsCk != null and xmMsCk != ''"> and ri.xm_ms_ck = #{xmMsCk}</if>
<if test="wlNo != null and wlNo != ''"> and ri.wl_no = #{wlNo}</if>
<if test="wlMs != null and wlMs != ''"> and ri.wl_ms = #{wlMs}</if>
<if test="gysNo != null and gysNo != ''"> and ri.gys_no = #{gysNo}</if>
<if test="gysMc != null and gysMc != ''"> and ri.gys_mc = #{gysMc}</if>
<if test="jhAmt != null "> and ri.jh_amt = #{jhAmt}</if>
<if test="htDj != null "> and ri.ht_dj = #{htDj}</if>
<if test="sapNo != null and sapNo != ''"> and ri.sap_no = #{sapNo}</if>
<if test="xh != null and xh != ''"> and ri.xh = #{xh}</if>
<if test="jhQty != null "> and ri.jh_qty = #{jhQty}</if>
<if test="htQty != null "> and ri.ht_qty = #{htQty}</if>
<if test="dw != null and dw != ''"> and ri.dw = #{dw}</if>
<if test="realQty != null "> and ri.real_qty = #{realQty}</if>
<if test="pcode != null and pcode != ''"> and ri.pcode = #{pcode}</if>
<if test="pcodeId != null and pcodeId != ''"> and ri.pcode_id = #{pcodeId}</if>
<if test="trayCode != null and trayCode != ''"> and ri.tray_code = #{trayCode}</if>
<if test="entityId != null and entityId != ''"> and ri.entity_id = #{entityId}</if>
<if test="ckLihuoY != null and ckLihuoY != ''"> and ri.ck_lihuo_y = #{ckLihuoY}</if>
<if test="teamCode != null and teamCode != ''"> and ri.team_code = #{teamCode}</if>
<if test="ckType != null and ckType != ''"> and ri.ck_type = #{ckType}</if>
<if test="ckRemark != null and ckRemark != ''"> and ri.ck_remark = #{ckRemark}</if>
<if test="lyTime != null "> and ri.ly_time = #{lyTime}</if>
<if test="billNoCk != null and billNoCk != ''"> and ri.bill_no_ck = #{billNoCk}</if>
<if test="borrowTime != null "> and ri.borrow_time = #{borrowTime}</if>
<if test="returnTime != null "> and ri.return_time = #{returnTime}</if>
<if test="hasMoved != null and hasMoved != ''"> and ri.has_moved = #{hasMoved}</if>
<if test="isBorrowed != null and isBorrowed != ''"> and ri.is_borrowed = #{isBorrowed}</if>
<if test="isDelete != null and isDelete != ''"> and ri.is_delete = #{isDelete}</if>
<if test="gysJhId != null "> and ri.gys_jh_id = #{gysJhId}</if>
</where>
</select>
<!-- 按 ID 查询 -->
<select id="selectRkInfoById" parameterType="Long" resultMap="RkInfoResult">
<include refid="selectRkInfoVo"/>
where id = #{id}
SELECT
<include refid="rkInfoColumns"/>,
m.weight_kg,
m.volume_m3
<include refid="rkInfoFromJoinMtd"/>
WHERE ri.id = #{id}
</select>
<!--
按单据分组bill_no列表
复用 <sql id="selectRkInfoVo"> 作为子查询,外层分组聚合
返回字段bill_no、bill_no_ck + 你指定的通用字段rk_type、wl_type、cangku、rk_time、lihuo_y、is_chuku、xj、
xm_no、xm_ms、xm_no_ck、xm_ms_ck、wl_no、wl_ms、gys_no、sap_no
-->
<!-- RkInfoMapper.xml -->
<!-- 按单据分组bill_no列表复用同一个 SELECT 作为子查询,再做聚合 -->
<select id="selectGroupedByBill" resultMap="RkInfoResult">
SELECT
a.id,
@@ -171,110 +194,100 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
MAX(t.ly_time) AS ly_time,
MIN(t.ck_lihuo_y) AS ck_lihuo_y
FROM (
<include refid="selectRkInfoVo"/>
) t
SELECT
<include refid="rkInfoColumns"/>,
m.weight_kg,
m.volume_m3
<include refid="rkInfoFromJoinMtd"/>
<where>
<!-- 仅用 RkInfo 里真实存在的字段做筛选 -->
<!-- is_chuku单值 -->
(ri.is_delete = '0' OR ri.is_delete = 0 OR ri.is_delete IS NULL)
<!-- 这里参数名按你的 Service 传入保持:假设是 q -->
<if test="q.isChuku != null and q.isChuku != ''">
AND t.is_chuku = #{q.isChuku}
and ri.is_chuku = #{q.isChuku}
</if>
<!-- 维度筛选 -->
<if test="q.rkType != null and q.rkType != ''">
AND t.rk_type LIKE concat('%', #{q.rkType}, '%')
and ri.rk_type LIKE concat('%', #{q.rkType}, '%')
</if>
<if test="q.wlType != null and q.wlType != ''">
AND t.wl_type LIKE concat('%', #{q.wlType}, '%')
and ri.wl_type LIKE concat('%', #{q.wlType}, '%')
</if>
<if test="q.cangku != null and q.cangku != ''">
AND t.cangku LIKE concat('%', #{q.cangku}, '%')
and ri.cangku LIKE concat('%', #{q.cangku}, '%')
</if>
<!-- 其它等值/模糊 -->
<if test="q.lihuoY != null and q.lihuoY != ''">
AND t.lihuo_y LIKE concat('%', #{q.lihuoY}, '%')
and ri.lihuo_y LIKE concat('%', #{q.lihuoY}, '%')
</if>
<if test="q.xj != null and q.xj != ''">
AND t.xj LIKE concat('%', #{q.xj}, '%')
and ri.xj LIKE concat('%', #{q.xj}, '%')
</if>
<if test="q.billNo != null and q.billNo != ''">
AND t.bill_no LIKE concat('%', #{q.billNo}, '%')
and ri.bill_no LIKE concat('%', #{q.billNo}, '%')
</if>
<if test="q.billNoCk != null and q.billNoCk != ''">
AND t.bill_no_ck LIKE concat('%', #{q.billNoCk}, '%')
and ri.bill_no_ck LIKE concat('%', #{q.billNoCk}, '%')
</if>
<if test="q.xmNo != null and q.xmNo != ''">
AND t.xm_no LIKE concat('%', #{q.xmNo}, '%')
and ri.xm_no LIKE concat('%', #{q.xmNo}, '%')
</if>
<if test="q.xmMs != null and q.xmMs != ''">
AND t.xm_ms LIKE concat('%', #{q.xmMs}, '%')
and ri.xm_ms LIKE concat('%', #{q.xmMs}, '%')
</if>
<if test="q.wlNo != null and q.wlNo != ''">
AND t.wl_no LIKE concat('%', #{q.wlNo}, '%')
and ri.wl_no LIKE concat('%', #{q.wlNo}, '%')
</if>
<if test="q.wlMs != null and q.wlMs != ''">
AND t.wl_ms LIKE concat('%', #{q.wlMs}, '%')
and ri.wl_ms LIKE concat('%', #{q.wlMs}, '%')
</if>
<if test="q.gysNo != null and q.gysNo != ''">
AND t.gys_no LIKE concat('%', #{q.gysNo}, '%')
and ri.gys_no LIKE concat('%', #{q.gysNo}, '%')
</if>
<if test="q.gysMc != null and q.gysMc != ''">
AND t.gys_mc LIKE concat('%', #{q.gysMc}, '%')
and ri.gys_mc LIKE concat('%', #{q.gysMc}, '%')
</if>
<if test="q.jhAmt != null"> AND t.jh_amt = #{q.jhAmt} </if>
<if test="q.htDj != null"> AND t.ht_dj = #{q.htDj} </if>
<if test="q.jhAmt != null"> and ri.jh_amt = #{q.jhAmt} </if>
<if test="q.htDj != null"> and ri.ht_dj = #{q.htDj} </if>
<if test="q.sapNo != null and q.sapNo != ''">
AND t.sap_no LIKE concat('%', #{q.sapNo}, '%')
and ri.sap_no LIKE concat('%', #{q.sapNo}, '%')
</if>
<if test="q.xh != null and q.xh != ''">
AND t.xh LIKE concat('%', #{q.xh}, '%')
and ri.xh LIKE concat('%', #{q.xh}, '%')
</if>
<if test="q.jhQty != null"> AND t.jh_qty = #{q.jhQty} </if>
<if test="q.htQty != null"> AND t.ht_qty = #{q.htQty} </if>
<if test="q.jhQty != null"> and ri.jh_qty = #{q.jhQty} </if>
<if test="q.htQty != null"> and ri.ht_qty = #{q.htQty} </if>
<if test="q.dw != null and q.dw != ''">
AND t.dw LIKE concat('%', #{q.dw}, '%')
and ri.dw LIKE concat('%', #{q.dw}, '%')
</if>
<if test="q.realQty != null"> AND t.real_qty = #{q.realQty} </if>
<if test="q.realQty != null"> and ri.real_qty = #{q.realQty} </if>
<if test="q.pcode != null and q.pcode != ''">
AND t.pcode LIKE concat('%', #{q.pcode}, '%')
and ri.pcode LIKE concat('%', #{q.pcode}, '%')
</if>
<if test="q.lyTime != null"> AND t.ly_time = #{q.lyTime} </if>
<if test="q.returnTime != null"> AND t.return_time = #{q.returnTime} </if>
<if test="q.lyTime != null"> and ri.ly_time = #{q.lyTime} </if>
<if test="q.returnTime != null"> and ri.return_time = #{q.returnTime} </if>
<if test="q.trayCode != null and q.trayCode != ''">
AND t.tray_code LIKE concat('%', #{q.trayCode}, '%')
and ri.tray_code LIKE concat('%', #{q.trayCode}, '%')
</if>
<if test="q.entityId != null and q.entityId != ''">
AND t.entity_id LIKE concat('%', #{q.entityId}, '%')
and ri.entity_id LIKE concat('%', #{q.entityId}, '%')
</if>
<if test="q.ckType != null and q.ckType != ''">
AND t.ck_type LIKE concat('%', #{q.ckType}, '%')
and ri.ck_type LIKE concat('%', #{q.ckType}, '%')
</if>
<!-- 若查询“已出库”,则要求已有出库单号 -->
<if test="q.isChuku != null and q.isChuku == '1'">
AND t.bill_no_ck IS NOT NULL
</if>
<!-- 删除标记,默认为 0 -->
<choose>
<when test="q.isDelete != null and q.isDelete != ''">
AND t.is_delete = #{q.isDelete}
and ri.is_delete = #{q.isDelete}
</when>
<otherwise>
AND t.is_delete = 0
and (ri.is_delete = '0' OR ri.is_delete = 0 OR ri.is_delete IS NULL)
</otherwise>
</choose>
<!-- 只查需要配送 -->
<if test="q.isDelivery != null and q.isDelivery != ''">
AND t.is_delivery = #{q.isDelivery}
and ri.is_delivery = #{q.isDelivery}
</if>
<if test="q.isChuku != null and q.isChuku == '1'">
and ri.bill_no_ck IS NOT NULL
</if>
</where>
) t
GROUP BY t.bill_no
) a
LEFT JOIN stock_in_type si ON a.rk_type = si.type_code
@@ -283,7 +296,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ORDER BY a.rk_time DESC
</select>
<!-- 插入 -->
<insert id="insertRkInfo" parameterType="RkInfo" useGeneratedKeys="true" keyProperty="id">
insert into rk_info
<trim prefix="(" suffix=")" suffixOverrides=",">
@@ -386,6 +399,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
</insert>
<!-- 更新:照旧,不涉及 mtd -->
<update id="updateRkInfo" parameterType="RkInfo">
update rk_info
<trim prefix="SET" suffixOverrides=",">
@@ -427,7 +441,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="lyTime != null">ly_time = #{lyTime},</if>
<if test="billNoCk != null">bill_no_ck = #{billNoCk},</if>
<if test="borrowTime != null">borrow_time = #{borrowTime},</if>
<if test="returnTime != null">return_time = #{returnTime},</if>
<if test="returnTime != null">return_time = #{ReturnTime},</if>
<if test="hasMoved != null">has_moved = #{hasMoved},</if>
<if test="isBorrowed != null">is_borrowed = #{isBorrowed},</if>
<if test="createBy != null">create_by = #{createBy},</if>
@@ -445,7 +459,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<delete id="deleteRkInfoByIds" parameterType="String">
delete from rk_info where id in
delete from rk_info
where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.VehicleMapper">
<resultMap type="Vehicle" id="VehicleResult">
<result property="id" column="id" />
<result property="plateNo" column="plate_no" />
<result property="vin" column="vin" />
<result property="vehicleTypeId" column="vehicle_type_id" />
<result property="declaredWeightTon" column="declared_weight_ton" />
<result property="declaredVolumeM3" column="declared_volume_m3" />
<result property="driverName" column="driver_name" />
<result property="driverPhone" column="driver_phone" />
<result property="driverIdNo" column="driver_id_no" />
<result property="driverLicenseNo" column="driver_license_no" />
<result property="driverLicenseLevel" column="driver_license_level" />
<result property="inspectionExpireDate" column="inspection_expire_date" />
<result property="insuranceExpireDate" column="insurance_expire_date" />
<result property="status" column="status" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="isDelete" column="is_delete" />
</resultMap>
<sql id="selectVehicleVo">
select id, plate_no, vin, vehicle_type_id, declared_weight_ton, declared_volume_m3, driver_name, driver_phone, driver_id_no, driver_license_no, driver_license_level, inspection_expire_date, insurance_expire_date, status, remark, create_by, create_time, update_by, update_time, is_delete from vehicle
</sql>
<select id="selectVehicleList" parameterType="Vehicle" resultMap="VehicleResult">
<include refid="selectVehicleVo"/>
<where>
<if test="plateNo != null and plateNo != ''"> and plate_no = #{plateNo}</if>
<if test="vin != null and vin != ''"> and vin = #{vin}</if>
<if test="vehicleTypeId != null "> and vehicle_type_id = #{vehicleTypeId}</if>
<if test="declaredWeightTon != null "> and declared_weight_ton = #{declaredWeightTon}</if>
<if test="declaredVolumeM3 != null "> and declared_volume_m3 = #{declaredVolumeM3}</if>
<if test="driverName != null and driverName != ''"> and driver_name like concat('%', #{driverName}, '%')</if>
<if test="driverPhone != null and driverPhone != ''"> and driver_phone = #{driverPhone}</if>
<if test="driverIdNo != null and driverIdNo != ''"> and driver_id_no = #{driverIdNo}</if>
<if test="driverLicenseNo != null and driverLicenseNo != ''"> and driver_license_no = #{driverLicenseNo}</if>
<if test="driverLicenseLevel != null and driverLicenseLevel != ''"> and driver_license_level = #{driverLicenseLevel}</if>
<if test="inspectionExpireDate != null "> and inspection_expire_date = #{inspectionExpireDate}</if>
<if test="insuranceExpireDate != null "> and insurance_expire_date = #{insuranceExpireDate}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="isDelete != null and isDelete != ''"> and is_delete = #{isDelete}</if>
</where>
</select>
<select id="selectVehicleById" parameterType="Long" resultMap="VehicleResult">
<include refid="selectVehicleVo"/>
where id = #{id}
</select>
<insert id="insertVehicle" parameterType="Vehicle" useGeneratedKeys="true" keyProperty="id">
insert into vehicle
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">plate_no,</if>
<if test="vin != null">vin,</if>
<if test="vehicleTypeId != null">vehicle_type_id,</if>
<if test="declaredWeightTon != null">declared_weight_ton,</if>
<if test="declaredVolumeM3 != null">declared_volume_m3,</if>
<if test="driverName != null">driver_name,</if>
<if test="driverPhone != null">driver_phone,</if>
<if test="driverIdNo != null">driver_id_no,</if>
<if test="driverLicenseNo != null">driver_license_no,</if>
<if test="driverLicenseLevel != null">driver_license_level,</if>
<if test="inspectionExpireDate != null">inspection_expire_date,</if>
<if test="insuranceExpireDate != null">insurance_expire_date,</if>
<if test="status != null and status != ''">status,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="isDelete != null">is_delete,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">#{plateNo},</if>
<if test="vin != null">#{vin},</if>
<if test="vehicleTypeId != null">#{vehicleTypeId},</if>
<if test="declaredWeightTon != null">#{declaredWeightTon},</if>
<if test="declaredVolumeM3 != null">#{declaredVolumeM3},</if>
<if test="driverName != null">#{driverName},</if>
<if test="driverPhone != null">#{driverPhone},</if>
<if test="driverIdNo != null">#{driverIdNo},</if>
<if test="driverLicenseNo != null">#{driverLicenseNo},</if>
<if test="driverLicenseLevel != null">#{driverLicenseLevel},</if>
<if test="inspectionExpireDate != null">#{inspectionExpireDate},</if>
<if test="insuranceExpireDate != null">#{insuranceExpireDate},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="isDelete != null">#{isDelete},</if>
</trim>
</insert>
<update id="updateVehicle" parameterType="Vehicle">
update vehicle
<trim prefix="SET" suffixOverrides=",">
<if test="plateNo != null and plateNo != ''">plate_no = #{plateNo},</if>
<if test="vin != null">vin = #{vin},</if>
<if test="vehicleTypeId != null">vehicle_type_id = #{vehicleTypeId},</if>
<if test="declaredWeightTon != null">declared_weight_ton = #{declaredWeightTon},</if>
<if test="declaredVolumeM3 != null">declared_volume_m3 = #{declaredVolumeM3},</if>
<if test="driverName != null">driver_name = #{driverName},</if>
<if test="driverPhone != null">driver_phone = #{driverPhone},</if>
<if test="driverIdNo != null">driver_id_no = #{driverIdNo},</if>
<if test="driverLicenseNo != null">driver_license_no = #{driverLicenseNo},</if>
<if test="driverLicenseLevel != null">driver_license_level = #{driverLicenseLevel},</if>
<if test="inspectionExpireDate != null">inspection_expire_date = #{inspectionExpireDate},</if>
<if test="insuranceExpireDate != null">insurance_expire_date = #{insuranceExpireDate},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="isDelete != null">is_delete = #{isDelete},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteVehicleById" parameterType="Long">
delete from vehicle where id = #{id}
</delete>
<delete id="deleteVehicleByIds" parameterType="String">
delete from vehicle where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.delivery.project.document.mapper.VehicleTypeMapper">
<resultMap id="VehicleTypeResult" type="com.delivery.project.document.domain.VehicleType">
<id property="id" column="id"/>
<result property="typeCode" column="type_code"/>
<result property="typeName" column="type_name"/>
<result property="weightMinTon" column="weight_min_ton"/>
<result property="weightMaxTon" column="weight_max_ton"/>
<result property="volumeMinM3" column="volume_min_m3"/>
<result property="volumeMaxM3" column="volume_max_m3"/>
<result property="unitPricePerKm" column="unit_price_per_km"/>
<result property="status" column="status"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="isDelete" column="is_delete"/>
</resultMap>
<sql id="selectVehicleTypeVo">
select
id, type_code, type_name,
weight_min_ton, weight_max_ton,
volume_min_m3, volume_max_m3,
unit_price_per_km, status, remark,
create_by, create_time, update_by, update_time, is_delete
from vehicle_type
</sql>
<select id="selectVehicleTypeList" parameterType="VehicleType" resultMap="VehicleTypeResult">
<include refid="selectVehicleTypeVo"/>
<where>
<if test="typeCode != null and typeCode != ''"> and type_code = #{typeCode}</if>
<if test="typeName != null and typeName != ''"> and type_name like concat('%', #{typeName}, '%')</if>
<if test="weightMinTon != null "> and weight_min_ton = #{weightMinTon}</if>
<if test="weightMaxTon != null "> and weight_max_ton = #{weightMaxTon}</if>
<if test="volumeMinM3 != null "> and volume_min_m3 = #{volumeMinM3}</if>
<if test="volumeMaxM3 != null "> and volume_max_m3 = #{volumeMaxM3}</if>
<if test="unitPricePerKm != null "> and unit_price_per_km = #{unitPricePerKm}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="isDelete != null and isDelete != ''"> and is_delete = #{isDelete}</if>
</where>
</select>
<select id="selectVehicleTypeById" parameterType="Long" resultMap="VehicleTypeResult">
<include refid="selectVehicleTypeVo"/>
where id = #{id}
</select>
<insert id="insertVehicleType" parameterType="VehicleType" useGeneratedKeys="true" keyProperty="id">
insert into vehicle_type
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="typeCode != null">type_code,</if>
<if test="typeName != null">type_name,</if>
<if test="weightMinTon != null">weight_min_ton,</if>
<if test="weightMaxTon != null">weight_max_ton,</if>
<if test="volumeMinM3 != null">volume_min_m3,</if>
<if test="volumeMaxM3 != null">volume_max_m3,</if>
<if test="unitPricePerKm != null">unit_price_per_km,</if>
<if test="status != null">status,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="isDelete != null">is_delete,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="typeCode != null">#{typeCode},</if>
<if test="typeName != null">#{typeName},</if>
<if test="weightMinTon != null">#{weightMinTon},</if>
<if test="weightMaxTon != null">#{weightMaxTon},</if>
<if test="volumeMinM3 != null">#{volumeMinM3},</if>
<if test="volumeMaxM3 != null">#{volumeMaxM3},</if>
<if test="unitPricePerKm != null">#{unitPricePerKm},</if>
<if test="status != null">#{status},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="isDelete != null">#{isDelete},</if>
</trim>
</insert>
<update id="updateVehicleType" parameterType="VehicleType">
update vehicle_type
<trim prefix="SET" suffixOverrides=",">
<if test="typeCode != null">type_code = #{typeCode},</if>
<if test="typeName != null">type_name = #{typeName},</if>
<if test="weightMinTon != null">weight_min_ton = #{weightMinTon},</if>
<if test="weightMaxTon != null">weight_max_ton = #{weightMaxTon},</if>
<if test="volumeMinM3 != null">volume_min_m3 = #{volumeMinM3},</if>
<if test="volumeMaxM3 != null">volume_max_m3 = #{volumeMaxM3},</if>
<if test="unitPricePerKm != null">unit_price_per_km = #{unitPricePerKm},</if>
<if test="status != null">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="isDelete != null">is_delete = #{isDelete},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteVehicleTypeById" parameterType="Long">
delete from vehicle_type where id = #{id}
</delete>
<delete id="deleteVehicleTypeByIds" parameterType="String">
delete from vehicle_type where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!-- 严格匹配:改为使用 resultMap同时保留 XML 转义和 status='0'(启用) -->
<select id="selectMatchTypes" resultMap="VehicleTypeResult">
<include refid="selectVehicleTypeVo"/>
where is_delete = '0'
and status = '0'
and weight_min_ton &lt;= #{w} and weight_max_ton &gt;= #{w}
and volume_min_m3 &lt;= #{v} and volume_max_m3 &gt;= #{v}
order by unit_price_per_km asc, weight_max_ton asc, volume_max_m3 asc, id asc
</select>
<!-- 兜底匹配:同样用 resultMap -->
<select id="selectFallbackTypes" resultMap="VehicleTypeResult">
<include refid="selectVehicleTypeVo"/>
where is_delete = '0'
and status = '0'
and weight_max_ton &gt;= #{w}
and volume_max_m3 &gt;= #{v}
order by unit_price_per_km asc, weight_max_ton asc, volume_max_m3 asc, id asc
</select>
</mapper>