🔀 合并 websoft/dev,解决待回单状态与汇票可选冲突

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-24 14:50:05 +08:00
77 changed files with 6109 additions and 293 deletions
@@ -61,6 +61,9 @@ public class OaPersonSyncPageVO implements Serializable {
@Schema(description = "本页跳过条数")
private Integer skippedCount;
@Schema(description = "全量同步结束时删除的、不在本次 OA 数据中的 is_oa=2 人员数")
private Integer removedCount;
@Schema(description = "是否已到最后一页")
private Boolean finished;
@@ -0,0 +1,58 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.feign;
import org.springblade.core.tool.api.R;
import org.springblade.transport.pojo.dto.DriverEnsureProfileDTO;
import org.springblade.transport.pojo.vo.DriverEnsureProfileVO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 司机档案 Feign 接口
*
* @author Chill
*/
@FeignClient(value = "blade-transport")
public interface IDriverClient {
String API_PREFIX = "/feign/client/driver";
String ENSURE_PROFILE = API_PREFIX + "/ensure-profile";
/**
* 查找或创建司机档案,并把档案绑定到指定小程序账号
* <p>
* 幂等入口:按 user_id 命中时原样返回;冲突(同号多档案 / 已被其他账号占用)
* 不新建、不覆盖,通过返回值的 message 说明原因,不抛异常给登录方。
*
* @param param 租户、小程序账号与手机号
* @return 档案ID与本次处置标志
*/
@PostMapping(ENSURE_PROFILE)
R<DriverEnsureProfileVO> ensureProfile(@RequestBody DriverEnsureProfileDTO param);
}
@@ -0,0 +1,55 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.pojo.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 司机档案「查找或创建并绑定账号」参数
*
* @author Chill
*/
@Data
@Schema(description = "司机档案查找或创建参数")
public class DriverEnsureProfileDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "租户ID,为空时取当前请求租户;仍为空则拒绝写库")
private String tenantId;
@Schema(description = "关联小程序用户ID(blade_mp_user.id)")
private Long mpUserId;
@Schema(description = "手机号,仅在按账号未命中时用于查找已有档案")
private String phone;
}
@@ -0,0 +1,55 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.pojo.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 异常处置拒绝请求
* <p>
* 只有拒绝原因一个业务字段:拒绝复用了结终态,不留独立列,
* 原因随跟进记录落进 follow_content。
*
* @author Chill
*/
@Data
@Schema(description = "异常处置拒绝请求")
public class ExceptionDisposalRejectRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "异常处置ID")
private Long id;
@Schema(description = "拒绝原因,必填,最多200字")
private String rejectReason;
}
@@ -0,0 +1,78 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.pojo.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 异常处置「同意并调整路线」请求
* <p>
* 站点按数组顺序即途经顺序回传,kind 是站序的声明:首个 start、末个 end、其余 transit。
* 每个站点上的 tags 指向配载单里第 N 张子运单(形如「装1」「卸2」),后端据此落成站点行;
* 没有配载单的运单没有子运单归属,tags 不参与落库。
*
* @author Chill
*/
@Data
@Schema(description = "异常处置调整路线请求")
public class ExceptionDisposalRouteAdjustRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "异常处置ID")
private Long id;
@Schema(description = "调整后的站点,按途经顺序排列")
private List<RouteNode> routeNodes;
/**
* 一个站点:地址 + 该站装卸的子运单标记
*/
@Data
@Schema(description = "路线站点")
public static class RouteNode implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "站点类型:start 首站、transit 中间站、end 末站")
private String kind;
@Schema(description = "站点地址")
private String address;
@Schema(description = "该站的装卸标记,形如「装1」「卸2」,数字是配载单子运单序号")
private List<String> tags;
}
}
@@ -40,6 +40,7 @@ import org.springblade.transport.jackson.FlexibleLocalDateDeserializer;
import java.io.Serial;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 司机管理实体类
@@ -223,6 +224,17 @@ public class Driver extends TenantEntity {
@Schema(description = "关联小程序用户ID")
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
/**
* 档案来源:login_auto(登录自动建)/ login_bound(绑到已有档案)/
* admin(后台建)/ cert_backfill(存量订正);NULL 表示来源未知
*/
@Schema(description = "档案来源")
private String profileSource;
/**
* 档案与账号建立关联的时点
*/
@Schema(description = "账号绑定时间")
private LocalDateTime accountBoundTime;
/**
* 与联系人关系
*/
@@ -65,6 +65,9 @@ public class AdminWaybillCardVO implements Serializable {
@Schema(description = "状态:0待接单/1运输中/2已完成/3已取消")
private Integer status;
@Schema(description = "原始业务状态:pending / running / pending_return_confirm / completed / cancelled")
private String businessStatus;
@Schema(description = "承运方")
private String carrierName;
@@ -48,6 +48,9 @@ public class AdminWaybillDetailVO implements Serializable {
@Schema(description = "状态:0待接单/1运输中/2已完成/3已取消")
private Integer status;
@Schema(description = "原始业务状态:pending / running / pending_return_confirm / completed / cancelled")
private String businessStatus;
@Schema(description = "起点名称")
private String fromName;
@@ -0,0 +1,58 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.pojo.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 司机档案「查找或创建并绑定账号」结果
*
* @author Chill
*/
@Data
@Schema(description = "司机档案查找或创建结果")
public class DriverEnsureProfileVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "命中的司机档案ID,冲突时为null")
private Long driverId;
@Schema(description = "本次新建了档案")
private Boolean created;
@Schema(description = "本次把已有档案绑定到了账号")
private Boolean boundExisting;
@Schema(description = "冲突原因;成功时为null")
private String message;
}
@@ -52,4 +52,7 @@ public class DriverNodePunchVO implements Serializable {
@Schema(description = "本次打卡是否使运单自动完成")
private Boolean waybillCompleted;
@Schema(description = "本次打卡后的运单业务状态:running / pending_return_confirm / completed")
private String waybillBusinessStatus;
}
@@ -76,6 +76,9 @@ public class DriverWaybillCardVO implements Serializable {
@Schema(description = "状态:0待接单/1运输中/2已完成/3已取消")
private Integer status;
@Schema(description = "原始业务状态:pending / running / pending_return_confirm / completed / cancelled")
private String businessStatus;
@Schema(description = "创建时间")
private String createTime;
@@ -30,6 +30,7 @@ import org.springblade.transport.pojo.entity.ExceptionDisposal;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@@ -93,4 +94,40 @@ public class ExceptionDisposalVO extends ExceptionDisposal {
@Schema(description = "货物信息:{name, weight}")
private Map<String, String> cargo;
@TableField(exist = false)
@Schema(description = "关联运单的配载单号,没有配载单时为空")
private String loadingNo;
@TableField(exist = false)
@Schema(description = "配载单下的子运单号,按配载单运单集合的顺序排列")
private List<String> childWaybillNos;
@TableField(exist = false)
@Schema(description = "可调整的路线站点,少于两个站时为空")
private List<RouteNode> routeNodes;
/**
* 一个可调整的站点:站序声明、地址、该站的装卸标记与项目名
*/
@Data
@Schema(description = "路线站点")
public static class RouteNode implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "站点类型:start 首站、transit 中间站、end 末站")
private String kind;
@Schema(description = "站点地址")
private String address;
@Schema(description = "该站的装卸标记,形如「装1」「卸2」,数字是配载单子运单序号")
private List<String> tags;
@Schema(description = "该站装卸的子运单项目名,按标记顺序去重")
private List<String> projects;
}
}
@@ -65,7 +65,7 @@ public class TripQueryVO implements Serializable {
@Schema(description = "多档状态:同上取值,非空时优先于 status(待处理列表要待接单与进行中两档)")
private List<Integer> statuses;
@Schema(description = "关键字:运单号 / 配载单号 / 起终点 / 车牌")
@Schema(description = "关键字:运单号 / 配载单号 / 项目 / 司机 / 车牌 / 起终点 / 地址(任一子单命中即整趟车命中)")
private String keyword;
@Schema(description = "运输组织类型:load 公路配载 / common 普通运输,不传为全部(按子单行筛选)")
@@ -24,6 +24,7 @@ package org.springblade.system.feign;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.tool.api.R;
import org.springblade.system.pojo.dto.MpUserEnsureDTO;
import org.springblade.system.pojo.entity.MpUser;
import org.springblade.system.pojo.entity.MpUserInfo;
import org.springblade.system.pojo.vo.MpUserDataScopeVO;
@@ -47,6 +48,7 @@ public interface IMpUserClient {
String USER_BY_ID = API_PREFIX + "/user-by-id";
String USER_BY_PHONE = API_PREFIX + "/user-by-phone";
String USER_BY_ACCOUNT = API_PREFIX + "/user-by-account";
String USER_BY_OPENID = API_PREFIX + "/user-by-openid";
String USER_INFO_BY_ID = API_PREFIX + "/info-by-id";
String USER_INFO_BY_PHONE = API_PREFIX + "/info-by-phone";
String USER_INFO_BY_ACCOUNT = API_PREFIX + "/info-by-account";
@@ -55,6 +57,7 @@ public interface IMpUserClient {
String BIND_OPENID = API_PREFIX + "/bind-openid";
String SET_PASSWORD = API_PREFIX + "/set-password";
String RESOLVE_DATA_SCOPE = API_PREFIX + "/resolve-data-scope";
String ENSURE_USER = API_PREFIX + "/ensure-user";
/**
* 按主键查询
@@ -80,6 +83,18 @@ public interface IMpUserClient {
@GetMapping(USER_BY_ACCOUNT)
R<MpUser> userByAccount(@RequestParam("tenantId") String tenantId, @RequestParam("account") String account);
/**
* 按租户 + openid 查询
*/
@GetMapping(USER_BY_OPENID)
R<MpUser> userByOpenid(@RequestParam("tenantId") String tenantId, @RequestParam("openid") String openid);
/**
* 查找或创建小程序用户(登录路径专用,已存在时不抛异常、不改身份)
*/
@PostMapping(ENSURE_USER)
R<MpUser> ensureUser(@RequestBody MpUserEnsureDTO param);
/**
* 按主键查询登录信息
*/
@@ -0,0 +1,55 @@
/**
* 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>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.system.pojo.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 小程序用户「查找或创建」参数
*
* @author Chill
*/
@Data
@Schema(description = "小程序用户查找或创建参数")
public class MpUserEnsureDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "租户ID,为空时依次取 Tenant-Id 请求头与默认租户")
private String tenantId;
@Schema(description = "手机号")
private String phone;
@Schema(description = "微信小程序openid,非空时随首次建号一并写入")
private String openid;
}