2026-06-26 17:52:57 +08:00
|
|
|
|
<!-- 沿程鱼类变化详情组件 -->
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="yancheng-yulei">
|
|
|
|
|
|
<!-- 搜索表单 -->
|
|
|
|
|
|
<a-form layout="inline" class="search-form">
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<!-- 基地名称 -->
|
|
|
|
|
|
<a-form-item label="基地名称">
|
2026-06-26 17:52:57 +08:00
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="formState.baseId"
|
|
|
|
|
|
placeholder="请选择"
|
|
|
|
|
|
style="width: 150px"
|
|
|
|
|
|
@change="handleBaseChange"
|
2026-07-01 18:23:41 +08:00
|
|
|
|
>
|
|
|
|
|
|
<a-select-option
|
|
|
|
|
|
v-for="opt in baseOptions"
|
|
|
|
|
|
:key="opt.value"
|
|
|
|
|
|
:value="opt.value"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ opt.label }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 所在流域 -->
|
|
|
|
|
|
<a-form-item label="所在流域">
|
|
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="formState.rvcd"
|
|
|
|
|
|
placeholder="请选择"
|
|
|
|
|
|
style="width: 150px"
|
|
|
|
|
|
@change="handleRvcdChange"
|
2026-07-01 18:23:41 +08:00
|
|
|
|
>
|
|
|
|
|
|
<a-select-option
|
|
|
|
|
|
v-for="opt in lyOptions"
|
|
|
|
|
|
:key="opt.value"
|
|
|
|
|
|
:value="opt.value"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ opt.label }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 断面名称(沿程模式显示) -->
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<!-- <a-form-item v-if="props.ly" label="断面名称">
|
2026-06-26 17:52:57 +08:00
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="formState.stcd"
|
|
|
|
|
|
placeholder="请选择"
|
|
|
|
|
|
style="width: 150px"
|
|
|
|
|
|
@change="handleStcdChange"
|
2026-07-01 18:23:41 +08:00
|
|
|
|
>
|
|
|
|
|
|
<a-select-option
|
|
|
|
|
|
v-for="opt in dmOptions"
|
|
|
|
|
|
:key="opt.value"
|
|
|
|
|
|
:value="opt.value"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ opt.label }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
</a-form-item> -->
|
2026-06-26 17:52:57 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 年份 -->
|
|
|
|
|
|
<a-form-item label="年份">
|
|
|
|
|
|
<a-date-picker
|
|
|
|
|
|
v-model:value="yearValue"
|
|
|
|
|
|
picker="year"
|
|
|
|
|
|
format="YYYY"
|
|
|
|
|
|
:allow-clear="false"
|
|
|
|
|
|
style="width: 120px"
|
|
|
|
|
|
@change="handleYearChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item>
|
|
|
|
|
|
<a-space>
|
|
|
|
|
|
<a-button type="primary" @click="handleSearch">查询</a-button>
|
|
|
|
|
|
<a-button @click="handleReset">重置</a-button>
|
|
|
|
|
|
</a-space>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
</a-form>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tab 切换 + 表格 -->
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<a-tabs
|
|
|
|
|
|
v-model:activeKey="tabIndex"
|
|
|
|
|
|
class="ylycbh-tabs"
|
|
|
|
|
|
@change="handleTabChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-tab-pane
|
|
|
|
|
|
v-for="item in tabList"
|
|
|
|
|
|
:key="item.key"
|
|
|
|
|
|
:tab="item.labelWithTooltip"
|
|
|
|
|
|
>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
<div class="table-wrapper">
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<!-- 沿程模式表格 -->
|
|
|
|
|
|
<!-- <BasicTable
|
|
|
|
|
|
v-if="props.ly && tabIndex === item.key"
|
2026-06-26 17:52:57 +08:00
|
|
|
|
:ref="el => setTableRef(el, item.key)"
|
|
|
|
|
|
:columns="tableColumns"
|
|
|
|
|
|
:scroll-y="500"
|
|
|
|
|
|
:scroll-x="800"
|
|
|
|
|
|
:list-url="listUrl"
|
|
|
|
|
|
:search-params="searchParams"
|
|
|
|
|
|
:transform-data="customTransform"
|
|
|
|
|
|
>
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<template #rsctdName="{ record }">
|
2026-06-26 17:52:57 +08:00
|
|
|
|
{{ record.rsctdName || '-' }}
|
|
|
|
|
|
</template>
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<template #stcdList="{ record }">
|
2026-06-26 17:52:57 +08:00
|
|
|
|
<div v-for="st in record.stcdList" :key="st.stcd">
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<a
|
|
|
|
|
|
@click="handleViewDetail(st.stcd, st.stnm)"
|
|
|
|
|
|
class="text-link"
|
|
|
|
|
|
>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
{{ st.stnm }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<template #fishList="{ record }">
|
2026-06-26 17:52:57 +08:00
|
|
|
|
<a-list size="small" :data-source="record.fishList">
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<template #renderItem="{ item: fish }">
|
|
|
|
|
|
<a-list-item>{{ fish }}</a-list-item>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</a-list>
|
|
|
|
|
|
</template>
|
2026-07-01 18:23:41 +08:00
|
|
|
|
</BasicTable> -->
|
2026-06-26 17:52:57 +08:00
|
|
|
|
|
2026-07-01 18:23:41 +08:00
|
|
|
|
<!-- 基地模式表格 -->
|
|
|
|
|
|
<BasicTable
|
|
|
|
|
|
:ref="el => setTableRef(el, item.key)"
|
|
|
|
|
|
:columns="tableColumns"
|
|
|
|
|
|
:scroll-y="500"
|
|
|
|
|
|
:scroll-x="800"
|
|
|
|
|
|
:list-url="listUrl"
|
|
|
|
|
|
:search-params="searchParams"
|
|
|
|
|
|
:transform-data="customTransform"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #stnm="{ record }">
|
|
|
|
|
|
<a
|
|
|
|
|
|
@click="handleViewDetail(record.stcd, record.stnm)"
|
|
|
|
|
|
class="text-link"
|
|
|
|
|
|
>
|
2026-06-26 17:52:57 +08:00
|
|
|
|
{{ record.stnm }}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</BasicTable>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-tab-pane>
|
|
|
|
|
|
</a-tabs>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
|
import { ref, computed, watch, onMounted, nextTick, h } from 'vue';
|
|
|
|
|
|
import { Tooltip } from 'ant-design-vue';
|
|
|
|
|
|
import BasicTable from '@/components/BasicTable/index.vue';
|
|
|
|
|
|
import {
|
|
|
|
|
|
wbsbGetKendoList,
|
|
|
|
|
|
getStcdList,
|
|
|
|
|
|
getTabNum,
|
|
|
|
|
|
fishDetail,
|
|
|
|
|
|
fishQgcDetail
|
|
|
|
|
|
} from '@/api/stdc';
|
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
import { useModelStore } from '@/store/modules/model';
|
|
|
|
|
|
|
|
|
|
|
|
const modelStore = useModelStore();
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== Props ====================
|
|
|
|
|
|
const props = defineProps<{
|
2026-07-01 18:23:41 +08:00
|
|
|
|
tm: string; // 年份,如 "2024"
|
2026-06-26 17:52:57 +08:00
|
|
|
|
dataDimensionVal: string; // 基地ID
|
2026-07-01 18:23:41 +08:00
|
|
|
|
hbrvcd: string; // 流域代码
|
|
|
|
|
|
jdList: any[]; // 基地列表
|
|
|
|
|
|
stateName: string; // 鱼类类型名称(如"外来鱼类")
|
|
|
|
|
|
sectionName: string; // 断面名称
|
|
|
|
|
|
stcd: string; // 站点代码
|
|
|
|
|
|
ly: boolean; // 沿程模式标识
|
2026-06-26 17:52:57 +08:00
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== Tab 配置 ====================
|
|
|
|
|
|
const TAB_CONFIG = [
|
2026-07-01 18:23:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
label: '外来鱼类',
|
|
|
|
|
|
prompt: '通过人为行为引入的本流域原生态没有的鱼类'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
label: '本土受威胁鱼类',
|
|
|
|
|
|
prompt: '流域原生态鱼类中处于近危或者濒危的鱼类'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '3',
|
|
|
|
|
|
label: '本土无危鱼类',
|
|
|
|
|
|
prompt: '分类属于本土且保护类型属于无危的鱼类'
|
|
|
|
|
|
}
|
2026-06-26 17:52:57 +08:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 搜索表单状态 ====================
|
|
|
|
|
|
const formState = ref({
|
|
|
|
|
|
baseId: props.dataDimensionVal || 'all',
|
|
|
|
|
|
rvcd: props.hbrvcd || '',
|
|
|
|
|
|
stcd: props.stcd || '',
|
|
|
|
|
|
yr: props.tm || dayjs().format('YYYY')
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const yearValue = ref(props.tm ? dayjs(props.tm) : dayjs());
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 下拉选项 ====================
|
|
|
|
|
|
/** 基地下拉选项 */
|
|
|
|
|
|
const baseOptions = computed(() =>
|
|
|
|
|
|
props.jdList.map((item: any) => ({
|
|
|
|
|
|
label: item.wbsName,
|
|
|
|
|
|
value: item.wbsCode
|
|
|
|
|
|
}))
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/** 流域下拉选项 */
|
|
|
|
|
|
const lyOptions = ref<Array<{ label: string; value: string }>>([]);
|
|
|
|
|
|
|
|
|
|
|
|
/** 断面下拉选项 */
|
|
|
|
|
|
const dmOptions = ref<Array<{ label: string; value: string }>>([
|
|
|
|
|
|
{ label: '全部', value: '' }
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== Tab 状态 ====================
|
|
|
|
|
|
/** 根据 props.stateName 确定初始 Tab */
|
|
|
|
|
|
const initTabIndex = (() => {
|
|
|
|
|
|
if (props.stateName === '外来鱼类') return '1';
|
|
|
|
|
|
if (props.stateName === '本土受威胁鱼类') return '2';
|
|
|
|
|
|
return '3';
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
const tabIndex = ref(initTabIndex);
|
|
|
|
|
|
|
|
|
|
|
|
/** Tab 列表(带 Tooltip 渲染) */
|
|
|
|
|
|
const tabList = ref<any[]>(
|
|
|
|
|
|
TAB_CONFIG.map(item => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
labelWithTooltip: renderTabLabel(item.label, item.prompt)
|
|
|
|
|
|
}))
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 渲染 Tab 标签(带 Tooltip 提示)
|
|
|
|
|
|
*/
|
|
|
|
|
|
function renderTabLabel(label: string, prompt: string) {
|
|
|
|
|
|
return () =>
|
|
|
|
|
|
h('div', { style: { display: 'flex', alignItems: 'center' } }, [
|
|
|
|
|
|
h('span', label),
|
|
|
|
|
|
h(
|
|
|
|
|
|
Tooltip,
|
|
|
|
|
|
{ placement: 'topLeft', title: prompt },
|
|
|
|
|
|
{
|
|
|
|
|
|
default: () =>
|
|
|
|
|
|
h('span', {
|
|
|
|
|
|
class: 'icon iconfont icon-iconQuestion',
|
|
|
|
|
|
style: { marginLeft: '4px', cursor: 'pointer' }
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 表格配置 ====================
|
|
|
|
|
|
/** 沿程模式表格列 */
|
|
|
|
|
|
const lyColumns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: 'rsctdName',
|
|
|
|
|
|
title: '电站名称',
|
|
|
|
|
|
dataIndex: 'rsctdName',
|
|
|
|
|
|
width: 200,
|
2026-07-01 18:23:41 +08:00
|
|
|
|
// ellipsis: true,
|
2026-06-26 17:52:57 +08:00
|
|
|
|
slots: { customRender: 'rsctdName' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: 'stcdList',
|
|
|
|
|
|
title: '调查断面',
|
|
|
|
|
|
dataIndex: 'stcdList',
|
|
|
|
|
|
width: 200,
|
2026-07-01 18:23:41 +08:00
|
|
|
|
// ellipsis: true,
|
2026-06-26 17:52:57 +08:00
|
|
|
|
slots: { customRender: 'stcdList' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: 'fishList',
|
|
|
|
|
|
title: '渔获物种类',
|
|
|
|
|
|
dataIndex: 'fishList',
|
|
|
|
|
|
width: 300,
|
2026-07-01 18:23:41 +08:00
|
|
|
|
// ellipsis: true,
|
2026-06-26 17:52:57 +08:00
|
|
|
|
slots: { customRender: 'fishList' }
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
/** 基地模式表格列 */
|
|
|
|
|
|
const baseColumns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: 'stnm',
|
|
|
|
|
|
title: '调查断面',
|
|
|
|
|
|
dataIndex: 'stnm',
|
|
|
|
|
|
fixed: 'left' as const,
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
|
slots: { customRender: 'stnm' },
|
|
|
|
|
|
merge: true,
|
|
|
|
|
|
mergeDeps: ['stnm']
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: 'name',
|
|
|
|
|
|
title: '渔获物种类',
|
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
width: 300,
|
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
|
slots: { customRender: 'name' }
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
/** 根据 ly 模式切换表格列 */
|
2026-07-01 18:23:41 +08:00
|
|
|
|
const tableColumns = computed(() => (props.ly ? baseColumns : lyColumns));
|
2026-06-26 17:52:57 +08:00
|
|
|
|
|
|
|
|
|
|
/** 根据 ly 模式切换表格 API */
|
2026-07-01 18:23:41 +08:00
|
|
|
|
const listUrl = computed(() => (props.ly ?fishQgcDetail : fishDetail));
|
2026-06-26 17:52:57 +08:00
|
|
|
|
|
|
|
|
|
|
/** 表格搜索参数 */
|
|
|
|
|
|
const searchParams = computed(() => ({
|
|
|
|
|
|
group: [],
|
|
|
|
|
|
select: [],
|
|
|
|
|
|
groupResultFlat: true
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
/** 表格 ref 映射(每个 Tab 一个 ref) */
|
|
|
|
|
|
const tableRefs = ref<Record<string, any>>({});
|
|
|
|
|
|
|
|
|
|
|
|
function setTableRef(el: any, key: string) {
|
|
|
|
|
|
if (el) tableRefs.value[key] = el;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 数据转换 */
|
|
|
|
|
|
const customTransform = (res: any) => ({
|
|
|
|
|
|
records: res?.data?.data || [],
|
|
|
|
|
|
total: res?.data?.total || 0
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 获取流域列表 ====================
|
|
|
|
|
|
const fetchLyList = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
2026-07-01 18:23:41 +08:00
|
|
|
|
formState.value.baseId != 'all'
|
|
|
|
|
|
? {
|
|
|
|
|
|
field: 'fullPath',
|
|
|
|
|
|
operator: 'startswith',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: " formState.value.baseId+','"
|
|
|
|
|
|
}
|
|
|
|
|
|
: null,
|
2026-06-26 17:52:57 +08:00
|
|
|
|
{
|
2026-07-01 18:23:41 +08:00
|
|
|
|
field: 'wbsType',
|
|
|
|
|
|
operator: 'eq',
|
2026-06-26 17:52:57 +08:00
|
|
|
|
dataType: 'string',
|
2026-07-01 18:23:41 +08:00
|
|
|
|
value: 'PSB_RVCD'
|
2026-06-26 17:52:57 +08:00
|
|
|
|
}
|
2026-07-01 18:23:41 +08:00
|
|
|
|
].filter(Boolean)
|
2026-06-26 17:52:57 +08:00
|
|
|
|
},
|
|
|
|
|
|
group: [
|
2026-07-01 18:23:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
dir: 'asc',
|
|
|
|
|
|
field: 'objId'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
dir: 'asc',
|
|
|
|
|
|
field: 'orderIndex'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
dir: 'des',
|
|
|
|
|
|
field: 'wbsCode'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
dir: 'des',
|
|
|
|
|
|
field: 'wbsName'
|
|
|
|
|
|
}
|
2026-06-26 17:52:57 +08:00
|
|
|
|
],
|
2026-07-01 18:23:41 +08:00
|
|
|
|
groupResultFlat: 'true'
|
2026-06-26 17:52:57 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const res = await wbsbGetKendoList(params);
|
|
|
|
|
|
const data = res?.data?.data || [];
|
|
|
|
|
|
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
const options = data.map((item: any) => ({
|
|
|
|
|
|
label: item.wbsName,
|
|
|
|
|
|
value: item.wbsCode
|
|
|
|
|
|
}));
|
|
|
|
|
|
lyOptions.value = options;
|
|
|
|
|
|
|
|
|
|
|
|
// 匹配传入的 hbrvcd,否则默认第一个
|
|
|
|
|
|
const matched = options.find(o => o.value === props.hbrvcd);
|
|
|
|
|
|
formState.value.rvcd = matched?.value || options[0]?.value || '';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
lyOptions.value = [];
|
|
|
|
|
|
formState.value.rvcd = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取流域列表失败:', error);
|
|
|
|
|
|
lyOptions.value = [];
|
|
|
|
|
|
formState.value.rvcd = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 获取断面列表 ====================
|
|
|
|
|
|
const fetchDmList = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{ field: 'hbrvcd', operator: 'eq', value: formState.value.rvcd },
|
|
|
|
|
|
{ field: 'sttpCode', operator: 'eq', value: 'ENG' },
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'bldsttCcode',
|
|
|
|
|
|
operator: 'in',
|
|
|
|
|
|
value: ['1', '2']
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const res = await getStcdList(params);
|
|
|
|
|
|
const data = res?.data?.data || [];
|
|
|
|
|
|
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
const options = data.map((item: any) => ({
|
|
|
|
|
|
label: item.stnm,
|
|
|
|
|
|
value: item.stcd
|
|
|
|
|
|
}));
|
|
|
|
|
|
dmOptions.value = [{ label: '全部', value: '' }, ...options];
|
|
|
|
|
|
|
|
|
|
|
|
// 匹配传入的 sectionName,否则默认第一个
|
|
|
|
|
|
const matched = options.find(o => o.label === props.sectionName);
|
|
|
|
|
|
formState.value.stcd = matched?.value || options[0]?.value || '';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
dmOptions.value = [{ label: '全部', value: '' }];
|
|
|
|
|
|
formState.value.stcd = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取断面列表失败:', error);
|
|
|
|
|
|
dmOptions.value = [{ label: '全部', value: '' }];
|
|
|
|
|
|
formState.value.stcd = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 获取 Tab 数量统计 ====================
|
|
|
|
|
|
const getTabNumData = async () => {
|
2026-07-01 18:23:41 +08:00
|
|
|
|
let params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
formState.value.baseId != 'all'
|
|
|
|
|
|
? {
|
|
|
|
|
|
field: 'baseId',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: formState.value.baseId
|
|
|
|
|
|
}
|
|
|
|
|
|
: null,
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'rvcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: formState.value.rvcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'yr',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: dayjs(yearValue.value).format('YYYY')
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'ty',
|
|
|
|
|
|
operator: 'isnotnull',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: tabIndex.value
|
|
|
|
|
|
}
|
|
|
|
|
|
].filter(Boolean)
|
|
|
|
|
|
}
|
2026-06-26 17:52:57 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getTabNum(params);
|
|
|
|
|
|
// getTabNum 返回格式:res.data 直接是数组 [{ty, num}, ...]
|
2026-07-01 18:23:41 +08:00
|
|
|
|
const data = res?.data?.data || [];
|
|
|
|
|
|
// debugger
|
2026-06-26 17:52:57 +08:00
|
|
|
|
const list = TAB_CONFIG.map(item => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
labelWithTooltip: renderTabLabel(item.label, item.prompt)
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
data.forEach((el: any) => {
|
|
|
|
|
|
const found = list.find(item => item.key === el?.ty);
|
|
|
|
|
|
if (found) {
|
|
|
|
|
|
found.labelWithTooltip = renderTabLabel(
|
|
|
|
|
|
`${found.label}(${el?.num}种)`,
|
|
|
|
|
|
found.prompt
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tabList.value = list;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取 Tab 数量失败:', error);
|
|
|
|
|
|
tabList.value = TAB_CONFIG.map(item => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
labelWithTooltip: renderTabLabel(item.label, item.prompt)
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 搜索与重置 ====================
|
|
|
|
|
|
/** 构建表格过滤条件 */
|
|
|
|
|
|
const getFilter = () => {
|
|
|
|
|
|
const filters: any[] = [
|
2026-07-01 18:23:41 +08:00
|
|
|
|
formState.value.baseId != 'all'
|
|
|
|
|
|
? {
|
|
|
|
|
|
field: 'baseId',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: formState.value.baseId
|
|
|
|
|
|
}
|
|
|
|
|
|
: null,
|
2026-06-26 17:52:57 +08:00
|
|
|
|
{
|
|
|
|
|
|
field: 'rvcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: formState.value.rvcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'yr',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: dayjs(yearValue.value).format('YYYY')
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'ty',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: tabIndex.value
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 沿程模式传 stcd
|
2026-07-01 18:23:41 +08:00
|
|
|
|
// if (props.ly && formState.value.stcd) {
|
|
|
|
|
|
// filters.push({
|
|
|
|
|
|
// field: 'stcd',
|
|
|
|
|
|
// operator: 'eq',
|
|
|
|
|
|
// dataType: 'string',
|
|
|
|
|
|
// value: formState.value.stcd
|
|
|
|
|
|
// });
|
|
|
|
|
|
// }
|
2026-06-26 17:52:57 +08:00
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: filters.filter(Boolean)
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 查询 */
|
|
|
|
|
|
const handleSearch = () => {
|
|
|
|
|
|
const filter = getFilter();
|
|
|
|
|
|
const currentTable = tableRefs.value[tabIndex.value];
|
|
|
|
|
|
currentTable?.getList(filter);
|
|
|
|
|
|
getTabNumData();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 重置 */
|
|
|
|
|
|
const handleReset = () => {
|
|
|
|
|
|
formState.value = {
|
|
|
|
|
|
baseId: props.dataDimensionVal || 'all',
|
|
|
|
|
|
rvcd: props.hbrvcd || '',
|
|
|
|
|
|
stcd: props.stcd || '',
|
|
|
|
|
|
yr: props.tm || dayjs().format('YYYY')
|
|
|
|
|
|
};
|
|
|
|
|
|
yearValue.value = props.tm ? dayjs(props.tm) : dayjs();
|
|
|
|
|
|
handleSearch();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 表单联动 ====================
|
|
|
|
|
|
/** 基地变化 */
|
|
|
|
|
|
const handleBaseChange = () => {
|
|
|
|
|
|
formState.value.rvcd = '';
|
|
|
|
|
|
formState.value.stcd = '';
|
|
|
|
|
|
fetchLyList();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 流域变化 */
|
|
|
|
|
|
const handleRvcdChange = () => {
|
|
|
|
|
|
formState.value.stcd = '';
|
|
|
|
|
|
if (props.ly) {
|
|
|
|
|
|
fetchDmList();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 断面变化 */
|
|
|
|
|
|
const handleStcdChange = () => {
|
|
|
|
|
|
// 仅更新表单值,不触发请求
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 年份变化 */
|
|
|
|
|
|
const handleYearChange = () => {
|
|
|
|
|
|
// 年份变化不自动请求,需点击查询
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** Tab 切换 */
|
2026-07-01 18:23:41 +08:00
|
|
|
|
const handleTabChange = async () => {
|
|
|
|
|
|
// 等待新 Tab 的 BasicTable 渲染完成
|
|
|
|
|
|
await nextTick();
|
2026-06-26 17:52:57 +08:00
|
|
|
|
handleSearch();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 查看详情 ====================
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 点击断面链接弹出详情
|
|
|
|
|
|
* 参考 SsstdcgkTk.vue 的 handleViewDetail
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleViewDetail = (stcd: string, stnm: string) => {
|
|
|
|
|
|
modelStore.modalVisible = true;
|
|
|
|
|
|
modelStore.params.sttp = 'WE';
|
|
|
|
|
|
modelStore.params.stcd = stcd;
|
|
|
|
|
|
modelStore.params.timeRange = [
|
|
|
|
|
|
dayjs(yearValue.value).startOf('year'),
|
|
|
|
|
|
dayjs(yearValue.value).endOf('year')
|
|
|
|
|
|
];
|
|
|
|
|
|
modelStore.params.ty1 = tabIndex.value;
|
|
|
|
|
|
modelStore.title = stnm;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== Watch ====================
|
|
|
|
|
|
/** 监听 props 变化,同步表单状态 */
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => [props.tm, props.hbrvcd, props.stcd, props.sectionName],
|
|
|
|
|
|
() => {
|
|
|
|
|
|
formState.value = {
|
|
|
|
|
|
baseId: props.dataDimensionVal || 'all',
|
|
|
|
|
|
rvcd: props.hbrvcd || '',
|
|
|
|
|
|
stcd: props.stcd || '',
|
|
|
|
|
|
yr: props.tm || dayjs().format('YYYY')
|
|
|
|
|
|
};
|
|
|
|
|
|
yearValue.value = props.tm ? dayjs(props.tm) : dayjs();
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: false }
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 生命周期 ====================
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取流域列表
|
|
|
|
|
|
await fetchLyList();
|
|
|
|
|
|
|
|
|
|
|
|
// 沿程模式获取断面列表
|
|
|
|
|
|
if (props.ly) {
|
|
|
|
|
|
await fetchDmList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取 Tab 数量
|
|
|
|
|
|
await getTabNumData();
|
|
|
|
|
|
|
|
|
|
|
|
// 执行首次查询
|
|
|
|
|
|
handleSearch();
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.yancheng-yulei {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
.search-form {
|
|
|
|
|
|
padding: 16px 0;
|
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ylycbh-tabs {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.ant-tabs-content) {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.ant-tabs-tabpane) {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.table-wrapper {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.text-link {
|
|
|
|
|
|
color: #1990ff;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
color: #40a9ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|