diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveController.java index 35442fb0..ac6a36bc 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveController.java @@ -29,12 +29,15 @@ import lombok.AllArgsConstructor; import org.springblade.core.boot.ctrl.BladeController; import org.springblade.core.tool.api.R; import org.springblade.transport.pojo.vo.ArchiveManageStatsVO; +import org.springblade.transport.pojo.vo.DeptTreeNodeVO; import org.springblade.transport.service.IManageArchiveService; import org.springblade.transport.support.MpUserDataScopeSupport; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + /** * 调度端档案(小程序管理端) *

@@ -53,6 +56,13 @@ import org.springframework.web.bind.annotation.RestController; @Tag(name = "调度端档案", description = "小程序调度端资料页档案统计") public class ManageArchiveController extends BladeController { + /** + * 权限不足的业务码。小程序请求层把 401 当会话失效,接口一律不得回 401。 + */ + private static final int FORBIDDEN_CODE = 403; + + private static final String FORBIDDEN_MSG = "仅调度端管理员可选择组织"; + private final IManageArchiveService manageArchiveService; private final MpUserDataScopeSupport mpUserDataScopeSupport; @@ -71,4 +81,14 @@ public class ManageArchiveController extends BladeController { return R.data(mpUserDataScopeSupport.isMpDispatcher()); } + @GetMapping("/dept/tree") + @ApiOperationSupport(order = 3) + @Operation(summary = "组织树", description = "小程序组织选择器用:启用中的部门树,已剔除「外部组织」整支;非管理员回业务 403") + public R> deptTree() { + if (!mpUserDataScopeSupport.isMpDispatcher()) { + return R.fail(FORBIDDEN_CODE, FORBIDDEN_MSG); + } + return R.data(manageArchiveService.deptTree()); + } + } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveDriverController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveDriverController.java index 7390edd6..e5e25fcb 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveDriverController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/ManageArchiveDriverController.java @@ -23,6 +23,7 @@ package org.springblade.transport.controller; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -33,6 +34,7 @@ import org.springblade.core.boot.ctrl.BladeController; import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.tool.api.R; +import org.springblade.core.tool.utils.Func; import org.springblade.transport.pojo.entity.Driver; import org.springblade.transport.pojo.vo.DriverVO; import org.springblade.transport.service.IDriverService; @@ -122,7 +124,14 @@ public class ManageArchiveDriverController extends BladeController { } // 生效指针只由认证审核流水写(通过才建立生效快照),不接受管理端写入 driver.setEffectiveCertRecordId(null); - return R.status(driverService.submit(driver)); + boolean saved = driverService.submit(driver); + // submit 内部把空串 trimToNull,update-strategy=not_null 会跳过该字段,导致删不掉大头照;这里显式清空 + if (saved && driver.getId() != null && Func.isBlank(driver.getHeadPhoto())) { + driverService.update(Wrappers.lambdaUpdate() + .eq(Driver::getId, driver.getId()) + .set(Driver::getHeadPhoto, null)); + } + return R.status(saved); } /** diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ManageArchiveDeptMapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ManageArchiveDeptMapper.java new file mode 100644 index 00000000..73ae3d92 --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/mapper/ManageArchiveDeptMapper.java @@ -0,0 +1,26 @@ +package org.springblade.transport.mapper; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springblade.system.pojo.entity.Dept; + +import java.util.List; + +/** + * 组织树只读查询(小程序组织选择器) + *

