优化行政区划和媒体类型字典界面

This commit is contained in:
wangchengming 2025-08-12 14:01:16 +08:00
parent da0dc6a667
commit 8047298f59
4 changed files with 401 additions and 133 deletions

View File

@ -14,12 +14,16 @@
<div class="el-dropdown avatar-container right-menu-item hover-effect"> <div class="el-dropdown avatar-container right-menu-item hover-effect">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<div class="feedback_icon"> <div class="feedback_icon">
<img :src="icon_feedback" class="custom-icon" @click="handleFeedBack" /> <el-tooltip class="box-item" effect="dark" content="问题反馈" placement="bottom-start">
<img :src="icon_feedback" class="custom-icon" @click="handleFeedBack" />
</el-tooltip>
</div> </div>
<img :src="userStore.avatar ? userStore.avatar : avatar_icon" class="user-avatar" /> <img :src="userStore.avatar ? userStore.avatar : avatar_icon" class="user-avatar" />
<span class="user-nickname"> {{ userStore.nickName }} admin </span> <span class="user-nickname"> {{ userStore.nickName }} admin </span>
<div class="logout_icon"> <div class="logout_icon">
<img :src="logout_icon" class="custom-icon" @click="logout" /> <el-tooltip class="box-item" effect="dark" content="退出" placement="bottom-start">
<img :src="logout_icon" class="custom-icon" @click="logout" />
</el-tooltip>
</div> </div>
</div> </div>
</div> </div>

View File

