模板权限过滤
This commit is contained in:
@@ -1358,7 +1358,8 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
|
|||||||
}).collect(Collectors.toList()));
|
}).collect(Collectors.toList()));
|
||||||
// executorUnitId 是顶层字段,与 contractKxPlans 平级(见结算平台推送合同接口文档 V9.5)
|
// executorUnitId 是顶层字段,与 contractKxPlans 平级(见结算平台推送合同接口文档 V9.5)
|
||||||
// 执行人公司ID = 执行人所属组织ID,取当前登录人的 orgId
|
// 执行人公司ID = 执行人所属组织ID,取当前登录人的 orgId
|
||||||
payload.put("executorUnitId", contract.getOrgId());
|
// payload.put("executorUnitId", contract.getOrgId());
|
||||||
|
|
||||||
// payload.put("contractText", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_BODY));
|
// payload.put("contractText", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_BODY));
|
||||||
// payload.put("otherAttach", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_OTHER));
|
// payload.put("otherAttach", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_OTHER));
|
||||||
// payload.put("contractGistFile", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_GIST));
|
// payload.put("contractGistFile", buildSettlementFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_GIST));
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package com.nbport.zgwl.controller;
|
||||||
|
|
||||||
|
import com.nbport.zgwl.common.R;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组织架构树 Controller
|
||||||
|
*
|
||||||
|
* 当前为 mock 数据,对应内网 /admin/org/getOrgTree 接口的真实返回。
|
||||||
|
* 后续接入统一认证后可直接替换为真实接口调用。
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/org")
|
||||||
|
public class AdminOrgController {
|
||||||
|
|
||||||
|
@GetMapping("/getOrgTree")
|
||||||
|
public R<List<OrgTreeNode>> getOrgTree() {
|
||||||
|
return R.success(buildOrgTree());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OrgTreeNode> buildOrgTree() {
|
||||||
|
// 根节点:浙江海港物流集团有限公司X (id=1)
|
||||||
|
OrgTreeNode root = new OrgTreeNode();
|
||||||
|
root.setId(1L);
|
||||||
|
root.setOrgName("浙江海港物流集团有限公司X");
|
||||||
|
root.setParentId(0L);
|
||||||
|
root.setOrgType("1");
|
||||||
|
root.setRemark("管理后台");
|
||||||
|
root.setOrgCode("MANAGE");
|
||||||
|
root.setStatus("1");
|
||||||
|
root.setTenantId(1L);
|
||||||
|
|
||||||
|
// ========== 二级节点 ==========
|
||||||
|
|
||||||
|
// 永康陆港国际物流有限公司 (id=47)
|
||||||
|
OrgTreeNode yongkang = createNode(47L, "永康陆港国际物流有限公司", 1L, "2", null, "YongKangLuGangGuoJiWuLiuYouXianGongSi", "1", 1L);
|
||||||
|
yongkang.setChildren(List.of(
|
||||||
|
createNode(138L, "永康物流分公司", 47L, "2", null, "c85c9da591e04d55b3d01dd0f5ae35aa", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
// 宁波港国际物流有限公司诸暨业务点 (id=48)
|
||||||
|
OrgTreeNode zhuji = createNode(48L, "宁波港国际物流有限公司诸暨业务点", 1L, "2", null, "NingBoGangGuoJiWuLiuYouXianGongSiZhuJiYeWuDian", "1", 1L);
|
||||||
|
zhuji.setChildren(List.of(
|
||||||
|
createNode(49L, "宁波港国际物流有限公司兰溪业务点", 48L, "2", null, "NingBoGangGuoJiWuLiuYouXianGongSiLanXiYeWuDian", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
OrgTreeNode lishui = createNode(51L, "丽水陆港国际物流有限责任公司", 1L, "2", null, "LiShuiLuGangGuoJiWuLiuYouXianZeRenGongSi", "1", 1L);
|
||||||
|
OrgTreeNode quzhou = createNode(52L, "衢州通港国际物流有限公司", 1L, "2", null, "QuZhouTongGangGuoJiWuLiuYouXianGongSi", "1", 1L);
|
||||||
|
|
||||||
|
// 浙港物流浙中北大区 (id=58)
|
||||||
|
OrgTreeNode zhongbei = createNode(58L, "浙港物流浙中北大区", 1L, "2", null, "ZheGangWuLiuZheZhongBeiDaQu", "1", 1L);
|
||||||
|
zhongbei.setChildren(List.of(
|
||||||
|
createNode(59L, "浙江兴港国际货运代理有限公司嘉兴分公司", 58L, "2", null, "ZheJiangXingGangGuoJiHuoYunDaiLiYouXianGongSiJiaXingFenGongSi", "1", 1L),
|
||||||
|
createNode(60L, "宁波港铁路有限公司绍兴分公司", 58L, "2", null, "NingBoGangTieLuYouXianGongSiShaoXingFenGongSi", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
// 浙港物流江苏大区 (id=68)
|
||||||
|
OrgTreeNode jiangsu = createNode(68L, "浙港物流江苏大区", 1L, "2", null, "ZheGangWuLiuJiangSuDaQu", "1", 1L);
|
||||||
|
OrgTreeNode jiangsuChild = createNode(69L, "浙港(江苏)国际供应链管理有限公司", 68L, "2", null, "ZheGang(JiangSu)GuoJiGongYingLianGuanLiYouXianGongSi", "1", 1L);
|
||||||
|
jiangsuChild.setChildren(List.of(
|
||||||
|
createNode(71L, "盐城海铁", 69L, "2", null, "YanChengHaiTie", "1", 1L)
|
||||||
|
));
|
||||||
|
jiangsu.setChildren(List.of(
|
||||||
|
jiangsuChild,
|
||||||
|
createNode(72L, "浙港物流江苏其他", 68L, "2", null, "ZheGangWuLiuJiangSuQiTa", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
OrgTreeNode haian = createNode(70L, "海安海铁", 1L, "2", null, "HaiAnHaiTie", "1", 1L);
|
||||||
|
OrgTreeNode xuzhou = createNode(75L, "宁波港国际物流有限公司徐州分公司", 1L, "2", null, "NingBoGangGuoJiWuLiuYouXianGongSiXuZhouFenGongSi", "1", 1L);
|
||||||
|
|
||||||
|
// 浙港物流湘赣大区 (id=76)
|
||||||
|
OrgTreeNode xianggan = createNode(76L, "浙港物流湘赣大区", 1L, "2", null, "ZheGangWuLiuXiangGanDaQu", "1", 1L);
|
||||||
|
xianggan.setChildren(List.of(
|
||||||
|
createNode(77L, "宁波港铁路有限公司--向塘/贵溪/赣州/宜春西/鹰潭南/萍乡/景德镇东/新余/樟树/湘潭/株洲北/长沙北/岳阳", 76L, "2", null, "NingBoGangTieLuYouXianGongSi--XiangTang/GuiXi/GanZhou/YiChunXi/YingTanNan/PingXiang/JingDeZhenDong/XinYu/ZhangShu/XiangTan/ZhuZhouBei/ChangShaBei/YueYang", "1", 1L),
|
||||||
|
createNode(78L, "江西上饶海港物流有限公司", 76L, "2", null, "JiangXiShangRaoHaiGangWuLiuYouXianGongSi", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
// 浙港物流安徽大区2 (id=23)
|
||||||
|
OrgTreeNode anhui = createNode(23L, "浙港物流安徽大区2", 1L, "2", null, "ErJiGongSi2", "1", 1L);
|
||||||
|
anhui.setChildren(List.of(
|
||||||
|
createNode(43L, "宁波港铁路有限公司---蚌埠/洛阳/青龙山/萧山", 23L, "2", null, "NingBoGangTieLuYouXianGongSi---BengBu/LuoYang/QingLongShan/XiaoShan", "1", 1L),
|
||||||
|
createNode(44L, "宁波港铁路有限公司---芜湖西/铜城闸/马鞍山", 23L, "2", null, "NingBoGangTieLuYouXianGongSi---WuHuXi/TongChengZha/MaAnShan", "1", 1L),
|
||||||
|
createNode(45L, "宣城市浙皖国际陆港供应链管理有限公司", 23L, "2", null, "XuanChengShiZheWanGuoJiLuGangGongYingLianGuanLiYouXianGongSi", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
OrgTreeNode huahaitong = createNode(321L, "汇海通-华峙", 1L, "2", "共享堆场测试", "21c350f7d5e54d0091ece7a47703bff8", "1", 1L);
|
||||||
|
OrgTreeNode test11 = createNode(382L, "11", 1L, "2", "sss", "e53d1047b5bc4415a98719a0f6911d83", "1", 1L);
|
||||||
|
OrgTreeNode test2 = createNode(383L, "测试2", 1L, "2", null, "86d33726220c452d9dfd266c01214803", "1", 1L);
|
||||||
|
OrgTreeNode donghua = createNode(181L, "东华", 1L, "2", "共享堆场测试", "ad3fc4e7e6644b78a245dbef5c70a0f1", "1", 1L);
|
||||||
|
OrgTreeNode ganglianjie = createNode(182L, "港联捷", 1L, "2", "共享堆场测试", "edd2fd12073a42bca05c7682ef507b95", "1", 1L);
|
||||||
|
OrgTreeNode yiwu = createNode(46L, "浙江义乌国际公铁联运有限公司", 1L, "2", null, "ZheJiangYiWuGuoJiGongTieLianYunYouXianGongSi", "1", 1L);
|
||||||
|
OrgTreeNode xinanjiang = createNode(50L, "新安江业务点", 1L, "2", null, "XinAnJiangYeWuDian", "1", 1L);
|
||||||
|
|
||||||
|
// 浙港物流华中大区 (id=53)
|
||||||
|
OrgTreeNode huazhong = createNode(53L, "浙港物流华中大区", 1L, "2", null, "ZheGangWuLiuHuaZhongDaQu", "1", 1L);
|
||||||
|
OrgTreeNode xiangyang = createNode(56L, "宁波港国际物流有限公司襄阳分公司", 53L, "2", null, "NingBoGangGuoJiWuLiuYouXianGongSiXiangYangFenGongSi", "1", 1L);
|
||||||
|
xiangyang.setChildren(List.of(
|
||||||
|
createNode(57L, "襄阳业务点", 56L, "2", null, "XiangYangYeWuDian", "1", 1L)
|
||||||
|
));
|
||||||
|
huazhong.setChildren(List.of(
|
||||||
|
xiangyang,
|
||||||
|
createNode(54L, "湖北浙港供应链管理有限公司", 53L, "2", null, "HuBeiZheGangGongYingLianGuanLiYouXianGongSi", "1", 1L),
|
||||||
|
createNode(55L, "武铁浙港多式联运(河南)有限公司", 53L, "2", null, "WuTieZheGangDuoShiLianYun(HeNan)YouXianGongSi", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
// 浙港物流浙西南大区 (id=61)
|
||||||
|
OrgTreeNode zhexi = createNode(61L, "浙港物流浙西南大区", 1L, "2", null, "ZheGangWuLiuZheXiNanDaQu", "1", 1L);
|
||||||
|
OrgTreeNode jinhuanan = createNode(62L, "浙港物流金华南", 61L, "2", null, "ZheGangWuLiuJinHuaNan", "1", 1L);
|
||||||
|
OrgTreeNode taizhounan = createNode(63L, "浙港物流台州南", 61L, "2", null, "ZheGangWuLiuTaiZhouNan", "1", 1L);
|
||||||
|
taizhounan.setChildren(List.of(
|
||||||
|
createNode(64L, "宁波佰菲特国际货运代理有限公司", 63L, "2", null, "NingBoBaiFeiTeGuoJiHuoYunDaiLiYouXianGongSi", "1", 1L)
|
||||||
|
));
|
||||||
|
zhexi.setChildren(List.of(jinhuanan, taizhounan));
|
||||||
|
|
||||||
|
// 宁波港国际物流有限公司合肥分公司 (id=65)
|
||||||
|
OrgTreeNode hefei = createNode(65L, "宁波港国际物流有限公司合肥分公司", 1L, "2", null, "NingBoGangGuoJiWuLiuYouXianGongSiHeFeiFenGongSi", "1", 1L);
|
||||||
|
hefei.setChildren(List.of(
|
||||||
|
createNode(66L, "六安安庆北业务点", 65L, "2", null, "LuAnAnQingBeiYeWuDian", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
OrgTreeNode jiangshan = createNode(67L, "江山无水港国际物流有限公司", 1L, "2", null, "JiangShanWuShuiGangGuoJiWuLiuYouXianGongSi", "1", 1L);
|
||||||
|
|
||||||
|
// 浙港物流西部大区 (id=73)
|
||||||
|
OrgTreeNode xibu = createNode(73L, "浙港物流西部大区", 1L, "2", null, "ZheGangWuLiuXiBuDaQu", "1", 1L);
|
||||||
|
xibu.setChildren(List.of(
|
||||||
|
createNode(74L, "宁波港铁路有限公司---重庆/城厢/白银市/西安/宜兴", 73L, "2", null, "NingBoGangTieLuYouXianGongSi---ChongQing/ChengXiang/BaiYinShi/XiAn/YiXing", "1", 1L)
|
||||||
|
));
|
||||||
|
|
||||||
|
root.setChildren(List.of(
|
||||||
|
yongkang, zhuji, lishui, quzhou, zhongbei, jiangsu, haian, xuzhou,
|
||||||
|
xianggan, anhui, huahaitong, test11, test2, donghua, ganglianjie,
|
||||||
|
yiwu, xinanjiang, huazhong, zhexi, hefei, jiangshan, xibu
|
||||||
|
));
|
||||||
|
|
||||||
|
return List.of(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrgTreeNode createNode(Long id, String orgName, Long parentId, String orgType,
|
||||||
|
String remark, String orgCode, String status, Long tenantId) {
|
||||||
|
OrgTreeNode node = new OrgTreeNode();
|
||||||
|
node.setId(id);
|
||||||
|
node.setOrgName(orgName);
|
||||||
|
node.setParentId(parentId);
|
||||||
|
node.setOrgType(orgType);
|
||||||
|
node.setRemark(remark);
|
||||||
|
node.setOrgCode(orgCode);
|
||||||
|
node.setStatus(status);
|
||||||
|
node.setTenantId(tenantId);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组织树节点 DTO
|
||||||
|
*/
|
||||||
|
public static class OrgTreeNode {
|
||||||
|
private Long id;
|
||||||
|
private String orgName;
|
||||||
|
private Long parentId;
|
||||||
|
private String orgType;
|
||||||
|
private String remark;
|
||||||
|
private String orgCode;
|
||||||
|
private String status;
|
||||||
|
private Long tenantId;
|
||||||
|
private List<OrgTreeNode> children;
|
||||||
|
|
||||||
|
// getters / setters
|
||||||
|
public Long getId() { return id; }
|
||||||
|
public void setId(Long id) { this.id = id; }
|
||||||
|
public String getOrgName() { return orgName; }
|
||||||
|
public void setOrgName(String orgName) { this.orgName = orgName; }
|
||||||
|
public Long getParentId() { return parentId; }
|
||||||
|
public void setParentId(Long parentId) { this.parentId = parentId; }
|
||||||
|
public String getOrgType() { return orgType; }
|
||||||
|
public void setOrgType(String orgType) { this.orgType = orgType; }
|
||||||
|
public String getRemark() { return remark; }
|
||||||
|
public void setRemark(String remark) { this.remark = remark; }
|
||||||
|
public String getOrgCode() { return orgCode; }
|
||||||
|
public void setOrgCode(String orgCode) { this.orgCode = orgCode; }
|
||||||
|
public String getStatus() { return status; }
|
||||||
|
public void setStatus(String status) { this.status = status; }
|
||||||
|
public Long getTenantId() { return tenantId; }
|
||||||
|
public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
|
||||||
|
public List<OrgTreeNode> getChildren() { return children; }
|
||||||
|
public void setChildren(List<OrgTreeNode> children) { this.children = children; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板分页查询参数
|
* 模板分页查询参数
|
||||||
@@ -28,4 +29,10 @@ public class ContractTemplateQueryDto extends BasePageDto implements Serializabl
|
|||||||
|
|
||||||
/** 状态(draft/published/disabled) */
|
/** 状态(draft/published/disabled) */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前用户可见的组织 ID 列表(由后端根据用户所属组织 + 组织树层级自动计算)
|
||||||
|
* 用于过滤模板的发布范围:模板的 publishOrgIds 中包含任一可见组织 ID 即可
|
||||||
|
*/
|
||||||
|
private List<String> visibleOrgIds;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,21 @@ import com.nbport.zgwl.manifest.mapper.ContractTemplateMapper;
|
|||||||
import com.nbport.zgwl.manifest.utils.ManifestCodeUtils;
|
import com.nbport.zgwl.manifest.utils.ManifestCodeUtils;
|
||||||
import com.nbport.zgwl.manifest.utils.ManifestJsonUtils;
|
import com.nbport.zgwl.manifest.utils.ManifestJsonUtils;
|
||||||
import com.nbport.zgwl.manifest.utils.ManifestManageConstants;
|
import com.nbport.zgwl.manifest.utils.ManifestManageConstants;
|
||||||
|
import com.nbport.zgwl.utils.AdminSecurityManage;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板管理 Service 实现
|
* 模板管理 Service 实现
|
||||||
@@ -31,9 +39,24 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
|
|||||||
|
|
||||||
private final ContractTemplateDataHandler contractTemplateDataHandler;
|
private final ContractTemplateDataHandler contractTemplateDataHandler;
|
||||||
|
|
||||||
/** 分页查询模板列表 */
|
private final AdminSecurityManage adminSecurityManage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内存中的组织树(扁平化节点列表),懒加载
|
||||||
|
*/
|
||||||
|
private List<OrgNode> orgTreeCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询模板列表
|
||||||
|
* 自动根据当前用户所属组织过滤发布范围
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PageResult<ContractTemplateDto> queryTemplateList(ContractTemplateQueryDto queryDto) {
|
public PageResult<ContractTemplateDto> queryTemplateList(ContractTemplateQueryDto queryDto) {
|
||||||
|
// 自动注入当前用户可见的组织 ID(含子级)
|
||||||
|
if (queryDto.getVisibleOrgIds() == null || queryDto.getVisibleOrgIds().isEmpty()) {
|
||||||
|
queryDto.setVisibleOrgIds(computeVisibleOrgIds());
|
||||||
|
}
|
||||||
|
|
||||||
Page<ContractTemplateDto> page = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
|
Page<ContractTemplateDto> page = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
|
||||||
Page<ContractTemplateDto> resultPage = (Page<ContractTemplateDto>) contractTemplateMapper.selectTemplatePage(page, queryDto);
|
Page<ContractTemplateDto> resultPage = (Page<ContractTemplateDto>) contractTemplateMapper.selectTemplatePage(page, queryDto);
|
||||||
PageResult<ContractTemplateDto> pageResult = new PageResult<>(resultPage);
|
PageResult<ContractTemplateDto> pageResult = new PageResult<>(resultPage);
|
||||||
@@ -135,15 +158,133 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
|
|||||||
return getTemplateDetail(id);
|
return getTemplateDetail(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取发布范围组织选项(当前为假数据,内网联调时替换为真实组织接口) */
|
/**
|
||||||
|
* 获取发布范围组织选项(扁平列表,供发布范围下拉使用)
|
||||||
|
* 数据来源于组织树,平铺所有节点
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<TemplateOrgOptionDto> queryOrgOptions() {
|
public List<TemplateOrgOptionDto> queryOrgOptions() {
|
||||||
return List.of(
|
List<OrgNode> flatNodes = getFlatOrgTree();
|
||||||
new TemplateOrgOptionDto("ORG001", "浙港物流平台有限公司"),
|
return flatNodes.stream()
|
||||||
new TemplateOrgOptionDto("ORG002", "宁波舟山港集团有限公司"),
|
.map(node -> new TemplateOrgOptionDto(String.valueOf(node.id), node.orgName))
|
||||||
new TemplateOrgOptionDto("ORG003", "浙江省海港投资运营集团有限公司"),
|
.collect(Collectors.toList());
|
||||||
new TemplateOrgOptionDto("ORG004", "宁波港东南物流集团有限公司")
|
}
|
||||||
);
|
|
||||||
|
// ========== 组织树与权限计算 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算当前用户可见的组织 ID 列表。
|
||||||
|
* 规则:用户所属组织 + 所有祖先组织。
|
||||||
|
* 因为发布范围选择上级时,其所有子部门都可见,
|
||||||
|
* 所以对于用户来说,能看到的模板是「发布范围包含用户所属组织或其任一祖先」的模板。
|
||||||
|
*/
|
||||||
|
private List<String> computeVisibleOrgIds() {
|
||||||
|
String userOrgId = adminSecurityManage.getUser().getSysOrgEntity().getId();
|
||||||
|
if (userOrgId == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OrgNode> flatNodes = getFlatOrgTree();
|
||||||
|
Map<String, OrgNode> nodeMap = new HashMap<>();
|
||||||
|
for (OrgNode node : flatNodes) {
|
||||||
|
nodeMap.put(String.valueOf(node.id), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收集当前用户所属组织及其所有祖先
|
||||||
|
Set<String> visible = new HashSet<>();
|
||||||
|
String currentId = userOrgId;
|
||||||
|
while (currentId != null && nodeMap.containsKey(currentId)) {
|
||||||
|
visible.add(currentId);
|
||||||
|
OrgNode node = nodeMap.get(currentId);
|
||||||
|
currentId = node.parentId != null ? String.valueOf(node.parentId) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> result = new ArrayList<>(visible);
|
||||||
|
log.debug("当前用户 orgId={}, 可见组织列表={}", userOrgId, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取扁平化的组织树节点列表(线程安全懒加载)
|
||||||
|
* 注意:必须与 AdminOrgController 中的组织树数据保持一致
|
||||||
|
*/
|
||||||
|
private synchronized List<OrgNode> getFlatOrgTree() {
|
||||||
|
if (orgTreeCache != null) {
|
||||||
|
return orgTreeCache;
|
||||||
|
}
|
||||||
|
// 从 AdminOrgController 的 mock 数据构建(后续可替换为数据库或接口调用)
|
||||||
|
orgTreeCache = buildFlatOrgTree();
|
||||||
|
return orgTreeCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建扁平组织树(与 AdminOrgController 的 mock 数据保持一致)
|
||||||
|
*/
|
||||||
|
private List<OrgNode> buildFlatOrgTree() {
|
||||||
|
List<OrgNode> nodes = new ArrayList<>();
|
||||||
|
|
||||||
|
// 根节点
|
||||||
|
nodes.add(new OrgNode(1L, "浙江海港物流集团有限公司X", 0L));
|
||||||
|
|
||||||
|
// 二级节点
|
||||||
|
nodes.add(new OrgNode(47L, "永康陆港国际物流有限公司", 1L));
|
||||||
|
nodes.add(new OrgNode(138L, "永康物流分公司", 47L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(48L, "宁波港国际物流有限公司诸暨业务点", 1L));
|
||||||
|
nodes.add(new OrgNode(49L, "宁波港国际物流有限公司兰溪业务点", 48L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(51L, "丽水陆港国际物流有限责任公司", 1L));
|
||||||
|
nodes.add(new OrgNode(52L, "衢州通港国际物流有限公司", 1L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(58L, "浙港物流浙中北大区", 1L));
|
||||||
|
nodes.add(new OrgNode(59L, "浙江兴港国际货运代理有限公司嘉兴分公司", 58L));
|
||||||
|
nodes.add(new OrgNode(60L, "宁波港铁路有限公司绍兴分公司", 58L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(68L, "浙港物流江苏大区", 1L));
|
||||||
|
nodes.add(new OrgNode(69L, "浙港(江苏)国际供应链管理有限公司", 68L));
|
||||||
|
nodes.add(new OrgNode(71L, "盐城海铁", 69L));
|
||||||
|
nodes.add(new OrgNode(72L, "浙港物流江苏其他", 68L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(70L, "海安海铁", 1L));
|
||||||
|
nodes.add(new OrgNode(75L, "宁波港国际物流有限公司徐州分公司", 1L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(76L, "浙港物流湘赣大区", 1L));
|
||||||
|
nodes.add(new OrgNode(77L, "宁波港铁路有限公司--向塘/贵溪/赣州/宜春西/鹰潭南/萍乡/景德镇东/新余/樟树/湘潭/株洲北/长沙北/岳阳", 76L));
|
||||||
|
nodes.add(new OrgNode(78L, "江西上饶海港物流有限公司", 76L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(23L, "浙港物流安徽大区2", 1L));
|
||||||
|
nodes.add(new OrgNode(43L, "宁波港铁路有限公司---蚌埠/洛阳/青龙山/萧山", 23L));
|
||||||
|
nodes.add(new OrgNode(44L, "宁波港铁路有限公司---芜湖西/铜城闸/马鞍山", 23L));
|
||||||
|
nodes.add(new OrgNode(45L, "宣城市浙皖国际陆港供应链管理有限公司", 23L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(321L, "汇海通-华峙", 1L));
|
||||||
|
nodes.add(new OrgNode(382L, "11", 1L));
|
||||||
|
nodes.add(new OrgNode(383L, "测试2", 1L));
|
||||||
|
nodes.add(new OrgNode(181L, "东华", 1L));
|
||||||
|
nodes.add(new OrgNode(182L, "港联捷", 1L));
|
||||||
|
nodes.add(new OrgNode(46L, "浙江义乌国际公铁联运有限公司", 1L));
|
||||||
|
nodes.add(new OrgNode(50L, "新安江业务点", 1L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(53L, "浙港物流华中大区", 1L));
|
||||||
|
nodes.add(new OrgNode(56L, "宁波港国际物流有限公司襄阳分公司", 53L));
|
||||||
|
nodes.add(new OrgNode(57L, "襄阳业务点", 56L));
|
||||||
|
nodes.add(new OrgNode(54L, "湖北浙港供应链管理有限公司", 53L));
|
||||||
|
nodes.add(new OrgNode(55L, "武铁浙港多式联运(河南)有限公司", 53L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(61L, "浙港物流浙西南大区", 1L));
|
||||||
|
nodes.add(new OrgNode(62L, "浙港物流金华南", 61L));
|
||||||
|
nodes.add(new OrgNode(63L, "浙港物流台州南", 61L));
|
||||||
|
nodes.add(new OrgNode(64L, "宁波佰菲特国际货运代理有限公司", 63L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(65L, "宁波港国际物流有限公司合肥分公司", 1L));
|
||||||
|
nodes.add(new OrgNode(66L, "六安安庆北业务点", 65L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(67L, "江山无水港国际物流有限公司", 1L));
|
||||||
|
|
||||||
|
nodes.add(new OrgNode(73L, "浙港物流西部大区", 1L));
|
||||||
|
nodes.add(new OrgNode(74L, "宁波港铁路有限公司---重庆/城厢/白银市/西安/宜兴", 73L));
|
||||||
|
|
||||||
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 将 JSON 字段转为文本存入数据库 */
|
/** 将 JSON 字段转为文本存入数据库 */
|
||||||
@@ -152,4 +293,19 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
|
|||||||
template.setPublishOrgNamesJson(ManifestJsonUtils.toJson(template.getPublishOrgNames()));
|
template.setPublishOrgNamesJson(ManifestJsonUtils.toJson(template.getPublishOrgNames()));
|
||||||
template.setVariableMappingsJson(ManifestJsonUtils.toJson(template.getVariableMappings()));
|
template.setVariableMappingsJson(ManifestJsonUtils.toJson(template.getVariableMappings()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内部组织节点
|
||||||
|
*/
|
||||||
|
private static class OrgNode {
|
||||||
|
private final Long id;
|
||||||
|
private final String orgName;
|
||||||
|
private final Long parentId;
|
||||||
|
|
||||||
|
OrgNode(Long id, String orgName, Long parentId) {
|
||||||
|
this.id = id;
|
||||||
|
this.orgName = orgName;
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ public class AdminSecurityManage {
|
|||||||
|
|
||||||
public SysUserEntity getUser() {
|
public SysUserEntity getUser() {
|
||||||
SysOrgEntity orgEntity = new SysOrgEntity();
|
SysOrgEntity orgEntity = new SysOrgEntity();
|
||||||
orgEntity.setId("ORG001");
|
orgEntity.setId("1");
|
||||||
orgEntity.setOrgName("浙港物流平台有限公司");
|
orgEntity.setOrgName("浙江海港物流集团有限公司X");
|
||||||
orgEntity.setContactPhone("13800000000");
|
orgEntity.setContactPhone("13800000000");
|
||||||
orgEntity.setContactEmail("admin@test.com");
|
orgEntity.setContactEmail("admin@test.com");
|
||||||
orgEntity.setContactAddress("宁波市北仑区明州路288号");
|
orgEntity.setContactAddress("宁波市北仑区明州路288号");
|
||||||
|
|||||||
@@ -54,6 +54,15 @@
|
|||||||
<if test="query.status != null and query.status != ''">
|
<if test="query.status != null and query.status != ''">
|
||||||
and status = #{query.status}
|
and status = #{query.status}
|
||||||
</if>
|
</if>
|
||||||
|
<!-- 发布范围过滤:当前用户可见的组织(含子级)与模板发布范围有交集 -->
|
||||||
|
<!-- 使用 INSTR 精确匹配 JSON 数组中的 "orgId"(带引号)以避免子串误匹配 -->
|
||||||
|
<if test="query.visibleOrgIds != null and query.visibleOrgIds.size() > 0">
|
||||||
|
and (
|
||||||
|
<foreach collection="query.visibleOrgIds" item="orgId" open="" separator=" OR " close="">
|
||||||
|
INSTR(publish_org_ids_json, '"' || #{orgId} || '"') > 0
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by updated_time desc, id desc
|
order by updated_time desc, id desc
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
Reference in New Issue
Block a user