Browse Source

虚拟单位重组功能开发

dev-V1.0.1
庄锐波 6 months ago
parent
commit
d29a64ae18
  1. 3
      script/sql/zfjd-refactoring-v1/011-1-重建虚拟单位树.sql
  2. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeVirtualUnit.java
  3. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeVirtualUnitBo.java
  4. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeVirtualUnitVo.java
  5. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java
  6. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/virtualUnit/types.ts
  7. 97
      zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/virtualUnit/unitBuilder.vue
  8. 38
      zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/InitVirtualUnitTest.java

3
script/sql/zfjd-refactoring-v1/011-1-重建虚拟单位树.sql

@ -15,7 +15,8 @@ create table efcode_virtual_unit
vir_remark varchar(500) null comment '备注',
sys_dept_id varchar(100) null comment '部门id',
srz_organization_id varchar(100) null comment '市认证的组织ID',
order_num int default 0 null comment '显示顺序',
order_num int default 0 null comment '显示顺序:使用部门的sequence值',
cust_order_num int default 0 null comment '自定义显示顺序',
create_dept varchar(100) null comment '创建部门',
create_by bigint null comment '创建者',
create_time datetime null comment '创建时间',

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeVirtualUnit.java

@ -102,5 +102,10 @@ public class EfcodeVirtualUnit extends BaseEntity {
*/
private Long orderNum;
/**
* 自定义显示顺序
*/
private Long custOrderNum;
}

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeVirtualUnitBo.java

@ -101,5 +101,10 @@ public class EfcodeVirtualUnitBo extends BaseEntity {
*/
private Long orderNum;
/**
* 自定义显示顺序
*/
private Long custOrderNum;
}

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeVirtualUnitVo.java

@ -124,5 +124,11 @@ public class EfcodeVirtualUnitVo implements Serializable {
@ExcelProperty(value = "显示顺序")
private Long orderNum;
/**
* 自定义显示顺序
*/
@ExcelProperty(value = "自定义显示顺序")
private Long custOrderNum;
}

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java

