1、调整导入运单
2、调整对账
This commit is contained in:
+11
@@ -64,6 +64,7 @@ public interface ISysClient {
|
|||||||
String ROLE_NAMES = API_PREFIX + "/role-names";
|
String ROLE_NAMES = API_PREFIX + "/role-names";
|
||||||
String ROLE_ALIAS = API_PREFIX + "/role-alias";
|
String ROLE_ALIAS = API_PREFIX + "/role-alias";
|
||||||
String ROLE_ALIASES = API_PREFIX + "/role-aliases";
|
String ROLE_ALIASES = API_PREFIX + "/role-aliases";
|
||||||
|
String ROLE_ID_BY_ALIAS = API_PREFIX + "/role-id-by-alias";
|
||||||
String TENANT = API_PREFIX + "/tenant";
|
String TENANT = API_PREFIX + "/tenant";
|
||||||
String TENANT_ID = API_PREFIX + "/tenant-id";
|
String TENANT_ID = API_PREFIX + "/tenant-id";
|
||||||
String TENANT_PACKAGE = API_PREFIX + "/tenant-package";
|
String TENANT_PACKAGE = API_PREFIX + "/tenant-package";
|
||||||
@@ -240,6 +241,16 @@ public interface ISysClient {
|
|||||||
@GetMapping(ROLE_ALIASES)
|
@GetMapping(ROLE_ALIASES)
|
||||||
R<List<String>> getRoleAliases(@RequestParam("roleIds") String roleIds);
|
R<List<String>> getRoleAliases(@RequestParam("roleIds") String roleIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色别名获取角色id
|
||||||
|
*
|
||||||
|
* @param tenantId 租户id
|
||||||
|
* @param roleAlias 角色别名
|
||||||
|
* @return 角色id
|
||||||
|
*/
|
||||||
|
@GetMapping(ROLE_ID_BY_ALIAS)
|
||||||
|
R<String> getRoleIdByAlias(@RequestParam("tenantId") String tenantId, @RequestParam("roleAlias") String roleAlias);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取租户
|
* 获取租户
|
||||||
*
|
*
|
||||||
|
|||||||
+5
@@ -129,6 +129,11 @@ public class ISysClientFallback implements ISysClient {
|
|||||||
return R.fail("获取数据失败");
|
return R.fail("获取数据失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> getRoleIdByAlias(String tenantId, String roleAlias) {
|
||||||
|
return R.fail("获取数据失败");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Tenant> getTenant(Long id) {
|
public R<Tenant> getTenant(Long id) {
|
||||||
return R.fail("获取数据失败");
|
return R.fail("获取数据失败");
|
||||||
|
|||||||
+5
@@ -191,6 +191,11 @@ public class Driver extends TenantEntity {
|
|||||||
*/
|
*/
|
||||||
@Schema(description = "手机号")
|
@Schema(description = "手机号")
|
||||||
private String mobile;
|
private String mobile;
|
||||||
|
/**
|
||||||
|
* 关联系统用户ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联系统用户ID")
|
||||||
|
private Long userId;
|
||||||
/**
|
/**
|
||||||
* 与联系人关系
|
* 与联系人关系
|
||||||
*/
|
*/
|
||||||
|
|||||||
+7
@@ -118,6 +118,9 @@ public class ProjectApply extends TenantEntity {
|
|||||||
@Schema(description = "业务类型")
|
@Schema(description = "业务类型")
|
||||||
private String businessType;
|
private String businessType;
|
||||||
|
|
||||||
|
@Schema(description = "业务模式")
|
||||||
|
private String businessMode;
|
||||||
|
|
||||||
@Schema(description = "项目规模(万元)")
|
@Schema(description = "项目规模(万元)")
|
||||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private BigDecimal projectScale;
|
private BigDecimal projectScale;
|
||||||
@@ -126,6 +129,10 @@ public class ProjectApply extends TenantEntity {
|
|||||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private BigDecimal estimatedProfit;
|
private BigDecimal estimatedProfit;
|
||||||
|
|
||||||
|
@Schema(description = "利润率(%)")
|
||||||
|
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||||
|
private BigDecimal profitRate;
|
||||||
|
|
||||||
@Schema(description = "资金需求(万元)")
|
@Schema(description = "资金需求(万元)")
|
||||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private BigDecimal fundDemand;
|
private BigDecimal fundDemand;
|
||||||
|
|||||||
+5
@@ -53,6 +53,11 @@ public class TransportVehicle extends TenantEntity {
|
|||||||
*/
|
*/
|
||||||
@Schema(description = "所属组织")
|
@Schema(description = "所属组织")
|
||||||
private String organizationName;
|
private String organizationName;
|
||||||
|
/**
|
||||||
|
* 使用部门
|
||||||
|
*/
|
||||||
|
@Schema(description = "使用部门")
|
||||||
|
private String useDepartment;
|
||||||
/**
|
/**
|
||||||
* 车牌号
|
* 车牌号
|
||||||
*/
|
*/
|
||||||
|
|||||||
+7
@@ -69,4 +69,11 @@ public class TransportVehicleVO extends TransportVehicle {
|
|||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDate warningDate;
|
private LocalDate warningDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定司机(按车牌反查司机驾驶车辆,多个用顿号拼接)
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Schema(description = "绑定司机")
|
||||||
|
private String boundDriver;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -57,6 +57,7 @@ public interface IUserClient {
|
|||||||
String USER_BY_ACCOUNT = API_PREFIX + "/user-by-account";
|
String USER_BY_ACCOUNT = API_PREFIX + "/user-by-account";
|
||||||
String USER_AUTH_INFO = API_PREFIX + "/user-auth-info";
|
String USER_AUTH_INFO = API_PREFIX + "/user-auth-info";
|
||||||
String SAVE_USER = API_PREFIX + "/save-user";
|
String SAVE_USER = API_PREFIX + "/save-user";
|
||||||
|
String UPDATE_USER = API_PREFIX + "/update-user";
|
||||||
String SAVE_IAM_USER = API_PREFIX + "/save-iam-user";
|
String SAVE_IAM_USER = API_PREFIX + "/save-iam-user";
|
||||||
String REGISTER_USER = API_PREFIX + "/register-user";
|
String REGISTER_USER = API_PREFIX + "/register-user";
|
||||||
String REMOVE_USER = API_PREFIX + "/remove-user";
|
String REMOVE_USER = API_PREFIX + "/remove-user";
|
||||||
@@ -150,6 +151,15 @@ public interface IUserClient {
|
|||||||
@PostMapping(SAVE_USER)
|
@PostMapping(SAVE_USER)
|
||||||
R<Boolean> saveUser(@RequestBody User user);
|
R<Boolean> saveUser(@RequestBody User user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户
|
||||||
|
*
|
||||||
|
* @param user 用户实体
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(UPDATE_USER)
|
||||||
|
R<Boolean> updateUser(@RequestBody User user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建IAM用户
|
* 新建IAM用户
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -167,6 +167,16 @@ public class SysClient implements ISysClient {
|
|||||||
return R.data(roleService.getRoleAliases(roleIds));
|
return R.data(roleService.getRoleAliases(roleIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@GetMapping(ROLE_ID_BY_ALIAS)
|
||||||
|
public R<String> getRoleIdByAlias(String tenantId, String roleAlias) {
|
||||||
|
Role role = roleService.getOne(Wrappers.<Role>lambdaQuery()
|
||||||
|
.eq(Role::getTenantId, tenantId)
|
||||||
|
.eq(Role::getRoleAlias, roleAlias)
|
||||||
|
.last("LIMIT 1"));
|
||||||
|
return R.data(role == null || role.getId() == null ? null : String.valueOf(role.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@GetMapping(TENANT)
|
@GetMapping(TENANT)
|
||||||
public R<Tenant> getTenant(Long id) {
|
public R<Tenant> getTenant(Long id) {
|
||||||
|
|||||||
@@ -108,6 +108,12 @@ public class UserClient implements IUserClient {
|
|||||||
return R.data(service.submit(user));
|
return R.data(service.submit(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PostMapping(UPDATE_USER)
|
||||||
|
public R<Boolean> updateUser(@RequestBody User user) {
|
||||||
|
return R.data(service.updateUser(user));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PostMapping(SAVE_IAM_USER)
|
@PostMapping(SAVE_IAM_USER)
|
||||||
public R<Boolean> saveIamUser(@RequestBody User user) {
|
public R<Boolean> saveIamUser(@RequestBody User user) {
|
||||||
|
|||||||
+7
-3
@@ -23,6 +23,7 @@ import org.springblade.core.excel.util.ExcelUtil;
|
|||||||
import org.springblade.transport.excel.CargoReconciliationExcel;
|
import org.springblade.transport.excel.CargoReconciliationExcel;
|
||||||
import org.springblade.transport.excel.CargoReconciliationFeeReader;
|
import org.springblade.transport.excel.CargoReconciliationFeeReader;
|
||||||
import org.springblade.transport.excel.CargoReconciliationFailureExcel;
|
import org.springblade.transport.excel.CargoReconciliationFailureExcel;
|
||||||
|
import org.springblade.transport.excel.ReconciliationImportTemplateExcel;
|
||||||
import org.springblade.transport.excel.VehicleReconciliationExcel;
|
import org.springblade.transport.excel.VehicleReconciliationExcel;
|
||||||
import org.springblade.transport.excel.VehicleReconciliationFeeReader;
|
import org.springblade.transport.excel.VehicleReconciliationFeeReader;
|
||||||
import org.springblade.transport.excel.VehicleReconciliationFailureExcel;
|
import org.springblade.transport.excel.VehicleReconciliationFailureExcel;
|
||||||
@@ -154,9 +155,12 @@ public class TransportReconciliationController extends BladeController {
|
|||||||
@GetMapping("/template")
|
@GetMapping("/template")
|
||||||
@ApiOperationSupport(order = 8)
|
@ApiOperationSupport(order = 8)
|
||||||
@Operation(summary = "下载运输对账模板")
|
@Operation(summary = "下载运输对账模板")
|
||||||
public void template(@RequestParam String mode, HttpServletResponse response) {
|
public void template(@RequestParam String mode, @RequestParam(required = false) Long id,
|
||||||
if ("cargo".equals(mode)) ExcelUtil.export(response, "货物明细对账模板", "货物明细对账模板", new ArrayList<CargoReconciliationExcel>(), CargoReconciliationExcel.class);
|
@RequestParam(required = false) Long formalSettlementId, @RequestParam(required = false) String feeItems,
|
||||||
else ExcelUtil.export(response, "整车总额对账模板", "整车总额对账模板", new ArrayList<VehicleReconciliationExcel>(), VehicleReconciliationExcel.class);
|
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")
|
@PostMapping("/match")
|
||||||
|
|||||||
+8
-1
@@ -131,8 +131,15 @@ public class WaybillController extends BladeController {
|
|||||||
return R.data(options);
|
return R.data(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/import-batch/list")
|
@GetMapping("/import-batch/next-code")
|
||||||
@ApiOperationSupport(order = 4)
|
@ApiOperationSupport(order = 4)
|
||||||
|
@Operation(summary = "下一个运单批次号")
|
||||||
|
public R<String> importBatchNextCode() {
|
||||||
|
return R.data(waybillImportBatchService.nextBatchNo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/import-batch/list")
|
||||||
|
@ApiOperationSupport(order = 5)
|
||||||
@Operation(summary = "运单批量导入批次分页")
|
@Operation(summary = "运单批量导入批次分页")
|
||||||
public R<IPage<WaybillImportBatchVO>> importBatchList(WaybillImportBatchRequest request, Query query) {
|
public R<IPage<WaybillImportBatchVO>> importBatchList(WaybillImportBatchRequest request, Query query) {
|
||||||
return R.data(waybillImportBatchService.page(Condition.getPage(query), request));
|
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("运输单价") @NumberFormat("0.00") private BigDecimal unitPrice;
|
||||||
@ExcelProperty("里程(KM)") @NumberFormat("0.00") private BigDecimal mileage;
|
@ExcelProperty("里程(KM)") @NumberFormat("0.00") private BigDecimal mileage;
|
||||||
@ExcelProperty("运输费") @NumberFormat("0.00") private BigDecimal freightAmount;
|
@ExcelProperty("运输费") @NumberFormat("0.00") private BigDecimal freightAmount;
|
||||||
@ExcelProperty("水费") @NumberFormat("0.00") private BigDecimal feeItemOne;
|
@ExcelIgnore @NumberFormat("0.00") private BigDecimal feeItemOne;
|
||||||
@ExcelProperty("罚款") @NumberFormat("0.00") private BigDecimal feeItemTwo;
|
@ExcelIgnore @NumberFormat("0.00") private BigDecimal feeItemTwo;
|
||||||
@ExcelProperty("结算费用合计") @NumberFormat("0.00") private BigDecimal settlementAmount;
|
@ExcelProperty("结算费用合计") @NumberFormat("0.00") private BigDecimal settlementAmount;
|
||||||
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
||||||
@ExcelIgnore private String errorMessage;
|
@ExcelIgnore private String errorMessage;
|
||||||
|
|||||||
+4
@@ -86,10 +86,14 @@ public class ProjectApplyExcel implements Serializable {
|
|||||||
private String transportType;
|
private String transportType;
|
||||||
@ExcelProperty("业务类型")
|
@ExcelProperty("业务类型")
|
||||||
private String businessType;
|
private String businessType;
|
||||||
|
@ExcelProperty("业务模式")
|
||||||
|
private String businessMode;
|
||||||
@ExcelProperty("项目规模(万元)")
|
@ExcelProperty("项目规模(万元)")
|
||||||
private BigDecimal projectScale;
|
private BigDecimal projectScale;
|
||||||
@ExcelProperty("预计利润(万元)")
|
@ExcelProperty("预计利润(万元)")
|
||||||
private BigDecimal estimatedProfit;
|
private BigDecimal estimatedProfit;
|
||||||
|
@ExcelProperty("利润率(%)")
|
||||||
|
private BigDecimal profitRate;
|
||||||
@ExcelProperty("资金需求(万元)")
|
@ExcelProperty("资金需求(万元)")
|
||||||
private BigDecimal fundDemand;
|
private BigDecimal fundDemand;
|
||||||
@ExcelProperty("结算方式")
|
@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("所属组织 *")
|
@ExcelProperty("所属组织 *")
|
||||||
private String organizationName;
|
private String organizationName;
|
||||||
|
|
||||||
|
@ExcelProperty("使用部门")
|
||||||
|
private String useDepartment;
|
||||||
|
|
||||||
@ExcelProperty("业务关系 *")
|
@ExcelProperty("业务关系 *")
|
||||||
private String businessRelation;
|
private String businessRelation;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class VehicleReconciliationExcel implements Serializable {
|
|||||||
@ExcelProperty("批次号") private String batchNo;
|
@ExcelProperty("批次号") private String batchNo;
|
||||||
@ExcelProperty("运输单价") @NumberFormat("0.00") private BigDecimal unitPrice;
|
@ExcelProperty("运输单价") @NumberFormat("0.00") private BigDecimal unitPrice;
|
||||||
@ExcelProperty("运输费") @NumberFormat("0.00") private BigDecimal freightAmount;
|
@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;
|
@ExcelProperty("结算费用合计") @NumberFormat("0.00") private BigDecimal settlementAmount;
|
||||||
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
@ExcelIgnore private Map<String, BigDecimal> feeItems;
|
||||||
@ExcelIgnore private String errorMessage;
|
@ExcelIgnore private String errorMessage;
|
||||||
|
|||||||
+2
@@ -40,6 +40,7 @@
|
|||||||
<result column="qualification_back" property="qualificationBack"/>
|
<result column="qualification_back" property="qualificationBack"/>
|
||||||
<result column="driver_type" property="driverType"/>
|
<result column="driver_type" property="driverType"/>
|
||||||
<result column="mobile" property="mobile"/>
|
<result column="mobile" property="mobile"/>
|
||||||
|
<result column="user_id" property="userId"/>
|
||||||
<result column="contact_relation" property="contactRelation"/>
|
<result column="contact_relation" property="contactRelation"/>
|
||||||
<result column="organization_name" property="organizationName"/>
|
<result column="organization_name" property="organizationName"/>
|
||||||
<result column="emergency_contact_name" property="emergencyContactName"/>
|
<result column="emergency_contact_name" property="emergencyContactName"/>
|
||||||
@@ -85,6 +86,7 @@
|
|||||||
qualification_back,
|
qualification_back,
|
||||||
driver_type,
|
driver_type,
|
||||||
mobile,
|
mobile,
|
||||||
|
user_id,
|
||||||
contact_relation,
|
contact_relation,
|
||||||
organization_name,
|
organization_name,
|
||||||
emergency_contact_name,
|
emergency_contact_name,
|
||||||
|
|||||||
+6
@@ -13,6 +13,7 @@
|
|||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="is_deleted" property="isDeleted"/>
|
<result column="is_deleted" property="isDeleted"/>
|
||||||
<result column="organization_name" property="organizationName"/>
|
<result column="organization_name" property="organizationName"/>
|
||||||
|
<result column="use_department" property="useDepartment"/>
|
||||||
<result column="plate_no" property="plateNo"/>
|
<result column="plate_no" property="plateNo"/>
|
||||||
<result column="plate_color" property="plateColor"/>
|
<result column="plate_color" property="plateColor"/>
|
||||||
<result column="vehicle_type" property="vehicleType"/>
|
<result column="vehicle_type" property="vehicleType"/>
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
status,
|
status,
|
||||||
is_deleted,
|
is_deleted,
|
||||||
organization_name,
|
organization_name,
|
||||||
|
use_department,
|
||||||
plate_no,
|
plate_no,
|
||||||
plate_color,
|
plate_color,
|
||||||
vehicle_type,
|
vehicle_type,
|
||||||
@@ -116,6 +118,10 @@
|
|||||||
<bind name="organizationNameLike" value="'%' + vehicle.organizationName + '%'"/>
|
<bind name="organizationNameLike" value="'%' + vehicle.organizationName + '%'"/>
|
||||||
AND organization_name LIKE #{organizationNameLike}
|
AND organization_name LIKE #{organizationNameLike}
|
||||||
</if>
|
</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 != ''">
|
<if test="vehicle.plateNo != null and vehicle.plateNo != ''">
|
||||||
<bind name="plateNoLike" value="'%' + vehicle.plateNo + '%'"/>
|
<bind name="plateNoLike" value="'%' + vehicle.plateNo + '%'"/>
|
||||||
AND plate_no LIKE #{plateNoLike}
|
AND plate_no LIKE #{plateNoLike}
|
||||||
|
|||||||
+11
@@ -6,9 +6,20 @@ package org.springblade.transport.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
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;
|
import org.springblade.transport.pojo.entity.WaybillImportBatch;
|
||||||
|
|
||||||
/** 运单批次 Mapper。 */
|
/** 运单批次 Mapper。 */
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface WaybillImportBatchMapper extends BaseMapper<WaybillImportBatch> {
|
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> {
|
public interface ITransportReconciliationService extends BaseService<TransportReconciliation> {
|
||||||
IPage<TransportReconciliationVO> selectPage(IPage<TransportReconciliation> page, TransportReconciliationVO query);
|
IPage<TransportReconciliationVO> selectPage(IPage<TransportReconciliation> page, TransportReconciliationVO query);
|
||||||
IPage<FormalSettlement> formalOptions(IPage<FormalSettlement> page, String settlementType, String keyword);
|
IPage<FormalSettlement> formalOptions(IPage<FormalSettlement> page, String settlementType, String keyword);
|
||||||
|
List<String> templateFeeItems(Long id, Long formalSettlementId, String feeItems);
|
||||||
TransportReconciliationVO detail(Long id);
|
TransportReconciliationVO detail(Long id);
|
||||||
Long saveDraft(TransportReconciliationSaveRequest request);
|
Long saveDraft(TransportReconciliationSaveRequest request);
|
||||||
void removeDraft(Long id);
|
void removeDraft(Long id);
|
||||||
|
|||||||
+1
@@ -15,4 +15,5 @@ public interface IWaybillImportBatchService extends BaseService<WaybillImportBat
|
|||||||
void confirm(WaybillImportBatchRequest request, HttpServletResponse response);
|
void confirm(WaybillImportBatchRequest request, HttpServletResponse response);
|
||||||
IPage<WaybillImportBatchVO> page(IPage<WaybillImportBatch> page, WaybillImportBatchRequest request);
|
IPage<WaybillImportBatchVO> page(IPage<WaybillImportBatch> page, WaybillImportBatchRequest request);
|
||||||
BusinessRemoveResultVO removeBatches(String ids);
|
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.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
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.log.exception.ServiceException;
|
||||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
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.BeanUtil;
|
||||||
import org.springblade.core.tool.utils.Func;
|
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.excel.DriverExcel;
|
||||||
import org.springblade.transport.mapper.DriverMapper;
|
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.Driver;
|
||||||
|
import org.springblade.transport.pojo.entity.TransportVehicle;
|
||||||
import org.springblade.transport.pojo.vo.DriverExpiryStatVO;
|
import org.springblade.transport.pojo.vo.DriverExpiryStatVO;
|
||||||
import org.springblade.transport.pojo.vo.DriverVO;
|
import org.springblade.transport.pojo.vo.DriverVO;
|
||||||
import org.springblade.transport.service.IDriverService;
|
import org.springblade.transport.service.IDriverService;
|
||||||
@@ -50,6 +62,7 @@ import java.util.Objects;
|
|||||||
* @author Chill
|
* @author Chill
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> implements IDriverService {
|
public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> implements IDriverService {
|
||||||
|
|
||||||
private static final int NAME_MAX_LENGTH = 10;
|
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_ENABLED_STATUS = 1;
|
||||||
private static final int DEFAULT_FALSE = 0;
|
private static final int DEFAULT_FALSE = 0;
|
||||||
|
|
||||||
|
private final TransportVehicleMapper transportVehicleMapper;
|
||||||
|
private final IUserClient userClient;
|
||||||
|
private final ISysClient sysClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<DriverVO> selectDriverPage(IPage<DriverVO> page, DriverVO driver) {
|
public IPage<DriverVO> selectDriverPage(IPage<DriverVO> page, DriverVO driver) {
|
||||||
prepareQuery(driver);
|
prepareQuery(driver);
|
||||||
@@ -74,7 +91,13 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
|||||||
prepare(driver);
|
prepare(driver);
|
||||||
validate(driver);
|
validate(driver);
|
||||||
prepareSubmitTarget(driver);
|
prepareSubmitTarget(driver);
|
||||||
return saveOrUpdate(driver);
|
// 编辑场景下字段无变化时 update 可能返回 false,不能据此跳过用户同步
|
||||||
|
saveOrUpdate(driver);
|
||||||
|
if (Func.isEmpty(driver.getId())) {
|
||||||
|
throw new ServiceException("保存司机失败");
|
||||||
|
}
|
||||||
|
syncDriverUser(driver);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -228,6 +251,14 @@ public class DriverServiceImpl extends BaseServiceImpl<DriverMapper, Driver> imp
|
|||||||
validateLength(driver.getMobile(), MOBILE_MAX_LENGTH, "手机号不能超过20字");
|
validateLength(driver.getMobile(), MOBILE_MAX_LENGTH, "手机号不能超过20字");
|
||||||
validateLength(driver.getEmergencyContactMobile(), MOBILE_MAX_LENGTH, "紧急联系人手机号不能超过20字");
|
validateLength(driver.getEmergencyContactMobile(), MOBILE_MAX_LENGTH, "紧急联系人手机号不能超过20字");
|
||||||
validateLength(driver.getDrivingVehicle(), VEHICLE_NO_MAX_LENGTH, "驾驶车辆不能超过30字");
|
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.getDrivingLicenseNo(), SHORT_TEXT_MAX_LENGTH, "驾驶证档案编号不能超过50字");
|
||||||
validateLength(driver.getQualificationNo(), SHORT_TEXT_MAX_LENGTH, "资格证号不能超过50字");
|
validateLength(driver.getQualificationNo(), SHORT_TEXT_MAX_LENGTH, "资格证号不能超过50字");
|
||||||
validateLength(driver.getOrganizationName(), 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) {
|
private Long defaultZero(Long value) {
|
||||||
return value == null ? 0L : value;
|
return value == null ? 0L : value;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -348,6 +348,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
projectApply.setTransportRoute(TransportBusinessSupport.trimToNull(projectApply.getTransportRoute()));
|
projectApply.setTransportRoute(TransportBusinessSupport.trimToNull(projectApply.getTransportRoute()));
|
||||||
projectApply.setTransportType(TransportBusinessSupport.trimToNull(projectApply.getTransportType()));
|
projectApply.setTransportType(TransportBusinessSupport.trimToNull(projectApply.getTransportType()));
|
||||||
projectApply.setBusinessType(TransportBusinessSupport.trimToNull(projectApply.getBusinessType()));
|
projectApply.setBusinessType(TransportBusinessSupport.trimToNull(projectApply.getBusinessType()));
|
||||||
|
projectApply.setBusinessMode(TransportBusinessSupport.trimToNull(projectApply.getBusinessMode()));
|
||||||
normalizeOptionalFields(projectApply);
|
normalizeOptionalFields(projectApply);
|
||||||
projectApply.setSettlementMode(TransportBusinessSupport.trimToNull(projectApply.getSettlementMode()));
|
projectApply.setSettlementMode(TransportBusinessSupport.trimToNull(projectApply.getSettlementMode()));
|
||||||
projectApply.setHandlerUserName(TransportBusinessSupport.trimToNull(projectApply.getHandlerUserName()));
|
projectApply.setHandlerUserName(TransportBusinessSupport.trimToNull(projectApply.getHandlerUserName()));
|
||||||
@@ -364,6 +365,9 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
if (projectApply.getEstimatedProfit() != null && projectApply.getEstimatedProfit().signum() < 0) {
|
if (projectApply.getEstimatedProfit() != null && projectApply.getEstimatedProfit().signum() < 0) {
|
||||||
projectApply.setEstimatedProfit(null);
|
projectApply.setEstimatedProfit(null);
|
||||||
}
|
}
|
||||||
|
if (projectApply.getProfitRate() != null && projectApply.getProfitRate().signum() < 0) {
|
||||||
|
projectApply.setProfitRate(null);
|
||||||
|
}
|
||||||
if (projectApply.getFundDemand() != null && projectApply.getFundDemand().signum() < 0) {
|
if (projectApply.getFundDemand() != null && projectApply.getFundDemand().signum() < 0) {
|
||||||
projectApply.setFundDemand(null);
|
projectApply.setFundDemand(null);
|
||||||
}
|
}
|
||||||
@@ -390,9 +394,11 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
target.setTransportRoute(source.getTransportRoute());
|
target.setTransportRoute(source.getTransportRoute());
|
||||||
target.setTransportType(source.getTransportType());
|
target.setTransportType(source.getTransportType());
|
||||||
target.setBusinessType(source.getBusinessType());
|
target.setBusinessType(source.getBusinessType());
|
||||||
|
target.setBusinessMode(source.getBusinessMode());
|
||||||
target.setProjectScale(source.getProjectScale());
|
target.setProjectScale(source.getProjectScale());
|
||||||
target.setSettlementMode(source.getSettlementMode());
|
target.setSettlementMode(source.getSettlementMode());
|
||||||
target.setEstimatedProfit(source.getEstimatedProfit());
|
target.setEstimatedProfit(source.getEstimatedProfit());
|
||||||
|
target.setProfitRate(source.getProfitRate());
|
||||||
target.setFundDemand(source.getFundDemand());
|
target.setFundDemand(source.getFundDemand());
|
||||||
target.setHandlerUserId(source.getHandlerUserId());
|
target.setHandlerUserId(source.getHandlerUserId());
|
||||||
target.setHandlerUserName(source.getHandlerUserName());
|
target.setHandlerUserName(source.getHandlerUserName());
|
||||||
@@ -420,6 +426,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
|
TransportBusinessSupport.validateRequired(projectApply.getProjectShortName(), "请输入项目简称");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
|
TransportBusinessSupport.validateRequired(projectApply.getBusinessDeptName(), "请选择业务部门");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择承办部门");
|
TransportBusinessSupport.validateRequired(projectApply.getUndertakeDeptName(), "请选择承办部门");
|
||||||
|
TransportBusinessSupport.validateRequired(projectApply.getBusinessMode(), "请选择业务模式");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
|
TransportBusinessSupport.validateRequired(projectApply.getCustomerNames(), "请选择客户");
|
||||||
TransportBusinessSupport.validateRequired(projectApply.getCarrierNames(), "请选择下游承运商");
|
TransportBusinessSupport.validateRequired(projectApply.getCarrierNames(), "请选择下游承运商");
|
||||||
validateAmount(projectApply.getFundLimit(), "项目资金使用额度", false);
|
validateAmount(projectApply.getFundLimit(), "项目资金使用额度", false);
|
||||||
@@ -431,6 +438,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl<ProjectApplyMapper,
|
|||||||
validateDays(projectApply.getPaymentDays(), "回款账期");
|
validateDays(projectApply.getPaymentDays(), "回款账期");
|
||||||
validateAmount(projectApply.getProjectScale(), "项目规模", true);
|
validateAmount(projectApply.getProjectScale(), "项目规模", true);
|
||||||
validateAmount(projectApply.getEstimatedProfit(), "预计利润", true);
|
validateAmount(projectApply.getEstimatedProfit(), "预计利润", true);
|
||||||
|
validateAmount(projectApply.getProfitRate(), "利润率", true);
|
||||||
validateAmount(projectApply.getFundDemand(), "资金需求", true);
|
validateAmount(projectApply.getFundDemand(), "资金需求", true);
|
||||||
TransportBusinessSupport.validateDateRange(projectApply.getBusinessStartDate(), projectApply.getBusinessEndDate(), "业务周期开始日期不能晚于结束日期");
|
TransportBusinessSupport.validateDateRange(projectApply.getBusinessStartDate(), projectApply.getBusinessEndDate(), "业务周期开始日期不能晚于结束日期");
|
||||||
if (Func.isEmpty(projectApply.getHandlerUserId()) || Func.isEmpty(projectApply.getPrincipalUserId())) {
|
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.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -93,6 +94,7 @@ public class TransportReconciliationServiceImpl
|
|||||||
private static final String DUPLICATE = "suspected_duplicate";
|
private static final String DUPLICATE = "suspected_duplicate";
|
||||||
private static final String MASTER_ORDER_SOURCE = "总单系统生成";
|
private static final String MASTER_ORDER_SOURCE = "总单系统生成";
|
||||||
private static final String LOADING_ORDER_SOURCE = "配载单系统生成";
|
private static final String LOADING_ORDER_SOURCE = "配载单系统生成";
|
||||||
|
private static final String FORMAL_DRAFT = "draft";
|
||||||
private final FormalSettlementMapper formalSettlementMapper;
|
private final FormalSettlementMapper formalSettlementMapper;
|
||||||
private final FormalSettlementSourceMapper formalSourceMapper;
|
private final FormalSettlementSourceMapper formalSourceMapper;
|
||||||
private final FormalSettlementDetailMapper formalDetailMapper;
|
private final FormalSettlementDetailMapper formalDetailMapper;
|
||||||
@@ -134,7 +136,7 @@ public class TransportReconciliationServiceImpl
|
|||||||
.select(TransportReconciliation::getFormalSettlementId))
|
.select(TransportReconciliation::getFormalSettlementId))
|
||||||
.stream().map(TransportReconciliation::getFormalSettlementId).filter(Objects::nonNull).toList();
|
.stream().map(TransportReconciliation::getFormalSettlementId).filter(Objects::nonNull).toList();
|
||||||
LambdaQueryWrapper<FormalSettlement> wrapper = Wrappers.<FormalSettlement>lambdaQuery()
|
LambdaQueryWrapper<FormalSettlement> wrapper = Wrappers.<FormalSettlement>lambdaQuery()
|
||||||
.eq(FormalSettlement::getApprovalStatus, "approved")
|
.eq(FormalSettlement::getApprovalStatus, FORMAL_DRAFT)
|
||||||
.eq(Func.isNotEmpty(settlementType), FormalSettlement::getSettlementType, settlementType)
|
.eq(Func.isNotEmpty(settlementType), FormalSettlement::getSettlementType, settlementType)
|
||||||
.and(Func.isNotEmpty(keyword), value -> value.like(FormalSettlement::getFormalSettlementNo, keyword)
|
.and(Func.isNotEmpty(keyword), value -> value.like(FormalSettlement::getFormalSettlementNo, keyword)
|
||||||
.or().like(FormalSettlement::getContractNo, keyword).or().like(FormalSettlement::getContractName, 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));
|
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
|
@Override
|
||||||
public TransportReconciliationVO detail(Long id) {
|
public TransportReconciliationVO detail(Long id) {
|
||||||
TransportReconciliationVO vo = TransportReconciliationWrapper.build().entityVO(existing(id));
|
TransportReconciliationVO vo = TransportReconciliationWrapper.build().entityVO(existing(id));
|
||||||
@@ -166,7 +222,9 @@ public class TransportReconciliationServiceImpl
|
|||||||
throw new ServiceException("请选择正确的对账模式");
|
throw new ServiceException("请选择正确的对账模式");
|
||||||
}
|
}
|
||||||
FormalSettlement formal = formalSettlementMapper.selectById(request.getFormalSettlementId());
|
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()
|
long occupied = count(Wrappers.<TransportReconciliation>lambdaQuery()
|
||||||
.eq(TransportReconciliation::getFormalSettlementId, formal.getId())
|
.eq(TransportReconciliation::getFormalSettlementId, formal.getId())
|
||||||
.ne(request.getId() != null, TransportReconciliation::getId, request.getId()));
|
.ne(request.getId() != null, TransportReconciliation::getId, request.getId()));
|
||||||
@@ -394,9 +452,9 @@ public class TransportReconciliationServiceImpl
|
|||||||
external.setActualCompletionTime(parseTimeNullable(row.getActualCompletionTime(), "实际完成时间"));
|
external.setActualCompletionTime(parseTimeNullable(row.getActualCompletionTime(), "实际完成时间"));
|
||||||
Map<String, BigDecimal> feeItems = row.getFeeItems();
|
Map<String, BigDecimal> feeItems = row.getFeeItems();
|
||||||
if (feeItems == null || feeItems.isEmpty()) {
|
if (feeItems == null || feeItems.isEmpty()) {
|
||||||
feeItems = new HashMap<>();
|
feeItems = new LinkedHashMap<>();
|
||||||
feeItems.put("水费", money(row.getFeeItemOne()));
|
if (row.getFeeItemOne() != null) feeItems.put("水费", money(row.getFeeItemOne()));
|
||||||
feeItems.put("罚款", money(row.getFeeItemTwo()));
|
if (row.getFeeItemTwo() != null) feeItems.put("罚款", money(row.getFeeItemTwo()));
|
||||||
}
|
}
|
||||||
external.setFeeItemsJson(JsonUtil.toJson(feeItems));
|
external.setFeeItemsJson(JsonUtil.toJson(feeItems));
|
||||||
external.setMatchStatus(UNMATCHED);
|
external.setMatchStatus(UNMATCHED);
|
||||||
@@ -434,7 +492,7 @@ public class TransportReconciliationServiceImpl
|
|||||||
addImportDecimalErrors(validationErrors, row.getMileage(), "里程(KM)", 2);
|
addImportDecimalErrors(validationErrors, row.getMileage(), "里程(KM)", 2);
|
||||||
addImportDecimalErrors(validationErrors, row.getUnitPrice(), "运输单价", 2);
|
addImportDecimalErrors(validationErrors, row.getUnitPrice(), "运输单价", 2);
|
||||||
addImportDecimalErrors(validationErrors, row.getFreightAmount(), "运输费", 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));
|
row.getFeeItems().forEach((name, value) -> addImportDecimalErrors(validationErrors, value, name, 2));
|
||||||
} else {
|
} else {
|
||||||
addImportDecimalErrors(validationErrors, row.getFeeItemOne(), "水费", 2);
|
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.conditions.Wrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springblade.core.log.exception.ServiceException;
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||||
import org.springblade.core.tool.utils.BeanUtil;
|
import org.springblade.core.tool.utils.BeanUtil;
|
||||||
import org.springblade.core.tool.utils.Func;
|
import org.springblade.core.tool.utils.Func;
|
||||||
import org.springblade.transport.excel.TransportVehicleExcel;
|
import org.springblade.transport.excel.TransportVehicleExcel;
|
||||||
|
import org.springblade.transport.mapper.DriverMapper;
|
||||||
import org.springblade.transport.mapper.TransportVehicleMapper;
|
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.entity.TransportVehicle;
|
||||||
import org.springblade.transport.pojo.vo.TransportVehicleExpiryStatVO;
|
import org.springblade.transport.pojo.vo.TransportVehicleExpiryStatVO;
|
||||||
import org.springblade.transport.pojo.vo.TransportVehicleVO;
|
import org.springblade.transport.pojo.vo.TransportVehicleVO;
|
||||||
@@ -42,9 +45,13 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 车辆管理 服务实现类
|
* 车辆管理 服务实现类
|
||||||
@@ -52,9 +59,13 @@ import java.util.regex.Pattern;
|
|||||||
* @author Chill
|
* @author Chill
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicleMapper, TransportVehicle> implements ITransportVehicleService {
|
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 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 SHORT_TEXT_MAX_LENGTH = 50;
|
||||||
private static final int ORG_MAX_LENGTH = 50;
|
private static final int ORG_MAX_LENGTH = 50;
|
||||||
private static final int REMARK_MAX_LENGTH = 200;
|
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_APPROVED = 1;
|
||||||
private static final int CERTIFICATION_REJECTED = 2;
|
private static final int CERTIFICATION_REJECTED = 2;
|
||||||
|
|
||||||
|
private final DriverMapper driverMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<TransportVehicleVO> selectTransportVehiclePage(IPage<TransportVehicleVO> page, TransportVehicleVO vehicle) {
|
public IPage<TransportVehicleVO> selectTransportVehiclePage(IPage<TransportVehicleVO> page, TransportVehicleVO vehicle) {
|
||||||
prepareQuery(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
|
@Override
|
||||||
@@ -148,8 +204,10 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
|||||||
|
|
||||||
private void prepare(TransportVehicle vehicle) {
|
private void prepare(TransportVehicle vehicle) {
|
||||||
vehicle.setOrganizationName(trimToEmpty(vehicle.getOrganizationName()));
|
vehicle.setOrganizationName(trimToEmpty(vehicle.getOrganizationName()));
|
||||||
|
vehicle.setUseDepartment(trimToNull(vehicle.getUseDepartment()));
|
||||||
vehicle.setPlateNo(trimToEmpty(vehicle.getPlateNo()).toUpperCase());
|
vehicle.setPlateNo(trimToEmpty(vehicle.getPlateNo()).toUpperCase());
|
||||||
vehicle.setPlateColor(trimToNull(vehicle.getPlateColor()));
|
// 车牌颜色由车牌号规则推断,不接收前端传入值
|
||||||
|
vehicle.setPlateColor(resolvePlateColor(vehicle.getPlateNo()));
|
||||||
vehicle.setVehicleType(trimToEmpty(vehicle.getVehicleType()));
|
vehicle.setVehicleType(trimToEmpty(vehicle.getVehicleType()));
|
||||||
vehicle.setBusinessRelation(trimToEmpty(vehicle.getBusinessRelation()));
|
vehicle.setBusinessRelation(trimToEmpty(vehicle.getBusinessRelation()));
|
||||||
vehicle.setEnergyType(trimToEmpty(vehicle.getEnergyType()));
|
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) {
|
private void validate(TransportVehicle vehicle) {
|
||||||
if (Func.isEmpty(vehicle.getOrganizationName())) {
|
if (Func.isEmpty(vehicle.getOrganizationName())) {
|
||||||
throw new ServiceException("所属组织不能为空");
|
throw new ServiceException("所属组织不能为空");
|
||||||
@@ -192,7 +266,7 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
|||||||
throw new ServiceException("车牌号格式不正确");
|
throw new ServiceException("车牌号格式不正确");
|
||||||
}
|
}
|
||||||
if (Func.isEmpty(vehicle.getPlateColor())) {
|
if (Func.isEmpty(vehicle.getPlateColor())) {
|
||||||
throw new ServiceException("车牌颜色不能为空");
|
throw new ServiceException("无法根据车牌号识别车牌颜色");
|
||||||
}
|
}
|
||||||
if (Func.isEmpty(vehicle.getVehicleType())) {
|
if (Func.isEmpty(vehicle.getVehicleType())) {
|
||||||
throw new ServiceException("车辆类型不能为空");
|
throw new ServiceException("车辆类型不能为空");
|
||||||
@@ -230,7 +304,7 @@ public class TransportVehicleServiceImpl extends BaseServiceImpl<TransportVehicl
|
|||||||
validateNonNegative(vehicle.getApprovedLoadKg(), "核定载质量不能小于0");
|
validateNonNegative(vehicle.getApprovedLoadKg(), "核定载质量不能小于0");
|
||||||
validateNonNegative(vehicle.getTractionMassKg(), "准牵引总质量不能小于0");
|
validateNonNegative(vehicle.getTractionMassKg(), "准牵引总质量不能小于0");
|
||||||
validateLength(vehicle.getOrganizationName(), ORG_MAX_LENGTH, "所属组织不能超过50字");
|
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.getVehicleType(), SHORT_TEXT_MAX_LENGTH, "车辆类型不能超过50字");
|
||||||
validateLength(vehicle.getBusinessRelation(), SHORT_TEXT_MAX_LENGTH, "业务关系不能超过50字");
|
validateLength(vehicle.getBusinessRelation(), SHORT_TEXT_MAX_LENGTH, "业务关系不能超过50字");
|
||||||
validateLength(vehicle.getEnergyType(), 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.common.excel.ImportFailureExcelUtil;
|
||||||
import org.springblade.core.log.exception.ServiceException;
|
import org.springblade.core.log.exception.ServiceException;
|
||||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
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.api.R;
|
||||||
import org.springblade.core.tool.utils.BeanUtil;
|
import org.springblade.core.tool.utils.BeanUtil;
|
||||||
import org.springblade.core.tool.utils.DateUtil;
|
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("请选择导入类型");
|
if (Func.isEmpty(request.getImportType())) throw new ServiceException("请选择导入类型");
|
||||||
WaybillImportBatch batch = new WaybillImportBatch();
|
WaybillImportBatch batch = new WaybillImportBatch();
|
||||||
BeanUtil.copyProperties(request, batch);
|
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.setCarrierIds(joinIds(request.getCarrierIds()));
|
||||||
batch.setCarrierName(resolveCarrierNames(request.getCarrierIds(), request.getCarrierName()));
|
batch.setCarrierName(resolveCarrierNames(request.getCarrierIds(), request.getCarrierName()));
|
||||||
batch.setImportStatus(importStatus);
|
batch.setImportStatus(importStatus);
|
||||||
@@ -422,10 +423,15 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
|||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String nextBatchNo() {
|
||||||
|
return nextCode();
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized String nextCode() {
|
private synchronized String nextCode() {
|
||||||
String prefix = "YDB" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
String prefix = "PC" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||||
long count = count(Wrappers.<WaybillImportBatch>lambdaQuery().likeRight(WaybillImportBatch::getBatchNo, prefix));
|
Long maxSequence = baseMapper.selectMaxDailySequence(AuthUtil.getTenantId(), prefix);
|
||||||
return prefix + String.format("%04d", count + 1);
|
return prefix + String.format("%04d", (maxSequence == null ? 0 : maxSequence) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- 项目立项增加业务模式、利润率
|
||||||
|
ALTER TABLE `blade_project_apply`
|
||||||
|
ADD COLUMN `business_mode` varchar(50) DEFAULT NULL COMMENT '业务模式' AFTER `business_type`,
|
||||||
|
ADD COLUMN `profit_rate` decimal(18,2) DEFAULT NULL COMMENT '利润率(%)' AFTER `estimated_profit`;
|
||||||
@@ -33,8 +33,10 @@ CREATE TABLE `blade_project_apply` (
|
|||||||
`transport_route` varchar(200) DEFAULT NULL COMMENT '运输线路',
|
`transport_route` varchar(200) DEFAULT NULL COMMENT '运输线路',
|
||||||
`transport_type` varchar(100) DEFAULT NULL COMMENT '运输类型',
|
`transport_type` varchar(100) DEFAULT NULL COMMENT '运输类型',
|
||||||
`business_type` varchar(100) DEFAULT NULL COMMENT '业务类型',
|
`business_type` varchar(100) DEFAULT NULL COMMENT '业务类型',
|
||||||
|
`business_mode` varchar(50) DEFAULT NULL COMMENT '业务模式',
|
||||||
`project_scale` decimal(18,2) DEFAULT NULL COMMENT '项目规模(万元)',
|
`project_scale` decimal(18,2) DEFAULT NULL COMMENT '项目规模(万元)',
|
||||||
`estimated_profit` decimal(18,2) DEFAULT NULL COMMENT '预计利润(万元)',
|
`estimated_profit` decimal(18,2) DEFAULT NULL COMMENT '预计利润(万元)',
|
||||||
|
`profit_rate` decimal(18,2) DEFAULT NULL COMMENT '利润率(%)',
|
||||||
`fund_demand` decimal(18,2) DEFAULT NULL COMMENT '资金需求(万元)',
|
`fund_demand` decimal(18,2) DEFAULT NULL COMMENT '资金需求(万元)',
|
||||||
`settlement_mode` varchar(100) DEFAULT NULL COMMENT '结算方式',
|
`settlement_mode` varchar(100) DEFAULT NULL COMMENT '结算方式',
|
||||||
`handler_user_id` bigint(20) DEFAULT NULL COMMENT '项目经办人ID',
|
`handler_user_id` bigint(20) DEFAULT NULL COMMENT '项目经办人ID',
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ CREATE TABLE `blade_transport_driver` (
|
|||||||
`qualification_back` varchar(1000) DEFAULT NULL COMMENT '从业资格证内容页',
|
`qualification_back` varchar(1000) DEFAULT NULL COMMENT '从业资格证内容页',
|
||||||
`driver_type` varchar(20) NOT NULL COMMENT '司机类型:自有/外协',
|
`driver_type` varchar(20) NOT NULL COMMENT '司机类型:自有/外协',
|
||||||
`mobile` varchar(20) NOT NULL COMMENT '手机号',
|
`mobile` varchar(20) NOT NULL COMMENT '手机号',
|
||||||
|
`user_id` bigint(20) DEFAULT NULL COMMENT '关联系统用户ID',
|
||||||
`contact_relation` varchar(20) DEFAULT NULL COMMENT '与联系人关系',
|
`contact_relation` varchar(20) DEFAULT NULL COMMENT '与联系人关系',
|
||||||
`organization_name` varchar(50) NOT NULL COMMENT '所属组织',
|
`organization_name` varchar(50) NOT NULL COMMENT '所属组织',
|
||||||
`emergency_contact_name` varchar(20) NOT NULL COMMENT '紧急联系人姓名',
|
`emergency_contact_name` varchar(20) NOT NULL COMMENT '紧急联系人姓名',
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- 司机同步系统用户依赖角色别名 role_alias = 'driver'
|
||||||
|
-- 请在系统管理 -> 角色管理中为对应租户新增/维护角色,并设置角色别名为 driver
|
||||||
|
-- 参考 blade_role 表结构:id, tenant_id, parent_id, role_name, sort, role_alias, status, is_deleted
|
||||||
|
-- 示例(请按实际租户与主键策略自行调整,勿直接照抄执行):
|
||||||
|
-- INSERT INTO blade_role (id, tenant_id, parent_id, role_name, sort, role_alias, status, is_deleted)
|
||||||
|
-- VALUES (你的雪花ID, '你的租户ID', 0, '司机', 10, 'driver', 1, 0);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- 司机表增加关联系统用户ID
|
||||||
|
ALTER TABLE `blade_transport_driver`
|
||||||
|
ADD COLUMN `user_id` bigint(20) DEFAULT NULL COMMENT '关联系统用户ID' AFTER `mobile`;
|
||||||
@@ -6,6 +6,7 @@ CREATE TABLE `blade_transport_vehicle` (
|
|||||||
`id` bigint(20) NOT NULL COMMENT '主键',
|
`id` bigint(20) NOT NULL COMMENT '主键',
|
||||||
`tenant_id` varchar(12) DEFAULT '000000' COMMENT '租户ID',
|
`tenant_id` varchar(12) DEFAULT '000000' COMMENT '租户ID',
|
||||||
`organization_name` varchar(50) NOT NULL COMMENT '所属组织',
|
`organization_name` varchar(50) NOT NULL COMMENT '所属组织',
|
||||||
|
`use_department` varchar(50) DEFAULT NULL COMMENT '使用部门',
|
||||||
`plate_no` varchar(16) NOT NULL COMMENT '车牌号',
|
`plate_no` varchar(16) NOT NULL COMMENT '车牌号',
|
||||||
`plate_color` varchar(20) DEFAULT NULL COMMENT '车牌颜色',
|
`plate_color` varchar(20) DEFAULT NULL COMMENT '车牌颜色',
|
||||||
`vehicle_type` varchar(50) NOT NULL COMMENT '车辆类型',
|
`vehicle_type` varchar(50) NOT NULL COMMENT '车辆类型',
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- 车辆表增加使用部门
|
||||||
|
ALTER TABLE `blade_transport_vehicle`
|
||||||
|
ADD COLUMN `use_department` varchar(50) DEFAULT NULL COMMENT '使用部门' AFTER `organization_name`;
|
||||||
Reference in New Issue
Block a user