飞行路径管理,沿程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({
|
return request({
|
||||||
url: '/base/msalongb/noAuth/GetKendoList',
|
url: '/base/msalongb/noAuth/GetKendoList',
|
||||||
method: 'post',
|
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
|
data: queryParams
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//获取电站
|
||||||
|
export function overviewvmsstbprptGetKendoList(queryParams: any) {
|
||||||
|
return request({
|
||||||
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
|
method: 'post',
|
||||||
|
data: queryParams
|
||||||
|
});
|
||||||
|
}
|
||||||
export function vmsstbprptGetKendoList1(queryParams: any) {
|
export function vmsstbprptGetKendoList1(queryParams: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/eq/vmsstbprpt/GetKendoList',
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export function getCxswList(data: any) {
|
|||||||
//获取出入库水温下拉选则树
|
//获取出入库水温下拉选则树
|
||||||
export function getVmsstbprpt(data: any) {
|
export function getVmsstbprpt(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/wt/vmsstbprpt/GetKendoList',
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
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
|
<Yanchengyulei
|
||||||
v-if="modalVisible && JidiSelectEventStore.jidiData.length > 0"
|
v-if="modalVisible && JidiSelectEventStore.jidiData.length > 0"
|
||||||
:tm="modalYear"
|
:tm="modalYear"
|
||||||
:dataDimensionVal="baseid"
|
:dataDimensionVal="moreSelect.value.value"
|
||||||
:hbrvcd="modalHbrvcd"
|
:hbrvcd="modalHbrvcd"
|
||||||
:jdList="JidiSelectEventStore.jidiData"
|
:jdList="JidiSelectEventStore.jidiData"
|
||||||
:stateName="modalStateName"
|
:stateName="modalStateName"
|
||||||
@ -52,7 +52,7 @@ import type { EChartsOption } from 'echarts';
|
|||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import Yanchengyulei from './TwoLayers/Yanchengyulei.vue';
|
import Yanchengyulei from './TwoLayers/Yanchengyulei.vue';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { wbsbGetKendoList, getDftYear, fishChanges2 } from '@/api/stdc';
|
import { getDftYear, fishChanges2 } from '@/api/stdc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { useDraggable } from '@/utils/drag';
|
import { useDraggable } from '@/utils/drag';
|
||||||
|
|
||||||
@ -64,8 +64,6 @@ defineOptions({
|
|||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
|
||||||
// ==================== 基础状态 ====================
|
// ==================== 基础状态 ====================
|
||||||
/** 当前选中的基地ID,来自 JidiSelectEventStore.selectedItem */
|
|
||||||
const baseid = ref('');
|
|
||||||
/** 图表数据加载状态 */
|
/** 图表数据加载状态 */
|
||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
/** 初始化标志位:初始化期间不响应控件变化触发数据请求 */
|
/** 初始化标志位:初始化期间不响应控件变化触发数据请求 */
|
||||||
@ -253,8 +251,8 @@ const handleResize = () => {
|
|||||||
const getYearData = async () => {
|
const getYearData = async () => {
|
||||||
try {
|
try {
|
||||||
const filter: any = {};
|
const filter: any = {};
|
||||||
if (baseid.value && baseid.value !== 'all') {
|
if (moreSelect.value.value) {
|
||||||
filter.baseId = baseid.value;
|
filter.baseId = moreSelect.value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
@ -285,7 +283,7 @@ const getYearData = async () => {
|
|||||||
);
|
);
|
||||||
const latestYear = uniqueYears[0];
|
const latestYear = uniqueYears[0];
|
||||||
|
|
||||||
// baseid 为 all 时取第一个有数据的流域
|
// 取第一个有数据的流域
|
||||||
const firstWbsCode = Object.keys(data)[0];
|
const firstWbsCode = Object.keys(data)[0];
|
||||||
select.value.options = objYear[firstWbsCode] || [];
|
select.value.options = objYear[firstWbsCode] || [];
|
||||||
select.value.value = latestYear
|
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
|
* 根据当前选中的流域(hbrvcd)、年份(yr)、基地(baseId)调用 fishChanges2 API
|
||||||
@ -404,28 +338,18 @@ const getChartData = async () => {
|
|||||||
filter: {
|
filter: {
|
||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
moreSelect.value.value
|
{
|
||||||
? {
|
field: 'baseId',
|
||||||
field: 'hbrvcd',
|
operator: 'eq',
|
||||||
operator: 'eq',
|
dataType: 'string',
|
||||||
dataType: 'string',
|
value: moreSelect.value.value
|
||||||
value: moreSelect.value.value
|
},
|
||||||
}
|
|
||||||
: null,
|
|
||||||
{
|
{
|
||||||
field: 'yr',
|
field: 'yr',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: moment(select.value.value).format('YYYY')
|
value: moment(select.value.value).format('YYYY')
|
||||||
},
|
}
|
||||||
baseid.value !== 'all'
|
|
||||||
? {
|
|
||||||
field: 'baseId',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: baseid.value
|
|
||||||
}
|
|
||||||
: null
|
|
||||||
].filter(Boolean)
|
].filter(Boolean)
|
||||||
},
|
},
|
||||||
group: [
|
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,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
async newVal => {
|
async newVal => {
|
||||||
if (newVal && newVal.wbsCode) {
|
if (newVal && newVal.wbsCode) {
|
||||||
baseid.value = newVal.wbsCode;
|
if (newVal.wbsCode === 'all') {
|
||||||
await getMoreSelectData();
|
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 }
|
{ deep: true, immediate: true }
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
<churukushuiwen
|
<churukushuiwen
|
||||||
v-if="clickDataInfo"
|
v-if="clickDataInfo"
|
||||||
:tm="[clickDataInfo.date, clickDataInfo.date]"
|
:tm="[clickDataInfo.date, clickDataInfo.date]"
|
||||||
:stcd="paramsOne.value"
|
:stcd="select.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@ -49,7 +49,7 @@ import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
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 { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import churukushuiwen from './churukushuiwen.vue';
|
import churukushuiwen from './churukushuiwen.vue';
|
||||||
import { MapClass } from '@/components/gis/map.class';
|
import { MapClass } from '@/components/gis/map.class';
|
||||||
@ -93,7 +93,6 @@ const scopeDate = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ==================== 业务变量 ====================
|
// ==================== 业务变量 ====================
|
||||||
const baseid = ref(''); // 当前选中的基地ID
|
|
||||||
const modalVisible = ref(false); // 弹框显示状态
|
const modalVisible = ref(false); // 弹框显示状态
|
||||||
const clickDataInfo = ref<any>(null); // 点击的数据点信息
|
const clickDataInfo = ref<any>(null); // 点击的数据点信息
|
||||||
const stationName = ref(''); // 站点名称
|
const stationName = ref(''); // 站点名称
|
||||||
@ -169,7 +168,6 @@ function calculateXAxisInterval(dateCount: number): number {
|
|||||||
return Math.ceil(dateCount / 4) - 1; // 动态计算间隔,保证最多4个刻度
|
return Math.ceil(dateCount / 4) - 1; // 动态计算间隔,保证最多4个刻度
|
||||||
}
|
}
|
||||||
const paramsOne: any = ref({
|
const paramsOne: any = ref({
|
||||||
value: '',
|
|
||||||
tm: [currentMonth, currentMonth]
|
tm: [currentMonth, currentMonth]
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
@ -194,20 +192,10 @@ async function fetchChartData() {
|
|||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
// OR逻辑:查询入库或出库水温
|
field: 'baseId',
|
||||||
logic: 'or',
|
operator: 'eq',
|
||||||
filters: [
|
dataType: 'string',
|
||||||
{
|
value: select.value.value
|
||||||
field: 'engDwtCode',
|
|
||||||
operator: 'eq',
|
|
||||||
value: paramsOne.value.value
|
|
||||||
}, // 出库站点编码
|
|
||||||
{
|
|
||||||
field: 'engIwtCode',
|
|
||||||
operator: 'eq',
|
|
||||||
value: paramsOne.value.value
|
|
||||||
} // 入库站点编码
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
// 时间范围过滤
|
// 时间范围过滤
|
||||||
{ field: 'dt', operator: 'gte', dataType: 'date', value: startDate },
|
{ field: 'dt', operator: 'gte', dataType: 'date', value: startDate },
|
||||||
@ -584,12 +572,10 @@ const handleChartClick = (params: any) => {
|
|||||||
dataIndex: dataIndex // 数据索引
|
dataIndex: dataIndex // 数据索引
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取站点名称(从下拉选项中查找)
|
// 获取站点名称
|
||||||
// console.log('站点名称:', select.value.options, paramsOne.value.value);
|
stationName.value = select.value.options?.find(
|
||||||
const selectedStation = select.value.options
|
(item: any) => item.value === select.value.value
|
||||||
.flatMap((base: any) => base.children || [])
|
)?.title || '未知站点';
|
||||||
.find((station: any) => station.stcd === paramsOne.value.value);
|
|
||||||
stationName.value = selectedStation?.title || '未知站点';
|
|
||||||
|
|
||||||
// 打开弹框
|
// 打开弹框
|
||||||
modalVisible.value = true;
|
modalVisible.value = true;
|
||||||
@ -612,7 +598,7 @@ const handleModalClose = () => {
|
|||||||
const handlePanelChange1 = (data: any, type: string) => {
|
const handlePanelChange1 = (data: any, type: string) => {
|
||||||
// TODO: 后续可扩展联动逻辑
|
// TODO: 后续可扩展联动逻辑
|
||||||
if (data.moreSelect && data.scopeDate) {
|
if (data.moreSelect && data.scopeDate) {
|
||||||
paramsOne.value.value = data.moreSelect;
|
select.value.value = data.moreSelect;
|
||||||
paramsOne.value.tm = data.scopeDate;
|
paramsOne.value.tm = data.scopeDate;
|
||||||
fetchChartData();
|
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监听器 ====================
|
||||||
|
|
||||||
/**
|
|
||||||
* 监听基地选择变化
|
|
||||||
* 当用户切换基地时,重新加载站点下拉选项
|
|
||||||
*/
|
|
||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem, // 监听Store中的选中项
|
() => JidiSelectEventStore.selectedItem,
|
||||||
newVal => {
|
newVal => {
|
||||||
baseid.value = newVal.wbsCode; // 更新基地ID
|
select.value.value = newVal.wbsCode;
|
||||||
getselsectData(); // 重新获取站点数据
|
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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
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 { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||||
import MonthlyAverage from './monthlyAverage.vue'
|
import MonthlyAverage from './monthlyAverage.vue'
|
||||||
import MonthlyAverageMaxModal from './TwoLayers/monthlyAverageMaxModal.vue'
|
import MonthlyAverageMaxModal from './TwoLayers/monthlyAverageMaxModal.vue'
|
||||||
@ -55,7 +55,6 @@ const searchParams = ref({
|
|||||||
dateValue: '' // 可以是 string 或 Dayjs 对象
|
dateValue: '' // 可以是 string 或 Dayjs 对象
|
||||||
});
|
});
|
||||||
const unit = '°C'
|
const unit = '°C'
|
||||||
const baseid: any = ref(null);
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const showemit = ref(true);
|
const showemit = ref(true);
|
||||||
|
|
||||||
@ -94,123 +93,6 @@ const datetimePicker = ref({
|
|||||||
options: [],
|
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 () => {
|
const getEchartsData = async () => {
|
||||||
if (loading.value) return; // 防止重复请求
|
if (loading.value) return; // 防止重复请求
|
||||||
@ -238,7 +120,7 @@ const getEchartsData = async () => {
|
|||||||
"logic": "and",
|
"logic": "and",
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"field": "rvcd",
|
"field": "baseId",
|
||||||
"operator": "eq",
|
"operator": "eq",
|
||||||
"dataType": "string",
|
"dataType": "string",
|
||||||
"value": select.value.value
|
"value": select.value.value
|
||||||
@ -527,7 +409,7 @@ const initChart = (newXData: any[], actualData: any[], lastData: any[], naturalD
|
|||||||
// 设置弹框数据
|
// 设置弹框数据
|
||||||
stationName.value = stnm;
|
stationName.value = stnm;
|
||||||
modalData.value = {
|
modalData.value = {
|
||||||
baseid: baseid.value,
|
baseid: select.value.value,
|
||||||
rvcd: select.value.value,
|
rvcd: select.value.value,
|
||||||
date: datetimePicker.value.value,
|
date: datetimePicker.value.value,
|
||||||
stcd: stcd,
|
stcd: stcd,
|
||||||
@ -575,8 +457,24 @@ const handlePanelChange1 = (data) => {
|
|||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
baseid.value = newVal.wbsCode;
|
select.value.value = newVal.wbsCode;
|
||||||
getSelectConfig()
|
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 }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -38,12 +38,20 @@
|
|||||||
class="tab-style"
|
class="tab-style"
|
||||||
@change="fetchTableData"
|
@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>
|
</a-tabs>
|
||||||
<div class="body_zhengti">
|
<div class="body_zhengti">
|
||||||
<div class="echarts">
|
<div class="echarts">
|
||||||
<a-spin :spinning="dataLoading">
|
<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
|
<a-empty
|
||||||
v-if="!dataLoading && pieData.length === 0"
|
v-if="!dataLoading && pieData.length === 0"
|
||||||
description="暂无数据"
|
description="暂无数据"
|
||||||
@ -55,7 +63,6 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:scrollY="380"
|
:scrollY="380"
|
||||||
|
|
||||||
:list-url="vmsstbprptGetKendoList"
|
:list-url="vmsstbprptGetKendoList"
|
||||||
:search-params="searchParams"
|
:search-params="searchParams"
|
||||||
:transform-data="customTransform"
|
:transform-data="customTransform"
|
||||||
@ -80,10 +87,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-empty
|
<a-empty v-else-if="!bodyLoading" description="暂无数据" />
|
||||||
v-else-if="!bodyLoading"
|
|
||||||
description="暂无数据"
|
|
||||||
/>
|
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -96,6 +100,7 @@ import dayjs from 'dayjs';
|
|||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import {
|
import {
|
||||||
dayGetKendoListCust,
|
dayGetKendoListCust,
|
||||||
|
overviewvmsstbprptGetKendoList,
|
||||||
vmsstbprptGetKendoList,
|
vmsstbprptGetKendoList,
|
||||||
msstbprptGetKendoList
|
msstbprptGetKendoList
|
||||||
} from '@/api/stll';
|
} from '@/api/stll';
|
||||||
@ -745,7 +750,7 @@ watch(ecoFlowType, () => {
|
|||||||
// 监听 tabList 变化,当变为空时清理图表实例
|
// 监听 tabList 变化,当变为空时清理图表实例
|
||||||
watch(
|
watch(
|
||||||
() => tabList.value.length,
|
() => tabList.value.length,
|
||||||
(newLen) => {
|
newLen => {
|
||||||
if (newLen === 0 && chartInstance) {
|
if (newLen === 0 && chartInstance) {
|
||||||
chartInstance.dispose();
|
chartInstance.dispose();
|
||||||
chartInstance = null;
|
chartInstance = null;
|
||||||
@ -766,12 +771,18 @@ const rstcdOption = async () => {
|
|||||||
filters: [
|
filters: [
|
||||||
params.value.qid != 'all'
|
params.value.qid != 'all'
|
||||||
? {
|
? {
|
||||||
field: 'sttpCode',
|
field: 'baseId',
|
||||||
operator: 'eq',
|
operator: 'contains',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: 'ENG'
|
value: params.value.qid
|
||||||
}
|
}
|
||||||
: null
|
: null,
|
||||||
|
{
|
||||||
|
field: 'sttpCode',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: 'ENG'
|
||||||
|
}
|
||||||
].filter(Boolean)
|
].filter(Boolean)
|
||||||
},
|
},
|
||||||
sort: [
|
sort: [
|
||||||
@ -782,7 +793,34 @@ const rstcdOption = async () => {
|
|||||||
],
|
],
|
||||||
select: ['stcd', 'stnm']
|
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) => {
|
rstcdOptions.value = res.data.data.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
value: item.stcd,
|
value: item.stcd,
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import * as echarts from 'echarts';
|
|||||||
import type { EChartsOption } from 'echarts';
|
import type { EChartsOption } from 'echarts';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { wbsbGetKendoList, getDftYear, getFishListStat } from '@/api/stdc';
|
import { getDftYear, getFishListStat } from '@/api/stdc';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -41,7 +41,6 @@ defineOptions({
|
|||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
|
||||||
// ==================== 基础状态 ====================
|
// ==================== 基础状态 ====================
|
||||||
const baseid = ref('');
|
|
||||||
const isInitializing = ref(false);
|
const isInitializing = ref(false);
|
||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
|
|
||||||
@ -174,8 +173,8 @@ const handleResize = () => {
|
|||||||
const getYearData = async () => {
|
const getYearData = async () => {
|
||||||
try {
|
try {
|
||||||
const filter: any = {};
|
const filter: any = {};
|
||||||
if (baseid.value && baseid.value !== 'all') {
|
if (moreSelect.value.value) {
|
||||||
filter.baseId = baseid.value;
|
filter.baseId = moreSelect.value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = {
|
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
|
* 根据当前选中的流域(hbrvcd)调用 getFishListStat API
|
||||||
@ -314,7 +250,7 @@ const getChartData = async () => {
|
|||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
field: 'hbrvcd',
|
field: 'baseId',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: moreSelect.value.value
|
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) => {
|
const handlePanelChange = async (data: any) => {
|
||||||
@ -421,8 +302,32 @@ watch(
|
|||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
async newVal => {
|
async newVal => {
|
||||||
if (newVal && newVal.wbsCode) {
|
if (newVal && newVal.wbsCode) {
|
||||||
baseid.value = newVal.wbsCode;
|
if (newVal.wbsCode === 'all') {
|
||||||
await getMoreSelectData();
|
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 }
|
{ deep: true, immediate: true }
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import type { EChartsOption } from 'echarts';
|
import type { EChartsOption } from 'echarts';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
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 { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
import {
|
import {
|
||||||
@ -835,12 +835,6 @@ const getecharts = async () => {
|
|||||||
field: 'baseId',
|
field: 'baseId',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: wbsCode.value
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'rvcd',
|
|
||||||
operator: 'eq',
|
|
||||||
dataType: 'string',
|
|
||||||
value: select.value.value
|
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 => {
|
const handlePanelChange1 = async data => {
|
||||||
console.log('当前所有控件状态:', data);
|
console.log('当前所有控件状态:', data);
|
||||||
@ -1269,7 +1176,21 @@ watch(
|
|||||||
newVal => {
|
newVal => {
|
||||||
console.log(newVal);
|
console.log(newVal);
|
||||||
wbsCode.value = newVal.wbsCode;
|
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 }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -25,11 +25,9 @@ import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue';
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import type { ECharts } from 'echarts';
|
import type { ECharts } from 'echarts';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
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 { 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';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
@ -50,9 +48,7 @@ const getCurrentHourTime = () => {
|
|||||||
return `${year}-${month}-${day} ${hour}`;
|
return `${year}-${month}-${day} ${hour}`;
|
||||||
};
|
};
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
const baseid: any = ref(null);
|
|
||||||
const paramsOne = {
|
const paramsOne = {
|
||||||
rvcd: '',
|
|
||||||
tm: []
|
tm: []
|
||||||
};
|
};
|
||||||
const dataOne = ref('');
|
const dataOne = ref('');
|
||||||
@ -300,10 +296,10 @@ const init = async () => {
|
|||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
field: 'rvcd',
|
field: 'baseId',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: paramsOne.rvcd
|
value: select.value.value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'tm',
|
field: 'tm',
|
||||||
@ -378,151 +374,11 @@ const init = async () => {
|
|||||||
loading.value = false;
|
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 => {
|
const handlePanelChange1 = data => {
|
||||||
console.log('当前所有控件状态:', data);
|
console.log('当前所有控件状态:', data);
|
||||||
if (data.moreSelect) {
|
if (data.moreSelect) {
|
||||||
paramsOne.rvcd = data.moreSelect;
|
select.value.value = data.moreSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.datetime) {
|
if (data.datetime) {
|
||||||
@ -565,7 +421,7 @@ const handlePanelChange1 = data => {
|
|||||||
paramsOne.tm = result;
|
paramsOne.tm = result;
|
||||||
console.log(paramsOne.tm, 'paramsOne.tm');
|
console.log(paramsOne.tm, 'paramsOne.tm');
|
||||||
}
|
}
|
||||||
if (paramsOne.rvcd || paramsOne.tm.length > 0) {
|
if (select.value.value || paramsOne.tm.length > 0) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -573,8 +429,26 @@ const handlePanelChange1 = data => {
|
|||||||
watch(
|
watch(
|
||||||
() => JidiSelectEventStore.selectedItem,
|
() => JidiSelectEventStore.selectedItem,
|
||||||
newVal => {
|
newVal => {
|
||||||
baseid.value = newVal.wbsCode;
|
// if (newVal.baseId) {
|
||||||
getSelectConfig();
|
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 }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export const useJidiSelectEventStore = defineStore('jidiSelectEvent', () => {
|
|||||||
dir: 'asc'
|
dir: 'asc'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
select: ['wbsCode', 'wbsName']
|
select: ['wbsCode', 'wbsName', 'baseId']
|
||||||
};
|
};
|
||||||
const res = await wbsbGetKendoList(params);
|
const res = await wbsbGetKendoList(params);
|
||||||
const data = res?.data?.data || [
|
const data = res?.data?.data || [
|
||||||
|
|||||||
@ -34,7 +34,7 @@ service.interceptors.request.use(
|
|||||||
config.headers._sysid = '10EC2E0B-AEA9-4757-83A2-201BA1BC54E9';
|
config.headers._sysid = '10EC2E0B-AEA9-4757-83A2-201BA1BC54E9';
|
||||||
|
|
||||||
config.headers.authorization =
|
config.headers.authorization =
|
||||||
'bearer 223f63a2-0b13-4757-8e15-f342098e63ca';
|
'bearer b142d8ee-7e9d-4704-97c9-da935615bac3';
|
||||||
config.baseURL = '/';
|
config.baseURL = '/';
|
||||||
} else {
|
} else {
|
||||||
const user = useUserStoreHook();
|
const user = useUserStoreHook();
|
||||||
|
|||||||
@ -37,13 +37,13 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="所在河段" name="rvcd">
|
<a-form-item label="水电基地" name="baseId">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="formData.rvcd"
|
v-model:value="formData.baseId"
|
||||||
show-search
|
show-search
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="请选择所在河段"
|
placeholder="请选择水电基地"
|
||||||
:options="riverOptions"
|
:options="filteredRiverOptions"
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@change="handleRiverSelect"
|
@change="handleRiverSelect"
|
||||||
:disabled="isEdit"
|
:disabled="isEdit"
|
||||||
@ -108,7 +108,9 @@
|
|||||||
<template #title="{ dataRef }">
|
<template #title="{ dataRef }">
|
||||||
<!-- 编辑状态:只显示编辑区域 -->
|
<!-- 编辑状态:只显示编辑区域 -->
|
||||||
<div
|
<div
|
||||||
v-if="editingNode && editingNodeKey === dataRef.key"
|
v-if="
|
||||||
|
editingNode && editingNodeKey === dataRef.key && !dataRef.parentId
|
||||||
|
"
|
||||||
class="add-child-node-row w-[300px]"
|
class="add-child-node-row w-[300px]"
|
||||||
>
|
>
|
||||||
<a-select
|
<a-select
|
||||||
@ -155,8 +157,8 @@
|
|||||||
size="small"
|
size="small"
|
||||||
@click.stop="handleAddChild(dataRef)"
|
@click.stop="handleAddChild(dataRef)"
|
||||||
:title="
|
:title="
|
||||||
dataRef.sttpName
|
dataRef.stnm
|
||||||
? `子级添加-${dataRef.sttpName}`
|
? `子级添加-${dataRef.stnm}`
|
||||||
: '子级添加'
|
: '子级添加'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
@ -238,47 +240,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
</template>
|
</template>
|
||||||
</a-tree>
|
</a-tree>
|
||||||
<a-empty v-else description="暂无数据" style="margin-top: 20px" />
|
<a-empty v-else description="暂无数据" style="margin-top: 20px" />
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 测站选择弹窗(子节点新增/编辑用) -->
|
||||||
|
<StationSelectModal
|
||||||
|
:baseId="formData.baseId"
|
||||||
|
v-model:visible="stationSelectVisible"
|
||||||
|
@confirm="handleStationSelectConfirm"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -294,8 +268,9 @@ import {
|
|||||||
ArrowUpOutlined,
|
ArrowUpOutlined,
|
||||||
ArrowDownOutlined
|
ArrowDownOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} 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 {
|
interface Props {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
initialValues?: any | null;
|
initialValues?: any | null;
|
||||||
@ -315,7 +290,7 @@ const modalVisible = computed({
|
|||||||
get: () => props.visible,
|
get: () => props.visible,
|
||||||
set: val => emit('update:visible', val)
|
set: val => emit('update:visible', val)
|
||||||
});
|
});
|
||||||
|
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:visible', value: boolean): void;
|
(e: 'update:visible', value: boolean): void;
|
||||||
(e: 'cancel'): void;
|
(e: 'cancel'): void;
|
||||||
@ -328,7 +303,7 @@ const defaultFormData = reactive({
|
|||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
rvcd: undefined,
|
baseId: undefined,
|
||||||
remark: undefined
|
remark: undefined
|
||||||
});
|
});
|
||||||
const formData: any = reactive({ ...defaultFormData });
|
const formData: any = reactive({ ...defaultFormData });
|
||||||
@ -336,19 +311,16 @@ const formData: any = reactive({ ...defaultFormData });
|
|||||||
const rules: Record<string, Rule[]> = {
|
const rules: Record<string, Rule[]> = {
|
||||||
name: [{ required: true, message: '请输入沿程配置名称', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入沿程配置名称', trigger: 'blur' }],
|
||||||
code: [{ required: true, message: '请输入配置编码', trigger: 'blur' }],
|
code: [{ required: true, message: '请输入配置编码', trigger: 'blur' }],
|
||||||
rvcd: [{ required: true, message: '请选择所在河段', trigger: 'change' }]
|
baseId: [{ 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
|
|
||||||
}));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isEdit = computed(() => !!props.initialValues);
|
const isEdit = computed(() => !!props.initialValues);
|
||||||
|
|
||||||
|
// 过滤掉"当前全部"项(wbsCode === 'all')
|
||||||
|
const filteredRiverOptions = computed(() =>
|
||||||
|
props.riverOptions.filter((item: any) => item.value !== 'all')
|
||||||
|
);
|
||||||
|
|
||||||
// 树形数据
|
// 树形数据
|
||||||
const treeData = ref<any[]>([]);
|
const treeData = ref<any[]>([]);
|
||||||
|
|
||||||
@ -357,17 +329,12 @@ const addingNewNode = ref(false);
|
|||||||
const newNodeData = ref({
|
const newNodeData = ref({
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
ennm: '',
|
ennm: '',
|
||||||
sttpName: ''
|
stnm: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加子节点相关
|
// 测站选择弹窗(子节点新增/编辑用)
|
||||||
const addingChildNode = ref(false);
|
const stationSelectVisible = ref(false);
|
||||||
const currentParentKey = ref<string | null>(null);
|
const currentParentKey = ref<string | null>(null);
|
||||||
const childNodeData = ref({
|
|
||||||
stcd: undefined,
|
|
||||||
ennm: '',
|
|
||||||
sttpName: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
// 编辑节点相关
|
// 编辑节点相关
|
||||||
const editingNode = ref(false);
|
const editingNode = ref(false);
|
||||||
@ -375,7 +342,7 @@ const editingNodeKey = ref<string | null>(null);
|
|||||||
const editNodeData = ref({
|
const editNodeData = ref({
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
ennm: '',
|
ennm: '',
|
||||||
sttpName: '',
|
stnm: '',
|
||||||
originalData: null as any
|
originalData: null as any
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -386,12 +353,30 @@ const childStationList = ref([]);
|
|||||||
let nodeIdCounter = 0;
|
let nodeIdCounter = 0;
|
||||||
const generateNodeId = () => `node_${Date.now()}_${++nodeIdCounter}`;
|
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) => {
|
const getNodeTitle = (dataRef: any) => {
|
||||||
if (!dataRef.parentId) {
|
if (!dataRef.parentId) {
|
||||||
return dataRef.ennm || '';
|
return dataRef.ennm || '';
|
||||||
} else {
|
} 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 = () => {
|
const handleAdd = () => {
|
||||||
if (!formData.rvcd) {
|
if (!formData.baseId) {
|
||||||
message.warning('请先选择所在河段');
|
message.warning('请先选择水电基地');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addingNewNode.value = true;
|
addingNewNode.value = true;
|
||||||
newNodeData.value = {
|
newNodeData.value = {
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
ennm: '',
|
ennm: '',
|
||||||
sttpName: ''
|
stnm: ''
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,7 +448,7 @@ const handleNodeSelect = (value: string) => {
|
|||||||
const station = stationList.value.find(item => item.stcd === value);
|
const station = stationList.value.find(item => item.stcd === value);
|
||||||
if (station) {
|
if (station) {
|
||||||
newNodeData.value.ennm = station.stnm;
|
newNodeData.value.ennm = station.stnm;
|
||||||
newNodeData.value.sttpName = station.sttpName;
|
newNodeData.value.stnm = station.stnm;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -474,16 +459,22 @@ const handleSaveNewNode = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkDuplicateStcd(newNodeData.value.stcd, treeData.value)) {
|
||||||
|
message.warning('该站点已存在,请勿重复添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
key: generateNodeId(),
|
key: generateNodeId(),
|
||||||
stcd: newNodeData.value.stcd,
|
stcd: newNodeData.value.stcd,
|
||||||
ennm: newNodeData.value.ennm,
|
ennm: newNodeData.value.ennm,
|
||||||
sttpName: newNodeData.value.sttpName,
|
stnm: newNodeData.value.stnm,
|
||||||
parentId: null,
|
parentId: null,
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
|
|
||||||
treeData.value.push(newNode);
|
treeData.value.push(newNode);
|
||||||
|
refreshNodeSort(treeData.value);
|
||||||
addingNewNode.value = false;
|
addingNewNode.value = false;
|
||||||
message.success('添加成功');
|
message.success('添加成功');
|
||||||
};
|
};
|
||||||
@ -494,93 +485,34 @@ const handleCancelAdd = () => {
|
|||||||
newNodeData.value = {
|
newNodeData.value = {
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
ennm: '',
|
ennm: '',
|
||||||
sttpName: ''
|
stnm: ''
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加子节点(二级节点)
|
// 添加子节点(二级节点)- 打开测站选择弹窗
|
||||||
const handleAddChild = async (parentData: any) => {
|
const handleAddChild = (parentData: any) => {
|
||||||
addingChildNode.value = true;
|
|
||||||
currentParentKey.value = parentData.key;
|
currentParentKey.value = parentData.key;
|
||||||
childNodeData.value = {
|
editingNodeKey.value = null; // 清除编辑状态
|
||||||
stcd: undefined,
|
stationSelectVisible.value = true;
|
||||||
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: ''
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 编辑节点
|
// 编辑节点
|
||||||
const handleEditNode = async (dataRef: any) => {
|
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) {
|
if (dataRef.parentId) {
|
||||||
const parent = findNodeByKey(treeData.value, dataRef.parentId);
|
// 二级节点:打开测站选择弹窗
|
||||||
if (parent) {
|
editingNodeKey.value = dataRef.key;
|
||||||
const res = await getAddvcdDropdownByRvcd({ stcd: parent.stcd });
|
currentParentKey.value = null; // 清除新增状态
|
||||||
childStationList.value = res.data || [];
|
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);
|
const station = list.find(item => item.stcd === value);
|
||||||
if (station) {
|
if (station) {
|
||||||
editNodeData.value.ennm = station.stnm;
|
editNodeData.value.ennm = station.stnm;
|
||||||
editNodeData.value.sttpName = station.sttpName;
|
editNodeData.value.stnm = station.stnm;
|
||||||
editNodeData.value.stcd = station.stcd;
|
editNodeData.value.stcd = station.stcd;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -610,10 +542,16 @@ const handleSaveEditNode = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否与同级其他节点重复
|
||||||
|
if (checkDuplicateStcd(editNodeData.value.stcd, treeData.value, editingNodeKey.value!)) {
|
||||||
|
message.warning('该站点在当前层级已存在,请重新选择');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 更新节点数据
|
// 更新节点数据
|
||||||
node.stcd = editNodeData.value.stcd;
|
node.stcd = editNodeData.value.stcd;
|
||||||
node.ennm = editNodeData.value.ennm;
|
node.ennm = editNodeData.value.ennm;
|
||||||
node.sttpName = editNodeData.value.sttpName;
|
node.stnm = editNodeData.value.stnm;
|
||||||
|
|
||||||
editingNode.value = false;
|
editingNode.value = false;
|
||||||
editingNodeKey.value = null;
|
editingNodeKey.value = null;
|
||||||
@ -627,11 +565,66 @@ const handleCancelEditNode = () => {
|
|||||||
editNodeData.value = {
|
editNodeData.value = {
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
ennm: '',
|
ennm: '',
|
||||||
sttpName: '',
|
stnm: '',
|
||||||
originalData: null
|
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 handleMoveUp = (dataRef: any) => {
|
||||||
const siblings = getSiblings(dataRef);
|
const siblings = getSiblings(dataRef);
|
||||||
@ -643,6 +636,7 @@ const handleMoveUp = (dataRef: any) => {
|
|||||||
siblings[index],
|
siblings[index],
|
||||||
siblings[index - 1]
|
siblings[index - 1]
|
||||||
];
|
];
|
||||||
|
refreshNodeSort(siblings);
|
||||||
message.success('上移成功');
|
message.success('上移成功');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -658,6 +652,7 @@ const handleMoveDown = (dataRef: any) => {
|
|||||||
siblings[index + 1],
|
siblings[index + 1],
|
||||||
siblings[index]
|
siblings[index]
|
||||||
];
|
];
|
||||||
|
refreshNodeSort(siblings);
|
||||||
message.success('下移成功');
|
message.success('下移成功');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -739,15 +734,21 @@ const initForm = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 编辑时调用接口获取一级站点列表
|
// 编辑时调用接口获取一级站点列表
|
||||||
if (formData.rvcd) {
|
if (formData.baseId) {
|
||||||
const res = await getEngInfoDropdown({ rvcd: formData.rvcd });
|
const res = await getEngInfoDropdown({ baseId: formData.baseId });
|
||||||
stationList.value = (res.data || []).map((item: any) => ({
|
stationList.value = (res.data || []).map((item: any) => ({
|
||||||
...item,
|
...item,
|
||||||
stnm: item.ennm
|
stnm: item.ennm
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
resetForm();
|
resetForm();
|
||||||
|
const res = await getEngInfoDropdown({});
|
||||||
|
stationList.value = (res.data || []).map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
stnm: item.ennm
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -776,6 +777,14 @@ watch(
|
|||||||
{ immediate: false }
|
{ immediate: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 测站选择弹窗关闭时清除状态
|
||||||
|
watch(stationSelectVisible, visible => {
|
||||||
|
if (!visible) {
|
||||||
|
editingNodeKey.value = null;
|
||||||
|
currentParentKey.value = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
localLoading
|
localLoading
|
||||||
});
|
});
|
||||||
|
|||||||
@ -38,7 +38,7 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
name: null,
|
name: null,
|
||||||
rvcd: null
|
baseId: 'all'
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchData = ref<any>({ ...initSearchData });
|
const searchData = ref<any>({ ...initSearchData });
|
||||||
@ -53,12 +53,10 @@ const searchList: any = computed(() => [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Select',
|
type: 'Select',
|
||||||
name: 'rvcd',
|
name: 'baseId',
|
||||||
label: '所在河段',
|
label: '水电基地',
|
||||||
width: 300,
|
width: 300,
|
||||||
fieldProps: {
|
|
||||||
allowClear: true
|
|
||||||
},
|
|
||||||
options: props.riverOptions,
|
options: props.riverOptions,
|
||||||
loading: props.riverOptionsLoad
|
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>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import ConfigManagementSearch from './ConfigManagementSearch.vue';
|
import ConfigManagementSearch from './ConfigManagementSearch.vue';
|
||||||
import ConfigManagementForm from './ConfigManagementForm.vue';
|
import ConfigManagementForm from './ConfigManagementForm.vue';
|
||||||
@ -62,7 +62,8 @@ import {
|
|||||||
} from '@/api/system/map/ConfigManagement';
|
} from '@/api/system/map/ConfigManagement';
|
||||||
import { getRvcdDropdown } from '@/api/select';
|
import { getRvcdDropdown } from '@/api/select';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// 表格实例
|
// 表格实例
|
||||||
const basicTable = ref<any>(null);
|
const basicTable = ref<any>(null);
|
||||||
// 表格列配置
|
// 表格列配置
|
||||||
@ -88,9 +89,9 @@ const columns = [
|
|||||||
width: 120
|
width: 120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '所在河段',
|
title: '水电基地',
|
||||||
dataIndex: 'rvnm',
|
dataIndex: 'baseName',
|
||||||
key: 'rvnm',
|
key: 'baseName',
|
||||||
width: 300,
|
width: 300,
|
||||||
ellipsis: true
|
ellipsis: true
|
||||||
},
|
},
|
||||||
@ -129,12 +130,12 @@ const columns = [
|
|||||||
|
|
||||||
// 搜索参数
|
// 搜索参数
|
||||||
const searchParams = ref({
|
const searchParams = ref({
|
||||||
"sort": [
|
sort: [
|
||||||
{
|
{
|
||||||
"field": "recordTime",
|
field: 'recordTime',
|
||||||
"dir": "desc"
|
dir: 'desc'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
});
|
});
|
||||||
// 编辑弹窗数据
|
// 编辑弹窗数据
|
||||||
const currentRecord = ref<any | null>(null);
|
const currentRecord = ref<any | null>(null);
|
||||||
@ -181,9 +182,10 @@ const handleEdit = async (record: any) => {
|
|||||||
const res = await getChildConfigTree(params);
|
const res = await getChildConfigTree(params);
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
const data = res.data.data || [];
|
const data = res.data.data || [];
|
||||||
|
|
||||||
const firstLevelNodes = data.filter((item: any) => !item.rstcd);
|
const firstLevelNodes = data.filter((item: any) => !item.rstcd);
|
||||||
const secondLevelNodes = data.filter((item: any) => item.rstcd);
|
const secondLevelNodes = data.filter((item: any) => item.rstcd);
|
||||||
|
// debugger
|
||||||
const configNodes = firstLevelNodes.map((node: any, index: number) => {
|
const configNodes = firstLevelNodes.map((node: any, index: number) => {
|
||||||
const children = secondLevelNodes.filter(
|
const children = secondLevelNodes.filter(
|
||||||
(child: any) => child.rstcd === node.stcd
|
(child: any) => child.rstcd === node.stcd
|
||||||
@ -194,19 +196,23 @@ const handleEdit = async (record: any) => {
|
|||||||
stcd: node.stcd,
|
stcd: node.stcd,
|
||||||
ennm: node.stnm,
|
ennm: node.stnm,
|
||||||
sttpName: node.sttpName,
|
sttpName: node.sttpName,
|
||||||
|
sort: node.sort,
|
||||||
parentId: null,
|
parentId: null,
|
||||||
children: children.map((child: any, childIndex: number) => ({
|
children: children.map((child: any, childIndex: number) => ({
|
||||||
key: `child-${index}-${childIndex}`,
|
key: `child-${index}-${childIndex}`,
|
||||||
stcd: child.stcd,
|
stcd: child.stcd,
|
||||||
ennm: child.stnm,
|
ennm: child.stnm,
|
||||||
sttpName: child.sttpName,
|
sttpName: child.sttpName,
|
||||||
|
sort: child.sort,
|
||||||
parentId: `parent-${index}`,
|
parentId: `parent-${index}`,
|
||||||
|
ioDirection: child.ioDirection,
|
||||||
children: []
|
children: []
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
currentRecord.value.configNodes = configNodes;
|
currentRecord.value.configNodes = configNodes;
|
||||||
|
// debugger
|
||||||
}
|
}
|
||||||
editModalVisible.value = true;
|
editModalVisible.value = true;
|
||||||
};
|
};
|
||||||
@ -239,12 +245,12 @@ const onSearchFinish = (values: any) => {
|
|||||||
const params = {
|
const params = {
|
||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
values.rvcd
|
values.baseId != 'all'
|
||||||
? {
|
? {
|
||||||
field: 'rvcd',
|
field: 'baseId',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.rvcd
|
value: values.baseId
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
values.name
|
values.name
|
||||||
@ -280,6 +286,7 @@ const handleEditSubmit = async (values: any) => {
|
|||||||
const formData = {
|
const formData = {
|
||||||
...currentRecord.value,
|
...currentRecord.value,
|
||||||
...values,
|
...values,
|
||||||
|
baseName: (JidiSelectEventStore.jidiData.find(element => element.wbsCode === values.baseId) || {}).wbsName,
|
||||||
modifyTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
modifyTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||||
};
|
};
|
||||||
delete formData.configNodes;
|
delete formData.configNodes;
|
||||||
@ -299,7 +306,8 @@ const handleEditSubmit = async (values: any) => {
|
|||||||
const formatTreeData = (
|
const formatTreeData = (
|
||||||
nodes: any[],
|
nodes: any[],
|
||||||
parentId: string | null = null,
|
parentId: string | null = null,
|
||||||
parentStcd: string | null = null
|
parentStcd: string | null = null,
|
||||||
|
type: string | null = null
|
||||||
) => {
|
) => {
|
||||||
return nodes.map(node => ({
|
return nodes.map(node => ({
|
||||||
alongId,
|
alongId,
|
||||||
@ -308,15 +316,15 @@ const handleEditSubmit = async (values: any) => {
|
|||||||
sttpName: node.sttpName,
|
sttpName: node.sttpName,
|
||||||
parentId: parentId ? parentId : null,
|
parentId: parentId ? parentId : null,
|
||||||
rstcd: parentStcd || null,
|
rstcd: parentStcd || null,
|
||||||
|
ioDirection: node.type ||node.ioDirection || null,
|
||||||
children:
|
children:
|
||||||
node.children && node.children.length > 0
|
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 detailData = formatTreeData(treeData);
|
||||||
|
|
||||||
const detailRes = await saveBaseWbsbChildDetail(detailData);
|
const detailRes = await saveBaseWbsbChildDetail(detailData);
|
||||||
if (detailRes.code == 0) {
|
if (detailRes.code == 0) {
|
||||||
message.success(`保存成功`);
|
message.success(`保存成功`);
|
||||||
@ -339,19 +347,29 @@ const handleEditSubmit = async (values: any) => {
|
|||||||
return;
|
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 riverOptionsLoad = ref(false);
|
||||||
const initOption = () => {
|
const initOption = () => {
|
||||||
const params = {};
|
// const params = {};
|
||||||
riverOptionsLoad.value = true;
|
// riverOptionsLoad.value = true;
|
||||||
getRvcdDropdown(params).then((res: any) => {
|
// riverOptions.value = JidiSelectEventStore.jidiData.map((item:any)=>{
|
||||||
res.data.forEach((item: any) => {
|
// return{
|
||||||
item.value = item.rvcd;
|
// }
|
||||||
item.label = item.rvnm;
|
// })
|
||||||
});
|
// getRvcdDropdown(params).then((res: any) => {
|
||||||
riverOptions.value = res.data || [];
|
// res.data.forEach((item: any) => {
|
||||||
riverOptionsLoad.value = false;
|
// item.value = item.rvcd;
|
||||||
});
|
// item.label = item.rvnm;
|
||||||
|
// });
|
||||||
|
// riverOptions.value = res.data || [];
|
||||||
|
// riverOptionsLoad.value = false;
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initOption();
|
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