+ * 不复用 blade-system 的部门接口:那些接口全挂在 {@code @PreAuth(menu = "dept")} 下, + * 小程序令牌的 roleId 是占位值 "0"、查不到 blade_role_menu,任何小程序账号都会被拒。 + * 这里直接按租户读表,只取组织选择需要的四列。 + */ +public interface ManageArchiveDeptMapper { + + /** + * 租户内启用中的部门,按排序号升序(不含已删除) + */ + @Select("SELECT id, parent_id AS parentId, dept_name AS deptName, sort FROM blade_dept " + + "WHERE is_deleted = 0 AND status = 1 AND tenant_id = #{tenantId} " + + "ORDER BY sort, id") + List selectEnabledByTenant(@Param("tenantId") String tenantId); + +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/pojo/vo/DeptTreeNodeVO.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/pojo/vo/DeptTreeNodeVO.java new file mode 100644 index 00000000..4908d3ca --- /dev/null +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/pojo/vo/DeptTreeNodeVO.java @@ -0,0 +1,62 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.transport.pojo.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 组织树节点(小程序组织选择器) + * + * @author Chill + */ +@Data +@Schema(description = "组织树节点") +public class DeptTreeNodeVO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 部门主键:雪花 ID 超出 JS 安全整数,序列化成字符串,前端不做 Number() + */ + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "部门主键") + private Long id; + + @Schema(description = "部门名称") + private String name; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + @Schema(description = "子部门") + private List children = new ArrayList<>(); + +} diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IManageArchiveService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IManageArchiveService.java index 478f7654..2379ac66 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IManageArchiveService.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IManageArchiveService.java @@ -23,6 +23,9 @@ package org.springblade.transport.service; import org.springblade.transport.pojo.vo.ArchiveManageStatsVO; +import org.springblade.transport.pojo.vo.DeptTreeNodeVO; + +import java.util.List; /** * 调度端档案统计 @@ -34,4 +37,9 @@ public interface IManageArchiveService { */ ArchiveManageStatsVO stats(); + /** + * 组织树:启用中的部门,已剔除「外部组织」整支 + */ + List deptTree(); + } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageArchiveServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageArchiveServiceImpl.java index 8bf23edf..3a62188b 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageArchiveServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageArchiveServiceImpl.java @@ -23,7 +23,12 @@ package org.springblade.transport.service.impl; import lombok.AllArgsConstructor; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.Func; +import org.springblade.system.pojo.entity.Dept; +import org.springblade.transport.mapper.ManageArchiveDeptMapper; import org.springblade.transport.pojo.vo.ArchiveManageStatsVO; +import org.springblade.transport.pojo.vo.DeptTreeNodeVO; import org.springblade.transport.pojo.vo.DriverVO; import org.springblade.transport.pojo.vo.TransportVehicleVO; import org.springblade.transport.service.IDriverService; @@ -31,6 +36,11 @@ import org.springblade.transport.service.IManageArchiveService; import org.springblade.transport.service.ITransportVehicleService; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + /** * 调度端档案统计 */ @@ -38,8 +48,14 @@ import org.springframework.stereotype.Service; @AllArgsConstructor public class ManageArchiveServiceImpl implements IManageArchiveService { + /** + * 组织选择器不提供这一支:web 端司机/车辆表单同样剔除「外部组织」。 + */ + private static final String EXTERNAL_ORG_NAME = "外部组织"; + private final IDriverService driverService; private final ITransportVehicleService transportVehicleService; + private final ManageArchiveDeptMapper manageArchiveDeptMapper; @Override public ArchiveManageStatsVO stats() { @@ -51,4 +67,36 @@ public class ManageArchiveServiceImpl implements IManageArchiveService { return vo; } + @Override + public List deptTree() { + List rows = manageArchiveDeptMapper.selectEnabledByTenant(AuthUtil.getTenantId()); + Map nodes = new LinkedHashMap<>(); + for (Dept row : rows) { + DeptTreeNodeVO node = new DeptTreeNodeVO(); + node.setId(row.getId()); + node.setName(Func.toStr(row.getDeptName())); + nodes.put(row.getId(), node); + } + List roots = new ArrayList<>(); + for (Dept row : rows) { + DeptTreeNodeVO node = nodes.get(row.getId()); + DeptTreeNodeVO parent = row.getParentId() == null ? null : nodes.get(row.getParentId()); + // 父部门停用或删除时该节点作为根保留,避免整支在树上消失 + if (parent == null) { + roots.add(node); + } else { + parent.getChildren().add(node); + } + } + removeExternalOrg(roots); + return roots; + } + + private static void removeExternalOrg(List nodes) { + nodes.removeIf(node -> EXTERNAL_ORG_NAME.equals(Func.toStr(node.getName()).trim())); + for (DeptTreeNodeVO node : nodes) { + removeExternalOrg(node.getChildren()); + } + } + }