@ -11,20 +11,15 @@
<el-col :span="24"> <el-col :span="24">
<el-button type="primary" class="primaryBtn" @click="handleAddRootNode" <el-button type="primary" class="primaryBtn" @click="handleAddRootNode"
v-hasPermi="['system:administrativeRegion:add']">新增根节点</el-button> v-hasPermi="['system:administrativeRegion:add']">新增根节点</el-button>
<!-- <el-button type="primary" class="primaryBtn" @click="toggleExpandAll">展开/折叠</el-button> -->
</el-col> </el-col>
</el-row> </el-row>
<el-table v-loading="loading" height="calc(100vh - 244px)" :data="regionTreeList" <el-table v-loading="loading" ref="tableRef" height="calc(100vh - 244px)" :data="regionTreeList" row-key="id"
row-key="id" lazy :load="loadChildren" :tree-props="{ children: 'childList', hasChildren: 'hasChildren' }"> lazy :load="loadChildren" @expand-change="handleExpandChange"
:tree-props="{ children: 'childList', hasChildren: 'hasChildren' }">
<el-table-column prop="name" label="区域名称"></el-table-column> <el-table-column prop="name" label="区域名称"></el-table-column>
<el-table-column prop="code" label="区域编号"></el-table-column> <el-table-column prop="code" label="区域编号"></el-table-column>
<el-table-column prop="sortNo" label="排序"></el-table-column> <el-table-column prop="sortNo" label="排序"></el-table-column>
<!-- <el-table-column label="创建时间" align="center" prop="createTime" min-width="210">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column> -->
<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)" <el-button link type="primary" @click="handleUpdate(scope.row)"
@ -76,8 +71,9 @@ const regionTreeList = ref([])
const open = ref(false) const open = ref(false)
const loading = ref(true) const loading = ref(true)
const title = ref("") const title = ref("")
const isExpandAll = ref(true)
const refreshTable = ref(true) const tableRef = ref();
const expandedKeys = ref(new Set());
const data = reactive({ const data = reactive({
form: {}, form: {},
@ -93,38 +89,83 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data) const { queryParams, form, rules } = toRefs(data)
// - ID
const findRowById = (id, rows = regionTreeList.value) => {
for (const row of rows) {
if (row.id === id) return row;
if (row.childList) {
const found = findRowById(id, row.childList);
if (found) return found;
}
}
return null;
};
// - ID
const findParentId = (id, rows = regionTreeList.value, parentId = 0) => {
for (const row of rows) {
if (row.id === id) return parentId;
if (row.childList) {
const found = findParentId(id, row.childList, row.id);
if (found) return found;
}
}
return null;
};
// -
const findParentNode = (id, rows = regionTreeList.value, parent = null) => {
for (const row of rows) {
if (row.id === id) return parent;
if (row.childList) {
const found = findParentNode(id, row.childList, row);
if (found) return found;
}
}
return null;
};
// handleExpandChange
const handleExpandChange = (row, expanded) => {
if (expanded) {
expandedKeys.value.add(row.id);
} else {
expandedKeys.value.delete(row.id);
}
};
/** 查询行政区域树列表 */ /** 查询行政区域树列表 */
const getsysRegionTreeList = () => { const getsysRegionTreeList = (parentId = 0) => {
loading.value = true loading.value = true
queryParams.value.parentId = parentId;
sysRegionListByPid(queryParams.value).then(res => { sysRegionListByPid(queryParams.value).then(res => {
regionTreeList.value = res.data if (parentId === 0) {
regionTreeList.value = res.data
}
loading.value = false loading.value = false
}) })
} }
// //
const loadChildren = async (row, treeNode, resolve) => { const loadChildren = async (row, treeNode, resolve) => {
try { try {
// API queryParams.value.parentId = row.id;
// const children = await fetchChildrenData(row.id) const response = await sysRegionListByPid(queryParams.value);
queryParams.value.parentId = row.id row.childList = response.data; //
const children = await sysRegionListByPid(queryParams.value)
//
resolve(children.data)
} catch (error) {
console.error('加载子节点失败:', error)
resolve([])
}
}
// /** / */ if (expandedKeys.value.has(row.id)) {
// const toggleExpandAll = () => { nextTick(() => {
// refreshTable.value = false tableRef.value?.toggleRowExpansion(row, true);
// isExpandAll.value = !isExpandAll.value });
// nextTick(() => { }
// refreshTable.value = true
// }) resolve(response.data);
// } } catch (error) {
console.error('加载子节点失败:', error);
resolve([]);
}
}
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
@ -174,34 +215,105 @@ const cancel = () => {
const submitForm = () => { const submitForm = () => {
proxy.$refs["regionRef"].validate(valid => { proxy.$refs["regionRef"].validate(valid => {
if (valid) { if (valid) {
if (form.value.id != undefined) { const saveExpanded = new Set(expandedKeys.value);
updateSysRegion(form.value).then(response => { const isEdit = !!form.value.id;
proxy.$modal.msgSuccess("修改成功")
open.value = false const operation = isEdit
getsysRegionTreeList() ? updateSysRegion(form.value)
}) : addSysRegion(form.value);
} else {
addSysRegion(form.value).then(response => { operation.then(response => {
proxy.$modal.msgSuccess("新增成功") proxy.$modal.msgSuccess(isEdit ? "修改成功" : "新增成功");
open.value = false open.value = false;
getsysRegionTreeList()
}) if (isEdit) {
} // 1
const updatedRow = findRowById(form.value.id);
if (updatedRow) {
//
const newRowData = { ...updatedRow, ...form.value };
Object.assign(updatedRow, newRowData);
}
//
const parentId = findParentId(form.value.id) || 0;
if (parentId !== 0) {
getsysRegionTreeList(parentId);
}
} else {
//
getsysRegionTreeList(form.value.parentId || 0);
}
//
nextTick(() => {
saveExpanded.forEach(id => {
const row = findRowById(id);
if (row) {
tableRef.value?.toggleRowExpansion(row, true);
}
});
});
}).catch(error => {
console.error("操作失败:", error);
});
} }
}) });
} };
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = (row) => { const handleDelete = async (row) => {
proxy.$modal.confirm('是否确认删除名称为"' + row.name + '"的数据项?').then(function () { try {
return deleteSysRegion(row.id) await proxy.$modal.confirm(`是否确认删除名称为"${row.name}"的数据项?`);
}).then(() => {
regionTreeList.value = [] // 1.
queryParams.value.parentId = '0' const saveExpanded = new Set(expandedKeys.value);
getsysRegionTreeList() // 2.
proxy.$modal.msgSuccess("删除成功") const parentNode = findParentNode(row.id);
}).catch(() => { })
} // 3. API
await deleteSysRegion(row.id);
// 4.
saveExpanded.delete(row.id);
expandedKeys.value = new Set(saveExpanded);
// 5.
if (!parentNode) {
// -
regionTreeList.value = [];
await getsysRegionTreeList();
} else {
// - childList
const index = parentNode.childList.findIndex(item => item.id === row.id);
if (index !== -1) {
parentNode.childList.splice(index, 1); //
//
nextTick(() => {
tableRef.value?.doLayout();
});
}
}
proxy.$modal.msgSuccess("删除成功");
// 6.
nextTick(() => {
saveExpanded.forEach(id => {
const row = findRowById(id);
if (row) {
tableRef.value?.toggleRowExpansion(row, true);
}
});
});
} catch (error) {
if (error !== 'cancel') {
console.error('删除失败:', error);
proxy.$modal.msgError("删除失败");
}
}
};
// //
onMounted(() => { onMounted(() => {

View File

@ -3,17 +3,20 @@
<div class="searchPanel"> <div class="searchPanel">
<el-form :inline="true" v-show="showSearch" class="searchPanelForm"> <el-form :inline="true" v-show="showSearch" class="searchPanelForm">
<el-form-item label="城市:"> <el-form-item label="城市:">
<el-select v-model="queryParams.provinceId" placeholder="请选择" @change="getCityList" clearable style="min-width: 30px"> <el-select v-model="queryParams.provinceId" placeholder="请选择" @change="getCityList" clearable
style="min-width: 30px">
<el-option v-for="item in province" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in province" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label=""> <el-form-item label="">
<el-select v-model="queryParams.cityId" placeholder="请选择" @change="getCountyList" clearable style="min-width: 30px"> <el-select v-model="queryParams.cityId" placeholder="请选择" @change="getCountyList" clearable
style="min-width: 30px">
<el-option v-for="item in city" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in city" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label=""> <el-form-item label="">
<el-select v-model="queryParams.countyId" placeholder="请选择" @change="getTownList" clearable style="min-width: 30px"> <el-select v-model="queryParams.countyId" placeholder="请选择" @change="getTownList" clearable
style="min-width: 30px">
<el-option v-for="item in county" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in county" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -79,7 +82,7 @@
<el-dialog :title="title" v-model="open" width="800px" class="my_dialog" align-center :destroy-on-close="true" <el-dialog :title="title" v-model="open" width="800px" class="my_dialog" align-center :destroy-on-close="true"
:close-on-click-modal="false"> :close-on-click-modal="false">
<el-form ref="businessAreaRef" :model="form" :rules="rules" label-width="120px" class="myInsertForm"> <el-form ref="businessAreaRef" :model="form" :rules="rules" label-width="120px" class="myInsertForm">
<el-form-item label="省/直辖市" prop="provinceId" > <el-form-item label="省/直辖市" prop="provinceId">
<el-select v-model="form.provinceId" placeholder="请选择" clearable @change="getCityList1"> <el-select v-model="form.provinceId" placeholder="请选择" clearable @change="getCityList1">
<el-option v-for="item in province1" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in province1" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
@ -245,6 +248,27 @@ const getTownList1 = (value) => {
}) })
} }
// /
const getCityList2 = (value) => {
sysRegionListByPid({ parentId: value }).then(res => {
city1.value = res.data
})
}
// /
const getCountyList2 = (value) => {
sysRegionListByPid({ parentId: value }).then(res => {
county1.value = res.data
})
}
//
const getTownList2 = (value) => {
sysRegionListByPid({ parentId: value }).then(res => {
town1.value = res.data
})
}
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
form.value = { form.value = {
@ -290,12 +314,30 @@ const handleUpdate = (row) => {
reset() reset()
getProvinceList1() getProvinceList1()
getBusTradingArea(row.id).then(response => { getBusTradingArea(row.id).then(response => {
form.value = response.data handleResponse(response)
open.value = true
title.value = "修改商圈"
}) })
} }
async function handleResponse(response) {
const promises = [];
if (response.data.provinceId) {
promises.push(getCityList2(response.data.provinceId));
}
if (response.data.cityId) {
promises.push(getCountyList2(response.data.cityId));
}
if (response.data.countyId) {
promises.push(getTownList2(response.data.countyId));
}
//
await Promise.all(promises);
//
form.value = response.data;
open.value = true;
title.value = "修改商圈";
}
/** 取消按钮 */ /** 取消按钮 */
const cancel = () => { const cancel = () => {
open.value = false open.value = false

View File

@ -11,20 +11,15 @@
<el-col :span="24"> <el-col :span="24">
<el-button type="primary" class="primaryBtn" @click="handleAddRootNode" <el-button type="primary" class="primaryBtn" @click="handleAddRootNode"
v-hasPermi="['system:mediaType:add']">新增根节点</el-button> v-hasPermi="['system:mediaType:add']">新增根节点</el-button>
<!-- <el-button type="primary" class="primaryBtn" @click="toggleExpandAll">展开/折叠</el-button> -->
</el-col> </el-col>
</el-row> </el-row>
<el-table v-loading="loading" height="calc(100vh - 244px)" :data="mediaTypeTreeList" row-key="id" lazy <el-table v-loading="loading" ref="tableRef" height="calc(100vh - 244px)" :data="mediaTypeTreeList"
:load="loadChildren" :tree-props="{ children: 'childList', hasChildren: 'hasChildren' }"> row-key="id" lazy :load="loadChildren" @expand-change="handleExpandChange"
:tree-props="{ children: 'childList', hasChildren: 'hasChildren' }">
<el-table-column prop="name" label="类型名称"></el-table-column> <el-table-column prop="name" label="类型名称"></el-table-column>
<el-table-column prop="value" label="类型标识"></el-table-column> <el-table-column prop="value" label="类型标识"></el-table-column>
<el-table-column prop="sortNo" label="排序"></el-table-column> <el-table-column prop="sortNo" label="排序"></el-table-column>
<!-- <el-table-column label="创建时间" align="center" prop="createTime" min-width="210">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column> -->
<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row)" <el-button link type="primary" @click="handleUpdate(scope.row)"
@ -76,8 +71,9 @@ const mediaTypeTreeList = ref([])
const open = ref(false) const open = ref(false)
const loading = ref(true) const loading = ref(true)
const title = ref("") const title = ref("")
const isExpandAll = ref(true)
const refreshTable = ref(true) const tableRef = ref();
const expandedKeys = ref(new Set());
const data = reactive({ const data = reactive({
form: {}, form: {},
@ -93,38 +89,82 @@ const data = reactive({
const { queryParams, form, rules } = toRefs(data) const { queryParams, form, rules } = toRefs(data)
/** 查询媒体类型树列表 */ // - ID
const getsysMediaTypeTreeList = () => { const findRowById = (id, rows = mediaTypeTreeList.value) => {
loading.value = true for (const row of rows) {
sysMediaTypeListByPid(queryParams.value).then(res => { if (row.id === id) return row;
mediaTypeTreeList.value = res.data if (row.childList) {
loading.value = false const found = findRowById(id, row.childList);
}) if (found) return found;
} }
}
return null;
};
// - ID
const findParentId = (id, rows = mediaTypeTreeList.value, parentId = 0) => {
for (const row of rows) {
if (row.id === id) return parentId;
if (row.childList) {
const found = findParentId(id, row.childList, row.id);
if (found) return found;
}
}
return null;
};
// -
const findParentNode = (id, rows = mediaTypeTreeList.value, parent = null) => {
for (const row of rows) {
if (row.id === id) return parent;
if (row.childList) {
const found = findParentNode(id, row.childList, row);
if (found) return found;
}
}
return null;
};
// handleExpandChange
const handleExpandChange = (row, expanded) => {
if (expanded) {
expandedKeys.value.add(row.id);
} else {
expandedKeys.value.delete(row.id);
}
};
/** 查询媒体类型树列表 */
const getsysMediaTypeTreeList = (parentId = 0) => {
loading.value = true;
queryParams.value.parentId = parentId;
sysMediaTypeListByPid(queryParams.value).then(res => {
if (parentId === 0) {
mediaTypeTreeList.value = res.data;
}
loading.value = false;
});
};
// //
const loadChildren = async (row, treeNode, resolve) => { const loadChildren = async (row, treeNode, resolve) => {
try { try {
// API queryParams.value.parentId = row.id;
queryParams.value.parentId = row.id const response = await sysMediaTypeListByPid(queryParams.value);
const children = await sysMediaTypeListByPid(queryParams.value) row.childList = response.data; //
//
resolve(children.data)
} catch (error) {
console.error('加载子节点失败:', error)
resolve([])
}
}
// /** / */ if (expandedKeys.value.has(row.id)) {
// const toggleExpandAll = () => { nextTick(() => {
// refreshTable.value = false tableRef.value?.toggleRowExpansion(row, true);
// isExpandAll.value = !isExpandAll.value });
// nextTick(() => { }
// refreshTable.value = true
// }) resolve(response.data);
// } } catch (error) {
console.error('加载子节点失败:', error);
resolve([]);
}
};
/** 表单重置 */ /** 表单重置 */
const reset = () => { const reset = () => {
@ -173,34 +213,104 @@ const cancel = () => {
const submitForm = () => { const submitForm = () => {
proxy.$refs["mediaTypeRef"].validate(valid => { proxy.$refs["mediaTypeRef"].validate(valid => {
if (valid) { if (valid) {
if (form.value.id != undefined) { const saveExpanded = new Set(expandedKeys.value);
updateSysMediaType(form.value).then(response => { const isEdit = !!form.value.id;
proxy.$modal.msgSuccess("修改成功")
open.value = false
getsysMediaTypeTreeList()
})
} else {
addSysMediaType(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getsysMediaTypeTreeList()
})
}
}
})
}
const operation = isEdit
? updateSysMediaType(form.value)
: addSysMediaType(form.value);
operation.then(response => {
proxy.$modal.msgSuccess(isEdit ? "修改成功" : "新增成功");
open.value = false;
if (isEdit) {
// 1
const updatedRow = findRowById(form.value.id);
if (updatedRow) {
//
const newRowData = { ...updatedRow, ...form.value };
Object.assign(updatedRow, newRowData);
}
//
const parentId = findParentId(form.value.id) || 0;
if (parentId !== 0) {
getsysMediaTypeTreeList(parentId);
}
} else {
//
getsysMediaTypeTreeList(form.value.parentId || 0);
}
//
nextTick(() => {
saveExpanded.forEach(id => {
const row = findRowById(id);
if (row) {
tableRef.value?.toggleRowExpansion(row, true);
}
});
});
}).catch(error => {
console.error("操作失败:", error);
});
}
});
};
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = (row) => { const handleDelete = async (row) => {
proxy.$modal.confirm('是否确认删除媒体类型名称为"' + row.name + '"的数据项?').then(function () { try {
return deleteSysMediaType(row.id) await proxy.$modal.confirm(`是否确认删除媒体类型名称为"${row.name}"的数据项?`);
}).then(() => {
mediaTypeTreeList.value = [] // 1.
queryParams.value.parentId = 0 const saveExpanded = new Set(expandedKeys.value);
getsysMediaTypeTreeList() // 2.
proxy.$modal.msgSuccess("删除成功") const parentNode = findParentNode(row.id);
}).catch(() => { })
} // 3. API
await deleteSysMediaType(row.id);
// 4.
saveExpanded.delete(row.id);
expandedKeys.value = new Set(saveExpanded);
// 5.
if (!parentNode) {
// -
mediaTypeTreeList.value = [];
await getsysMediaTypeTreeList();
} else {
// - childList
const index = parentNode.childList.findIndex(item => item.id === row.id);
if (index !== -1) {
parentNode.childList.splice(index, 1); //
//
nextTick(() => {
tableRef.value?.doLayout();
});
}
}
proxy.$modal.msgSuccess("删除成功");
// 6.
nextTick(() => {
saveExpanded.forEach(id => {
const row = findRowById(id);
if (row) {
tableRef.value?.toggleRowExpansion(row, true);
}
});
});
} catch (error) {
if (error !== 'cancel') {
console.error('删除失败:', error);
proxy.$modal.msgError("删除失败");
}
}
};
// //
onMounted(() => { onMounted(() => {