飞行路径管理,沿程bug修改
This commit is contained in:
parent
51ea9e5cb8
commit
4c0c267842
@ -115,10 +115,18 @@ export function uploadFile(data: any) {
|
||||
});
|
||||
}
|
||||
// 所在位置下拉列表
|
||||
export function getAddvcdDropdownByRvcd(params: any) {
|
||||
export function getAddvcdDropdownByRvcd(data: any = {}) {
|
||||
return request({
|
||||
url: '/base/msalongb/noAuth/GetKendoList',
|
||||
method: 'post',
|
||||
params
|
||||
data
|
||||
});
|
||||
}
|
||||
//沿程配置下拉列表
|
||||
export function noAuthGetKendoPage(data: any = {}) {
|
||||
return request({
|
||||
url: '/base/msalongb/noAuth/GetKendoPage',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
@ -39,6 +39,14 @@ export function vmsstbprptGetKendoList(queryParams: any) {
|
||||
data: queryParams
|
||||
});
|
||||
}
|
||||
//获取电站
|
||||
export function overviewvmsstbprptGetKendoList(queryParams: any) {
|
||||
return request({
|
||||
url: '/eq/vmsstbprpt/GetKendoList',
|
||||
method: 'post',
|
||||
data: queryParams
|
||||
});
|
||||
}
|
||||
export function vmsstbprptGetKendoList1(queryParams: any) {
|
||||
return request({
|
||||
url: '/eq/vmsstbprpt/GetKendoList',
|
||||
|
||||
@ -42,7 +42,7 @@ export function getCxswList(data: any) {
|
||||
//获取出入库水温下拉选则树
|
||||
export function getVmsstbprpt(data: any) {
|
||||
return request({
|
||||
url: '/wt/vmsstbprpt/GetKendoList',
|
||||
url: '/eq/vmsstbprpt/GetKendoList',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
|
||||
50
frontend/src/api/system/disposeManage/index.ts
Normal file
50
frontend/src/api/system/disposeManage/index.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 获取所有沿程配置数据
|
||||
export function threedroambGetKendoListCust(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/GetKendoListCust',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
export function threedroambsave(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
export function threedroambdelete(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/delete',
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
//根据id查询弹窗
|
||||
export function threedroambGetKendoById(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/getThreedRoamDetails',
|
||||
method: 'get',
|
||||
params: data
|
||||
});
|
||||
}
|
||||
// 导入接口
|
||||
export function threedroambimport(data: FormData) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/import',
|
||||
method: 'post',
|
||||
data: data,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
});
|
||||
}
|
||||
// 导出模板
|
||||
export function threedroambexport(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-sys-server/sys/threedroamb/export',
|
||||
method: 'post',
|
||||
data: data,
|
||||
responseType: 'blob'
|
||||
});
|
||||
}
|
||||
@ -34,7 +34,7 @@
|
||||
<Yanchengyulei
|
||||
v-if="modalVisible && JidiSelectEventStore.jidiData.length > 0"
|
||||
:tm="modalYear"
|
||||
:dataDimensionVal="baseid"
|
||||
:dataDimensionVal="moreSelect.value.value"
|
||||
:hbrvcd="modalHbrvcd"
|
||||
:jdList="JidiSelectEventStore.jidiData"
|
||||
:stateName="modalStateName"
|
||||
@ -52,7 +52,7 @@ import type { EChartsOption } from 'echarts';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import Yanchengyulei from './TwoLayers/Yanchengyulei.vue';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import { wbsbGetKendoList, getDftYear, fishChanges2 } from '@/api/stdc';
|
||||
import { getDftYear, fishChanges2 } from '@/api/stdc';
|
||||
import moment from 'moment';
|
||||
import { useDraggable } from '@/utils/drag';
|
||||
|
||||
@ -64,8 +64,6 @@ defineOptions({
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
|
||||
// ==================== 基础状态 ====================
|
||||
/** 当前选中的基地ID,来自 JidiSelectEventStore.selectedItem */
|
||||
const baseid = ref('');
|
||||
/** 图表数据加载状态 */
|
||||
const dataLoading = ref(false);
|
||||
/** 初始化标志位:初始化期间不响应控件变化触发数据请求 */
|
||||
@ -253,8 +251,8 @@ const handleResize = () => {
|
||||
const getYearData = async () => {
|
||||
try {
|
||||
const filter: any = {};
|
||||
if (baseid.value && baseid.value !== 'all') {
|
||||
filter.baseId = baseid.value;
|
||||
if (moreSelect.value.value) {
|
||||
filter.baseId = moreSelect.value.value;
|
||||
}
|
||||
|
||||
const params = {
|
||||
@ -285,7 +283,7 @@ const getYearData = async () => {
|
||||
);
|
||||
const latestYear = uniqueYears[0];
|
||||
|
||||
// baseid 为 all 时取第一个有数据的流域
|
||||
// 取第一个有数据的流域
|
||||
const firstWbsCode = Object.keys(data)[0];
|
||||
select.value.options = objYear[firstWbsCode] || [];
|
||||
select.value.value = latestYear
|
||||
@ -326,70 +324,6 @@ const updateYearOptionsByBase = async (wbsCode: string) => {
|
||||
* 获取流域树形选择器数据 + 年份数据 + 图表数据
|
||||
* 在基地变化时调用,是整个模块数据加载的入口
|
||||
*/
|
||||
const getMoreSelectData = async () => {
|
||||
if (!baseid.value) return;
|
||||
|
||||
isInitializing.value = true;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'wbsType',
|
||||
operator: 'eq',
|
||||
value: 'PSB_RVCD'
|
||||
},
|
||||
baseid.value !== 'all'
|
||||
? {
|
||||
field: 'objid',
|
||||
operator: 'eq',
|
||||
value: baseid.value
|
||||
}
|
||||
: null
|
||||
].filter(Boolean)
|
||||
},
|
||||
group: [
|
||||
{ dir: 'asc', field: 'orderIndex' },
|
||||
{ dir: 'asc', field: 'wbsCode' },
|
||||
{ dir: 'asc', field: 'wbsName' },
|
||||
{ dir: 'asc', field: 'objid' }
|
||||
],
|
||||
groupResultFlat: true
|
||||
};
|
||||
|
||||
const res = await wbsbGetKendoList(params);
|
||||
const data = res?.data?.data || [];
|
||||
|
||||
if (data.length > 0) {
|
||||
const treeData = buildTreeData(data);
|
||||
const filteredData = filterSelectOptions(treeData);
|
||||
|
||||
// 只有一个流域时隐藏树形选择器
|
||||
moreSelect.value.options = filteredData;
|
||||
moreSelect.value.value = treeData?.[0]?.children?.[0]?.value;
|
||||
|
||||
// 先获取年份数据缓存到 yearOptions,再根据实际选中的流域设置年份选项
|
||||
await getYearData();
|
||||
if (moreSelect.value.value) {
|
||||
await updateYearOptionsByBase(moreSelect.value.value);
|
||||
}
|
||||
await getChartData();
|
||||
} else {
|
||||
moreSelect.value.options = [];
|
||||
moreSelect.value.value = undefined;
|
||||
await getYearData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取树形选择器数据失败:', error);
|
||||
moreSelect.value.options = [];
|
||||
moreSelect.value.value = undefined;
|
||||
} finally {
|
||||
isInitializing.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取图表数据
|
||||
* 根据当前选中的流域(hbrvcd)、年份(yr)、基地(baseId)调用 fishChanges2 API
|
||||
@ -404,28 +338,18 @@ const getChartData = async () => {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
moreSelect.value.value
|
||||
? {
|
||||
field: 'hbrvcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: moreSelect.value.value
|
||||
}
|
||||
: null,
|
||||
{
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: moreSelect.value.value
|
||||
},
|
||||
{
|
||||
field: 'yr',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: moment(select.value.value).format('YYYY')
|
||||
},
|
||||
baseid.value !== 'all'
|
||||
? {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: baseid.value
|
||||
}
|
||||
: null
|
||||
}
|
||||
].filter(Boolean)
|
||||
},
|
||||
group: [
|
||||
@ -452,73 +376,6 @@ const getChartData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== 树形工具函数 ====================
|
||||
|
||||
/**
|
||||
* 将 API 返回的扁平数据转换为树形结构
|
||||
* 按 objid(基地)分组,每个基地下包含其流域列表
|
||||
* @param data 扁平的流域数据数组
|
||||
*/
|
||||
const buildTreeData = (data: any[]) => {
|
||||
if (!data || data.length === 0) return [];
|
||||
|
||||
// 构建基地名称映射
|
||||
const jiDiListMap: Record<string, string> = {};
|
||||
JidiSelectEventStore.jidiData.forEach((item: any) => {
|
||||
jiDiListMap[item.wbsCode] = item.wbsName;
|
||||
});
|
||||
|
||||
// 按 objid 分组并去重
|
||||
const dataMapNameMap: Record<string, any[]> = {};
|
||||
data.forEach(item => {
|
||||
const objId = item.objid || item.objId;
|
||||
if (!dataMapNameMap[objId]) {
|
||||
dataMapNameMap[objId] = [];
|
||||
}
|
||||
const exists = dataMapNameMap[objId].some(
|
||||
existing => existing.wbsCode === item.wbsCode
|
||||
);
|
||||
if (!exists) {
|
||||
dataMapNameMap[objId].push(item);
|
||||
}
|
||||
});
|
||||
|
||||
const treeData = Object.keys(dataMapNameMap).map(objId => ({
|
||||
title: jiDiListMap[objId] || '---',
|
||||
value: objId,
|
||||
selectable: false,
|
||||
children: dataMapNameMap[objId].map((item: any) => ({
|
||||
title: item.wbsName,
|
||||
value: item.wbsCode
|
||||
}))
|
||||
}));
|
||||
|
||||
// 排序:数字在前升序,非数字排在最后
|
||||
treeData.sort((a, b) => {
|
||||
const numA = Number(a.value);
|
||||
const numB = Number(b.value);
|
||||
const aIsNum = !isNaN(numA);
|
||||
const bIsNum = !isNaN(numB);
|
||||
if (aIsNum && bIsNum) return numA - numB;
|
||||
if (aIsNum) return -1;
|
||||
if (bIsNum) return 1;
|
||||
return a.value.localeCompare(b.value);
|
||||
});
|
||||
|
||||
return treeData;
|
||||
};
|
||||
|
||||
/**
|
||||
* 过滤树形选择器数据
|
||||
* 当只有一个基地且只有一个流域时,直接返回流域列表(跳过基地层级)
|
||||
*/
|
||||
const filterSelectOptions = (options: any[]) => {
|
||||
if (options?.length === 1 && options?.[0]?.children?.length === 1) {
|
||||
return options[0].children;
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
// ==================== 弹框相关 ====================
|
||||
|
||||
/**
|
||||
@ -581,8 +438,32 @@ watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
async newVal => {
|
||||
if (newVal && newVal.wbsCode) {
|
||||
baseid.value = newVal.wbsCode;
|
||||
await getMoreSelectData();
|
||||
if (newVal.wbsCode === 'all') {
|
||||
moreSelect.value.value = moreSelect.value.options[0]?.value;
|
||||
} else {
|
||||
moreSelect.value.value = newVal.wbsCode;
|
||||
}
|
||||
await getYearData();
|
||||
if (moreSelect.value.value) {
|
||||
await updateYearOptionsByBase(moreSelect.value.value);
|
||||
}
|
||||
await getChartData();
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步 moreSelect 下拉框选项
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
const filtered = newVal.filter(item => item.wbsCode !== 'all');
|
||||
moreSelect.value.options = filtered.map(item => ({
|
||||
value: item.wbsCode,
|
||||
title: item.wbsName
|
||||
}));
|
||||
if (!moreSelect.value.value && filtered.length > 0) {
|
||||
moreSelect.value.value = filtered[0].wbsCode;
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
<churukushuiwen
|
||||
v-if="clickDataInfo"
|
||||
:tm="[clickDataInfo.date, clickDataInfo.date]"
|
||||
:stcd="paramsOne.value"
|
||||
:stcd="select.value"
|
||||
/>
|
||||
</div>
|
||||
</a-modal>
|
||||
@ -49,7 +49,7 @@ import { ref, onMounted, onUnmounted, watch } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import dayjs from 'dayjs';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { getVmsstbprpt, inOutOneGetKendoListCust } from '@/api/sw';
|
||||
import { inOutOneGetKendoListCust } from '@/api/sw';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import churukushuiwen from './churukushuiwen.vue';
|
||||
import { MapClass } from '@/components/gis/map.class';
|
||||
@ -93,7 +93,6 @@ const scopeDate = ref({
|
||||
});
|
||||
|
||||
// ==================== 业务变量 ====================
|
||||
const baseid = ref(''); // 当前选中的基地ID
|
||||
const modalVisible = ref(false); // 弹框显示状态
|
||||
const clickDataInfo = ref<any>(null); // 点击的数据点信息
|
||||
const stationName = ref(''); // 站点名称
|
||||
@ -169,7 +168,6 @@ function calculateXAxisInterval(dateCount: number): number {
|
||||
return Math.ceil(dateCount / 4) - 1; // 动态计算间隔,保证最多4个刻度
|
||||
}
|
||||
const paramsOne: any = ref({
|
||||
value: '',
|
||||
tm: [currentMonth, currentMonth]
|
||||
});
|
||||
/**
|
||||
@ -194,20 +192,10 @@ async function fetchChartData() {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
// OR逻辑:查询入库或出库水温
|
||||
logic: 'or',
|
||||
filters: [
|
||||
{
|
||||
field: 'engDwtCode',
|
||||
operator: 'eq',
|
||||
value: paramsOne.value.value
|
||||
}, // 出库站点编码
|
||||
{
|
||||
field: 'engIwtCode',
|
||||
operator: 'eq',
|
||||
value: paramsOne.value.value
|
||||
} // 入库站点编码
|
||||
]
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: select.value.value
|
||||
},
|
||||
// 时间范围过滤
|
||||
{ field: 'dt', operator: 'gte', dataType: 'date', value: startDate },
|
||||
@ -584,12 +572,10 @@ const handleChartClick = (params: any) => {
|
||||
dataIndex: dataIndex // 数据索引
|
||||
};
|
||||
|
||||
// 获取站点名称(从下拉选项中查找)
|
||||
// console.log('站点名称:', select.value.options, paramsOne.value.value);
|
||||
const selectedStation = select.value.options
|
||||
.flatMap((base: any) => base.children || [])
|
||||
.find((station: any) => station.stcd === paramsOne.value.value);
|
||||
stationName.value = selectedStation?.title || '未知站点';
|
||||
// 获取站点名称
|
||||
stationName.value = select.value.options?.find(
|
||||
(item: any) => item.value === select.value.value
|
||||
)?.title || '未知站点';
|
||||
|
||||
// 打开弹框
|
||||
modalVisible.value = true;
|
||||
@ -612,7 +598,7 @@ const handleModalClose = () => {
|
||||
const handlePanelChange1 = (data: any, type: string) => {
|
||||
// TODO: 后续可扩展联动逻辑
|
||||
if (data.moreSelect && data.scopeDate) {
|
||||
paramsOne.value.value = data.moreSelect;
|
||||
select.value.value = data.moreSelect;
|
||||
paramsOne.value.tm = data.scopeDate;
|
||||
fetchChartData();
|
||||
}
|
||||
@ -628,143 +614,31 @@ const handlePanelChange1 = (data: any, type: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取站点下拉选项数据
|
||||
* 根据选中的基地ID查询对应的站点列表
|
||||
*/
|
||||
const getselsectData = async () => {
|
||||
loading.value = true; // 开始加载站点数据
|
||||
|
||||
try {
|
||||
let params = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
// 如果baseid不是'all',则添加基地过滤条件
|
||||
baseid.value != 'all'
|
||||
? {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: baseid.value
|
||||
}
|
||||
: null,
|
||||
// 站点类型过滤:只查询ENG类型站点
|
||||
{
|
||||
field: 'sttpCode',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: 'ENG'
|
||||
},
|
||||
// 只查询有效站点(dtin=1)
|
||||
{
|
||||
field: 'dtin',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: 1
|
||||
}
|
||||
].filter(Boolean) // 过滤掉null值
|
||||
},
|
||||
sort: [
|
||||
// 如果是'all',按基地排序;否则不排序
|
||||
baseid.value == 'all'
|
||||
? {
|
||||
field: 'baseStepSort',
|
||||
dir: 'asc'
|
||||
}
|
||||
: null,
|
||||
{
|
||||
field: 'rvcdStepSort',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
field: 'siteStepSort',
|
||||
dir: 'asc'
|
||||
}
|
||||
].filter(Boolean), // 过滤掉null值
|
||||
select: [
|
||||
'stcd', // 站点编码
|
||||
'stnm', // 站点名称
|
||||
'lgtd', // 经度
|
||||
'lttd', // 纬度
|
||||
'siteStepSort', // 站点排序
|
||||
'baseId', // 基地ID
|
||||
'baseName' // 基地名称
|
||||
]
|
||||
};
|
||||
|
||||
// 调用API获取站点数据
|
||||
const res = await getVmsstbprpt(params);
|
||||
console.log('res', res);
|
||||
const data = res?.data?.data || res?.data;
|
||||
const obj: any = {};
|
||||
if (data) {
|
||||
// 将扁平数据转换为树形结构(按基地分组)
|
||||
data.map(e => {
|
||||
if (obj[e.baseId]) {
|
||||
// 如果基地已存在,添加子节点
|
||||
obj[e.baseId] = {
|
||||
...obj[e.baseId],
|
||||
children: [
|
||||
...obj[e.baseId].children,
|
||||
{ ...e, value: e.stcd, title: e.stnm }
|
||||
]
|
||||
};
|
||||
} else {
|
||||
// 创建新的基地节点
|
||||
obj[e.baseId] = {
|
||||
value: e.baseId,
|
||||
title: e.baseName,
|
||||
selectable: false,
|
||||
key: e.baseId,
|
||||
children: [{ ...e, value: e.stcd, title: e.stnm }]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// 转换为数组并按jiDiList顺序排序
|
||||
let treeData: any = [];
|
||||
const dataMapNameArr: any = Object.entries(obj).map(([, v]) => v);
|
||||
treeData = dataMapNameArr?.sort((a: any, b: any) => {
|
||||
const indexA = JidiSelectEventStore.jidiData.findIndex(
|
||||
item => item.wbsCode === a.value
|
||||
);
|
||||
const indexB = JidiSelectEventStore.jidiData.findIndex(
|
||||
item => item.wbsCode === b.value
|
||||
);
|
||||
return indexA - indexB;
|
||||
});
|
||||
console.log('treeData', treeData);
|
||||
// 更新下拉框选项
|
||||
select.value.options = treeData;
|
||||
|
||||
// 设置默认选中值
|
||||
if (baseid.value == 'all') {
|
||||
select.value.value = '008640203800000001'; // 默认选中第一个站点
|
||||
} else {
|
||||
select.value.value = treeData?.[0]?.children[0]?.value; // 选中当前基地的第一个站点
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取站点数据失败:', error);
|
||||
} finally {
|
||||
loading.value = false; // 关闭loading
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== Watch监听器 ====================
|
||||
|
||||
/**
|
||||
* 监听基地选择变化
|
||||
* 当用户切换基地时,重新加载站点下拉选项
|
||||
*/
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem, // 监听Store中的选中项
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
newVal => {
|
||||
baseid.value = newVal.wbsCode; // 更新基地ID
|
||||
getselsectData(); // 重新获取站点数据
|
||||
select.value.value = newVal.wbsCode;
|
||||
fetchChartData();
|
||||
},
|
||||
{ deep: true, immediate: true } // 深度监听,立即执行
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步下拉框选项
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
select.value.options = newVal.map(item => ({
|
||||
value: item.wbsCode,
|
||||
title: item.wbsName
|
||||
}));
|
||||
// 如果当前没有选中值,默认选中第一个有效项
|
||||
if (!select.value.value && newVal.length > 0) {
|
||||
select.value.value = newVal[0].wbsCode;
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { wbsbGetKendoList, avgMonGetKendoListCust } from "@/api/sw";
|
||||
import { avgMonGetKendoListCust } from "@/api/sw";
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import MonthlyAverage from './monthlyAverage.vue'
|
||||
import MonthlyAverageMaxModal from './TwoLayers/monthlyAverageMaxModal.vue'
|
||||
@ -55,7 +55,6 @@ const searchParams = ref({
|
||||
dateValue: '' // 可以是 string 或 Dayjs 对象
|
||||
});
|
||||
const unit = '°C'
|
||||
const baseid: any = ref(null);
|
||||
const loading = ref(false);
|
||||
const showemit = ref(true);
|
||||
|
||||
@ -94,123 +93,6 @@ const datetimePicker = ref({
|
||||
options: [],
|
||||
});
|
||||
|
||||
const filterSelectOptions = (selectOptions: any) => {
|
||||
if (selectOptions?.length === 1 && selectOptions?.[0]?.children?.length === 1) {
|
||||
return [{ ...selectOptions?.[0]?.children?.[0], isLeaf: true }]
|
||||
} else if (selectOptions.length) {
|
||||
return selectOptions.map((e) => {
|
||||
if (e?.children?.length > 1) {
|
||||
return { ...e, isLeaf: false, selectable: true, children: e.children.map((item) => ({ ...item, isLeaf: true })) }
|
||||
} else {
|
||||
return { ...e.children[0], isLeaf: true }
|
||||
}
|
||||
})
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
//获取选择器配置参数
|
||||
const getSelectConfig = async () => {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
let obj: any = {}
|
||||
if (baseid.value === 'all') {
|
||||
obj = { rstcdStepSort: 'asc', siteStepSort: 'asc' }
|
||||
} else {
|
||||
obj = { siteStepSort: 'asc' }
|
||||
}
|
||||
const filters = [
|
||||
{
|
||||
field: 'wbsType',
|
||||
operator: 'eq',
|
||||
value: 'PSB_RVCD'
|
||||
}
|
||||
]
|
||||
if (baseid.value && baseid.value !== 'all') {
|
||||
filters.push({
|
||||
field: 'objId',
|
||||
operator: 'eq',
|
||||
value: baseid.value
|
||||
})
|
||||
}
|
||||
let data: any = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters
|
||||
}
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
data.sort = [obj]
|
||||
} else {
|
||||
data = {
|
||||
...data,
|
||||
group: [
|
||||
{ dir: 'asc', field: 'orderIndex' },
|
||||
{ dir: 'asc', field: 'wbsCode' },
|
||||
{ dir: 'asc', field: 'wbsName' },
|
||||
{ dir: 'asc', field: 'objid' },
|
||||
],
|
||||
groupResultFlat: true
|
||||
}
|
||||
}
|
||||
let res = await wbsbGetKendoList(data)
|
||||
let dataOne = res?.data?.data || res?.data
|
||||
|
||||
if (dataOne.length > 0) {
|
||||
let dataMapNameMap: any = {}
|
||||
let jiDiListMap: any = {}
|
||||
JidiSelectEventStore.jidiData.forEach((item: any) => {
|
||||
jiDiListMap[item.wbsCode] = item.wbsName
|
||||
})
|
||||
|
||||
dataOne.map((item: any, index: number) => {
|
||||
const { stcd, stnm, objId } = item
|
||||
if (dataMapNameMap[objId]) {
|
||||
dataMapNameMap[objId].push({ ...item, baseName: jiDiListMap[objId], baseId: objId })
|
||||
} else {
|
||||
dataMapNameMap[objId] = [{ ...item, baseName: jiDiListMap[objId], baseId: objId }]
|
||||
}
|
||||
return { label: item.wbsName, value: item.wbsCode, baseId: objId, baseName: jiDiListMap[objId] }
|
||||
})
|
||||
|
||||
let dataMapNameArr: any = []
|
||||
|
||||
Object.keys(dataMapNameMap).forEach((item: any) => {
|
||||
dataMapNameArr.push({
|
||||
title: dataMapNameMap[item]?.[0]?.baseName,
|
||||
value: item,
|
||||
selectable: false,
|
||||
children: dataMapNameMap[item].map((item2: any) => {
|
||||
return {
|
||||
title: item2.wbsName,
|
||||
value: item2.wbsCode
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
dataMapNameArr = dataMapNameArr.sort((a: any, b: any) => {
|
||||
const indexA = JidiSelectEventStore.jidiData.findIndex(item => item.wbsCode === a.value);
|
||||
const indexB = JidiSelectEventStore.jidiData.findIndex(item => item.wbsCode === b.value);
|
||||
return indexA - indexB;
|
||||
})
|
||||
select.value.options = filterSelectOptions(dataMapNameArr)
|
||||
if (filterSelectOptions(dataMapNameArr)[0]?.children) {
|
||||
select.value.value = filterSelectOptions(dataMapNameArr)[0]?.children[0]?.value
|
||||
} else if (filterSelectOptions(dataMapNameArr)[0]?.value) {
|
||||
select.value.value = filterSelectOptions(dataMapNameArr)[0]?.value
|
||||
} else {
|
||||
select.value.value = ''
|
||||
}
|
||||
}
|
||||
getEchartsData()
|
||||
} catch (error) {
|
||||
console.error('选择器配置加载失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
//获取图表配置
|
||||
const getEchartsData = async () => {
|
||||
if (loading.value) return; // 防止重复请求
|
||||
@ -238,7 +120,7 @@ const getEchartsData = async () => {
|
||||
"logic": "and",
|
||||
"filters": [
|
||||
{
|
||||
"field": "rvcd",
|
||||
"field": "baseId",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": select.value.value
|
||||
@ -527,7 +409,7 @@ const initChart = (newXData: any[], actualData: any[], lastData: any[], naturalD
|
||||
// 设置弹框数据
|
||||
stationName.value = stnm;
|
||||
modalData.value = {
|
||||
baseid: baseid.value,
|
||||
baseid: select.value.value,
|
||||
rvcd: select.value.value,
|
||||
date: datetimePicker.value.value,
|
||||
stcd: stcd,
|
||||
@ -575,8 +457,24 @@ const handlePanelChange1 = (data) => {
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
baseid.value = newVal.wbsCode;
|
||||
getSelectConfig()
|
||||
select.value.value = newVal.wbsCode;
|
||||
getEchartsData()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步下拉框选项
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
select.value.options = newVal.map(item => ({
|
||||
value: item.wbsCode,
|
||||
title: item.wbsName
|
||||
}));
|
||||
// 如果当前没有选中值,默认选中第一个有效项
|
||||
if (!select.value.value && newVal.length > 0) {
|
||||
select.value.value = newVal[0].wbsCode;
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
@ -38,12 +38,20 @@
|
||||
class="tab-style"
|
||||
@change="fetchTableData"
|
||||
>
|
||||
<a-tab-pane v-for="item in tabList" :key="item.key" :tab="item.label" />
|
||||
<a-tab-pane
|
||||
v-for="item in tabList"
|
||||
:key="item.key"
|
||||
:tab="item.label"
|
||||
/>
|
||||
</a-tabs>
|
||||
<div class="body_zhengti">
|
||||
<div class="echarts">
|
||||
<a-spin :spinning="dataLoading">
|
||||
<div v-if="pieData.length > 0" ref="chartRef" class="pie-chart"></div>
|
||||
<div
|
||||
v-if="pieData.length > 0"
|
||||
ref="chartRef"
|
||||
class="pie-chart"
|
||||
></div>
|
||||
<a-empty
|
||||
v-if="!dataLoading && pieData.length === 0"
|
||||
description="暂无数据"
|
||||
@ -55,7 +63,6 @@
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:scrollY="380"
|
||||
|
||||
:list-url="vmsstbprptGetKendoList"
|
||||
:search-params="searchParams"
|
||||
:transform-data="customTransform"
|
||||
@ -80,10 +87,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a-empty
|
||||
v-else-if="!bodyLoading"
|
||||
description="暂无数据"
|
||||
/>
|
||||
<a-empty v-else-if="!bodyLoading" description="暂无数据" />
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
@ -96,6 +100,7 @@ import dayjs from 'dayjs';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import {
|
||||
dayGetKendoListCust,
|
||||
overviewvmsstbprptGetKendoList,
|
||||
vmsstbprptGetKendoList,
|
||||
msstbprptGetKendoList
|
||||
} from '@/api/stll';
|
||||
@ -745,7 +750,7 @@ watch(ecoFlowType, () => {
|
||||
// 监听 tabList 变化,当变为空时清理图表实例
|
||||
watch(
|
||||
() => tabList.value.length,
|
||||
(newLen) => {
|
||||
newLen => {
|
||||
if (newLen === 0 && chartInstance) {
|
||||
chartInstance.dispose();
|
||||
chartInstance = null;
|
||||
@ -766,12 +771,18 @@ const rstcdOption = async () => {
|
||||
filters: [
|
||||
params.value.qid != 'all'
|
||||
? {
|
||||
field: 'sttpCode',
|
||||
operator: 'eq',
|
||||
field: 'baseId',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: 'ENG'
|
||||
value: params.value.qid
|
||||
}
|
||||
: null
|
||||
: null,
|
||||
{
|
||||
field: 'sttpCode',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: 'ENG'
|
||||
}
|
||||
].filter(Boolean)
|
||||
},
|
||||
sort: [
|
||||
@ -782,7 +793,34 @@ const rstcdOption = async () => {
|
||||
],
|
||||
select: ['stcd', 'stnm']
|
||||
};
|
||||
let res = await vmsstbprptGetKendoList(obj);
|
||||
if (params.value.qid == 'all') {
|
||||
obj.sort = [
|
||||
{
|
||||
field: 'ttpwr',
|
||||
dir: 'desc'
|
||||
}
|
||||
];
|
||||
} else {
|
||||
obj.sort = [
|
||||
{
|
||||
field: 'baseId',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
field: 'rvcdStepSort',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
field: 'rstcdStepSort',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
field: 'siteStepSort',
|
||||
dir: 'asc'
|
||||
}
|
||||
];
|
||||
}
|
||||
let res = await overviewvmsstbprptGetKendoList(obj);
|
||||
rstcdOptions.value = res.data.data.map((item: any) => {
|
||||
return {
|
||||
value: item.stcd,
|
||||
@ -834,7 +872,7 @@ const handleResize = () => {
|
||||
width: 35%;
|
||||
height: 482px;
|
||||
// position: relative;
|
||||
|
||||
|
||||
.pie-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@ -30,7 +30,7 @@ import * as echarts from 'echarts';
|
||||
import type { EChartsOption } from 'echarts';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import { wbsbGetKendoList, getDftYear, getFishListStat } from '@/api/stdc';
|
||||
import { getDftYear, getFishListStat } from '@/api/stdc';
|
||||
import moment from 'moment';
|
||||
|
||||
defineOptions({
|
||||
@ -41,7 +41,6 @@ defineOptions({
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
|
||||
// ==================== 基础状态 ====================
|
||||
const baseid = ref('');
|
||||
const isInitializing = ref(false);
|
||||
const dataLoading = ref(false);
|
||||
|
||||
@ -174,8 +173,8 @@ const handleResize = () => {
|
||||
const getYearData = async () => {
|
||||
try {
|
||||
const filter: any = {};
|
||||
if (baseid.value && baseid.value !== 'all') {
|
||||
filter.baseId = baseid.value;
|
||||
if (moreSelect.value.value) {
|
||||
filter.baseId = moreSelect.value.value;
|
||||
}
|
||||
|
||||
const params = {
|
||||
@ -236,69 +235,6 @@ const updateYearOptionsByBase = async (wbsCode: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getMoreSelectData = async () => {
|
||||
if (!baseid.value) return;
|
||||
|
||||
isInitializing.value = true;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'wbsType',
|
||||
operator: 'eq',
|
||||
value: 'PSB_RVCD'
|
||||
},
|
||||
baseid.value !== 'all'
|
||||
? {
|
||||
field: 'objid',
|
||||
operator: 'eq',
|
||||
value: baseid.value
|
||||
}
|
||||
: null
|
||||
].filter(Boolean)
|
||||
},
|
||||
group: [
|
||||
{ dir: 'asc', field: 'orderIndex' },
|
||||
{ dir: 'asc', field: 'wbsCode' },
|
||||
{ dir: 'asc', field: 'wbsName' },
|
||||
{ dir: 'asc', field: 'objid' }
|
||||
],
|
||||
groupResultFlat: true
|
||||
};
|
||||
|
||||
const res = await wbsbGetKendoList(params);
|
||||
const data = res?.data?.data || [];
|
||||
// debugger
|
||||
|
||||
if (data.length > 0) {
|
||||
const treeData = buildTreeData(data);
|
||||
const filteredData = filterSelectOptions(treeData);
|
||||
|
||||
moreSelect.value.options = filteredData;
|
||||
moreSelect.value.value = treeData?.[0]?.children?.[0]?.value;
|
||||
|
||||
await getYearData();
|
||||
if (moreSelect.value.value) {
|
||||
await updateYearOptionsByBase(moreSelect.value.value);
|
||||
}
|
||||
await getChartData();
|
||||
} else {
|
||||
moreSelect.value.options = [];
|
||||
moreSelect.value.value = undefined;
|
||||
await getYearData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取树形选择器数据失败:', error);
|
||||
moreSelect.value.options = [];
|
||||
moreSelect.value.value = undefined;
|
||||
} finally {
|
||||
isInitializing.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取图表数据
|
||||
* 根据当前选中的流域(hbrvcd)调用 getFishListStat API
|
||||
@ -314,7 +250,7 @@ const getChartData = async () => {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'hbrvcd',
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: moreSelect.value.value
|
||||
@ -340,61 +276,6 @@ const getChartData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== 树形工具函数 ====================
|
||||
|
||||
const buildTreeData = (data: any[]) => {
|
||||
if (!data || data.length === 0) return [];
|
||||
|
||||
const jiDiListMap: Record<string, string> = {};
|
||||
JidiSelectEventStore.jidiData.forEach((item: any) => {
|
||||
jiDiListMap[item.wbsCode] = item.wbsName;
|
||||
});
|
||||
|
||||
const dataMapNameMap: Record<string, any[]> = {};
|
||||
data.forEach(item => {
|
||||
const objId = item.objid || item.objId;
|
||||
if (!dataMapNameMap[objId]) {
|
||||
dataMapNameMap[objId] = [];
|
||||
}
|
||||
const exists = dataMapNameMap[objId].some(
|
||||
existing => existing.wbsCode === item.wbsCode
|
||||
);
|
||||
if (!exists) {
|
||||
dataMapNameMap[objId].push(item);
|
||||
}
|
||||
});
|
||||
|
||||
const treeData = Object.keys(dataMapNameMap).map(objId => ({
|
||||
title: jiDiListMap[objId] || '---',
|
||||
value: objId,
|
||||
selectable: false,
|
||||
children: dataMapNameMap[objId].map((item: any) => ({
|
||||
title: item.wbsName,
|
||||
value: item.wbsCode
|
||||
}))
|
||||
}));
|
||||
|
||||
treeData.sort((a, b) => {
|
||||
const numA = Number(a.value);
|
||||
const numB = Number(b.value);
|
||||
const aIsNum = !isNaN(numA);
|
||||
const bIsNum = !isNaN(numB);
|
||||
if (aIsNum && bIsNum) return numA - numB;
|
||||
if (aIsNum) return -1;
|
||||
if (bIsNum) return 1;
|
||||
return a.value.localeCompare(b.value);
|
||||
});
|
||||
|
||||
return treeData;
|
||||
};
|
||||
|
||||
const filterSelectOptions = (options: any[]) => {
|
||||
if (options?.length === 1 && options?.[0]?.children?.length === 1) {
|
||||
return options[0].children;
|
||||
}
|
||||
return options;
|
||||
};
|
||||
|
||||
// ==================== 事件处理 ====================
|
||||
|
||||
const handlePanelChange = async (data: any) => {
|
||||
@ -421,8 +302,32 @@ watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
async newVal => {
|
||||
if (newVal && newVal.wbsCode) {
|
||||
baseid.value = newVal.wbsCode;
|
||||
await getMoreSelectData();
|
||||
if (newVal.wbsCode === 'all') {
|
||||
moreSelect.value.value = moreSelect.value.options[0]?.value;
|
||||
} else {
|
||||
moreSelect.value.value = newVal.wbsCode;
|
||||
}
|
||||
await getYearData();
|
||||
if (moreSelect.value.value) {
|
||||
await updateYearOptionsByBase(moreSelect.value.value);
|
||||
}
|
||||
await getChartData();
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步 moreSelect 下拉框选项
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
const filtered = newVal.filter(item => item.wbsCode !== 'all');
|
||||
moreSelect.value.options = filtered.map(item => ({
|
||||
value: item.wbsCode,
|
||||
title: item.wbsName
|
||||
}));
|
||||
if (!moreSelect.value.value && filtered.length > 0) {
|
||||
moreSelect.value.value = filtered[0].wbsCode;
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
|
||||
@ -26,7 +26,7 @@ import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import type { EChartsOption } from 'echarts';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { qgcGetKendoListCust, wbsbGetKendoList } from '@/api/sz';
|
||||
import { qgcGetKendoListCust } from '@/api/sz';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
import {
|
||||
@ -835,12 +835,6 @@ const getecharts = async () => {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: wbsCode.value
|
||||
},
|
||||
{
|
||||
field: 'rvcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: select.value.value
|
||||
},
|
||||
{
|
||||
@ -1154,93 +1148,6 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
});
|
||||
|
||||
//根据流域获取河段
|
||||
const getSelect = async () => {
|
||||
if (!wbsCode.value) {
|
||||
console.warn('wbsCode 为空,无法获取河段数据');
|
||||
return;
|
||||
}
|
||||
|
||||
let params = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'objId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: wbsCode.value
|
||||
},
|
||||
{
|
||||
field: 'wbsType',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: 'PSB_RVCD'
|
||||
}
|
||||
]
|
||||
},
|
||||
group: [
|
||||
{
|
||||
dir: 'asc',
|
||||
field: 'orderIndex'
|
||||
},
|
||||
{
|
||||
dir: 'des',
|
||||
field: 'wbsCode'
|
||||
},
|
||||
{
|
||||
dir: 'des',
|
||||
field: 'wbsName'
|
||||
}
|
||||
],
|
||||
groupResultFlat: 'true'
|
||||
};
|
||||
|
||||
try {
|
||||
let res = await wbsbGetKendoList(params);
|
||||
|
||||
// 处理返回的数据 - 注意数据结构可能是嵌套的
|
||||
let data;
|
||||
if (res && res.data && res.data.data) {
|
||||
// 如果 res.data.data 是数组,直接使用
|
||||
if (Array.isArray(res.data.data)) {
|
||||
data = res.data.data;
|
||||
}
|
||||
// 如果 res.data.data 是对象且有 data 属性,使用 res.data.data.data
|
||||
else if (res.data.data.data && Array.isArray(res.data.data.data)) {
|
||||
data = res.data.data.data;
|
||||
} else {
|
||||
console.warn('无法解析河段数据:', res);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.warn('未获取到河段数据');
|
||||
return;
|
||||
}
|
||||
|
||||
if (data && data.length > 0) {
|
||||
select.value.value = data[0].wbsCode;
|
||||
select.value.options = data.map(item => {
|
||||
return {
|
||||
value: item.wbsCode,
|
||||
label: item.wbsName
|
||||
};
|
||||
});
|
||||
|
||||
// 获取完选择器数据后,立即加载图表数据
|
||||
await nextTick();
|
||||
getecharts();
|
||||
} else {
|
||||
console.warn('河段数据为空');
|
||||
select.value.value = '';
|
||||
select.value.options = [];
|
||||
hasData.value = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取河段数据失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
//监听子组件的数据变化
|
||||
const handlePanelChange1 = async data => {
|
||||
console.log('当前所有控件状态:', data);
|
||||
@ -1269,7 +1176,21 @@ watch(
|
||||
newVal => {
|
||||
console.log(newVal);
|
||||
wbsCode.value = newVal.wbsCode;
|
||||
getSelect();
|
||||
select.value.value = newVal.wbsCode;
|
||||
getecharts();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步下拉框选项(过滤掉"当前全部"项)
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
const filtered = newVal.filter(item => item.wbsCode !== 'all');
|
||||
select.value.options = filtered.map(item => ({
|
||||
value: item.wbsCode,
|
||||
label: item.wbsName
|
||||
}));
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
@ -25,11 +25,9 @@ import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import type { ECharts } from 'echarts';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { getKendoListCust, wbsbGetKendoList } from '@/api/sw';
|
||||
import { getKendoListCust } from '@/api/sw';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
|
||||
import { da } from 'element-plus/es/locale/index.mjs';
|
||||
import { f } from 'vue-router/dist/router-CWoNjPRp.mjs';
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
@ -50,9 +48,7 @@ const getCurrentHourTime = () => {
|
||||
return `${year}-${month}-${day} ${hour}`;
|
||||
};
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
const baseid: any = ref(null);
|
||||
const paramsOne = {
|
||||
rvcd: '',
|
||||
tm: []
|
||||
};
|
||||
const dataOne = ref('');
|
||||
@ -300,10 +296,10 @@ const init = async () => {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'rvcd',
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: paramsOne.rvcd
|
||||
value: select.value.value
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
@ -378,151 +374,11 @@ const init = async () => {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
//获取选择器配置参数
|
||||
const getSelectConfig = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
let obj: any = {};
|
||||
if (baseid.value === 'all') {
|
||||
obj = { rstcdStepSort: 'asc', siteStepSort: 'asc' };
|
||||
} else {
|
||||
obj = { siteStepSort: 'asc' };
|
||||
}
|
||||
const filters = [
|
||||
{
|
||||
field: 'wbsType',
|
||||
operator: 'eq',
|
||||
value: 'PSB_RVCD'
|
||||
}
|
||||
];
|
||||
if (baseid.value && baseid.value !== 'all') {
|
||||
filters.push({
|
||||
field: 'objId',
|
||||
operator: 'eq', // contains
|
||||
value: baseid.value
|
||||
});
|
||||
}
|
||||
let data: any = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters
|
||||
}
|
||||
// select: ['WBS_CODE', 'WBS_NAME']
|
||||
};
|
||||
|
||||
if (obj) {
|
||||
data.sort = [obj];
|
||||
} else {
|
||||
data = {
|
||||
...data,
|
||||
group: [
|
||||
{ dir: 'asc', field: 'orderIndex' },
|
||||
{ dir: 'asc', field: 'wbsCode' },
|
||||
{ dir: 'asc', field: 'wbsName' },
|
||||
{ dir: 'asc', field: 'objid' }
|
||||
],
|
||||
groupResultFlat: true
|
||||
};
|
||||
}
|
||||
let res = await wbsbGetKendoList(data);
|
||||
let dataOne = res?.data?.data || res?.data;
|
||||
|
||||
if (dataOne.length > 0) {
|
||||
let dataMapNameMap: any = {};
|
||||
let jiDiListMap: any = {};
|
||||
JidiSelectEventStore.jidiData.forEach((item: any) => {
|
||||
jiDiListMap[item.wbsCode] = item.wbsName;
|
||||
});
|
||||
|
||||
dataOne.map((item: any, index: number) => {
|
||||
const { stcd, stnm, objId } = item;
|
||||
if (dataMapNameMap[objId]) {
|
||||
dataMapNameMap[objId].push({
|
||||
...item,
|
||||
baseName: jiDiListMap[objId],
|
||||
baseId: objId
|
||||
});
|
||||
} else {
|
||||
dataMapNameMap[objId] = [
|
||||
{ ...item, baseName: jiDiListMap[objId], baseId: objId }
|
||||
];
|
||||
}
|
||||
return {
|
||||
label: item.wbsName,
|
||||
value: item.wbsCode,
|
||||
baseId: objId,
|
||||
baseName: jiDiListMap[objId]
|
||||
};
|
||||
});
|
||||
let dataMapNameArr: any = [];
|
||||
|
||||
Object.keys(dataMapNameMap).forEach((item: any) => {
|
||||
dataMapNameArr.push({
|
||||
title: dataMapNameMap[item]?.[0]?.baseName,
|
||||
value: item,
|
||||
selectable: false,
|
||||
// baseId:dataMapNameMap[item]?.[0]?.baseId,
|
||||
children: dataMapNameMap[item].map((item2: any) => {
|
||||
return {
|
||||
title: item2.wbsName,
|
||||
value: item2.wbsCode
|
||||
};
|
||||
})
|
||||
});
|
||||
});
|
||||
dataMapNameArr = dataMapNameArr.sort((a: any, b: any) => {
|
||||
const indexA = JidiSelectEventStore.jidiData.findIndex(
|
||||
item => item.wbsCode === a.value
|
||||
);
|
||||
const indexB = JidiSelectEventStore.jidiData.findIndex(
|
||||
item => item.wbsCode === b.value
|
||||
);
|
||||
return indexA - indexB;
|
||||
});
|
||||
select.value.options = filterSelectOptions(dataMapNameArr);
|
||||
if (filterSelectOptions(dataMapNameArr)[0]?.children) {
|
||||
select.value.value =
|
||||
filterSelectOptions(dataMapNameArr)[0]?.children[0]?.value;
|
||||
} else if (filterSelectOptions(dataMapNameArr)[0]?.value) {
|
||||
select.value.value = filterSelectOptions(dataMapNameArr)[0]?.value;
|
||||
} else {
|
||||
select.value.value = '';
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择器配置加载失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const filterSelectOptions = (selectOptions: any) => {
|
||||
if (
|
||||
selectOptions?.length === 1 &&
|
||||
selectOptions?.[0]?.children?.length === 1
|
||||
) {
|
||||
return [{ ...selectOptions?.[0]?.children?.[0], isLeaf: true }];
|
||||
} else if (selectOptions.length) {
|
||||
return selectOptions.map(e => {
|
||||
if (e?.children?.length > 1) {
|
||||
return {
|
||||
...e,
|
||||
isLeaf: false,
|
||||
selectable: true,
|
||||
children: e.children.map(item => ({ ...item, isLeaf: true }))
|
||||
};
|
||||
} else {
|
||||
return { ...e.children[0], isLeaf: true };
|
||||
}
|
||||
});
|
||||
}
|
||||
return [];
|
||||
};
|
||||
//监听子组件的数据变化
|
||||
const handlePanelChange1 = data => {
|
||||
console.log('当前所有控件状态:', data);
|
||||
if (data.moreSelect) {
|
||||
paramsOne.rvcd = data.moreSelect;
|
||||
select.value.value = data.moreSelect;
|
||||
}
|
||||
|
||||
if (data.datetime) {
|
||||
@ -565,7 +421,7 @@ const handlePanelChange1 = data => {
|
||||
paramsOne.tm = result;
|
||||
console.log(paramsOne.tm, 'paramsOne.tm');
|
||||
}
|
||||
if (paramsOne.rvcd || paramsOne.tm.length > 0) {
|
||||
if (select.value.value || paramsOne.tm.length > 0) {
|
||||
init();
|
||||
}
|
||||
};
|
||||
@ -573,8 +429,26 @@ const handlePanelChange1 = data => {
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
newVal => {
|
||||
baseid.value = newVal.wbsCode;
|
||||
getSelectConfig();
|
||||
// if (newVal.baseId) {
|
||||
select.value.value = newVal.wbsCode;
|
||||
init();
|
||||
// }
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 监听 JidiSelectEventStore.jidiData 变化,同步下拉框选项(不过滤"当前全部"项)
|
||||
watch(
|
||||
() => JidiSelectEventStore.jidiData,
|
||||
newVal => {
|
||||
select.value.options = newVal.map(item => ({
|
||||
value: item.wbsCode,
|
||||
title: item.wbsName
|
||||
}));
|
||||
// 如果当前没有选中值,默认选中第一个有效项
|
||||
if (!select.value.value && newVal.length > 0) {
|
||||
select.value.value = newVal[0].baseId || newVal[0].wbsCode;
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
@ -47,7 +47,7 @@ export const useJidiSelectEventStore = defineStore('jidiSelectEvent', () => {
|
||||
dir: 'asc'
|
||||
}
|
||||
],
|
||||
select: ['wbsCode', 'wbsName']
|
||||
select: ['wbsCode', 'wbsName', 'baseId']
|
||||
};
|
||||
const res = await wbsbGetKendoList(params);
|
||||
const data = res?.data?.data || [
|
||||
|
||||
@ -34,7 +34,7 @@ service.interceptors.request.use(
|
||||
config.headers._sysid = '10EC2E0B-AEA9-4757-83A2-201BA1BC54E9';
|
||||
|
||||
config.headers.authorization =
|
||||
'bearer 223f63a2-0b13-4757-8e15-f342098e63ca';
|
||||
'bearer b142d8ee-7e9d-4704-97c9-da935615bac3';
|
||||
config.baseURL = '/';
|
||||
} else {
|
||||
const user = useUserStoreHook();
|
||||
|
||||
@ -37,13 +37,13 @@
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="所在河段" name="rvcd">
|
||||
<a-form-item label="水电基地" name="baseId">
|
||||
<a-select
|
||||
v-model:value="formData.rvcd"
|
||||
v-model:value="formData.baseId"
|
||||
show-search
|
||||
style="width: 100%"
|
||||
placeholder="请选择所在河段"
|
||||
:options="riverOptions"
|
||||
placeholder="请选择水电基地"
|
||||
:options="filteredRiverOptions"
|
||||
:filter-option="filterOption"
|
||||
@change="handleRiverSelect"
|
||||
:disabled="isEdit"
|
||||
@ -108,7 +108,9 @@
|
||||
<template #title="{ dataRef }">
|
||||
<!-- 编辑状态:只显示编辑区域 -->
|
||||
<div
|
||||
v-if="editingNode && editingNodeKey === dataRef.key"
|
||||
v-if="
|
||||
editingNode && editingNodeKey === dataRef.key && !dataRef.parentId
|
||||
"
|
||||
class="add-child-node-row w-[300px]"
|
||||
>
|
||||
<a-select
|
||||
@ -155,8 +157,8 @@
|
||||
size="small"
|
||||
@click.stop="handleAddChild(dataRef)"
|
||||
:title="
|
||||
dataRef.sttpName
|
||||
? `子级添加-${dataRef.sttpName}`
|
||||
dataRef.stnm
|
||||
? `子级添加-${dataRef.stnm}`
|
||||
: '子级添加'
|
||||
"
|
||||
>
|
||||
@ -238,47 +240,19 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 子节点添加区域 -->
|
||||
<div
|
||||
v-if="addingChildNode && currentParentKey === dataRef.key"
|
||||
class="add-child-node-row"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="childNodeData.stcd"
|
||||
show-search
|
||||
placeholder="请选择站点"
|
||||
style="width: 300px"
|
||||
:filter-option="filterOption"
|
||||
@change="handleChildNodeSelect"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="item in childStationList"
|
||||
:key="item.stcd"
|
||||
:value="item.stcd"
|
||||
>
|
||||
{{ item.stnm }}-{{ item.sttpName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.stop="handleSaveChildNode"
|
||||
style="margin-left: 8px"
|
||||
>
|
||||
保存
|
||||
</a-button>
|
||||
<a-button
|
||||
@click.stop="handleCancelAddChild"
|
||||
style="margin-left: 8px"
|
||||
>
|
||||
<MinusOutlined />
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-tree>
|
||||
<a-empty v-else description="暂无数据" style="margin-top: 20px" />
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 测站选择弹窗(子节点新增/编辑用) -->
|
||||
<StationSelectModal
|
||||
:baseId="formData.baseId"
|
||||
v-model:visible="stationSelectVisible"
|
||||
@confirm="handleStationSelectConfirm"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@ -294,8 +268,9 @@ import {
|
||||
ArrowUpOutlined,
|
||||
ArrowDownOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { getEngInfoDropdown, getAddvcdDropdownByRvcd } from '@/api/select';
|
||||
|
||||
import { getEngInfoDropdown } from '@/api/select';
|
||||
import StationSelectModal from './StationSelectModal.vue';
|
||||
import { useDraggable } from '@/utils/drag';
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
initialValues?: any | null;
|
||||
@ -315,7 +290,7 @@ const modalVisible = computed({
|
||||
get: () => props.visible,
|
||||
set: val => emit('update:visible', val)
|
||||
});
|
||||
|
||||
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'cancel'): void;
|
||||
@ -328,7 +303,7 @@ const defaultFormData = reactive({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
rvcd: undefined,
|
||||
baseId: undefined,
|
||||
remark: undefined
|
||||
});
|
||||
const formData: any = reactive({ ...defaultFormData });
|
||||
@ -336,19 +311,16 @@ const formData: any = reactive({ ...defaultFormData });
|
||||
const rules: Record<string, Rule[]> = {
|
||||
name: [{ required: true, message: '请输入沿程配置名称', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '请输入配置编码', trigger: 'blur' }],
|
||||
rvcd: [{ required: true, message: '请选择所在河段', trigger: 'change' }]
|
||||
};
|
||||
|
||||
const handleRiverSelect = async (value: string) => {
|
||||
const res = await getEngInfoDropdown({ rvcd: value });
|
||||
stationList.value = (res.data || []).map((item: any) => ({
|
||||
...item,
|
||||
stnm: item.ennm
|
||||
}));
|
||||
baseId: [{ required: true, message: '请选择水电基地', trigger: 'change' }]
|
||||
};
|
||||
|
||||
const isEdit = computed(() => !!props.initialValues);
|
||||
|
||||
// 过滤掉"当前全部"项(wbsCode === 'all')
|
||||
const filteredRiverOptions = computed(() =>
|
||||
props.riverOptions.filter((item: any) => item.value !== 'all')
|
||||
);
|
||||
|
||||
// 树形数据
|
||||
const treeData = ref<any[]>([]);
|
||||
|
||||
@ -357,17 +329,12 @@ const addingNewNode = ref(false);
|
||||
const newNodeData = ref({
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
stnm: ''
|
||||
});
|
||||
|
||||
// 添加子节点相关
|
||||
const addingChildNode = ref(false);
|
||||
// 测站选择弹窗(子节点新增/编辑用)
|
||||
const stationSelectVisible = ref(false);
|
||||
const currentParentKey = ref<string | null>(null);
|
||||
const childNodeData = ref({
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
});
|
||||
|
||||
// 编辑节点相关
|
||||
const editingNode = ref(false);
|
||||
@ -375,7 +342,7 @@ const editingNodeKey = ref<string | null>(null);
|
||||
const editNodeData = ref({
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: '',
|
||||
stnm: '',
|
||||
originalData: null as any
|
||||
});
|
||||
|
||||
@ -386,12 +353,30 @@ const childStationList = ref([]);
|
||||
let nodeIdCounter = 0;
|
||||
const generateNodeId = () => `node_${Date.now()}_${++nodeIdCounter}`;
|
||||
|
||||
// 刷新排序(按数组下标重算 sort)
|
||||
const refreshNodeSort = (nodes: any[]) => {
|
||||
nodes.forEach((node, index) => {
|
||||
node.sort = index;
|
||||
});
|
||||
};
|
||||
|
||||
// 检查同级节点中 stcd 是否重复(编辑时排除自身)
|
||||
const checkDuplicateStcd = (stcd: string, siblings: any[], excludeKey?: string): boolean => {
|
||||
return siblings.some(node => node.stcd === stcd && node.key !== excludeKey);
|
||||
};
|
||||
const handleRiverSelect = async (value: string) => {
|
||||
const res = await getEngInfoDropdown({ baseId: value });
|
||||
stationList.value = (res.data || []).map((item: any) => ({
|
||||
...item,
|
||||
stnm: item.ennm
|
||||
}));
|
||||
};
|
||||
// 获取节点标题
|
||||
const getNodeTitle = (dataRef: any) => {
|
||||
if (!dataRef.parentId) {
|
||||
return dataRef.ennm || '';
|
||||
} else {
|
||||
return `${dataRef.ennm || ''} ${dataRef.sttpName || ''}`;
|
||||
return `${dataRef.stnm ||dataRef.ennm || ''}-${dataRef.type == 1 || dataRef.ioDirection == 1 ? '出库' : '入库'}`;
|
||||
}
|
||||
};
|
||||
|
||||
@ -446,15 +431,15 @@ const findNodeByKey = (nodes: any[], key: string): any => {
|
||||
|
||||
// 新增一级节点
|
||||
const handleAdd = () => {
|
||||
if (!formData.rvcd) {
|
||||
message.warning('请先选择所在河段');
|
||||
if (!formData.baseId) {
|
||||
message.warning('请先选择水电基地');
|
||||
return;
|
||||
}
|
||||
addingNewNode.value = true;
|
||||
newNodeData.value = {
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
stnm: ''
|
||||
};
|
||||
};
|
||||
|
||||
@ -463,7 +448,7 @@ const handleNodeSelect = (value: string) => {
|
||||
const station = stationList.value.find(item => item.stcd === value);
|
||||
if (station) {
|
||||
newNodeData.value.ennm = station.stnm;
|
||||
newNodeData.value.sttpName = station.sttpName;
|
||||
newNodeData.value.stnm = station.stnm;
|
||||
}
|
||||
};
|
||||
|
||||
@ -474,16 +459,22 @@ const handleSaveNewNode = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkDuplicateStcd(newNodeData.value.stcd, treeData.value)) {
|
||||
message.warning('该站点已存在,请勿重复添加');
|
||||
return;
|
||||
}
|
||||
|
||||
const newNode = {
|
||||
key: generateNodeId(),
|
||||
stcd: newNodeData.value.stcd,
|
||||
ennm: newNodeData.value.ennm,
|
||||
sttpName: newNodeData.value.sttpName,
|
||||
stnm: newNodeData.value.stnm,
|
||||
parentId: null,
|
||||
children: []
|
||||
};
|
||||
|
||||
treeData.value.push(newNode);
|
||||
refreshNodeSort(treeData.value);
|
||||
addingNewNode.value = false;
|
||||
message.success('添加成功');
|
||||
};
|
||||
@ -494,93 +485,34 @@ const handleCancelAdd = () => {
|
||||
newNodeData.value = {
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
stnm: ''
|
||||
};
|
||||
};
|
||||
|
||||
// 添加子节点(二级节点)
|
||||
const handleAddChild = async (parentData: any) => {
|
||||
addingChildNode.value = true;
|
||||
// 添加子节点(二级节点)- 打开测站选择弹窗
|
||||
const handleAddChild = (parentData: any) => {
|
||||
currentParentKey.value = parentData.key;
|
||||
childNodeData.value = {
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
};
|
||||
const res = await getAddvcdDropdownByRvcd({ stcd: parentData.stcd });
|
||||
childStationList.value = res.data || [];
|
||||
};
|
||||
|
||||
// 选择子节点
|
||||
const handleChildNodeSelect = (value: string) => {
|
||||
const station = childStationList.value.find(item => item.stcd === value);
|
||||
if (station) {
|
||||
childNodeData.value.ennm = station.stnm;
|
||||
childNodeData.value.sttpName = station.sttpName;
|
||||
}
|
||||
};
|
||||
|
||||
// 保存新增子节点
|
||||
const handleSaveChildNode = () => {
|
||||
if (!childNodeData.value.stcd) {
|
||||
message.error('请选择站点');
|
||||
return;
|
||||
}
|
||||
|
||||
const parent = findNodeByKey(treeData.value, currentParentKey.value!);
|
||||
if (!parent) {
|
||||
message.error('父节点不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
const newChild = {
|
||||
key: generateNodeId(),
|
||||
stcd: childNodeData.value.stcd,
|
||||
ennm: childNodeData.value.ennm,
|
||||
sttpName: childNodeData.value.sttpName,
|
||||
parentId: parent.key,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
// 在子节点列表顶部添加
|
||||
parent.children.unshift(newChild);
|
||||
|
||||
addingChildNode.value = false;
|
||||
currentParentKey.value = null;
|
||||
message.success('添加子节点成功');
|
||||
};
|
||||
|
||||
// 取消添加子节点
|
||||
const handleCancelAddChild = () => {
|
||||
addingChildNode.value = false;
|
||||
currentParentKey.value = null;
|
||||
childNodeData.value = {
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: ''
|
||||
};
|
||||
editingNodeKey.value = null; // 清除编辑状态
|
||||
stationSelectVisible.value = true;
|
||||
};
|
||||
|
||||
// 编辑节点
|
||||
const handleEditNode = async (dataRef: any) => {
|
||||
editingNode.value = true;
|
||||
editingNodeKey.value = dataRef.key;
|
||||
// 保存原始数据
|
||||
editNodeData.value = {
|
||||
stcd: dataRef.stcd,
|
||||
ennm: dataRef.ennm,
|
||||
sttpName: dataRef.sttpName,
|
||||
originalData: { ...dataRef }
|
||||
};
|
||||
if (dataRef.parentId) {
|
||||
const parent = findNodeByKey(treeData.value, dataRef.parentId);
|
||||
if (parent) {
|
||||
const res = await getAddvcdDropdownByRvcd({ stcd: parent.stcd });
|
||||
childStationList.value = res.data || [];
|
||||
}
|
||||
// 二级节点:打开测站选择弹窗
|
||||
editingNodeKey.value = dataRef.key;
|
||||
currentParentKey.value = null; // 清除新增状态
|
||||
stationSelectVisible.value = true;
|
||||
} else {
|
||||
// 一级节点:内联编辑
|
||||
editingNode.value = true;
|
||||
editingNodeKey.value = dataRef.key;
|
||||
editNodeData.value = {
|
||||
stcd: dataRef.stcd,
|
||||
ennm: dataRef.ennm,
|
||||
stnm: dataRef.stnm,
|
||||
originalData: { ...dataRef }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -591,7 +523,7 @@ const handleEditNodeSelect = (dataRef: any) => {
|
||||
const station = list.find(item => item.stcd === value);
|
||||
if (station) {
|
||||
editNodeData.value.ennm = station.stnm;
|
||||
editNodeData.value.sttpName = station.sttpName;
|
||||
editNodeData.value.stnm = station.stnm;
|
||||
editNodeData.value.stcd = station.stcd;
|
||||
}
|
||||
};
|
||||
@ -610,10 +542,16 @@ const handleSaveEditNode = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否与同级其他节点重复
|
||||
if (checkDuplicateStcd(editNodeData.value.stcd, treeData.value, editingNodeKey.value!)) {
|
||||
message.warning('该站点在当前层级已存在,请重新选择');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新节点数据
|
||||
node.stcd = editNodeData.value.stcd;
|
||||
node.ennm = editNodeData.value.ennm;
|
||||
node.sttpName = editNodeData.value.sttpName;
|
||||
node.stnm = editNodeData.value.stnm;
|
||||
|
||||
editingNode.value = false;
|
||||
editingNodeKey.value = null;
|
||||
@ -627,11 +565,66 @@ const handleCancelEditNode = () => {
|
||||
editNodeData.value = {
|
||||
stcd: undefined,
|
||||
ennm: '',
|
||||
sttpName: '',
|
||||
stnm: '',
|
||||
originalData: null
|
||||
};
|
||||
};
|
||||
|
||||
// 测站选择弹窗确认回调(子节点新增/编辑)
|
||||
const handleStationSelectConfirm = (data: { record: any; type: number }) => {
|
||||
if (editingNodeKey.value && currentParentKey.value === null) {
|
||||
// 编辑模式 - 更新已有二级节点
|
||||
const node = findNodeByKey(treeData.value, editingNodeKey.value);
|
||||
if (node) {
|
||||
// 获取同级节点判断重复(排除自身)
|
||||
const siblings = node.parentId
|
||||
? findNodeByKey(treeData.value, node.parentId)?.children || []
|
||||
: treeData.value;
|
||||
if (checkDuplicateStcd(data.record.stcd, siblings, editingNodeKey.value!)) {
|
||||
message.warning('该站点在当前层级已存在,请重新选择');
|
||||
return;
|
||||
}
|
||||
|
||||
node.stcd = data.record.stcd;
|
||||
node.ennm = data.record.ennm;
|
||||
node.sttpName = data.record.sttpName;
|
||||
node.baseName = data.record.baseName;
|
||||
node.type = data.type;
|
||||
node.stnm = data.record.stnm;
|
||||
message.success('编辑成功');
|
||||
}
|
||||
editingNodeKey.value = null;
|
||||
} else {
|
||||
// 新增模式 - 创建新子节点
|
||||
const parent = findNodeByKey(treeData.value, currentParentKey.value!);
|
||||
if (!parent) {
|
||||
message.error('父节点不存在');
|
||||
return;
|
||||
}
|
||||
if (checkDuplicateStcd(data.record.stcd, parent.children || [])) {
|
||||
message.warning('该站点在当前层级已存在,请勿重复添加');
|
||||
return;
|
||||
}
|
||||
const newChild = {
|
||||
key: generateNodeId(),
|
||||
stcd: data.record.stcd,
|
||||
ennm: data.record.ennm,
|
||||
sttpName: data.record.sttpName,
|
||||
baseName: data.record.baseName,
|
||||
stnm: data.record.stnm,
|
||||
type: data.type,
|
||||
parentId: parent.key,
|
||||
children: []
|
||||
};
|
||||
if (!parent.children) parent.children = [];
|
||||
parent.children.unshift(newChild);
|
||||
refreshNodeSort(parent.children);
|
||||
message.success('添加子节点成功');
|
||||
}
|
||||
currentParentKey.value = null;
|
||||
stationSelectVisible.value = false;
|
||||
};
|
||||
|
||||
// 上移
|
||||
const handleMoveUp = (dataRef: any) => {
|
||||
const siblings = getSiblings(dataRef);
|
||||
@ -643,6 +636,7 @@ const handleMoveUp = (dataRef: any) => {
|
||||
siblings[index],
|
||||
siblings[index - 1]
|
||||
];
|
||||
refreshNodeSort(siblings);
|
||||
message.success('上移成功');
|
||||
}
|
||||
};
|
||||
@ -658,6 +652,7 @@ const handleMoveDown = (dataRef: any) => {
|
||||
siblings[index + 1],
|
||||
siblings[index]
|
||||
];
|
||||
refreshNodeSort(siblings);
|
||||
message.success('下移成功');
|
||||
}
|
||||
};
|
||||
@ -739,15 +734,21 @@ const initForm = async () => {
|
||||
}
|
||||
|
||||
// 编辑时调用接口获取一级站点列表
|
||||
if (formData.rvcd) {
|
||||
const res = await getEngInfoDropdown({ rvcd: formData.rvcd });
|
||||
if (formData.baseId) {
|
||||
const res = await getEngInfoDropdown({ baseId: formData.baseId });
|
||||
stationList.value = (res.data || []).map((item: any) => ({
|
||||
...item,
|
||||
stnm: item.ennm
|
||||
}));
|
||||
}
|
||||
|
||||
} else {
|
||||
resetForm();
|
||||
const res = await getEngInfoDropdown({});
|
||||
stationList.value = (res.data || []).map((item: any) => ({
|
||||
...item,
|
||||
stnm: item.ennm
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -776,6 +777,14 @@ watch(
|
||||
{ immediate: false }
|
||||
);
|
||||
|
||||
// 测站选择弹窗关闭时清除状态
|
||||
watch(stationSelectVisible, visible => {
|
||||
if (!visible) {
|
||||
editingNodeKey.value = null;
|
||||
currentParentKey.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
localLoading
|
||||
});
|
||||
|
||||
@ -38,7 +38,7 @@ const emit = defineEmits<{
|
||||
|
||||
const initSearchData = {
|
||||
name: null,
|
||||
rvcd: null
|
||||
baseId: 'all'
|
||||
};
|
||||
|
||||
const searchData = ref<any>({ ...initSearchData });
|
||||
@ -53,12 +53,10 @@ const searchList: any = computed(() => [
|
||||
},
|
||||
{
|
||||
type: 'Select',
|
||||
name: 'rvcd',
|
||||
label: '所在河段',
|
||||
name: 'baseId',
|
||||
label: '水电基地',
|
||||
width: 300,
|
||||
fieldProps: {
|
||||
allowClear: true
|
||||
},
|
||||
|
||||
options: props.riverOptions,
|
||||
loading: props.riverOptionsLoad
|
||||
}
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:open="visible"
|
||||
title="选择测站"
|
||||
width="1536px"
|
||||
:footer="null"
|
||||
:body-style="{ height: '700px', padding: '16px' }"
|
||||
:destroy-on-close="true"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<!-- 搜索表单 -->
|
||||
<a-form layout="inline" class="search-form">
|
||||
<a-form-item label="名称">
|
||||
<a-input
|
||||
v-model:value="searchName"
|
||||
placeholder="请输入测站名称"
|
||||
style="width: 180px"
|
||||
allow-clear
|
||||
@press-enter="handleSearch"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="table-wrapper">
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:scrollY="460"
|
||||
:list-url="noAuthGetKendoPage"
|
||||
:search-params="searchParams"
|
||||
:transform-data="transformData"
|
||||
:enable-row-selection="true"
|
||||
row-key="stcd"
|
||||
@selection-change="onSelectionChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="footer-actions">
|
||||
<a-button type="primary" :disabled="!selectedRow" @click="handleConfirm">
|
||||
确认选择
|
||||
</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 出库/入库选择弹窗 -->
|
||||
<a-modal
|
||||
:open="typeModalVisible"
|
||||
title="选择类型"
|
||||
width="400px"
|
||||
:z-index="2000"
|
||||
ok-text="确认"
|
||||
:ok-button-props="{ disabled: selectedType === null }"
|
||||
@ok="handleTypeConfirm"
|
||||
@cancel="handleTypeCancel"
|
||||
>
|
||||
<a-radio-group v-model:value="selectedType">
|
||||
<a-radio :value="1">出库</a-radio>
|
||||
<a-radio :value="2">入库</a-radio>
|
||||
</a-radio-group>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { noAuthGetKendoPage } from '@/api/select';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
baseId: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
visible: false,
|
||||
baseId: ''
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'confirm', data: { record: any; type: number }): void;
|
||||
}>();
|
||||
|
||||
// 搜索
|
||||
const searchName = ref('');
|
||||
|
||||
// 表格
|
||||
const tableRef = ref();
|
||||
const selectedRow = ref<any>(null);
|
||||
|
||||
// 类型选择
|
||||
const typeModalVisible = ref(false);
|
||||
const selectedType = ref<number | null>(null);
|
||||
|
||||
const columns = [
|
||||
{ title: '测站名称', key: 'stnm', dataIndex: 'stnm', width: 200 },
|
||||
{ title: '测站类型', key: 'sttpName', dataIndex: 'sttpName', width: 200 },
|
||||
{ title: '水电基地', key: 'baseName', dataIndex: 'baseName', width: 200 },
|
||||
{ title: '电站名称', key: 'ennm', dataIndex: 'ennm', width: 200 }
|
||||
];
|
||||
|
||||
const searchParams = computed(() => ({
|
||||
sort: [
|
||||
{
|
||||
field: 'ORDER_INDEX',
|
||||
dir: 'asc'
|
||||
}
|
||||
]
|
||||
}));
|
||||
|
||||
const transformData = (res: any) => {
|
||||
return {
|
||||
records: res?.data?.data || res?.data || [],
|
||||
total: res?.data?.total || res?.data?.length || 0
|
||||
};
|
||||
};
|
||||
|
||||
// 表格选择变更:限制最多只能选一个
|
||||
const onSelectionChange = (keys: string[], rows: any[]) => {
|
||||
if (keys.length > 1) {
|
||||
// 只保留最后选中的那个
|
||||
const lastKey = keys[keys.length - 1];
|
||||
const lastRow = rows[rows.length - 1];
|
||||
tableRef.value.setSelectedRowKeys([lastKey]);
|
||||
selectedRow.value = lastRow;
|
||||
} else {
|
||||
selectedRow.value = rows.length > 0 ? rows[0] : null;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
const filters: any[] = [
|
||||
props.baseId != 'all'
|
||||
? {
|
||||
field: 'BASE_ID',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: props.baseId
|
||||
}
|
||||
: null
|
||||
].filter(Boolean);
|
||||
if (searchName.value) {
|
||||
filters.push({
|
||||
field: 'STNM',
|
||||
operator: 'contains',
|
||||
value: searchName.value
|
||||
});
|
||||
}
|
||||
const filter = {
|
||||
logic: 'and',
|
||||
filters
|
||||
};
|
||||
tableRef.value?.getList(filter);
|
||||
};
|
||||
|
||||
// 弹窗打开时自动请求带参数据
|
||||
watch(
|
||||
() => props.visible,
|
||||
visible => {
|
||||
if (visible) {
|
||||
searchName.value = '';
|
||||
// 等 DOM 更新后自动请求
|
||||
setTimeout(() => handleSearch(), 0);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 确认选择 → 弹出类型选择
|
||||
const handleConfirm = () => {
|
||||
if (!selectedRow.value) return;
|
||||
selectedType.value = null;
|
||||
typeModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 类型确认
|
||||
const handleTypeConfirm = () => {
|
||||
if (selectedType.value === null) return;
|
||||
emit('confirm', {
|
||||
record: selectedRow.value,
|
||||
type: selectedType.value
|
||||
});
|
||||
typeModalVisible.value = false;
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 类型取消
|
||||
const handleTypeCancel = () => {
|
||||
typeModalVisible.value = false;
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-form {
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.footer-actions {
|
||||
margin-top: 16px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@ -48,7 +48,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, onMounted } from 'vue';
|
||||
import { ref, nextTick, onMounted, computed } from 'vue';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import ConfigManagementSearch from './ConfigManagementSearch.vue';
|
||||
import ConfigManagementForm from './ConfigManagementForm.vue';
|
||||
@ -62,7 +62,8 @@ import {
|
||||
} from '@/api/system/map/ConfigManagement';
|
||||
import { getRvcdDropdown } from '@/api/select';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
// 表格实例
|
||||
const basicTable = ref<any>(null);
|
||||
// 表格列配置
|
||||
@ -88,9 +89,9 @@ const columns = [
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '所在河段',
|
||||
dataIndex: 'rvnm',
|
||||
key: 'rvnm',
|
||||
title: '水电基地',
|
||||
dataIndex: 'baseName',
|
||||
key: 'baseName',
|
||||
width: 300,
|
||||
ellipsis: true
|
||||
},
|
||||
@ -129,12 +130,12 @@ const columns = [
|
||||
|
||||
// 搜索参数
|
||||
const searchParams = ref({
|
||||
"sort": [
|
||||
{
|
||||
"field": "recordTime",
|
||||
"dir": "desc"
|
||||
}
|
||||
],
|
||||
sort: [
|
||||
{
|
||||
field: 'recordTime',
|
||||
dir: 'desc'
|
||||
}
|
||||
]
|
||||
});
|
||||
// 编辑弹窗数据
|
||||
const currentRecord = ref<any | null>(null);
|
||||
@ -181,9 +182,10 @@ const handleEdit = async (record: any) => {
|
||||
const res = await getChildConfigTree(params);
|
||||
if (res.code == 0) {
|
||||
const data = res.data.data || [];
|
||||
|
||||
const firstLevelNodes = data.filter((item: any) => !item.rstcd);
|
||||
const secondLevelNodes = data.filter((item: any) => item.rstcd);
|
||||
|
||||
// debugger
|
||||
const configNodes = firstLevelNodes.map((node: any, index: number) => {
|
||||
const children = secondLevelNodes.filter(
|
||||
(child: any) => child.rstcd === node.stcd
|
||||
@ -194,19 +196,23 @@ const handleEdit = async (record: any) => {
|
||||
stcd: node.stcd,
|
||||
ennm: node.stnm,
|
||||
sttpName: node.sttpName,
|
||||
sort: node.sort,
|
||||
parentId: null,
|
||||
children: children.map((child: any, childIndex: number) => ({
|
||||
key: `child-${index}-${childIndex}`,
|
||||
stcd: child.stcd,
|
||||
ennm: child.stnm,
|
||||
sttpName: child.sttpName,
|
||||
sort: child.sort,
|
||||
parentId: `parent-${index}`,
|
||||
ioDirection: child.ioDirection,
|
||||
children: []
|
||||
}))
|
||||
};
|
||||
});
|
||||
|
||||
currentRecord.value.configNodes = configNodes;
|
||||
// debugger
|
||||
}
|
||||
editModalVisible.value = true;
|
||||
};
|
||||
@ -239,12 +245,12 @@ const onSearchFinish = (values: any) => {
|
||||
const params = {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
values.rvcd
|
||||
values.baseId != 'all'
|
||||
? {
|
||||
field: 'rvcd',
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: values.rvcd
|
||||
value: values.baseId
|
||||
}
|
||||
: null,
|
||||
values.name
|
||||
@ -280,6 +286,7 @@ const handleEditSubmit = async (values: any) => {
|
||||
const formData = {
|
||||
...currentRecord.value,
|
||||
...values,
|
||||
baseName: (JidiSelectEventStore.jidiData.find(element => element.wbsCode === values.baseId) || {}).wbsName,
|
||||
modifyTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||
};
|
||||
delete formData.configNodes;
|
||||
@ -299,7 +306,8 @@ const handleEditSubmit = async (values: any) => {
|
||||
const formatTreeData = (
|
||||
nodes: any[],
|
||||
parentId: string | null = null,
|
||||
parentStcd: string | null = null
|
||||
parentStcd: string | null = null,
|
||||
type: string | null = null
|
||||
) => {
|
||||
return nodes.map(node => ({
|
||||
alongId,
|
||||
@ -308,15 +316,15 @@ const handleEditSubmit = async (values: any) => {
|
||||
sttpName: node.sttpName,
|
||||
parentId: parentId ? parentId : null,
|
||||
rstcd: parentStcd || null,
|
||||
ioDirection: node.type ||node.ioDirection || null,
|
||||
children:
|
||||
node.children && node.children.length > 0
|
||||
? formatTreeData(node.children, node.key, node.stcd)
|
||||
? formatTreeData(node.children, node.key, node.stcd, node.type)
|
||||
: []
|
||||
}));
|
||||
};
|
||||
|
||||
const detailData = formatTreeData(treeData);
|
||||
|
||||
const detailRes = await saveBaseWbsbChildDetail(detailData);
|
||||
if (detailRes.code == 0) {
|
||||
message.success(`保存成功`);
|
||||
@ -339,19 +347,29 @@ const handleEditSubmit = async (values: any) => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
const riverOptions = ref<any>([]);
|
||||
// const riverOptions = ref<any>([]);
|
||||
const riverOptions = computed(() => {
|
||||
return JidiSelectEventStore.jidiData.map((item: any) => ({
|
||||
label: item.wbsName,
|
||||
value: item.wbsCode
|
||||
}));
|
||||
});
|
||||
const riverOptionsLoad = ref(false);
|
||||
const initOption = () => {
|
||||
const params = {};
|
||||
riverOptionsLoad.value = true;
|
||||
getRvcdDropdown(params).then((res: any) => {
|
||||
res.data.forEach((item: any) => {
|
||||
item.value = item.rvcd;
|
||||
item.label = item.rvnm;
|
||||
});
|
||||
riverOptions.value = res.data || [];
|
||||
riverOptionsLoad.value = false;
|
||||
});
|
||||
// const params = {};
|
||||
// riverOptionsLoad.value = true;
|
||||
// riverOptions.value = JidiSelectEventStore.jidiData.map((item:any)=>{
|
||||
// return{
|
||||
// }
|
||||
// })
|
||||
// getRvcdDropdown(params).then((res: any) => {
|
||||
// res.data.forEach((item: any) => {
|
||||
// item.value = item.rvcd;
|
||||
// item.label = item.rvnm;
|
||||
// });
|
||||
// riverOptions.value = res.data || [];
|
||||
// riverOptionsLoad.value = false;
|
||||
// });
|
||||
};
|
||||
onMounted(() => {
|
||||
initOption();
|
||||
|
||||
567
frontend/src/views/system/disposeManage/disposeManageForm.vue
Normal file
567
frontend/src/views/system/disposeManage/disposeManageForm.vue
Normal file
@ -0,0 +1,567 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:title="isEdit ? '编辑飞行路径' : '新增飞行路径'"
|
||||
v-model:open="modalVisible"
|
||||
:confirm-loading="localLoading"
|
||||
width="1536px"
|
||||
:destroy-on-close="true"
|
||||
ok-text="保存"
|
||||
@cancel="handleCancel"
|
||||
@ok="handleOk"
|
||||
>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
name="edit_form"
|
||||
:labelCol="{ span: 5 }"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="飞行路径名称" name="name">
|
||||
<a-input
|
||||
v-model:value="formData.name"
|
||||
style="width: 100%"
|
||||
placeholder="请输入飞行路径名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="飞行路径Code" name="code">
|
||||
<a-input
|
||||
v-model:value="formData.code"
|
||||
style="width: 100%"
|
||||
placeholder="请输入飞行路径Code"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea
|
||||
v-model:value="formData.remark"
|
||||
:rows="4"
|
||||
style="width: 100%"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="水电基地" name="baseId">
|
||||
<a-select
|
||||
v-model:value="formData.baseId"
|
||||
show-search
|
||||
style="width: 100%"
|
||||
placeholder="请选择水电基地"
|
||||
:options="ennmOptions"
|
||||
:filter-option="filterOption"
|
||||
:disabled="isEdit"
|
||||
@change="getdianzha"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider />
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<a-button type="primary" @click="handleAddRow"> 新增行</a-button>
|
||||
</div>
|
||||
<div ref="tableWrapperRef">
|
||||
<a-table
|
||||
:data-source="currentPageData"
|
||||
:columns="columns"
|
||||
:pagination="false"
|
||||
row-key="id"
|
||||
size="small"
|
||||
:scroll="{ x: 950 }"
|
||||
:custom-row="customRow"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'drag'">
|
||||
<UnorderedListOutlined
|
||||
v-if="editingRowId !== record.id"
|
||||
class="drag-handle cursor-move text-gray-400"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'index'">
|
||||
{{ (currentPage - 1) * pageSize + index + 1 }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'time'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-input-number
|
||||
v-model:value="record.time"
|
||||
style="width: 100%"
|
||||
placeholder="时间(s)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record.time ?? '-' }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'lgtd'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-input-number
|
||||
v-model:value="record.lgtd"
|
||||
style="width: 100%"
|
||||
placeholder="经度"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record.lgtd ?? '-' }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'lttd'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-input-number
|
||||
v-model:value="record.lttd"
|
||||
style="width: 100%"
|
||||
placeholder="纬度"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record.lttd ?? '-' }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'dtmel'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-input-number
|
||||
v-model:value="record.dtmel"
|
||||
style="width: 100%"
|
||||
placeholder="高程(m)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record.dtmel ?? '-' }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'stnm'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-select
|
||||
v-model:value="record.stcd"
|
||||
style="width: 100%"
|
||||
placeholder="请选择电站"
|
||||
:options="stationOptions"
|
||||
allow-clear
|
||||
@change="(val) => handleStnmChange(record, val)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ getStationLabel(record.stcd) || '-' }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<template v-if="editingRowId === record.id">
|
||||
<a-button
|
||||
type="link"
|
||||
size="small"
|
||||
@click="handleSaveRow(record)"
|
||||
>保存</a-button
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button
|
||||
type="link"
|
||||
size="small"
|
||||
@click="handleStartEdit(record)"
|
||||
>编辑</a-button
|
||||
>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="确定删除该航点?"
|
||||
@confirm="handleDeleteRow(record)"
|
||||
>
|
||||
<a-button type="link" danger size="small">删除</a-button>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<div v-if="formData.list.length > pageSize" class="flex justify-end mt-2">
|
||||
<a-pagination
|
||||
v-model:current="currentPage"
|
||||
:total="formData.list.length"
|
||||
:page-size="pageSize"
|
||||
size="small"
|
||||
show-size-changer
|
||||
:page-size-options="['5', '10', '20', '50']"
|
||||
show-total
|
||||
@change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed, watch, nextTick, onBeforeUnmount } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { Rule } from 'ant-design-vue/es/form';
|
||||
import { UnorderedListOutlined } from '@ant-design/icons-vue';
|
||||
import Sortable from 'sortablejs';
|
||||
import dayjs from 'dayjs';
|
||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||
import { getEngInfoDropdown } from '@/api/select';
|
||||
import { useDraggable } from '@/utils/drag';
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
|
||||
// 电站名称下拉(假数据)
|
||||
const stationOptions = ref([]);
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '排序', key: 'drag', width: 60, align: 'center' as const },
|
||||
{ title: '序号', key: 'index', width: 60, align: 'center' as const },
|
||||
{ title: '时间(s)', key: 'time', width: 130 },
|
||||
{ title: '经度°', key: 'lgtd', width: 150 },
|
||||
{ title: '纬度°', key: 'lttd', width: 150 },
|
||||
{ title: '高程(m)', key: 'dtmel', width: 120 },
|
||||
{ title: '电站名称', key: 'stnm', width: 160 },
|
||||
{ title: '操作', key: 'action', width: 120, align: 'center' as const }
|
||||
];
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
initialValues?: any | null;
|
||||
loading?: boolean;
|
||||
}
|
||||
const localLoading = ref(false);
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
visible: false,
|
||||
initialValues: null,
|
||||
loading: false
|
||||
});
|
||||
|
||||
const modalVisible = computed({
|
||||
get: () => props.visible,
|
||||
set: val => emit('update:visible', val)
|
||||
});
|
||||
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'cancel'): void;
|
||||
(e: 'ok', values: any): void;
|
||||
}>();
|
||||
|
||||
const formRef = ref();
|
||||
const tableWrapperRef = ref<HTMLElement | null>(null);
|
||||
let sortableInstance: Sortable | null = null;
|
||||
|
||||
// 当前正在编辑的行 ID(同一时间只允许编辑一行)
|
||||
const editingRowId = ref<string | null>(null);
|
||||
|
||||
// 给每行添加 data-row-key 属性,供拖拽时识别行身份
|
||||
const customRow = (record: any) => {
|
||||
return {
|
||||
attrs: {
|
||||
'data-row-key': record?.id
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(5);
|
||||
const currentPageData = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize.value;
|
||||
return formData.list.slice(start, start + pageSize.value);
|
||||
});
|
||||
|
||||
const defaultFormData = reactive({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
baseId: undefined,
|
||||
code: undefined,
|
||||
remark: undefined,
|
||||
list: [] as any[]
|
||||
});
|
||||
const formData: any = reactive({ ...defaultFormData });
|
||||
|
||||
const rules: Record<string, Rule[]> = {
|
||||
name: [{ required: true, message: '请输入飞行路径名称', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '请输入飞行路径Code', trigger: 'blur' }]
|
||||
};
|
||||
|
||||
const isEdit = computed(() => !!props.initialValues);
|
||||
|
||||
// 生成唯一ID
|
||||
const generateId = () => {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
const r = (Math.random() * 16) | 0;
|
||||
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16).toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
// 开始编辑行
|
||||
const handleStartEdit = (record: any) => {
|
||||
editingRowId.value = record.id;
|
||||
};
|
||||
|
||||
// 保存行(退出编辑模式,保留当前输入值)
|
||||
const handleSaveRow = (record: any) => {
|
||||
editingRowId.value = null;
|
||||
};
|
||||
|
||||
// 新增航点
|
||||
const handleAddRow = () => {
|
||||
if(!formData.baseId){
|
||||
message.warning('请先选择水电基地');
|
||||
return;
|
||||
}
|
||||
// 有行正在编辑时禁止新增
|
||||
if (editingRowId.value) {
|
||||
message.warning('请先保存当前编辑的行');
|
||||
return;
|
||||
}
|
||||
const newRow = {
|
||||
_tls: {},
|
||||
id: generateId(),
|
||||
recordUser: null,
|
||||
recordTime: null,
|
||||
modifyTime: null,
|
||||
displayRecordUser: null,
|
||||
roamId: null,
|
||||
code: formData.code || null,
|
||||
name: formData.name || null,
|
||||
lgtd: undefined,
|
||||
lttd: undefined,
|
||||
dtmel: undefined,
|
||||
time: undefined,
|
||||
orderIndex: formData.list.length,
|
||||
stcd: null,
|
||||
stnm: undefined,
|
||||
departmentId: null,
|
||||
displayDepartment: null
|
||||
};
|
||||
formData.list.push(newRow);
|
||||
// 新增行自动进入编辑模式
|
||||
editingRowId.value = newRow.id;
|
||||
// 翻到最后一页
|
||||
const lastPage = Math.ceil(formData.list.length / pageSize.value);
|
||||
currentPage.value = lastPage;
|
||||
nextTick(() => initSortable());
|
||||
};
|
||||
|
||||
// 删除航点
|
||||
const handleDeleteRow = (record: any) => {
|
||||
// 如果正编辑的行被删了,退出编辑
|
||||
if (editingRowId.value === record.id) {
|
||||
editingRowId.value = null;
|
||||
}
|
||||
const idx = formData.list.findIndex((item: any) => item.id === record.id);
|
||||
if (idx !== -1) {
|
||||
formData.list.splice(idx, 1);
|
||||
// 如果当前页没数据了,往前翻一页
|
||||
if (currentPageData.value.length === 0 && currentPage.value > 1) {
|
||||
currentPage.value--;
|
||||
}
|
||||
nextTick(() => initSortable());
|
||||
}
|
||||
};
|
||||
|
||||
// 页码变化
|
||||
const handlePageChange = () => {
|
||||
editingRowId.value = null; // 切换页时退出编辑
|
||||
nextTick(() => initSortable());
|
||||
};
|
||||
|
||||
// Sortable 拖拽 — 基于 DOM data-row-key 排序,不依赖 oldIndex/newIndex
|
||||
const initSortable = () => {
|
||||
destroySortable();
|
||||
if (!tableWrapperRef.value) return;
|
||||
const tbody = tableWrapperRef.value.querySelector('.ant-table-tbody');
|
||||
if (!tbody) return;
|
||||
sortableInstance = new Sortable(tbody as HTMLElement, {
|
||||
handle: '.drag-handle',
|
||||
animation: 150,
|
||||
onEnd: evt => {
|
||||
if (!tbody) return;
|
||||
// 读取拖拽后 DOM 中的行顺序(只读当前页)
|
||||
const rows = tbody.querySelectorAll<HTMLElement>('tr.ant-table-row');
|
||||
const domIds: (string | null)[] = [];
|
||||
rows.forEach(row => {
|
||||
const id = row.getAttribute('data-row-key');
|
||||
if (id) domIds.push(id);
|
||||
});
|
||||
if (domIds.length === 0) return;
|
||||
|
||||
const page = currentPage.value;
|
||||
const size = pageSize.value;
|
||||
const start = (page - 1) * size;
|
||||
const end = start + size;
|
||||
|
||||
// 按 DOM 顺序重排当前页数据
|
||||
const pageItems = domIds
|
||||
.map(id => formData.list.find((item: any) => item.id === id))
|
||||
.filter(Boolean);
|
||||
|
||||
if (pageItems.length === 0) return;
|
||||
|
||||
// 重建完整数组:前面 + 当前页(新顺序)+ 后面
|
||||
const before = formData.list.slice(0, start);
|
||||
const after = formData.list.slice(end);
|
||||
formData.list.splice(
|
||||
0,
|
||||
formData.list.length,
|
||||
...before,
|
||||
...pageItems,
|
||||
...after
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const destroySortable = () => {
|
||||
if (sortableInstance) {
|
||||
sortableInstance.destroy();
|
||||
sortableInstance = null;
|
||||
}
|
||||
};
|
||||
|
||||
// 表单提交
|
||||
const handleOk = async () => {
|
||||
// 有行正在编辑时禁止保存
|
||||
if (editingRowId.value) {
|
||||
message.warning('请先保存当前编辑的行');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await formRef.value.validate();
|
||||
// 转换数据:baseId → rvcd,更新 orderIndex
|
||||
const submitValues = {
|
||||
name: formData.name,
|
||||
code: formData.code,
|
||||
remark: formData.remark || null,
|
||||
baseId: formData.baseId,
|
||||
id: formData.id || undefined,
|
||||
list: formData.list.map((item: any, index: number) => ({
|
||||
...item,
|
||||
orderIndex: index,
|
||||
time: item.time ?? null,
|
||||
lgtd: item.lgtd ?? null,
|
||||
lttd: item.lttd ?? null,
|
||||
dtmel: item.dtmel ?? null
|
||||
}))
|
||||
};
|
||||
|
||||
emit('ok', submitValues);
|
||||
} catch (error) {
|
||||
console.error('Validate Failed:', error);
|
||||
message.error('请检查表单填写是否正确');
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化表单
|
||||
const initForm = () => {
|
||||
currentPage.value = 1;
|
||||
editingRowId.value = null;
|
||||
if (props.initialValues) {
|
||||
const values = props.initialValues;
|
||||
// 先将匹配的字段复制到 formData
|
||||
Object.keys(formData).forEach(key => {
|
||||
if (key === 'list') return; // list 单独处理
|
||||
if (values.hasOwnProperty(key)) {
|
||||
if (key === 'captureDate' && values[key]) {
|
||||
formData[key] = dayjs(values[key]);
|
||||
} else {
|
||||
formData[key] = values[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
// rvcd → baseId 映射
|
||||
if (values.baseId) {
|
||||
formData.baseId = values.baseId;
|
||||
}
|
||||
// list 数据
|
||||
formData.list = values.list
|
||||
? values.list.map((item: any) => ({ ...item }))
|
||||
: [];
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
nextTick(() => initSortable());
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
Object.assign(formData, defaultFormData);
|
||||
formData.list = [];
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('update:visible', false);
|
||||
emit('cancel');
|
||||
resetForm();
|
||||
};
|
||||
|
||||
// 搜索过滤
|
||||
const filterOption = (inputValue: string, option: any) => {
|
||||
const label = option.label || option.name || '';
|
||||
const reachcdName = option.reachcdName || '';
|
||||
const keyword = inputValue || '';
|
||||
return label.indexOf(keyword) !== -1 || reachcdName.indexOf(keyword) !== -1;
|
||||
};
|
||||
|
||||
const ennmOptions = computed(() => {
|
||||
return JidiSelectEventStore.jidiData.map((item: any) => ({
|
||||
label: item.wbsName,
|
||||
value: item.wbsCode
|
||||
}));
|
||||
});
|
||||
const getdianzha = async (data: any) => {
|
||||
// 切换水电基地时,清空已新增的航点(仅在新增模式下)
|
||||
if (!isEdit.value && formData.list.length > 0) {
|
||||
formData.list = [];
|
||||
currentPage.value = 1;
|
||||
editingRowId.value = null;
|
||||
nextTick(() => initSortable());
|
||||
}
|
||||
const res = await getEngInfoDropdown({ baseId: data });
|
||||
stationOptions.value = res.data.map((item: any) => ({
|
||||
label: item.ennm,
|
||||
value: item.stcd
|
||||
}));
|
||||
};
|
||||
|
||||
// select 选中 stcd 后同步填充 stnm,供展示时使用
|
||||
const handleStnmChange = (record: any, stcd: string | undefined) => {
|
||||
const option = stationOptions.value.find((opt: any) => opt.value === stcd);
|
||||
record.stnm = option ? option.label : null;
|
||||
};
|
||||
|
||||
// 根据 stcd 查找电站名称 label 用于展示
|
||||
const getStationLabel = (stcd: string | undefined) => {
|
||||
const option = stationOptions.value.find((opt: any) => opt.value === stcd);
|
||||
return option ? option.label : stcd;
|
||||
};
|
||||
watch(
|
||||
() => props.visible,
|
||||
newVisible => {
|
||||
if (newVisible) {
|
||||
initForm();
|
||||
} else {
|
||||
destroySortable();
|
||||
}
|
||||
},
|
||||
{ immediate: false }
|
||||
);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
destroySortable();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
localLoading
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.drag-handle {
|
||||
cursor: grab;
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="content-search">
|
||||
<BasicSearch
|
||||
ref="basicSearchRef"
|
||||
:searchList="searchList"
|
||||
:initial-values="initSearchData"
|
||||
@reset="handleReset"
|
||||
@finish="onSearchFinish"
|
||||
@values-change="onValuesChange"
|
||||
>
|
||||
<template #actions>
|
||||
|
||||
<a-tooltip title="新增飞行路径">
|
||||
<a-button @click="props.handleAdd" type="primary"> 新增飞行路径 </a-button>
|
||||
</a-tooltip>
|
||||
<a-button @click="props.handleImport">导入</a-button>
|
||||
<a-button @click="props.handleExport">导出模板</a-button>
|
||||
</template>
|
||||
</BasicSearch>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from "vue";
|
||||
import BasicSearch from "@/components/BasicSearch/index.vue";
|
||||
|
||||
interface Props {
|
||||
handleAdd: () => void;
|
||||
handleImport: () => void;
|
||||
handleExport: () => void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "reset", values: any): void;
|
||||
(e: "searchFinish", values: any): void;
|
||||
}>();
|
||||
|
||||
const initSearchData = {
|
||||
name: "",
|
||||
};
|
||||
|
||||
const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "Input",
|
||||
name: "name",
|
||||
label: "倾斜影像名称",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const onSearchFinish = (values: any) => {
|
||||
emit("searchFinish", values);
|
||||
};
|
||||
|
||||
const onValuesChange = (changedValues: any, allValues: any) => {
|
||||
searchData.value = { ...searchData.value, ...allValues };
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
emit("reset", initSearchData);
|
||||
};
|
||||
|
||||
// 初始数据加载由父组件的 onMounted 统一触发,避免子组件挂载时序问题
|
||||
</script>
|
||||
<style scoped lang="scss"></style>
|
||||
293
frontend/src/views/system/disposeManage/index.vue
Normal file
293
frontend/src/views/system/disposeManage/index.vue
Normal file
@ -0,0 +1,293 @@
|
||||
<!-- d:\wordpack\WholeProcessPlatform\frontend\src\views\system\map\components\disposeManage\index.vue -->
|
||||
<template>
|
||||
<div class="content">
|
||||
<disposeManageSearch
|
||||
ref="disposeManageSearchRef"
|
||||
:handle-add="handleAdd"
|
||||
:handle-import="handleImport"
|
||||
:handle-export="handleExport"
|
||||
@reset="handleReset"
|
||||
@search-finish="onSearchFinish"
|
||||
/>
|
||||
<BasicTable
|
||||
ref="basicTable"
|
||||
:columns="columns"
|
||||
:list-url="threedroambGetKendoListCust"
|
||||
:search-params="searchParams"
|
||||
>
|
||||
<template #action="{ column, record }">
|
||||
<div class="flex gap-[6px]">
|
||||
<a-button
|
||||
class="!p-0"
|
||||
type="link"
|
||||
size="small"
|
||||
@click="handleEdit(record)"
|
||||
>编辑</a-button
|
||||
>
|
||||
<a-button
|
||||
class="!p-0"
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
@click="handleDelete(record)"
|
||||
>删除</a-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<disposeManageForm
|
||||
ref="disposeManageFormRef"
|
||||
v-model:visible="editModalVisible"
|
||||
:initial-values="currentRecord"
|
||||
@cancel="editModalCancel"
|
||||
@ok="handleEditSubmit"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, onMounted } from 'vue';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import disposeManageSearch from './disposeManageSearch.vue';
|
||||
import disposeManageForm from './disposeManageForm.vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import {
|
||||
threedroambGetKendoListCust,
|
||||
threedroambsave,
|
||||
threedroambdelete,
|
||||
threedroambGetKendoById,
|
||||
threedroambimport,
|
||||
threedroambexport
|
||||
} from '@/api/system/disposeManage';
|
||||
import { downloadFile } from '@/utils/index';
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
customRender: ({ text, record, index }) => index + 1
|
||||
},
|
||||
{
|
||||
title: '飞行路径名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '飞行路径Code',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
key: 'recordUser',
|
||||
dataIndex: 'recordUser',
|
||||
width: 350
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'recordTime',
|
||||
dataIndex: 'recordTime',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'modifyTime',
|
||||
dataIndex: 'modifyTime',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
key: 'remark',
|
||||
dataIndex: 'remark',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
fixed: 'right',
|
||||
slots: { customRender: 'action' }
|
||||
}
|
||||
];
|
||||
|
||||
// 表格实例
|
||||
const basicTable = ref<any>(null);
|
||||
// 搜索参数
|
||||
const searchParams = ref({});
|
||||
// 编辑弹窗数据
|
||||
const currentRecord = ref<any | null>(null);
|
||||
const editModalVisible = ref(false);
|
||||
|
||||
// 添加处理
|
||||
const handleAdd = () => {
|
||||
currentRecord.value = null;
|
||||
editModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 导入处理
|
||||
const handleImport = () => {
|
||||
// 创建隐藏文件输入
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = '.xlsx,.xls,.csv';
|
||||
input.onchange = async (e: any) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
try {
|
||||
await threedroambimport(formData);
|
||||
message.success('导入成功');
|
||||
basicTable.value.refresh();
|
||||
} catch (error) {
|
||||
message.error('导入失败');
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
};
|
||||
|
||||
// 导出处理
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await threedroambexport({});
|
||||
downloadFile(res, '飞行路径模板', 'xlsx');
|
||||
} catch (error) {
|
||||
message.error('导出失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑处理 - 请求详情回显
|
||||
const handleEdit = async (record: any) => {
|
||||
try {
|
||||
const res = await threedroambGetKendoById({ id: record.id });
|
||||
currentRecord.value = res?.data || res;
|
||||
editModalVisible.value = true;
|
||||
} catch (error) {
|
||||
message.error('获取数据失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 删除处理
|
||||
const handleDelete = (record: any) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
zIndex: 2002,
|
||||
onOk: async () => {
|
||||
try {
|
||||
let res = await threedroambdelete({ id: record.id });
|
||||
message.success('删除成功');
|
||||
basicTable.value.refresh();
|
||||
} catch (error) {
|
||||
message.error('删除失败');
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 搜索完成处理
|
||||
const onSearchFinish = (values: any) => {
|
||||
const params = {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
values.name? {
|
||||
field: 'name',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: values.name
|
||||
}:null,
|
||||
{
|
||||
field: 'isDeleted',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: '0'
|
||||
}
|
||||
].filter(Boolean)
|
||||
};
|
||||
basicTable.value.getList(params);
|
||||
};
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
nextTick(() => {
|
||||
basicTable.value.getList({
|
||||
logic: 'and',
|
||||
filters: [ {
|
||||
field: 'isDeleted',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: '0'
|
||||
}]
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 表单取消
|
||||
const editModalCancel = () => {
|
||||
currentRecord.value = null;
|
||||
editModalVisible.value = false;
|
||||
};
|
||||
|
||||
// 表单提交
|
||||
const handleEditSubmit = async (values: any) => {
|
||||
try {
|
||||
// let res = await threedroambsave({
|
||||
// ...currentRecord.value,
|
||||
// ...values,
|
||||
// });
|
||||
let res = await threedroambsave(values);
|
||||
message.success(`保存成功`);
|
||||
|
||||
editModalVisible.value = false;
|
||||
basicTable.value.refresh();
|
||||
} catch (error) {
|
||||
message.error(`保存失败`);
|
||||
|
||||
editModalVisible.value = false;
|
||||
return;
|
||||
}
|
||||
};
|
||||
const initOption = () => {
|
||||
// 页面初始化时触发一次数据加载
|
||||
nextTick(() => {
|
||||
basicTable.value?.getList({
|
||||
logic: 'and',
|
||||
filters: [{
|
||||
field: 'isDeleted',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: '0'
|
||||
}]
|
||||
});
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
initOption();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tilt-photo-management {
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 900;
|
||||
pointer-events: all;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user