1、调整导入运单
2、调整对账
This commit is contained in:
+7
-3
@@ -23,6 +23,7 @@ import org.springblade.core.excel.util.ExcelUtil;
|
||||
import org.springblade.transport.excel.CargoReconciliationExcel;
|
||||
import org.springblade.transport.excel.CargoReconciliationFeeReader;
|
||||
import org.springblade.transport.excel.CargoReconciliationFailureExcel;
|
||||
import org.springblade.transport.excel.ReconciliationImportTemplateExcel;
|
||||
import org.springblade.transport.excel.VehicleReconciliationExcel;
|
||||
import org.springblade.transport.excel.VehicleReconciliationFeeReader;
|
||||
import org.springblade.transport.excel.VehicleReconciliationFailureExcel;
|
||||
@@ -154,9 +155,12 @@ public class TransportReconciliationController extends BladeController {
|
||||
@GetMapping("/template")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "下载运输对账模板")
|
||||
public void template(@RequestParam String mode, HttpServletResponse response) {
|
||||
if ("cargo".equals(mode)) ExcelUtil.export(response, "货物明细对账模板", "货物明细对账模板", new ArrayList<CargoReconciliationExcel>(), CargoReconciliationExcel.class);
|
||||
else ExcelUtil.export(response, "整车总额对账模板", "整车总额对账模板", new ArrayList<VehicleReconciliationExcel>(), VehicleReconciliationExcel.class);
|
||||
public void template(@RequestParam String mode, @RequestParam(required = false) Long id,
|
||||
@RequestParam(required = false) Long formalSettlementId, @RequestParam(required = false) String feeItems,
|
||||
HttpServletResponse response) {
|
||||
List<String> extraFeeItems = reconciliationService.templateFeeItems(id, formalSettlementId, feeItems);
|
||||
if ("cargo".equals(mode)) ReconciliationImportTemplateExcel.exportCargo(response, extraFeeItems);
|
||||
else ReconciliationImportTemplateExcel.exportVehicle(response, extraFeeItems);
|
||||
}
|
||||
|
||||
@PostMapping("/match")
|
||||
|
||||
+8
-1
@@ -131,8 +131,15 @@ public class WaybillController extends BladeController {
|
||||
return R.data(options);
|
||||
}
|
||||
|
||||
@GetMapping("/import-batch/list")
|
||||
@GetMapping("/import-batch/next-code")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "下一个运单批次号")
|
||||
public R<String> importBatchNextCode() {
|
||||
return R.data(waybillImportBatchService.nextBatchNo());
|
||||
}
|
||||
|
||||
@GetMapping("/import-batch/list")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "运单批量导入批次分页")
|
||||
public R<IPage<WaybillImportBatchVO>> importBatchList(WaybillImportBatchRequest request, Query query) {
|
||||
return R.data(waybillImportBatchService.page(Condition.getPage(query), request));
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ public class CargoReconciliationExcel implements Serializable {
|
||||
@ExcelProperty("运输单价") @NumberFormat("0.00") private BigDecimal unitPrice;
|
||||
@ExcelProperty("里程(KM)") @NumberFormat("0.00") private BigDecimal mileage;
|
||||
@ExcelProperty("运输费") @NumberFormat("0.00") private BigDecimal freightAmount;
|
||||
@ExcelProperty("水费") @NumberFormat("0.00") private BigDecimal feeItemOne;
|
||||
@ExcelProperty("罚款") @NumberFormat("0.00") private BigDecimal feeItemTwo;
|
||||
@ExcelIgnore @NumberFormat("0.00") private BigDecimal feeItemOne;
|
||||
@ExcelIgnore @NumberFormat("0.00") private BigDecimal feeItemTwo;
|
||||
@ExcelProperty("结算费用合计") @NumberFormat("0.00") private BigDecimal settlementAmount;
|
||||
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
||||
@ExcelIgnore private String errorMessage;
|
||||
|
||||
+4
@@ -86,10 +86,14 @@ public class ProjectApplyExcel implements Serializable {
|
||||
private String transportType;
|
||||
@ExcelProperty("业务类型")
|
||||
private String businessType;
|
||||
@ExcelProperty("业务模式")
|
||||
private String businessMode;
|
||||
@ExcelProperty("项目规模(万元)")
|
||||
private BigDecimal projectScale;
|
||||
@ExcelProperty("预计利润(万元)")
|
||||
private BigDecimal estimatedProfit;
|
||||
@ExcelProperty("利润率(%)")
|
||||
private BigDecimal profitRate;
|
||||
@ExcelProperty("资金需求(万元)")
|
||||
private BigDecimal fundDemand;
|
||||
@ExcelProperty("结算方式")
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* 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>
|
||||
* <p>Author: Chill Zhuang (bladejava@qq.com)</p>
|
||||
*/
|
||||
package org.springblade.transport.excel;
|
||||
|
||||
import cn.idev.excel.FastExcel;
|
||||
import cn.idev.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** 运输对账导入模板导出。费用列按当前内部账单收费项动态生成。 */
|
||||
public final class ReconciliationImportTemplateExcel {
|
||||
|
||||
private static final List<String> VEHICLE_HEADERS = List.of(
|
||||
"车牌号", "发货地址", "到货地址", "实际发货时间", "实际完成时间", "运输类型",
|
||||
"货物名称", "货物类型", "运输总量", "里程(KM)", "批次号", "运输单价", "运输费"
|
||||
);
|
||||
private static final List<String> CARGO_HEADERS = List.of(
|
||||
"车牌号", "发货地址", "到货地址", "实际发货时间", "实际完成时间", "货物名称",
|
||||
"货物类型", "规格", "型号", "运输总量", "运输单价", "里程(KM)", "运输费"
|
||||
);
|
||||
private static final String SETTLEMENT_AMOUNT = "结算费用合计";
|
||||
|
||||
private ReconciliationImportTemplateExcel() {
|
||||
}
|
||||
|
||||
public static void exportVehicle(HttpServletResponse response, List<String> extraFeeItems) {
|
||||
export(response, "整车总额对账模板", VEHICLE_HEADERS, extraFeeItems);
|
||||
}
|
||||
|
||||
public static void exportCargo(HttpServletResponse response, List<String> extraFeeItems) {
|
||||
export(response, "货物明细对账模板", CARGO_HEADERS, extraFeeItems);
|
||||
}
|
||||
|
||||
private static void export(HttpServletResponse response, String fileName, List<String> baseHeaders,
|
||||
List<String> extraFeeItems) {
|
||||
List<List<String>> head = new ArrayList<>();
|
||||
for (String header : baseHeaders) {
|
||||
head.add(List.of(header));
|
||||
}
|
||||
if (extraFeeItems != null) {
|
||||
for (String feeItem : extraFeeItems) {
|
||||
if (feeItem != null && !feeItem.isBlank()) {
|
||||
head.add(List.of(feeItem.trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
head.add(List.of(SETTLEMENT_AMOUNT));
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
response.setHeader("Content-disposition",
|
||||
"attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ".xlsx");
|
||||
try {
|
||||
FastExcel.write(response.getOutputStream())
|
||||
.head(head)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.sheet(fileName)
|
||||
.doWrite(List.of());
|
||||
} catch (IOException exception) {
|
||||
throw new IllegalStateException("导出" + fileName + "失败", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -59,6 +59,9 @@ public class TransportVehicleExcel implements Serializable {
|
||||
@ExcelProperty("所属组织 *")
|
||||
private String organizationName;
|
||||
|
||||
@ExcelProperty("使用部门")
|
||||
private String useDepartment;
|
||||
|
||||
@ExcelProperty("业务关系 *")
|
||||
private String businessRelation;
|
||||
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class VehicleReconciliationExcel implements Serializable {
|
||||
@ExcelProperty("批次号") private String batchNo;
|
||||
@ExcelProperty("运输单价") @NumberFormat("0.00") private BigDecimal unitPrice;
|
||||
@ExcelProperty("运输费") @NumberFormat("0.00") private BigDecimal freightAmount;
|
||||
@ExcelProperty("费用项目1") @NumberFormat("0.00") private BigDecimal feeItemOne;
|
||||
@ExcelIgnore @NumberFormat("0.00") private BigDecimal feeItemOne;
|
||||
@ExcelProperty("结算费用合计") @NumberFormat("0.00") private BigDecimal settlementAmount;
|
||||
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
||||
@ExcelIgnore private String errorMessage;
|
||||
|
||||
+2
@@ -40,6 +40,7 @@
|
||||
<result column="qualification_back" property="qualificationBack"/>
|
||||
<result column="driver_type" property="driverType"/>
|
||||
<result column="mobile" property="mobile"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="contact_relation" property="contactRelation"/>
|
||||
<result column="organization_name" property="organizationName"/>
|
||||
<result column="emergency_contact_name" property="emergencyContactName"/>
|
||||
@@ -85,6 +86,7 @@
|
||||
qualification_back,
|
||||
driver_type,
|
||||
mobile,
|
||||
user_id,
|
||||
contact_relation,
|
||||
organization_name,
|
||||
emergency_contact_name,
|
||||
|
||||
+6
@@ -13,6 +13,7 @@
|
||||
<result column="status" property="status"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="organization_name" property="organizationName"/>
|
||||
<result column="use_department" property="useDepartment"/>
|
||||
<result column="plate_no" property="plateNo"/>
|
||||
<result column="plate_color" property="plateColor"/>
|
||||
<result column="vehicle_type" property="vehicleType"/>
|
||||
@@ -60,6 +61,7 @@
|
||||
status,
|
||||
is_deleted,
|
||||
organization_name,
|
||||
use_department,
|
||||
plate_no,
|
||||
plate_color,
|
||||
vehicle_type,
|
||||
@@ -116,6 +118,10 @@
|
||||
<bind name="organizationNameLike" value="'%' + vehicle.organizationName + '%'"/>
|
||||
AND organization_name LIKE #{organizationNameLike}
|
||||
</if>
|
||||
<if test="vehicle.useDepartment != null and vehicle.useDepartment != ''">
|
||||
<bind name="useDepartmentLike" value="'%' + vehicle.useDepartment + '%'"/>
|
||||
AND use_department LIKE #{useDepartmentLike}
|
||||
</if>
|
||||
<if test="vehicle.plateNo != null and vehicle.plateNo != ''">
|
||||
<bind name="plateNoLike" value="'%' + vehicle.plateNo + '%'"/>
|
||||
AND plate_no LIKE #{plateNoLike}
|
||||
|
||||
+11
@@ -6,9 +6,20 @@ package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springblade.transport.pojo.entity.WaybillImportBatch;
|
||||
|
||||
/** 运单批次 Mapper。 */
|
||||
@Mapper
|
||||
public interface WaybillImportBatchMapper extends BaseMapper<WaybillImportBatch> {
|
||||
|
||||
/**
|
||||
* 查询指定租户、指定日期前缀下已使用的最大批次流水号。
|
||||
* 不过滤逻辑删除数据,避免唯一索引仍占用历史编号时重复生成。
|
||||
*/
|
||||
@Select("SELECT COALESCE(MAX(CAST(SUBSTRING(batch_no, CHAR_LENGTH(#{prefix}) + 1) AS UNSIGNED)), 0) "
|
||||
+ "FROM blade_waybill_import_batch WHERE tenant_id = #{tenantId} "
|
||||
+ "AND batch_no LIKE CONCAT(#{prefix}, '%')")
|
||||
Long selectMaxDailySequence(@Param("tenantId") String tenantId, @Param("prefix") String prefix);
|
||||
}
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
public interface ITransportReconciliationService extends BaseService<TransportReconciliation> {
|
||||
IPage<TransportReconciliationVO> selectPage(IPage<TransportReconciliation> page, TransportReconciliationVO query);
|
||||
IPage<FormalSettlement> formalOptions(IPage<FormalSettlement> page, String settlementType, String keyword);
|
||||
List<String> templateFeeItems(Long id, Long formalSettlementId, String feeItems);
|
||||
TransportReconciliationVO detail(Long id);
|
||||
Long saveDraft(TransportReconciliationSaveRequest request);
|
||||
void removeDraft(Long id);
|
||||
|
||||
+1
@@ -15,4 +15,5 @@ public interface IWaybillImportBatchService extends BaseService<WaybillImportBat
|
||||
void confirm(WaybillImportBatchRequest request, HttpServletResponse response);
|
||||
IPage<WaybillImportBatchVO> page(IPage<WaybillImportBatch> page, WaybillImportBatchRequest request);
|
||||
BusinessRemoveResultVO removeBatches(String ids);
|
||||
String nextBatchNo();
|
||||
}
|
||||
|
||||
+190
-1
@@ -27,13 +27,25 @@ package org.springblade.transport.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.feign.ISysClient;
|
||||
import org.springblade.system.feign.IUserClient;
|
||||
import org.springblade.system.pojo.entity.User;
|
||||
import org.springblade.system.pojo.entity.UserInfo;
|
||||
import org.springblade.system.pojo.enums.UserSex;
|
||||
import org.springblade.system.pojo.enums.UserType;
|
||||
import org.springblade.transport.excel.DriverExcel;
|
||||
import org.springblade.transport.mapper.DriverMapper;
|
||||
import org.springblade.transport.mapper.TransportVehicleMapper;
|
||||
import org.springblade.transport.pojo.entity.Driver;
|
||||
import org.springblade.transport.pojo.entity.TransportVehicle;
|
||||
import org.springblade.transport.pojo.vo.DriverExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.DriverVO;
|
||||
import org.springblade.transport.service.IDriverService;
|
||||
@@ -50,6 +62,7 @@ import java.util.Objects;
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> implements IDriverService {
|
||||
|
||||
private static final int NAME_MAX_LENGTH = 10;
|
||||
@@ -62,6 +75,10 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
||||
private static final int DEFAULT_ENABLED_STATUS = 1;
|
||||
private static final int DEFAULT_FALSE = 0;
|
||||
|
||||
private final TransportVehicleMapper transportVehicleMapper;
|
||||
private final IUserClient userClient;
|
||||
private final ISysClient sysClient;
|
||||
|
||||
@Override
|
||||
public IPage<DriverVO> selectDriverPage(IPage<DriverVO> page, DriverVO driver) {
|
||||
prepareQuery(driver);
|
||||
@@ -74,7 +91,13 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
||||
prepare(driver);
|
||||
validate(driver);
|
||||
prepareSubmitTarget(driver);
|
||||
return saveOrUpdate(driver);
|
||||
// 编辑场景下字段无变化时 update 可能返回 false,不能据此跳过用户同步
|
||||
saveOrUpdate(driver);
|
||||
if (Func.isEmpty(driver.getId())) {
|
||||
throw new ServiceException("保存司机失败");
|
||||
}
|
||||
syncDriverUser(driver);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,6 +251,14 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
||||
validateLength(driver.getMobile(), MOBILE_MAX_LENGTH, "手机号不能超过20字");
|
||||
validateLength(driver.getEmergencyContactMobile(), MOBILE_MAX_LENGTH, "紧急联系人手机号不能超过20字");
|
||||
validateLength(driver.getDrivingVehicle(), VEHICLE_NO_MAX_LENGTH, "驾驶车辆不能超过30字");
|
||||
if (Func.isNotEmpty(driver.getDrivingVehicle())) {
|
||||
Long vehicleCount = transportVehicleMapper.selectCount(Wrappers.<TransportVehicle>lambdaQuery()
|
||||
.eq(TransportVehicle::getIsDeleted, 0)
|
||||
.eq(TransportVehicle::getPlateNo, driver.getDrivingVehicle()));
|
||||
if (vehicleCount == null || vehicleCount <= 0) {
|
||||
throw new ServiceException("驾驶车辆不存在,请重新选择");
|
||||
}
|
||||
}
|
||||
validateLength(driver.getDrivingLicenseNo(), SHORT_TEXT_MAX_LENGTH, "驾驶证档案编号不能超过50字");
|
||||
validateLength(driver.getQualificationNo(), SHORT_TEXT_MAX_LENGTH, "资格证号不能超过50字");
|
||||
validateLength(driver.getOrganizationName(), SHORT_TEXT_MAX_LENGTH, "所属组织不能超过50字");
|
||||
@@ -273,6 +304,164 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
||||
}
|
||||
}
|
||||
|
||||
private void syncDriverUser(Driver driver) {
|
||||
String tenantId = AuthUtil.getTenantId();
|
||||
if (Func.isEmpty(tenantId)) {
|
||||
tenantId = driver.getTenantId();
|
||||
}
|
||||
if (Func.isEmpty(tenantId)) {
|
||||
throw new ServiceException("租户信息为空,无法同步系统用户");
|
||||
}
|
||||
String mobile = driver.getMobile();
|
||||
if (Func.isEmpty(mobile) || mobile.length() < 6) {
|
||||
throw new ServiceException("手机号长度不足,无法同步系统用户");
|
||||
}
|
||||
// 编辑时前端可能不传 userId,从库中补齐已关联用户
|
||||
if (Func.isEmpty(driver.getUserId()) && Func.isNotEmpty(driver.getId())) {
|
||||
Driver dbDriver = getById(driver.getId());
|
||||
if (dbDriver != null && Func.isNotEmpty(dbDriver.getUserId())) {
|
||||
driver.setUserId(dbDriver.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
R<String> roleResult = sysClient.getRoleIdByAlias(tenantId, "driver");
|
||||
if (roleResult == null || !R.isSuccess(roleResult) || Func.isEmpty(roleResult.getData())) {
|
||||
throw new ServiceException("未配置角色别名为driver的角色,请先在系统角色中维护");
|
||||
}
|
||||
String roleId = roleResult.getData();
|
||||
|
||||
R<String> deptResult = sysClient.getDeptIds(tenantId, driver.getOrganizationName());
|
||||
if (deptResult == null || !R.isSuccess(deptResult) || Func.isEmpty(deptResult.getData())) {
|
||||
throw new ServiceException("所属组织未匹配到系统部门,无法同步用户");
|
||||
}
|
||||
String deptId = deptResult.getData();
|
||||
|
||||
User existing = findExistingUser(driver, tenantId, mobile);
|
||||
if (existing == null || Func.isEmpty(existing.getId())) {
|
||||
// 司机未关联有效用户时新建;密码为手机号后6位
|
||||
createAndLinkDriverUser(driver, tenantId, mobile, roleId, deptId);
|
||||
} else {
|
||||
updateAndLinkDriverUser(driver, existing, tenantId, mobile, roleId, deptId);
|
||||
}
|
||||
}
|
||||
|
||||
private User findExistingUser(Driver driver, String tenantId, String mobile) {
|
||||
if (Func.isNotEmpty(driver.getUserId())) {
|
||||
R<User> byId = userClient.userInfoById(driver.getUserId());
|
||||
if (byId != null && R.isSuccess(byId) && byId.getData() != null && Func.isNotEmpty(byId.getData().getId())) {
|
||||
return byId.getData();
|
||||
}
|
||||
// 关联的用户已不存在,清空后按手机号重建
|
||||
driver.setUserId(null);
|
||||
}
|
||||
return findExistingUserByAccountOrPhone(tenantId, mobile);
|
||||
}
|
||||
|
||||
private User findExistingUserByAccountOrPhone(String tenantId, String mobile) {
|
||||
R<User> byAccount = userClient.userByAccount(tenantId, mobile);
|
||||
if (byAccount != null && R.isSuccess(byAccount) && byAccount.getData() != null
|
||||
&& Func.isNotEmpty(byAccount.getData().getId())) {
|
||||
return byAccount.getData();
|
||||
}
|
||||
R<UserInfo> byPhone = userClient.userInfoByPhone(tenantId, mobile, UserType.WEB.getName());
|
||||
if (byPhone != null && R.isSuccess(byPhone) && byPhone.getData() != null
|
||||
&& byPhone.getData().getUser() != null && Func.isNotEmpty(byPhone.getData().getUser().getId())) {
|
||||
return byPhone.getData().getUser();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createAndLinkDriverUser(Driver driver, String tenantId, String mobile, String roleId, String deptId) {
|
||||
User user = buildSyncUser(null, tenantId, mobile, driver.getDriverName(), driver.getGender(), roleId, deptId);
|
||||
user.setPassword(mobile.substring(mobile.length() - 6));
|
||||
user.setUserType(UserType.WEB.getCategory());
|
||||
|
||||
R<Boolean> saveResult = null;
|
||||
try {
|
||||
saveResult = userClient.saveUser(user);
|
||||
} catch (Exception ex) {
|
||||
User existed = findExistingUserByAccountOrPhone(tenantId, mobile);
|
||||
if (existed != null) {
|
||||
updateAndLinkDriverUser(driver, existed, tenantId, mobile, roleId, deptId);
|
||||
return;
|
||||
}
|
||||
throw new ServiceException(Func.isNotEmpty(ex.getMessage()) ? ex.getMessage() : "同步系统用户失败");
|
||||
}
|
||||
if (!isFeignSuccess(saveResult)) {
|
||||
User existed = findExistingUserByAccountOrPhone(tenantId, mobile);
|
||||
if (existed != null) {
|
||||
updateAndLinkDriverUser(driver, existed, tenantId, mobile, roleId, deptId);
|
||||
return;
|
||||
}
|
||||
throw new ServiceException(resolveFeignError(saveResult, "同步系统用户失败"));
|
||||
}
|
||||
|
||||
R<User> created = userClient.userByAccount(tenantId, mobile);
|
||||
User createdUser = (created != null && R.isSuccess(created)) ? created.getData() : null;
|
||||
if (createdUser == null || Func.isEmpty(createdUser.getId())) {
|
||||
createdUser = findExistingUserByAccountOrPhone(tenantId, mobile);
|
||||
}
|
||||
if (createdUser == null || Func.isEmpty(createdUser.getId())) {
|
||||
throw new ServiceException("系统用户创建成功但无法回查用户ID");
|
||||
}
|
||||
linkDriverUserId(driver, createdUser.getId());
|
||||
}
|
||||
|
||||
private void updateAndLinkDriverUser(Driver driver, User existing, String tenantId, String mobile, String roleId, String deptId) {
|
||||
User user = buildSyncUser(existing.getId(), tenantId, mobile, driver.getDriverName(), driver.getGender(), roleId, deptId);
|
||||
R<Boolean> updateResult = userClient.updateUser(user);
|
||||
// updateById 无字段变化时可能返回 false,但业务上仍视为成功,以接口 code 为准
|
||||
if (!isFeignSuccess(updateResult)) {
|
||||
throw new ServiceException(resolveFeignError(updateResult, "同步更新系统用户失败"));
|
||||
}
|
||||
linkDriverUserId(driver, existing.getId());
|
||||
}
|
||||
|
||||
private boolean isFeignSuccess(R<?> result) {
|
||||
return result != null && R.isSuccess(result);
|
||||
}
|
||||
|
||||
private String resolveFeignError(R<?> result, String defaultMsg) {
|
||||
if (result == null || Func.isEmpty(result.getMsg())) {
|
||||
return defaultMsg;
|
||||
}
|
||||
String msg = result.getMsg().trim();
|
||||
// R.data(false) 也会带默认成功文案,不能当作业务错误抛出
|
||||
if ("操作成功".equals(msg) || "success".equalsIgnoreCase(msg)) {
|
||||
return defaultMsg;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private User buildSyncUser(Long userId, String tenantId, String mobile, String driverName, String gender,
|
||||
String roleId, String deptId) {
|
||||
User user = new User();
|
||||
user.setId(userId);
|
||||
user.setTenantId(tenantId);
|
||||
user.setAccount(mobile);
|
||||
user.setPhone(mobile);
|
||||
user.setName(driverName);
|
||||
user.setRealName(driverName);
|
||||
user.setSex(UserSex.getCodeByName(gender));
|
||||
user.setRoleId(roleId);
|
||||
user.setDeptId(deptId);
|
||||
return user;
|
||||
}
|
||||
|
||||
private void linkDriverUserId(Driver driver, Long userId) {
|
||||
if (Func.isEmpty(userId)) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(driver.getUserId(), userId)) {
|
||||
return;
|
||||
}
|
||||
driver.setUserId(userId);
|
||||
Driver patch = new Driver();
|
||||
patch.setId(driver.getId());
|
||||
patch.setUserId(userId);
|
||||
updateById(patch);
|
||||
}
|
||||
|
||||
private Long defaultZero(Long value) {
|
||||
return value == null ? 0L : value;
|
||||
}
|
||||
|
||||
+8
@@ -348,6 +348,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
||||
projectApply.setTransportRoute(TransportBusinessSupport.trimToNull(projectApply.getTransportRoute()));
|
||||
projectApply.setTransportType(TransportBusinessSupport.trimToNull(projectApply.getTransportType()));
|
||||
projectApply.setBusinessType(TransportBusinessSupport.trimToNull(projectApply.getBusinessType()));
|
||||
projectApply.setBusinessMode(TransportBusinessSupport.trimToNull(projectApply.getBusinessMode()));
|
||||
normalizeOptionalFields(projectApply);
|
||||
projectApply.setSettlementMode(TransportBusinessSupport.trimToNull(projectApply.getSettlementMode()));
|
||||
projectApply.setHandlerUserName(TransportBusinessSupport.trimToNull(projectApply.getHandlerUserName()));
|
||||
@@ -364,6 +365,9 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
||||
if (projectApply.getEstimatedProfit() != null && projectApply.getEstimatedProfit().signum() < 0) {
|
||||
projectApply.setEstimatedProfit(null);
|
||||
}
|
||||
if (projectApply.getProfitRate() != null && projectApply.getProfitRate().signum() < 0) {
|
||||
projectApply.setProfitRate(null);
|
||||
}
|
||||
if (projectApply.getFundDemand() != null && projectApply.getFundDemand().signum() < 0) {
|
||||
projectApply.setFundDemand(null);
|
||||
}
|
||||
@@ -390,9 +394,11 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
||||
target.setTransportRoute(source.getTransportRoute());
|
||||
target.setTransportType(source.getTransportType());
|
||||
target.setBusinessType(source.getBusinessType());
|
||||
target.setBusinessMode(source.getBusinessMode());
|
||||
target.setProjectScale(source.getProjectScale());
|
||||
target.setSettlementMode(source.getSettlementMode());
|
||||
target.setEstimatedProfit(source.getEstimatedProfit());
|
||||
target.setProfitRate(source.getProfitRate());
|
||||
target.setFundDemand(source.getFundDemand());
|
||||
target.setHandlerUserId(source.getHandlerUserId());
|
||||
target.setHandlerUserName(source.getHandlerUserName());
|
||||
@@ -420,6 +426,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
||||
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
|
||||
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
|
||||
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择承办部门");
|
||||
TransportBusinessSupport.validateRequired(projectApply.getBusinessMode(), "请选择业务模式");
|
||||
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
|
||||
TransportBusinessSupport.validateRequired(projectApply.getCarrierNames(), "请选择下游承运商");
|
||||
validateAmount(projectApply.getFundLimit(), "项目资金使用额度", false);
|
||||
@@ -431,6 +438,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
||||
validateDays(projectApply.getPaymentDays(), "回款账期");
|
||||
validateAmount(projectApply.getProjectScale(), "项目规模", true);
|
||||
validateAmount(projectApply.getEstimatedProfit(), "预计利润", true);
|
||||
validateAmount(projectApply.getProfitRate(), "利润率", true);
|
||||
validateAmount(projectApply.getFundDemand(), "资金需求", true);
|
||||
TransportBusinessSupport.validateDateRange(projectApply.getBusinessStartDate(), projectApply.getBusinessEndDate(), "业务周期开始日期不能晚于结束日期");
|
||||
if (Func.isEmpty(projectApply.getHandlerUserId()) || Func.isEmpty(projectApply.getPrincipalUserId())) {
|
||||
|
||||
+64
-6
@@ -65,6 +65,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -93,6 +94,7 @@ public class TransportReconciliationServiceImpl
|
||||
private static final String DUPLICATE = "suspected_duplicate";
|
||||
private static final String MASTER_ORDER_SOURCE = "总单系统生成";
|
||||
private static final String LOADING_ORDER_SOURCE = "配载单系统生成";
|
||||
private static final String FORMAL_DRAFT = "draft";
|
||||
private final FormalSettlementMapper formalSettlementMapper;
|
||||
private final FormalSettlementSourceMapper formalSourceMapper;
|
||||
private final FormalSettlementDetailMapper formalDetailMapper;
|
||||
@@ -134,7 +136,7 @@ public class TransportReconciliationServiceImpl
|
||||
.select(TransportReconciliation::getFormalSettlementId))
|
||||
.stream().map(TransportReconciliation::getFormalSettlementId).filter(Objects::nonNull).toList();
|
||||
LambdaQueryWrapper<FormalSettlement> wrapper = Wrappers.<FormalSettlement>lambdaQuery()
|
||||
.eq(FormalSettlement::getApprovalStatus, "approved")
|
||||
.eq(FormalSettlement::getApprovalStatus, FORMAL_DRAFT)
|
||||
.eq(Func.isNotEmpty(settlementType), FormalSettlement::getSettlementType, settlementType)
|
||||
.and(Func.isNotEmpty(keyword), value -> value.like(FormalSettlement::getFormalSettlementNo, keyword)
|
||||
.or().like(FormalSettlement::getContractNo, keyword).or().like(FormalSettlement::getContractName, keyword));
|
||||
@@ -142,6 +144,60 @@ public class TransportReconciliationServiceImpl
|
||||
return formalSettlementMapper.selectPage(page, wrapper.orderByDesc(FormalSettlement::getCreateTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> templateFeeItems(Long id, Long formalSettlementId, String feeItems) {
|
||||
LinkedHashSet<String> names = new LinkedHashSet<>();
|
||||
appendTemplateFeeItems(names, feeItems);
|
||||
if (id != null) {
|
||||
for (TransportReconciliationInternal row : internalRows(id)) {
|
||||
parseFeeItems(row.getFeeItemsJson()).keySet().forEach(name -> appendTemplateFeeItem(names, name));
|
||||
}
|
||||
TransportReconciliation bill = getById(id);
|
||||
if (bill != null) collectFormalTemplateFeeItems(names, bill.getFormalSettlementId());
|
||||
}
|
||||
collectFormalTemplateFeeItems(names, formalSettlementId);
|
||||
return new ArrayList<>(names);
|
||||
}
|
||||
|
||||
private void appendTemplateFeeItems(Set<String> names, String feeItems) {
|
||||
if (Func.isEmpty(feeItems)) return;
|
||||
for (String name : feeItems.split(",")) appendTemplateFeeItem(names, name);
|
||||
}
|
||||
|
||||
private void collectFormalTemplateFeeItems(Set<String> names, Long formalSettlementId) {
|
||||
if (formalSettlementId == null) return;
|
||||
List<FormalSettlementSummaryFee> summaries = formalSummaryFeeMapper.selectList(
|
||||
Wrappers.<FormalSettlementSummaryFee>lambdaQuery()
|
||||
.eq(FormalSettlementSummaryFee::getFormalSettlementId, formalSettlementId)
|
||||
.eq(FormalSettlementSummaryFee::getIsDeleted, 0)
|
||||
.orderByAsc(FormalSettlementSummaryFee::getLineNo));
|
||||
for (FormalSettlementSummaryFee summary : summaries) {
|
||||
appendTemplateFeeItem(names, summary.getFeeItem());
|
||||
}
|
||||
List<FormalSettlementDetail> details = formalDetailMapper.selectList(
|
||||
Wrappers.<FormalSettlementDetail>lambdaQuery()
|
||||
.eq(FormalSettlementDetail::getFormalSettlementId, formalSettlementId)
|
||||
.orderByAsc(FormalSettlementDetail::getLineNo));
|
||||
for (FormalSettlementDetail detail : details) {
|
||||
parseFeeItems(detail.getFeeItemsJson()).keySet().forEach(name -> appendTemplateFeeItem(names, name));
|
||||
List<FormalSettlementDetailFee> fees = formalDetailFeeMapper.selectList(
|
||||
Wrappers.<FormalSettlementDetailFee>lambdaQuery()
|
||||
.eq(FormalSettlementDetailFee::getFormalSettlementDetailId, detail.getId())
|
||||
.eq(FormalSettlementDetailFee::getIsDeleted, 0)
|
||||
.orderByAsc(FormalSettlementDetailFee::getLineNo));
|
||||
for (FormalSettlementDetailFee fee : fees) {
|
||||
parseFeeItems(fee.getFeeItemsJson()).keySet().forEach(name -> appendTemplateFeeItem(names, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTemplateFeeItem(Set<String> names, String name) {
|
||||
if (Func.isEmpty(name)) return;
|
||||
String trimmed = name.trim();
|
||||
if (trimmed.isEmpty() || isFreightFeeItem(trimmed) || "费用项目1".equals(trimmed)) return;
|
||||
names.add(trimmed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportReconciliationVO detail(Long id) {
|
||||
TransportReconciliationVO vo = TransportReconciliationWrapper.build().entityVO(existing(id));
|
||||
@@ -166,7 +222,9 @@ public class TransportReconciliationServiceImpl
|
||||
throw new ServiceException("请选择正确的对账模式");
|
||||
}
|
||||
FormalSettlement formal = formalSettlementMapper.selectById(request.getFormalSettlementId());
|
||||
if (formal == null || !"approved".equals(formal.getApprovalStatus())) throw new ServiceException("请选择已生效的正式结算单");
|
||||
if (formal == null || !FORMAL_DRAFT.equals(formal.getApprovalStatus())) {
|
||||
throw new ServiceException("请选择草稿状态的正式结算单");
|
||||
}
|
||||
long occupied = count(Wrappers.<TransportReconciliation>lambdaQuery()
|
||||
.eq(TransportReconciliation::getFormalSettlementId, formal.getId())
|
||||
.ne(request.getId() != null, TransportReconciliation::getId, request.getId()));
|
||||
@@ -394,9 +452,9 @@ public class TransportReconciliationServiceImpl
|
||||
external.setActualCompletionTime(parseTimeNullable(row.getActualCompletionTime(), "实际完成时间"));
|
||||
Map<String, BigDecimal> feeItems = row.getFeeItems();
|
||||
if (feeItems == null || feeItems.isEmpty()) {
|
||||
feeItems = new HashMap<>();
|
||||
feeItems.put("水费", money(row.getFeeItemOne()));
|
||||
feeItems.put("罚款", money(row.getFeeItemTwo()));
|
||||
feeItems = new LinkedHashMap<>();
|
||||
if (row.getFeeItemOne() != null) feeItems.put("水费", money(row.getFeeItemOne()));
|
||||
if (row.getFeeItemTwo() != null) feeItems.put("罚款", money(row.getFeeItemTwo()));
|
||||
}
|
||||
external.setFeeItemsJson(JsonUtil.toJson(feeItems));
|
||||
external.setMatchStatus(UNMATCHED);
|
||||
@@ -434,7 +492,7 @@ public class TransportReconciliationServiceImpl
|
||||
addImportDecimalErrors(validationErrors, row.getMileage(), "里程(KM)", 2);
|
||||
addImportDecimalErrors(validationErrors, row.getUnitPrice(), "运输单价", 2);
|
||||
addImportDecimalErrors(validationErrors, row.getFreightAmount(), "运输费", 2);
|
||||
if (row.getFeeItems() != null) {
|
||||
if (row.getFeeItems() != null && !row.getFeeItems().isEmpty()) {
|
||||
row.getFeeItems().forEach((name, value) -> addImportDecimalErrors(validationErrors, value, name, 2));
|
||||
} else {
|
||||
addImportDecimalErrors(validationErrors, row.getFeeItemOne(), "水费", 2);
|
||||
|
||||
+78
-4
@@ -28,12 +28,15 @@ package org.springblade.transport.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.transport.excel.TransportVehicleExcel;
|
||||
import org.springblade.transport.mapper.DriverMapper;
|
||||
import org.springblade.transport.mapper.TransportVehicleMapper;
|
||||
import org.springblade.transport.pojo.entity.Driver;
|
||||
import org.springblade.transport.pojo.entity.TransportVehicle;
|
||||
import org.springblade.transport.pojo.vo.TransportVehicleExpiryStatVO;
|
||||
import org.springblade.transport.pojo.vo.TransportVehicleVO;
|
||||
@@ -42,9 +45,13 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 车辆管理 服务实现类
|
||||
@@ -52,9 +59,13 @@ import java.util.regex.Pattern;
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicleMapper, TransportVehicle> implements ITransportVehicleService {
|
||||
|
||||
private static final Pattern PLATE_NO_PATTERN = Pattern.compile("^[\\u4e00-\\u9fa5][A-Z][A-Z0-9挂学警港澳]{5,6}$");
|
||||
private static final String PLATE_COLOR_BLUE = "蓝牌";
|
||||
private static final String PLATE_COLOR_YELLOW = "黄牌";
|
||||
private static final String PLATE_COLOR_GREEN = "绿牌";
|
||||
private static final int SHORT_TEXT_MAX_LENGTH = 50;
|
||||
private static final int ORG_MAX_LENGTH = 50;
|
||||
private static final int REMARK_MAX_LENGTH = 200;
|
||||
@@ -64,10 +75,55 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
||||
private static final int CERTIFICATION_APPROVED = 1;
|
||||
private static final int CERTIFICATION_REJECTED = 2;
|
||||
|
||||
private final DriverMapper driverMapper;
|
||||
|
||||
@Override
|
||||
public IPage<TransportVehicleVO> selectTransportVehiclePage(IPage<TransportVehicleVO> page, TransportVehicleVO vehicle) {
|
||||
prepareQuery(vehicle);
|
||||
return page.setRecords(baseMapper.selectTransportVehiclePage(page, vehicle));
|
||||
List<TransportVehicleVO> records = baseMapper.selectTransportVehiclePage(page, vehicle);
|
||||
fillBoundDrivers(records);
|
||||
return page.setRecords(records);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按车牌反查司机驾驶车辆,填充车辆列表「绑定司机」。
|
||||
*/
|
||||
private void fillBoundDrivers(List<TransportVehicleVO> records) {
|
||||
if (Func.isEmpty(records)) {
|
||||
return;
|
||||
}
|
||||
List<String> plateNos = records.stream()
|
||||
.map(TransportVehicleVO::getPlateNo)
|
||||
.filter(Func::isNotEmpty)
|
||||
.map(String::toUpperCase)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (plateNos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Driver> drivers = driverMapper.selectList(Wrappers.<Driver>lambdaQuery()
|
||||
.eq(Driver::getIsDeleted, 0)
|
||||
.in(Driver::getDrivingVehicle, plateNos)
|
||||
.select(Driver::getDriverName, Driver::getDrivingVehicle));
|
||||
Map<String, List<String>> namesByPlate = new LinkedHashMap<>();
|
||||
for (Driver driver : drivers) {
|
||||
if (Func.isEmpty(driver.getDrivingVehicle()) || Func.isEmpty(driver.getDriverName())) {
|
||||
continue;
|
||||
}
|
||||
namesByPlate
|
||||
.computeIfAbsent(driver.getDrivingVehicle().toUpperCase(), key -> new ArrayList<>())
|
||||
.add(driver.getDriverName());
|
||||
}
|
||||
for (TransportVehicleVO record : records) {
|
||||
if (Func.isEmpty(record.getPlateNo())) {
|
||||
continue;
|
||||
}
|
||||
List<String> names = namesByPlate.get(record.getPlateNo().toUpperCase());
|
||||
if (Func.isEmpty(names)) {
|
||||
continue;
|
||||
}
|
||||
record.setBoundDriver(names.stream().distinct().collect(Collectors.joining("、")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,8 +204,10 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
||||
|
||||
private void prepare(TransportVehicle vehicle) {
|
||||
vehicle.setOrganizationName(trimToEmpty(vehicle.getOrganizationName()));
|
||||
vehicle.setUseDepartment(trimToNull(vehicle.getUseDepartment()));
|
||||
vehicle.setPlateNo(trimToEmpty(vehicle.getPlateNo()).toUpperCase());
|
||||
vehicle.setPlateColor(trimToNull(vehicle.getPlateColor()));
|
||||
// 车牌颜色由车牌号规则推断,不接收前端传入值
|
||||
vehicle.setPlateColor(resolvePlateColor(vehicle.getPlateNo()));
|
||||
vehicle.setVehicleType(trimToEmpty(vehicle.getVehicleType()));
|
||||
vehicle.setBusinessRelation(trimToEmpty(vehicle.getBusinessRelation()));
|
||||
vehicle.setEnergyType(trimToEmpty(vehicle.getEnergyType()));
|
||||
@@ -181,6 +239,22 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据车牌号推断车牌颜色:新能源 8 位为绿牌,含“挂”为黄牌,其余为蓝牌。
|
||||
*/
|
||||
private String resolvePlateColor(String plateNo) {
|
||||
if (Func.isEmpty(plateNo)) {
|
||||
return null;
|
||||
}
|
||||
if (plateNo.length() == 8) {
|
||||
return PLATE_COLOR_GREEN;
|
||||
}
|
||||
if (plateNo.contains("挂")) {
|
||||
return PLATE_COLOR_YELLOW;
|
||||
}
|
||||
return PLATE_COLOR_BLUE;
|
||||
}
|
||||
|
||||
private void validate(TransportVehicle vehicle) {
|
||||
if (Func.isEmpty(vehicle.getOrganizationName())) {
|
||||
throw new ServiceException("所属组织不能为空");
|
||||
@@ -192,7 +266,7 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
||||
throw new ServiceException("车牌号格式不正确");
|
||||
}
|
||||
if (Func.isEmpty(vehicle.getPlateColor())) {
|
||||
throw new ServiceException("车牌颜色不能为空");
|
||||
throw new ServiceException("无法根据车牌号识别车牌颜色");
|
||||
}
|
||||
if (Func.isEmpty(vehicle.getVehicleType())) {
|
||||
throw new ServiceException("车辆类型不能为空");
|
||||
@@ -230,7 +304,7 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
||||
validateNonNegative(vehicle.getApprovedLoadKg(), "核定载质量不能小于0");
|
||||
validateNonNegative(vehicle.getTractionMassKg(), "准牵引总质量不能小于0");
|
||||
validateLength(vehicle.getOrganizationName(), ORG_MAX_LENGTH, "所属组织不能超过50字");
|
||||
validateLength(vehicle.getPlateColor(), SHORT_TEXT_MAX_LENGTH, "车牌颜色不能超过50字");
|
||||
validateLength(vehicle.getUseDepartment(), ORG_MAX_LENGTH, "使用部门不能超过50字");
|
||||
validateLength(vehicle.getVehicleType(), SHORT_TEXT_MAX_LENGTH, "车辆类型不能超过50字");
|
||||
validateLength(vehicle.getBusinessRelation(), SHORT_TEXT_MAX_LENGTH, "业务关系不能超过50字");
|
||||
validateLength(vehicle.getEnergyType(), SHORT_TEXT_MAX_LENGTH, "能源类型不能超过50字");
|
||||
|
||||
+10
-4
@@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.common.excel.ImportFailureExcelUtil;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
@@ -258,7 +259,7 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
if (Func.isEmpty(request.getImportType())) throw new ServiceException("请选择导入类型");
|
||||
WaybillImportBatch batch = new WaybillImportBatch();
|
||||
BeanUtil.copyProperties(request, batch);
|
||||
batch.setBatchNo(Func.isEmpty(request.getBatchNo()) ? nextCode() : request.getBatchNo());
|
||||
batch.setBatchNo(Func.isEmpty(request.getId()) ? nextCode() : request.getBatchNo());
|
||||
batch.setCarrierIds(joinIds(request.getCarrierIds()));
|
||||
batch.setCarrierName(resolveCarrierNames(request.getCarrierIds(), request.getCarrierName()));
|
||||
batch.setImportStatus(importStatus);
|
||||
@@ -422,10 +423,15 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextBatchNo() {
|
||||
return nextCode();
|
||||
}
|
||||
|
||||
private synchronized String nextCode() {
|
||||
String prefix = "YDB" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
long count = count(Wrappers.<WaybillImportBatch>lambdaQuery().likeRight(WaybillImportBatch::getBatchNo, prefix));
|
||||
return prefix + String.format("%04d", count + 1);
|
||||
String prefix = "PC" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
Long maxSequence = baseMapper.selectMaxDailySequence(AuthUtil.getTenantId(), prefix);
|
||||
return prefix + String.format("%04d", (maxSequence == null ? 0 : maxSequence) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user