1、修复基础配置

2、修复业务模块
This commit is contained in:
2026-09-03 03:30:57 +08:00
parent 25fee0656d
commit 88b04b7dac
37 changed files with 615 additions and 103 deletions
@@ -60,9 +60,9 @@ public class RailwayStation extends BaseEntity {
@Schema(description = "TMIS国标编码")
private String tmisCode;
/**
* 电报码
* 电报
*/
@Schema(description = "电报码")
@Schema(description = "电报")
private String telegraphCode;
/**
* 车站名称
@@ -34,6 +34,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 行政区划表实体类
@@ -134,6 +135,40 @@ public class Region implements Serializable {
*/
@Schema(description = "备注")
private String remark;
/**
* 数据来源
*/
@Schema(description = "数据来源")
private String dataSource;
/**
* 创建人
*/
@TableField("create_user")
@Schema(description = "创建人")
private Long createUser;
/**
* 创建时间
*/
@TableField("create_time")
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新人
*/
@TableField("update_user")
@Schema(description = "更新人")
private Long updateUser;
/**
* 更新时间
*/
@TableField("update_time")
@Schema(description = "更新时间")
private Date updateTime;
/**
* 状态:1启用,2停用
*/
@Schema(description = "状态")
private Integer status;
/**
* 原区划编号
@@ -112,6 +112,13 @@ public class ContractManage extends TenantEntity {
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
private Integer copyCount;
@Schema(description = "结算币种")
private String settlementCurrency;
@Schema(description = "开票周期(天)")
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
private Integer invoiceCycle;
@Schema(description = "回款账期(天)")
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
private Integer paymentDays;
@@ -59,6 +59,11 @@ public class TransportPlanVO extends TransportPlan {
@TableField(exist = false)
@Schema(description = "更新人姓名")
private String updateUserName;
@TableField(exist = false)
@Schema(description = "合同编号")
private String contractNo;
@TableField(exist = false)
@Schema(description = "业务状态名称")
private String businessStatusName;
@@ -46,6 +46,7 @@ import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.excel.FeeItemExcel;
import org.springblade.system.excel.FeeItemExportExcel;
import org.springblade.system.excel.FeeItemImportFailureExcel;
import org.springblade.system.pojo.entity.FeeItem;
import org.springblade.system.pojo.vo.FeeItemVO;
@@ -155,8 +156,8 @@ public class FeeItemController extends BladeController {
public void exportFeeItem(FeeItemVO feeItem,
@RequestParam(required = false) String ids,
HttpServletResponse response) {
List<FeeItemExcel> list = feeItemService.exportFeeItem(buildExportQuery(feeItem, ids));
ExcelUtil.export(response, "费用项" + DateUtil.time(), "费用项表", list, FeeItemExcel.class);
List<FeeItemExportExcel> list = feeItemService.exportFeeItem(buildExportQuery(feeItem, ids));
ExcelUtil.export(response, "费用项" + DateUtil.time(), "费用项表", list, FeeItemExportExcel.class);
}
/**
@@ -48,6 +48,7 @@ import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.system.pojo.entity.Region;
import org.springblade.system.excel.RegionExcel;
import org.springblade.system.excel.RegionExportExcel;
import org.springblade.system.excel.RegionImporter;
import org.springblade.system.service.IRegionService;
import org.springblade.system.pojo.vo.RegionVO;
@@ -206,8 +207,8 @@ public class RegionController extends BladeController {
@Operation(summary = "导出行政区划", description = "传入user")
public void exportRegion(@Parameter(hidden = true) @RequestParam Map<String, Object> region, HttpServletResponse response) {
QueryWrapper<Region> queryWrapper = Condition.getQueryWrapper(region, Region.class);
List<RegionExcel> list = regionService.exportRegion(queryWrapper);
ExcelUtil.export(response, "行政区划数据" + DateUtil.time(), "行政区划数据表", list, RegionExcel.class);
List<RegionExportExcel> list = regionService.exportRegion(queryWrapper);
ExcelUtil.export(response, "行政区划数据" + DateUtil.time(), "行政区划数据表", list, RegionExportExcel.class);
}
/**
@@ -27,6 +27,7 @@ package org.springblade.system.excel;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import cn.idev.excel.annotation.format.NumberFormat;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
@@ -36,6 +37,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 空港机场主数据导出 Excel
@@ -100,6 +102,17 @@ public class AirportMasterExportExcel implements Serializable {
@ExcelProperty("备注")
private String remark;
@ExcelProperty("更新人")
private String updateUserName;
@ExcelProperty("更新时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ExcelProperty("创建时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ExcelIgnore
private String errorMessage;
}
@@ -0,0 +1,62 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* This file is part of the TMS extension for BladeX.
*/
package org.springblade.system.excel;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
import cn.idev.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 费用项导出 Excel。
*
* <p>该模型仅用于导出,避免导出字段变更影响导入模板。</p>
*/
@Data
@ColumnWidth(22)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class FeeItemExportExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty("费用类型")
private String feeCategory;
@ExcelProperty("费用项代码")
private String englishName;
@ExcelProperty("费用项")
private String name;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("组织")
private String createDeptName;
@ExcelProperty("更新人")
private String updateUserName;
@ExcelProperty("更新时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ExcelProperty("创建时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ExcelProperty("状态")
private String statusName;
}
@@ -2,6 +2,7 @@ package org.springblade.system.excel;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import cn.idev.excel.annotation.format.NumberFormat;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
@@ -11,6 +12,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 港口码头主数据导出 Excel
@@ -75,6 +77,17 @@ public class PortTerminalExportExcel implements Serializable {
@ExcelProperty("备注")
private String remark;
@ExcelProperty("更新人")
private String updateUserName;
@ExcelProperty("更新时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ExcelProperty("创建时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ExcelIgnore
private String errorMessage;
}
@@ -54,7 +54,7 @@ public class RailwayStationExcel implements Serializable {
@ExcelProperty("TMIS国标编码*")
private String tmisCode;
@ExcelProperty("电报码*")
@ExcelProperty("电报码*")
private String telegraphCode;
@ExcelProperty("车站名称*")
@@ -56,7 +56,7 @@ public class RailwayStationExportExcel implements Serializable {
@ExcelProperty("TMIS国标编码*")
private String tmisCode;
@ExcelProperty("电报码*")
@ExcelProperty("电报码*")
private String telegraphCode;
@ExcelProperty("车站名称*")
@@ -48,54 +48,18 @@ public class RegionExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty("划编号")
@ExcelProperty("域编码")
private String code;
@ExcelProperty("父区划编号")
private String parentCode;
@ExcelProperty("祖区划编号")
private String ancestors;
@ExcelProperty("区划名称")
@ExcelProperty("区域名称")
private String name;
@ExcelProperty("省级区划编号")
private String provinceCode;
@ExcelProperty("父级编码")
private String parentCode;
@ExcelProperty("省级名称")
private String provinceName;
@ExcelProperty("市级区划编号")
private String cityCode;
@ExcelProperty("市级名称")
private String cityName;
@ExcelProperty("区级区划编号")
private String districtCode;
@ExcelProperty("区级名称")
private String districtName;
@ExcelProperty("镇级区划编号")
private String townCode;
@ExcelProperty("镇级名称")
private String townName;
@ExcelProperty("村级区划编号")
private String villageCode;
@ExcelProperty("村级名称")
private String villageName;
@ExcelProperty("层级")
@ExcelProperty("区域层级")
private Integer regionLevel;
@ExcelProperty("排序")
private Integer sort;
@ExcelProperty("备注")
private String remark;
@@ -0,0 +1,70 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* This file is part of the TMS extension for BladeX.
*/
package org.springblade.system.excel;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
import cn.idev.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 行政区划数据导出 Excel。
*
* <p>该模型仅用于导出,避免导入模板字段变更影响已有导入文件。</p>
*/
@Data
@ColumnWidth(18)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class RegionExportExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty("序号")
private Integer serialNumber;
@ExcelProperty("区域编码")
private String code;
@ExcelProperty("区域名称")
private String name;
@ExcelProperty("父级编码")
private String parentCode;
@ExcelProperty("父级名称")
private String parentName;
@ExcelProperty("区域层级")
private Integer regionLevel;
@ExcelProperty("状态")
private String statusName;
@ExcelProperty("数据来源")
private String dataSource;
@ExcelProperty("更新人")
private String updateUserName;
@ExcelProperty("更新时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ExcelProperty("创建时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private Date createTime;
}
@@ -30,6 +30,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springblade.system.pojo.entity.Region;
import org.springblade.system.excel.RegionExcel;
import org.springblade.system.excel.RegionExportExcel;
import org.springblade.system.pojo.vo.RegionVO;
import java.util.List;
@@ -66,6 +67,6 @@ public interface RegionMapper extends BaseMapper<Region> {
* @param queryWrapper
* @return
*/
List<RegionExcel> exportRegion(@Param("ew") Wrapper<Region> queryWrapper);
List<RegionExportExcel> exportRegion(@Param("ew") Wrapper<Region> queryWrapper);
}
@@ -18,7 +18,7 @@
<result column="town_name" property="townName"/>
<result column="village_code" property="villageCode"/>
<result column="village_name" property="villageName"/>
<result column="level" property="regionLevel"/>
<result column="region_level" property="regionLevel"/>
<result column="sort" property="sort"/>
<result column="remark" property="remark"/>
</resultMap>
@@ -38,7 +38,7 @@
<result column="town_name" property="townName"/>
<result column="village_code" property="villageCode"/>
<result column="village_name" property="villageName"/>
<result column="level" property="regionLevel"/>
<result column="region_level" property="regionLevel"/>
<result column="sort" property="sort"/>
<result column="remark" property="remark"/>
<result column="id" property="id"/>
@@ -72,7 +72,13 @@
and region.name like concat(concat('%', #{param2.name}),'%')
</if>
<if test="param2.regionLevel!=null">
and region.level = #{param2.regionLevel}
and region.region_level = #{param2.regionLevel}
</if>
<if test="param2.dataSource!=null and param2.dataSource!=''">
and region.data_source = #{param2.dataSource}
</if>
<if test="param2.status!=null and param2.status!=''">
and region.status = #{param2.status}
</if>
</where>
ORDER BY region.sort ASC, region.code ASC
@@ -92,21 +98,51 @@
<if test="param1!=null">
and region.parent_code = #{param1}
</if>
<if test="param2.code!=null and param2.code!=''">
and region.code like concat(concat('%', #{param2.code}),'%')
</if>
<if test="param2.name!=null and param2.name!=''">
and region.name like concat(concat('%', #{param2.name}),'%')
</if>
<if test="param2.regionLevel!=null">
and region.level = #{param2.regionLevel}
<if test="param2 != null and ((param2.code!=null and param2.code!='') or (param2.name!=null and param2.name!='') or param2.regionLevel!=null or (param2.dataSource!=null and param2.dataSource!='') or param2.status!=null)">
and exists (
select 1
from blade_region matched
where (matched.code = region.code or find_in_set(region.code, matched.ancestors) > 0)
<if test="param2.code!=null and param2.code!=''">
and matched.code like concat(concat('%', #{param2.code}),'%')
</if>
<if test="param2.name!=null and param2.name!=''">
and matched.name like concat(concat('%', #{param2.name}),'%')
</if>
<if test="param2.regionLevel!=null">
and matched.region_level = #{param2.regionLevel}
</if>
<if test="param2.dataSource!=null and param2.dataSource!=''">
and matched.data_source = #{param2.dataSource}
</if>
<if test="param2.status!=null and param2.status!=''">
and matched.status = #{param2.status}
</if>
)
</if>
</where>
ORDER BY region.sort ASC, region.code ASC
</select>
<select id="exportRegion" resultType="org.springblade.system.excel.RegionExcel">
SELECT * FROM blade_region ${ew.customSqlSegment}
<select id="exportRegion" resultType="org.springblade.system.excel.RegionExportExcel">
SELECT
region.code,
region.name,
region.parent_code,
CASE WHEN region.parent_code = '0' THEN '根节点'
ELSE (SELECT parent.name FROM blade_region parent WHERE parent.code = region.parent_code)
END AS parent_name,
region.region_level,
CASE region.status WHEN 1 THEN '启用' WHEN 2 THEN '停用' ELSE '' END AS status_name,
region.data_source,
COALESCE(updater.real_name, creator.real_name) AS update_user_name,
region.update_time,
region.create_time
FROM blade_region region
LEFT JOIN blade_user updater ON updater.id = region.update_user
LEFT JOIN blade_user creator ON creator.id = region.create_user
${ew.customSqlSegment}
ORDER BY region.create_time DESC, region.code ASC
</select>
</mapper>
@@ -29,6 +29,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.system.excel.FeeItemExcel;
import org.springblade.system.excel.FeeItemExportExcel;
import org.springblade.system.excel.FeeItemImportFailureExcel;
import org.springblade.system.pojo.entity.FeeItem;
import org.springblade.system.pojo.vo.FeeItemVO;
@@ -82,6 +83,6 @@ public interface IFeeItemService extends BaseService<FeeItem> {
* @param queryWrapper 查询条件
* @return 导出数据
*/
List<FeeItemExcel> exportFeeItem(Wrapper<FeeItem> queryWrapper);
List<FeeItemExportExcel> exportFeeItem(Wrapper<FeeItem> queryWrapper);
}
@@ -29,6 +29,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springblade.system.pojo.entity.Region;
import org.springblade.system.excel.RegionExcel;
import org.springblade.system.excel.RegionExportExcel;
import org.springblade.system.pojo.vo.RegionVO;
import java.util.List;
@@ -90,6 +91,6 @@ public interface IRegionService extends IService<Region> {
* @param queryWrapper
* @return
*/
List<RegionExcel> exportRegion(Wrapper<Region> queryWrapper);
List<RegionExportExcel> exportRegion(Wrapper<Region> queryWrapper);
}
@@ -34,6 +34,7 @@ import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.UserCache;
import org.springblade.system.excel.AirportMasterExcel;
import org.springblade.system.excel.AirportMasterExportExcel;
import org.springblade.system.mapper.AirportMasterMapper;
@@ -319,6 +320,7 @@ public class AirportMasterServiceImpl extends BaseServiceImpl<AirportMasterMappe
excel.setLatitude(scaleCoordinate(airportMaster.getLatitude(), MIN_LATITUDE, MAX_LATITUDE));
excel.setDataSource(normalizeDataSource(airportMaster.getDataSource()));
excel.setStatusName(Objects.equals(airportMaster.getStatus(), STATUS_ENABLED) ? "启用" : "停用");
excel.setUpdateUserName(UserCache.getUserRealName(airportMaster.getUpdateUser()));
return excel;
}).toList();
}
@@ -34,7 +34,10 @@ import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.DictBizCache;
import org.springblade.system.cache.SysCache;
import org.springblade.system.cache.UserCache;
import org.springblade.system.excel.FeeItemExcel;
import org.springblade.system.excel.FeeItemExportExcel;
import org.springblade.system.excel.FeeItemImportFailureExcel;
import org.springblade.system.mapper.FeeItemMapper;
import org.springblade.system.pojo.entity.DictBiz;
@@ -119,7 +122,7 @@ public class FeeItemServiceImpl extends BaseServiceImpl<FeeItemMapper, FeeItem>
}
@Override
public List<FeeItemExcel> exportFeeItem(Wrapper<FeeItem> queryWrapper) {
public List<FeeItemExportExcel> exportFeeItem(Wrapper<FeeItem> queryWrapper) {
return list(queryWrapper).stream().map(this::toExcel).toList();
}
@@ -193,9 +196,14 @@ public class FeeItemServiceImpl extends BaseServiceImpl<FeeItemMapper, FeeItem>
return feeItem;
}
private FeeItemExcel toExcel(FeeItem feeItem) {
FeeItemExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(feeItem, FeeItemExcel.class));
private FeeItemExportExcel toExcel(FeeItem feeItem) {
FeeItemExportExcel excel = Objects.requireNonNull(BeanUtil.copyProperties(feeItem, FeeItemExportExcel.class));
excel.setFeeCategory(formatFeeCategory(feeItem.getFeeCategory()));
excel.setCreateDeptName(
Func.isEmpty(feeItem.getCreateDept()) ? "" : SysCache.getDeptName(feeItem.getCreateDept())
);
excel.setUpdateUserName(UserCache.getUserRealName(feeItem.getUpdateUser()));
excel.setStatusName(Objects.equals(feeItem.getStatus(), STATUS_ENABLED) ? "启用" : "停用");
return excel;
}
@@ -34,6 +34,7 @@ import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.UserCache;
import org.springblade.system.excel.PortTerminalExcel;
import org.springblade.system.excel.PortTerminalExportExcel;
import org.springblade.system.mapper.PortTerminalMapper;
@@ -392,6 +393,7 @@ public class PortTerminalServiceImpl extends BaseServiceImpl<PortTerminalMapper,
excel.setLatitude(scaleCoordinate(portTerminal.getLatitude(), MIN_LATITUDE, MAX_LATITUDE));
excel.setDataSource(normalizeDataSource(portTerminal.getDataSource()));
excel.setStatusName(Objects.equals(portTerminal.getStatus(), STATUS_ENABLED) ? "启用" : "停用");
excel.setUpdateUserName(UserCache.getUserRealName(portTerminal.getUpdateUser()));
return excel;
}).toList();
}
@@ -230,15 +230,15 @@ public class RailwayStationServiceImpl extends BaseServiceImpl<RailwayStationMap
validateImportUnique(RailwayStation::getCode, railwayStation.getCode(), "该编码已存在", validationErrors);
}
if (Func.isEmpty(railwayStation.getTelegraphCode())) {
addValidationError(validationErrors, "电报码不能为空");
addValidationError(validationErrors, "电报码不能为空");
} else {
if (!TELEGRAPH_CODE_PATTERN.matcher(railwayStation.getTelegraphCode()).matches()) {
addValidationError(validationErrors, "电报码为3位大写字母");
addValidationError(validationErrors, "电报码为3位大写字母");
}
if (telegraphCodeCountMap.getOrDefault(railwayStation.getTelegraphCode(), 0) > 1) {
addValidationError(validationErrors, "电报码在本次导入中重复");
addValidationError(validationErrors, "电报码在本次导入中重复");
}
validateImportUnique(RailwayStation::getTelegraphCode, railwayStation.getTelegraphCode(), "电报码已存在", validationErrors);
validateImportUnique(RailwayStation::getTelegraphCode, railwayStation.getTelegraphCode(), "电报码已存在", validationErrors);
}
if (Func.isEmpty(railwayStation.getName())) {
addValidationError(validationErrors, "车站名称不能为空");
@@ -392,10 +392,10 @@ public class RailwayStationServiceImpl extends BaseServiceImpl<RailwayStationMap
throw new ServiceException("TMIS国标编码为5位数字");
}
if (Func.isEmpty(railwayStation.getTelegraphCode())) {
throw new ServiceException("电报码格式不正确或已存在");
throw new ServiceException("电报码格式不正确或已存在");
}
if (!TELEGRAPH_CODE_PATTERN.matcher(railwayStation.getTelegraphCode()).matches()) {
throw new ServiceException("电报码格式不正确或已存在");
throw new ServiceException("电报码格式不正确或已存在");
}
if (Func.isEmpty(railwayStation.getName())) {
throw new ServiceException("请输入车站名称");
@@ -427,7 +427,7 @@ public class RailwayStationServiceImpl extends BaseServiceImpl<RailwayStationMap
validateDataSource(railwayStation.getDataSource());
validateStatus(railwayStation.getStatus());
validateUnique(railwayStation, RailwayStation::getTmisCode, railwayStation.getTmisCode(), "该TMIS编码已存在");
validateUnique(railwayStation, RailwayStation::getTelegraphCode, railwayStation.getTelegraphCode(), "电报码格式不正确或已存在");
validateUnique(railwayStation, RailwayStation::getTelegraphCode, railwayStation.getTelegraphCode(), "电报码格式不正确或已存在");
validateUnique(railwayStation, RailwayStation::getCode, railwayStation.getCode(), "该编码已存在");
}
@@ -33,14 +33,17 @@ import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.system.pojo.entity.Region;
import org.springblade.system.excel.RegionExcel;
import org.springblade.system.excel.RegionExportExcel;
import org.springblade.system.mapper.RegionMapper;
import org.springblade.system.service.IRegionService;
import org.springblade.system.pojo.vo.RegionVO;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -57,9 +60,25 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
@Override
public boolean submit(Region region) {
Date now = new Date();
Long currentUserId = AuthUtil.getUserId();
boolean isNew = StringUtil.isBlank(region.getOriginalCode());
if (region.getStatus() == null) {
region.setStatus(1);
}
if (StringUtil.isBlank(region.getDataSource())) {
region.setDataSource("手动录入");
}
if (isNew) {
region.setCreateUser(currentUserId);
region.setCreateTime(now);
}
region.setUpdateUser(currentUserId);
region.setUpdateTime(now);
String regionCode = region.getCode();
String regionParentCode = region.getParentCode();
Integer level = region.getRegionLevel();
validateRegionLevel(level);
if (level != null && level == COUNTRY_LEVEL) {
region.setParentCode(ROOT_PARENT_CODE);
region.setAncestors(ROOT_PARENT_CODE);
@@ -86,17 +105,29 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
region.setAncestors(ancestors);
} else if (MAIN_CODE.equals(region.getParentCode())) {
region.setAncestors(MAIN_CODE);
} else if (ROOT_PARENT_CODE.equals(region.getParentCode())) {
region.setAncestors(ROOT_PARENT_CODE);
}
// 设置省、市、区、镇、村
// 设置省、市、区、镇、村,并继承上级区划信息
String code = region.getCode();
String name = region.getName();
if (level == PROVINCE_LEVEL) {
region.setProvinceCode(code);
region.setProvinceName(name);
} else if (level == CITY_LEVEL) {
if (Func.isNotEmpty(parent)) {
region.setProvinceCode(parent.getProvinceCode());
region.setProvinceName(parent.getProvinceName());
}
region.setCityCode(code);
region.setCityName(name);
} else if (level == DISTRICT_LEVEL) {
if (Func.isNotEmpty(parent)) {
region.setProvinceCode(parent.getProvinceCode());
region.setProvinceName(parent.getProvinceName());
region.setCityCode(parent.getCityCode());
region.setCityName(parent.getCityName());
}
region.setDistrictCode(code);
region.setDistrictName(name);
} else if (level == TOWN_LEVEL) {
@@ -128,6 +159,12 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
}
}
private void validateRegionLevel(Integer level) {
if (level != null && level > DISTRICT_LEVEL) {
throw new ServiceException("区划等级仅支持国家、省份/直辖市、地市、区县");
}
}
@Override
public boolean removeRegion(String id) {
Long cnt = baseMapper.selectCount(Wrappers.<Region>query().lambda().eq(Region::getParentCode, id));
@@ -162,11 +199,18 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
RegionExcel excel = data.get(index);
try {
Region region = BeanUtil.copyProperties(excel, Region.class);
if (Boolean.TRUE.equals(isCovered)) {
cacheChanged = this.saveOrUpdate(region) || cacheChanged;
} else {
cacheChanged = this.save(region) || cacheChanged;
validateRegionLevel(region.getRegionLevel());
region.setSort(index + 1);
if (region.getStatus() == null) {
region.setStatus(1);
}
if (StringUtil.isBlank(region.getDataSource())) {
region.setDataSource("初始化导入");
}
if (Boolean.TRUE.equals(isCovered) && this.getById(region.getCode()) != null) {
region.setOriginalCode(region.getCode());
}
cacheChanged = this.submit(region) || cacheChanged;
} catch (Exception exception) {
excel.setErrorMessage(exception.getMessage());
errorList.add(excel);
@@ -179,7 +223,11 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
}
@Override
public List<RegionExcel> exportRegion(Wrapper<Region> queryWrapper) {
return baseMapper.exportRegion(queryWrapper);
public List<RegionExportExcel> exportRegion(Wrapper<Region> queryWrapper) {
List<RegionExportExcel> list = baseMapper.exportRegion(queryWrapper);
for (int index = 0; index < list.size(); index++) {
list.get(index).setSerialNumber(index + 1);
}
return list;
}
}
@@ -77,6 +77,16 @@ public class ContractManageExcel implements Serializable {
private String contractStage;
@ExcelProperty("审核状态")
private String approvalStatus;
@ExcelProperty("结算币种")
private String settlementCurrency;
@ExcelProperty("结算方式")
private String settlementMode;
@ExcelProperty("开票周期(天)")
private Integer invoiceCycle;
@ExcelProperty("一式份数")
private Integer copyCount;
@ExcelProperty("回款账期(天)")
private Integer paymentDays;
@ExcelProperty("当前节点")
private String currentNode;
@ExcelProperty("当前处理人")
@@ -137,6 +137,10 @@
<bind name="driverNameLike" value="'%' + driver.driverName + '%'"/>
AND driver_name LIKE #{driverNameLike}
</if>
<if test="driver.posts != null and driver.posts != ''">
<bind name="postsLike" value="'%' + driver.posts + '%'"/>
AND posts LIKE #{postsLike}
</if>
<if test="driver.mobile != null and driver.mobile != ''">
<bind name="mobileLike" value="'%' + driver.mobile + '%'"/>
AND mobile LIKE #{mobileLike}
@@ -222,6 +222,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|| !List.of(STATUS_APPROVED, STATUS_CHANGE_APPROVED, STATUS_CHANGE_REJECTED).contains(source.getApprovalStatus())) {
throw new ServiceException("当前合同状态不允许发起变更");
}
TransportBusinessSupport.validateRequired(request.getSettlementCurrency(), "请选择结算币种");
ContractManage candidate = new ContractManage();
BeanUtil.copyProperties(source, candidate);
candidate.setPartyB(TransportBusinessSupport.trimToNull(request.getPartyB()));
@@ -231,6 +232,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
source.setContractName(request.getContractName()); source.setPartyB(request.getPartyB());
source.setStartDate(request.getStartDate()); source.setEndDate(request.getEndDate()); source.setContractFormat(request.getContractFormat());
source.setSettlementMode(request.getSettlementMode()); source.setLegalSealFlag(request.getLegalSealFlag()); source.setCopyCount(request.getCopyCount());
source.setSettlementCurrency(TransportBusinessSupport.trimToNull(request.getSettlementCurrency())); source.setInvoiceCycle(request.getInvoiceCycle());
source.setPaymentDays(request.getPaymentDays()); source.setRemark(request.getRemark()); source.setBillingEnabled(request.getBillingEnabled()); source.setFeeGenerationMode(request.getFeeGenerationMode());
normalizeOptionalIntegerFields(source);
source.setBillingPlanJson(request.getBillingPlanJson()); source.setSettlementRuleJson(request.getSettlementRuleJson()); source.setPreSettlementConfigJson(request.getPreSettlementConfigJson()); source.setFormalSettlementConfigJson(request.getFormalSettlementConfigJson()); source.setPaymentRatioJson(request.getPaymentRatioJson());
@@ -444,6 +446,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
contractManage.setSettlementMode(TransportBusinessSupport.trimToNull(contractManage.getSettlementMode()));
contractManage.setContractFormat(TransportBusinessSupport.trimToNull(contractManage.getContractFormat()));
contractManage.setRemark(TransportBusinessSupport.trimToNull(contractManage.getRemark()));
contractManage.setSettlementCurrency(TransportBusinessSupport.trimToNull(contractManage.getSettlementCurrency()));
contractManage.setContractFileJson(TransportBusinessSupport.trimToNull(contractManage.getContractFileJson()));
contractManage.setAttachmentsJson(TransportBusinessSupport.trimToNull(contractManage.getAttachmentsJson()));
contractManage.setBillingPlanJson(TransportBusinessSupport.trimToNull(contractManage.getBillingPlanJson()));
@@ -461,11 +464,15 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
if (contractManage.getPaymentDays() != null && contractManage.getPaymentDays() <= 0) {
contractManage.setPaymentDays(null);
}
if (contractManage.getInvoiceCycle() != null && contractManage.getInvoiceCycle() <= 0) {
contractManage.setInvoiceCycle(null);
}
}
private void validateDraft(ContractManage contractManage) {
TransportBusinessSupport.validateRequired(contractManage.getContractName(), "请输入合同名称");
TransportBusinessSupport.validateRequired(contractManage.getContractCategory(), "请选择合同类别");
TransportBusinessSupport.validateRequired(contractManage.getSettlementCurrency(), "请选择结算币种");
validateContractNameUnique(contractManage);
TransportBusinessSupport.validateLength(contractManage.getRemark(), 2000, "备注不能超过2000字");
validateBillingPlans(contractManage.getBillingPlanJson());
@@ -591,6 +598,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
}
private void validateFormal(ContractManage contractManage) {
TransportBusinessSupport.validateRequired(contractManage.getSettlementCurrency(), "请选择结算币种");
TransportBusinessSupport.validateRequired(contractManage.getPartyA(), "请输入甲方");
TransportBusinessSupport.validateRequired(contractManage.getPartyB(), "请输入乙方");
TransportBusinessSupport.validateRequired(contractManage.getStartDate() == null ? null : contractManage.getStartDate().toString(), "请选择合同期限");
@@ -584,7 +584,9 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
private void validateCarrierContract(LoadingManage loadingManage, boolean required) {
if (!Objects.equals(loadingManage.getCarrierType(), "承运商")) {
loadingManage.setCarrierContractId(null);
loadingManage.setCarrierName(null);
if (!Objects.equals(loadingManage.getCarrierType(), CARRIER_SELF)) {
loadingManage.setCarrierName(null);
}
return;
}
if (Func.isEmpty(loadingManage.getCarrierContractId())) {
@@ -604,7 +606,9 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
private void validateCompletedCarrierContract(LoadingManage loadingManage) {
if (!Objects.equals(loadingManage.getCarrierType(), "承运商")) {
loadingManage.setCarrierContractId(null);
loadingManage.setCarrierName(null);
if (!Objects.equals(loadingManage.getCarrierType(), CARRIER_SELF)) {
loadingManage.setCarrierName(null);
}
return;
}
if (Func.isEmpty(loadingManage.getCarrierContractId())) {
@@ -51,6 +51,8 @@ import java.util.Objects;
@Service
public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, MasterOrder> implements IMasterOrderService {
private static final String CARRIER_SELF = "自运";
private final IWaybillService waybillService;
private final ITransportPlanService transportPlanService;
private final IProjectApplyService projectApplyService;
@@ -418,7 +420,9 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
String carrierType = string(dispatch, "carrierType", "承运商");
if (!"承运商".equals(carrierType)) {
dispatch.remove("carrierContractId");
dispatch.remove("carrierName");
if (!CARRIER_SELF.equals(carrierType)) {
dispatch.remove("carrierName");
}
}
String carrierName = string(dispatch, "carrierName");
Long carrierContractId = longValue(dispatch, "carrierContractId");
@@ -441,7 +445,7 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
if (Func.isEmpty(string(dispatch, "carrierName")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) <= 0)) throw new ServiceException("承运商不能为空,里程填写时必须为正数");
return;
}
if (Func.isEmpty(string(dispatch, "driverName")) || Func.isEmpty(string(dispatch, "driverPhone")) || Func.isEmpty(string(dispatch, "trailerVehicleNo")) || Func.isEmpty(string(dispatch, "escortName")) || Func.isEmpty(string(dispatch, "escortPhone")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0)) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
if (Func.isEmpty(string(dispatch, "driverName")) || Func.isEmpty(string(dispatch, "driverPhone")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0)) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
}
private boolean isWaterTransport(String transportType) {
String value = transportType == null ? "" : transportType.trim().toLowerCase();
@@ -338,31 +338,73 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
if (isRoadTransport(shippingTemplate.getTransportType())) {
JSONArray freightItems = freight.getJSONArray("freightItems");
if (freightItems == null || freightItems.size() != goods.size()) {
throw new ServiceException("公路运输的运费明细必须与货物信息一一对应");
List<String> quantityUnits = goods.stream()
.map(item -> item instanceof JSONObject ? ((JSONObject) item).getString("quantityUnit") : null)
.map(TransportBusinessSupport::trimToNull)
.filter(Objects::nonNull)
.distinct()
.toList();
if (freightItems == null || (freightItems.size() != goods.size() && freightItems.size() != quantityUnits.size())) {
throw new ServiceException("公路运输的运费明细必须覆盖货物信息");
}
boolean groupedByQuantityUnit = freightItems.size() == quantityUnits.size() && freightItems.size() != goods.size();
BigDecimal totalFreightAmount = BigDecimal.ZERO;
for (int index = 0; index < freightItems.size(); index++) {
JSONObject freightItem = freightItems.getJSONObject(index);
if (freightItem == null) {
throw new ServiceException("" + (index + 1) + "条运费明细格式不正确");
}
String quantityUnit = TransportBusinessSupport.trimToNull(freightItem.getString("quantityUnit"));
if (groupedByQuantityUnit) {
quantityUnit = quantityUnit == null && index < quantityUnits.size() ? quantityUnits.get(index) : quantityUnit;
}
JSONObject goodsItem = groupedByQuantityUnit ? null : goods.getJSONObject(index);
if (quantityUnit == null && goodsItem != null) {
quantityUnit = TransportBusinessSupport.trimToNull(goodsItem.getString("quantityUnit"));
}
if (quantityUnit == null) {
throw new ServiceException("" + (index + 1) + "条运费明细数量单位不能为空");
}
final String itemQuantityUnit = quantityUnit;
BigDecimal quantity = groupedByQuantityUnit
? goods.stream()
.map(item -> item instanceof JSONObject ? (JSONObject) item : null)
.filter(item -> itemQuantityUnit.equals(TransportBusinessSupport.trimToNull(item.getString("quantityUnit"))))
.map(item -> amountValue(item.get("quantity"), "货物数量"))
.reduce(BigDecimal.ZERO, BigDecimal::add)
: amountValue(goodsItem == null ? null : goodsItem.get("quantity"), "" + (index + 1) + "条货物数量");
BigDecimal unitPrice = amountValue(freightItem.get("unitPrice"), "" + (index + 1) + "条货物单价");
String priceUnit = TransportBusinessSupport.trimToNull(freightItem.getString("priceUnit"));
if (StringUtil.isBlank(priceUnit)) {
throw new ServiceException("" + (index + 1) + "条货物计价单位不能为空");
}
JSONObject goodsItem = goods.getJSONObject(index);
BigDecimal quantity = amountValue(goodsItem == null ? null : goodsItem.get("quantity"), "" + (index + 1) + "条货物数量");
BigDecimal freightAmount = unitPrice.multiply(quantity);
BigDecimal calculatedAmount = unitPrice.multiply(quantity);
Object inputAmount = freightItem.get("freightAmount");
boolean autoCalculable = quantityUnits.size() == 1 && priceUnitMatchesQuantity(priceUnit, itemQuantityUnit)
&& freightItem.get("unitPrice") != null && StringUtil.isNotBlank(String.valueOf(freightItem.get("unitPrice")));
if (!autoCalculable && (inputAmount == null || StringUtil.isBlank(String.valueOf(inputAmount)))) {
throw new ServiceException("" + (index + 1) + "条货物运费不能为空");
}
boolean manualAmount = Boolean.TRUE.equals(freightItem.getBoolean("manualFreightAmount"))
|| Boolean.TRUE.equals(freightItem.getBoolean("freightAmountManual"));
if (!manualAmount && inputAmount != null && StringUtil.isNotBlank(String.valueOf(inputAmount))) {
BigDecimal enteredAmount = amountValue(inputAmount, "" + (index + 1) + "条货物运费");
manualAmount = enteredAmount.compareTo(calculatedAmount) != 0;
}
BigDecimal freightAmount = manualAmount
? amountValue(inputAmount, "" + (index + 1) + "条货物运费")
: calculatedAmount;
freightItem.put("cargoIndex", index);
freightItem.put("quantityUnit", quantityUnit);
freightItem.put("unitPrice", decimalText(unitPrice));
freightItem.put("priceUnit", priceUnit);
freightItem.put("quantity", decimalText(quantity));
freightItem.put("freightAmount", decimalText(freightAmount));
freightItem.put("manualFreightAmount", manualAmount);
totalFreightAmount = totalFreightAmount.add(freightAmount);
}
freight.put("totalFreightAmount", decimalText(totalFreightAmount));
BigDecimal otherFreightAmount = amountValue(freight.get("otherFreightAmount"), "其他运费合计");
freight.put("totalFreightAmount", decimalText(totalFreightAmount.add(otherFreightAmount)));
freight.remove("freightAmount");
freight.remove("quantity");
} else {
@@ -371,9 +413,11 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
.map(item -> amountValue(item == null ? null : item.get("quantity"), "货物数量"))
.reduce(BigDecimal.ZERO, BigDecimal::add);
freight.put("quantity", decimalText(quantity));
freight.put("freightAmount", amountText(freight.get("freightAmount"), "运费"));
String freightAmount = amountText(freight.get("freightAmount"), "运费");
freight.put("freightAmount", freightAmount);
BigDecimal otherFreightAmount = amountValue(freight.get("otherFreightAmount"), "其他运费合计");
freight.put("totalFreightAmount", decimalText(new BigDecimal(freightAmount).add(otherFreightAmount)));
freight.remove("freightItems");
freight.remove("totalFreightAmount");
}
shippingTemplate.setFreightJson(freight.toJSONString());
}
@@ -383,6 +427,26 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
return value.contains("公路") || value.contains("道路") || value.contains("road") || "gl".equals(value);
}
private boolean priceUnitMatchesQuantity(String priceUnit, String quantityUnit) {
String unit = normalizeQuantityUnit(quantityUnit).replaceAll("[·*.]", "");
String value = StringUtil.isBlank(priceUnit) ? "" : priceUnit.trim().toLowerCase().replaceAll("\\s+", "");
if (StringUtil.isBlank(unit) || StringUtil.isBlank(value)) return false;
String[] parts = value.split("/");
if (parts.length != 2) return false;
String left = normalizeQuantityUnit(parts[0]).replaceAll("[·*.]", "");
String right = normalizeQuantityUnit(parts[1]).replaceAll("[·*.]", "");
return (left.equals(unit) && isMoneyUnit(parts[1])) || (right.equals(unit) && isMoneyUnit(parts[0]));
}
private String normalizeQuantityUnit(String value) {
return StringUtil.isBlank(value) ? "" : value.trim().toLowerCase().replaceAll("\\s+", "")
.replace("立方米", "立方").replace("立方公尺", "立方").replace("", "立方");
}
private boolean isMoneyUnit(String value) {
return value.matches(".*(元|人民币|rmb|cny|\\$|美元|usd).*");
}
private String amountText(Object value, String fieldName) {
return decimalText(amountValue(value, fieldName));
}
@@ -42,11 +42,13 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springblade.transport.mapper.TransportPlanMapper;
import org.springblade.transport.pojo.dto.TransportPlanDispatchRequest;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.TransportPlan;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
import org.springblade.transport.pojo.vo.TransportPlanVO;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.service.IContractManageService;
import org.springblade.transport.service.ITransportPlanService;
import org.springblade.transport.service.IWaybillService;
import org.springblade.transport.support.TransportBusinessSupport;
@@ -73,6 +75,7 @@ import java.util.stream.Collectors;
public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMapper, TransportPlan> implements ITransportPlanService {
private final IWaybillService waybillService;
private final IContractManageService contractManageService;
@Override
public IPage<TransportPlanVO> selectTransportPlanPage(IPage<TransportPlan> page, TransportPlanVO transportPlan) {
@@ -85,10 +88,30 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
@Override
public TransportPlanVO detail(Long id) {
TransportPlanVO transportPlan = TransportPlanWrapper.build().entityVO(loadEditable(id, false));
fillContractNo(transportPlan);
fillDispatchRows(Collections.singletonList(transportPlan));
return transportPlan;
}
private void fillContractNo(TransportPlanVO transportPlan) {
ContractManage contract = resolveContract(transportPlan);
transportPlan.setContractNo(contract == null ? null : contract.getContractNo());
}
private ContractManage resolveContract(TransportPlanVO transportPlan) {
if (Func.isNotEmpty(transportPlan.getContractId())) {
ContractManage contract = contractManageService.getById(transportPlan.getContractId());
if (contract != null) return contract;
}
if (Func.isEmpty(transportPlan.getContractName())) return null;
LambdaQueryWrapper<ContractManage> query = new LambdaQueryWrapper<ContractManage>()
.eq(ContractManage::getContractName, transportPlan.getContractName());
if (Func.isNotEmpty(transportPlan.getProjectId())) {
query.eq(ContractManage::getProjectId, transportPlan.getProjectId());
}
return contractManageService.getOne(query, false);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean submit(TransportPlan transportPlan) {
@@ -39,6 +39,7 @@ import org.springblade.transport.mapper.WaybillMapper;
import org.springblade.transport.pojo.entity.LoadingManage;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.ProcessConfig;
import org.springblade.transport.pojo.entity.ProjectApply;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.dto.WaybillMileageRequest;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
@@ -46,6 +47,7 @@ import org.springblade.transport.pojo.vo.LoadingManageVO;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.service.ILoadingManageService;
import org.springblade.transport.service.IProcessConfigService;
import org.springblade.transport.service.IProjectApplyService;
import org.springblade.transport.service.IReceivablePayableDetailService;
import org.springblade.transport.service.IContractManageService;
import org.springblade.transport.service.IWaybillService;
@@ -81,6 +83,9 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
@jakarta.annotation.Resource
private IProcessConfigService processConfigService;
@jakarta.annotation.Resource
private IProjectApplyService projectApplyService;
@jakarta.annotation.Resource
private IContractManageService contractManageService;
@@ -135,11 +140,22 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
fillProjectProcessConfig(waybill);
}
prepare(waybill);
fillCustomerName(waybill);
if (created && Func.isEmpty(waybill.getWaybillNo())) {
waybill.setWaybillNo(nextCode());
}
}
private void fillCustomerName(Waybill waybill) {
if (Func.isNotEmpty(waybill.getCustomerName()) || Func.isEmpty(waybill.getProjectId())) {
return;
}
ProjectApply project = projectApplyService.getById(waybill.getProjectId());
if (project != null) {
waybill.setCustomerName(TransportBusinessSupport.trimToNull(project.getCustomerNames()));
}
}
private void fillProjectProcessConfig(Waybill waybill) {
if (Func.isNotEmpty(waybill.getProcessJson()) || Func.isEmpty(waybill.getProjectId())) {
return;
@@ -605,7 +621,7 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
waybill.setTaskRemark(TransportBusinessSupport.trimToNull(waybill.getTaskRemark()));
waybill.setOriginalNo(TransportBusinessSupport.trimToNull(waybill.getOriginalNo()));
waybill.setBusinessStatus(TransportBusinessSupport.trimToNull(waybill.getBusinessStatus()));
waybill.setDataSource(TransportBusinessSupport.trimToNull(waybill.getDataSource()));
waybill.setDataSource(TransportBusinessSupport.normalizeWaybillDataSource(waybill.getDataSource()));
waybill.setPlanName(TransportBusinessSupport.trimToNull(waybill.getPlanName()));
waybill.setMasterNo(TransportBusinessSupport.trimToNull(waybill.getMasterNo()));
waybill.setLoadingNo(TransportBusinessSupport.trimToNull(waybill.getLoadingNo()));
@@ -652,12 +668,6 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
} else {
TransportBusinessSupport.validateRequired(waybill.getDriverName(), "司机不能为空");
TransportBusinessSupport.validateRequired(waybill.getDriverPhone(), "司机手机号不能为空");
TransportBusinessSupport.validateRequired(waybill.getTrailerVehicleNo(), "挂车车牌号不能为空");
TransportBusinessSupport.validateRequired(waybill.getEscortName(), "押运人不能为空");
TransportBusinessSupport.validateRequired(waybill.getEscortPhone(), "押运人手机号不能为空");
if (Func.isEmpty(waybill.getMileage())) {
throw new ServiceException("里程不能为空");
}
}
}
TransportBusinessSupport.validateRequired(waybill.getCarrierJson(), "承运信息不能为空");
@@ -43,6 +43,7 @@ public final class TransportBusinessSupport {
public static final String DATA_SOURCE_BATCH_IMPORT = "批量导入";
public static final String DATA_SOURCE_MANUAL = "手工创建";
public static final String DATA_SOURCE_PLAN_DISPATCH = "计划调度";
public static final String DATA_SOURCE_EXTERNAL = "外部系统";
private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$");
@@ -110,6 +111,23 @@ public final class TransportBusinessSupport {
};
}
/**
* 归一化运单数据来源,保证列表只出现约定的三种来源。
*
* @param value 原始数据来源
* @return 批量导入、手工创建或计划调度
*/
public static String normalizeWaybillDataSource(String value) {
String source = trimToNull(value);
if (DATA_SOURCE_BATCH_IMPORT.equals(source)) {
return DATA_SOURCE_BATCH_IMPORT;
}
if (DATA_SOURCE_PLAN_DISPATCH.equals(source) || "多联总单调度".equals(source)) {
return DATA_SOURCE_PLAN_DISPATCH;
}
return DATA_SOURCE_MANUAL;
}
public static void validateRequired(String value, String message) {
if (Func.isEmpty(trimToNull(value))) {
throw new ServiceException(message);
@@ -29,6 +29,7 @@ import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.support.TransportBusinessSupport;
import java.util.Objects;
@@ -48,6 +49,7 @@ public class WaybillWrapper extends BaseEntityWrapper<Waybill, WaybillVO> {
WaybillVO waybillVO = Objects.requireNonNull(BeanUtil.copyProperties(waybill, WaybillVO.class));
waybillVO.setCreateUserName(UserCache.getUserRealName(waybill.getCreateUser()));
waybillVO.setUpdateUserName(UserCache.getUserRealName(waybill.getUpdateUser()));
waybillVO.setDataSource(TransportBusinessSupport.normalizeWaybillDataSource(waybill.getDataSource()));
Long currentDeptId = Func.firstLong(AuthUtil.getDeptId());
waybillVO.setReadonly(currentDeptId != null && !Objects.equals(waybill.getDeptId(), currentDeptId));
waybillVO.setBusinessStatusName(businessStatusName(waybill.getBusinessStatus()));
@@ -0,0 +1,4 @@
-- 合同管理补充结算币种、开票周期字段
ALTER TABLE `blade_contract_manage`
ADD COLUMN `settlement_currency` varchar(50) DEFAULT NULL COMMENT '结算币种' AFTER `copy_count`,
ADD COLUMN `invoice_cycle` int(11) DEFAULT NULL COMMENT '开票周期(天)' AFTER `settlement_currency`;
@@ -133,6 +133,8 @@ CREATE TABLE `blade_contract_manage` (
`contract_format` varchar(50) DEFAULT NULL COMMENT '合同格式',
`legal_seal_flag` int(11) DEFAULT '0' COMMENT '是否需要加盖法人章',
`copy_count` int(11) DEFAULT NULL COMMENT '一式份数',
`settlement_currency` varchar(50) DEFAULT NULL COMMENT '结算币种',
`invoice_cycle` int(11) DEFAULT NULL COMMENT '开票周期(天)',
`payment_days` int(11) DEFAULT NULL COMMENT '回款账期(天)',
`contract_stage` varchar(50) DEFAULT NULL COMMENT '合同阶段',
`approval_status` varchar(50) DEFAULT NULL COMMENT '审核状态',
@@ -0,0 +1,79 @@
-- 行政区划导出字段补充:支持状态、数据来源及审计信息。
-- 可重复执行,字段已存在时不会重复添加。
SET @db_name = DATABASE();
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'data_source'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `data_source` varchar(20) DEFAULT ''初始化导入'' COMMENT ''数据来源'' AFTER `remark`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'create_user'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `create_user` bigint(20) DEFAULT NULL COMMENT ''创建人'' AFTER `data_source`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'create_time'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `create_time` datetime DEFAULT NULL COMMENT ''创建时间'' AFTER `create_user`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'update_user'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `update_user` bigint(20) DEFAULT NULL COMMENT ''更新人'' AFTER `create_time`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'update_time'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `update_time` datetime DEFAULT NULL COMMENT ''更新时间'' AFTER `update_user`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = @db_name AND table_name = 'blade_region' AND column_name = 'status'
),
'SELECT 1',
'ALTER TABLE `blade_region` ADD COLUMN `status` int(11) DEFAULT 1 COMMENT ''状态'' AFTER `update_time`'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
UPDATE `blade_region` SET `data_source` = '初始化导入' WHERE `data_source` IS NULL OR TRIM(`data_source`) = '';
UPDATE `blade_region` SET `status` = 1 WHERE `status` IS NULL;
@@ -0,0 +1,6 @@
-- 行政区划等级仅保留:国家、省份/直辖市、地市、区县。
-- 删除乡镇(4)和村委(5)字典项;已有历史区域数据不做删除。
DELETE FROM `blade_dict`
WHERE `code` = 'region'
AND (`dict_key` IN ('4', '5') OR `dict_value` IN ('乡镇', '村委'));
+6 -2
View File
@@ -565,8 +565,6 @@ INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738777232, 1123598814738777230, 'region', '1', '省份/直辖市', 1, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738777233, 1123598814738777230, 'region', '2', '地市', 2, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738777234, 1123598814738777230, 'region', '3', '区县', 3, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738777235, 1123598814738777230, 'region', '4', '乡镇', 4, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738777236, 1123598814738777230, 'region', '5', '村委', 5, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738778200, 0, 'user_type', '-1', '用户平台', 14, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738778201, 1123598814738778200, 'user_type', '1', 'WEB', 1, NULL, 0, 1, 0);
INSERT INTO `blade_dict` (`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_sealed`, `status`, `is_deleted`) VALUES (1123598814738778202, 1123598814738778200, 'user_type', '2', 'APP', 2, NULL, 0, 1, 0);
@@ -1581,6 +1579,12 @@ CREATE TABLE `blade_region` (
`region_level` int(11) DEFAULT NULL COMMENT '层级',
`sort` int(11) DEFAULT NULL COMMENT '排序',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`data_source` varchar(20) DEFAULT '初始化导入' COMMENT '数据来源',
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_user` bigint(20) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`status` int(11) DEFAULT '1' COMMENT '状态',
PRIMARY KEY (`code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='行政区划表';