@ -166,8 +166,8 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService {
@Override
public List<EfcodeVirtualUnitVo> queryTreeList() {
LambdaQueryWrapper<EfcodeVirtualUnit> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(EfcodeVirtualUnit::getCustOrderNum);
lqw.orderByAsc(EfcodeVirtualUnit::getOrderNum);
lqw.orderByAsc(EfcodeVirtualUnit::getVirId);
return baseMapper.selectVoList(lqw);
}

2
zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/virtualUnit/types.ts

@ -18,6 +18,7 @@ export interface VirtualUnitVo {
sysDeptId: string;
srzOrganizationId: string;
orderNum: number;
custOrderNum: number;
children?: VirtualUnitVo[];
}
@ -41,4 +42,5 @@ export interface VirtualUnitForm {
sysDeptId?: string;
srzOrganizationId?: string;
orderNum?: number;
custOrderNum?: number;
}

97
zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/virtualUnit/unitBuilder.vue

@ -2,7 +2,7 @@
import {ref, computed, onMounted, nextTick} from 'vue';
import {ElMessage, ElMessageBox} from 'element-plus';
import {Delete, Back, Search} from '@element-plus/icons-vue';
import {getVirtualUnitTreeList, addVirtualUnit, delVirtualUnit} from '@/api/efcode/virtualUnit';
import {getVirtualUnitTreeList, addVirtualUnit, delVirtualUnit, updateVirtualUnit} from '@/api/efcode/virtualUnit';
import type {VirtualUnitVo, VirtualUnitForm} from '@/api/efcode/virtualUnit/types';
import SrzDeptFullLoadTree from '@/views/efcode/components/srz-dept-full-load-tree.vue';
@ -142,6 +142,30 @@ const tableRowClassName = ({row}: { row: TreeTableRow }) => {
return '';
};
/** 下拉选择是/否字段变更 */
const handleFieldChange = async (row: TreeTableRow, field: 'virIncludeStatistics' | 'virIncludeSearch' | 'virShowAtBusiness', newValue: string) => {
const oldValue = newValue === '是' ? '否' : '是';
try {
await updateVirtualUnit({ virId: row.virId, [field]: newValue });
} catch (e: any) {
row[field] = oldValue;
ElMessage.error(e.message || '更新失败');
}
};
/** 自定义排序变更 */
let custOrderTimer: ReturnType<typeof setTimeout> | null = null;
const handleCustOrderChange = (row: TreeTableRow) => {
if (custOrderTimer) clearTimeout(custOrderTimer);
custOrderTimer = setTimeout(async () => {
try {
await updateVirtualUnit({ virId: row.virId, custOrderNum: row.custOrderNum ?? 0 });
} catch (e: any) {
ElMessage.error(e.message || '更新排序失败');
}
}, 500);
};
/** 删除虚拟单位节点 */
const handleDelete = async (row: TreeTableRow) => {
if (row.children && row.children.length > 0) {
@ -305,19 +329,64 @@ onMounted(() => {
<span v-html="highlightName(row.virName)"></span>
</template>
</el-table-column>
<el-table-column prop="virIncludeStatistics" label="统计" width="60" align="center">
<el-table-column prop="virIncludeStatistics" label="统计" width="100" align="center">
<template #default="{ row }">
<el-radio-group
v-if="selectedVirNode?.virId === row.virId"
v-model="row.virIncludeStatistics"
size="small"
@change="(val: string) => handleFieldChange(row, 'virIncludeStatistics', val)"
@click.stop
>
<el-radio-button value="是">是</el-radio-button>
<el-radio-button value="否">否</el-radio-button>
</el-radio-group>
<span v-else :class="{ 'cell-red': row.virIncludeStatistics === '否' }">{{ row.virIncludeStatistics }}</span>
</template>
</el-table-column>
<el-table-column prop="virIncludeSearch" label="查询" width="100" align="center">
<template #default="{ row }">
<span :class="{ 'cell-red': row.virIncludeStatistics === '否' }">{{ row.virIncludeStatistics }}</span>
<el-radio-group
v-if="selectedVirNode?.virId === row.virId"
v-model="row.virIncludeSearch"
size="small"
@change="(val: string) => handleFieldChange(row, 'virIncludeSearch', val)"
@click.stop
>
<el-radio-button value="是">是</el-radio-button>
<el-radio-button value="否">否</el-radio-button>
</el-radio-group>
<span v-else :class="{ 'cell-red': row.virIncludeSearch === '否' }">{{ row.virIncludeSearch }}</span>
</template>
</el-table-column>
<el-table-column prop="virIncludeSearch" label="查询" width="60" align="center">
<el-table-column prop="virShowAtBusiness" label="业务" width="100" align="center">
<template #default="{ row }">
<span :class="{ 'cell-red': row.virIncludeSearch === '否' }">{{ row.virIncludeSearch }}</span>
<el-radio-group
v-if="selectedVirNode?.virId === row.virId"
v-model="row.virShowAtBusiness"
size="small"
@change="(val: string) => handleFieldChange(row, 'virShowAtBusiness', val)"
@click.stop
>
<el-radio-button value="是">是</el-radio-button>
<el-radio-button value="否">否</el-radio-button>
</el-radio-group>
<span v-else :class="{ 'cell-red': row.virShowAtBusiness === '否' }">{{ row.virShowAtBusiness }}</span>
</template>
</el-table-column>
<el-table-column prop="virShowAtBusiness" label="业务" width="60" align="center">
<el-table-column prop="custOrderNum" label="自定义排序" width="100" align="center">
<template #default="{ row }">
<span :class="{ 'cell-red': row.virShowAtBusiness === '否' }">{{ row.virShowAtBusiness }}</span>
<el-input-number
v-if="selectedVirNode?.virId === row.virId"
v-model="row.custOrderNum"
:min="0"
:controls="false"
size="small"
style="width: 70px;"
@change="handleCustOrderChange(row)"
@click.stop
/>
<span v-else>{{ row.custOrderNum ?? 0 }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="70" align="center" fixed="right">
@ -435,6 +504,12 @@ onMounted(() => {
}
}
:deep(.el-table__row:hover) {
td.el-table__cell {
background-color: var(--el-color-primary-light-9) !important;
}
}
:deep(.selected-row) {
td.el-table__cell {
background-color: var(--el-color-primary-light-7) !important;
@ -452,6 +527,14 @@ onMounted(() => {
font-weight: bold;
}
:deep(.el-radio-group) {
flex-wrap: nowrap;
}
:deep(.el-radio-button__inner) {
padding: 4px 8px;
}
:deep(.search-match) {
color: #f56c6c;
font-weight: bold;

38
zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/service/test/InitVirtualUnitTest.java

@ -55,6 +55,23 @@ public class InitVirtualUnitTest {
private static final String TEST_CLIENT_ID = "e5cd7e4891bf95d1d19206ce24a7b32e";
private static final String TENANT_ID = "000000";
/**
* 区级部门 deptId -> 固定 virId 映射
*/
private static final Map<String, String> FIXED_VIR_ID_MAP = new LinkedHashMap<>() {{
put("20210922211852148-9BC0-86CB268FF", "Area_LuoHuQu");
put("20210922211856415-B320-A08200FC3", "Area_FuTianQu");
put("20210922211901413-5636-0EE262A06", "Area_NanShanQu");
put("20210922211905159-EE09-09D606CFB", "Area_BaoAnQu");
put("20210922211909285-8169-1B6610932", "Area_LongGangQu");
put("20210922211913750-D059-984DC1A1A", "Area_YanTianQu");
put("20210922211918204-7059-2B73EBA45", "Area_GuangMingQu");
put("20210922211922409-1207-44E38EB4F", "Area_PingsHanQu");
put("20210922211924206-457B-09712EC36", "Area_LongHuaQu");
put("20210922211925882-0251-C23C3AA2E", "Area_DapengXinQu");
put("20210922211927734-9A30-921277192", "Area_ShenShanTeBieHeZuoQu");
}};
@BeforeEach
public void setUp() {
SaTokenContextMockUtil.setMockContext();
@ -181,7 +198,8 @@ public class InitVirtualUnitTest {
// 6. 为每个区创建 "区直" 虚拟节点,并将 zone=3/5/6 的部门挂到对应区直下
districtMap.forEach((pid, districtName) -> {
String quzhiName = districtName + "区直";
EfcodeVirtualUnit quzhiUnit = buildVirtualUnit(pid, quzhiName, null, 0L);
String virParentId = FIXED_VIR_ID_MAP.containsKey(pid) ? FIXED_VIR_ID_MAP.get(pid) : pid;
EfcodeVirtualUnit quzhiUnit = buildVirtualUnit(virParentId, quzhiName, null, 0L);
String quzhiId = quzhiUnit.getVirId();
allUnits.add(quzhiUnit);
idNameMap.put(quzhiId, quzhiName);
@ -207,7 +225,9 @@ public class InitVirtualUnitTest {
// 7.1 先为每个部门生成 UUID,并建立 deptId -> UUID 映射
Map<String, String> deptIdToVirIdMap = new HashMap<>();
for (SysDeptVo dept : depts) {
String virId = UUID.randomUUID().toString().replace("-", "");
String virId = FIXED_VIR_ID_MAP.containsKey(dept.getDeptId())
? FIXED_VIR_ID_MAP.get(dept.getDeptId())
: UUID.randomUUID().toString().replace("-", "");
deptIdToVirIdMap.put(dept.getDeptId(), virId);
// idNameMap 同时存 deptId 和 virId 两个 key,确保 ancestors/displayPath 构建时能找到名称
idNameMap.put(dept.getDeptId(), dept.getDeptName());
@ -331,6 +351,20 @@ public class InitVirtualUnitTest {
private EfcodeVirtualUnit buildVirtualUnit(String parentId, String name, Long zone, Long orderNum) {
EfcodeVirtualUnit unit = new EfcodeVirtualUnit();
unit.setVirId(UUID.randomUUID().toString().replace("-", ""));
if (parentId.equals("_root_")){
unit.setVirId("ShenZhen_City");
}
else if (parentId.equals("ShenZhen_City")&&name.equals("区")){
unit.setVirId("ShenZhen_Areas");
}
else if (parentId.indexOf("Area_")==0&&name.indexOf("区直")>=0){
String virId=parentId.replace("Area_","")+"_QuZhi";
unit.setVirId(virId);
}
else if (name.equals("市直")){
String virId="ShenZhen_ShiZhi";
unit.setVirId(virId);
}
unit.setVirIsVirtual("是");
unit.setVirParentId(parentId);
unit.setVirName(name);

Loading…
Cancel
Save