过鱼设施改动和用户权限改动
This commit is contained in:
parent
a8456cea47
commit
f4c57d380c
@ -7,7 +7,7 @@ VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台'
|
||||
VITE_APP_PORT = 3000
|
||||
VITE_APP_BASE_API = '/dev-api'
|
||||
# 本地环境
|
||||
# VITE_APP_BASE_URL = 'http://localhost:8093'
|
||||
# VITE_APP_BASE_URL = 'http://10.84.121.122:8093'
|
||||
# 测试环境
|
||||
# VITE_APP_BASE_URL = 'http://172.16.21.142:8093'
|
||||
# VITE_APP_BASE_URL = 'http://172.16.21.142:8096'
|
||||
|
||||
@ -52,7 +52,7 @@ export function registerUser(data: any): AxiosPromise<any> {
|
||||
*/
|
||||
export function getBasinList(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/env/hbrv/regDropdown',
|
||||
url: '/env/rvcd/regDropdown',
|
||||
method: 'get',
|
||||
// params: baseid ? { baseid } : {}
|
||||
});
|
||||
|
||||
17
frontend/src/api/gyss/index.ts
Normal file
17
frontend/src/api/gyss/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import request from '@/utils/request';
|
||||
//过鱼设施介绍
|
||||
export function vmsstbprptGetKendoList(data: any) {
|
||||
return request({
|
||||
url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
//过鱼设施
|
||||
export function buildGetKendoListCust(data: any) {
|
||||
return request({
|
||||
url: '/api/wmp-env-server/env/fp/build/GetKendoListCust',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
@ -11,7 +11,7 @@ export function getBaseDropdown(data:any) {
|
||||
// 流域下拉列表
|
||||
export function getSelectForDropdown(data:any) {
|
||||
return request({
|
||||
url: '/env/hbrv/selectForDropdown',
|
||||
url: '/env/rvcd/selectForDropdown',
|
||||
method: 'get',
|
||||
data
|
||||
});
|
||||
|
||||
@ -113,7 +113,7 @@ export function updatePassword (queryParams:any) {
|
||||
//获取过鱼设施权限树
|
||||
export function getFishtree(queryParams:any) {
|
||||
return request({
|
||||
url: '/env/tree/hbrvEng',
|
||||
url: '/env/tree/rvcdEng',
|
||||
method: 'get',
|
||||
params: queryParams
|
||||
});
|
||||
|
||||
@ -96,21 +96,22 @@
|
||||
</a-select> -->
|
||||
<!-- 流域下拉框 -->
|
||||
<a-select
|
||||
:value="formData.hbrvcd"
|
||||
:value="formData.rvcd"
|
||||
placeholder="请选择"
|
||||
@change="lyChange"
|
||||
show-search
|
||||
:loading="shuJuTianBaoStore.lyLoading"
|
||||
:filter-option="filterOption"
|
||||
style="width: 135px"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto', minWidth: '360px' }"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in shuJuTianBaoStore.lyOption"
|
||||
:key="opt.hbrvcd"
|
||||
:value="opt.hbrvcd"
|
||||
:label="opt.hbrvnm"
|
||||
:key="opt.rvcd"
|
||||
:value="opt.rvcd"
|
||||
:label="opt.rvnm"
|
||||
>
|
||||
{{ opt.hbrvnm }}
|
||||
{{ opt.rvnm }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<!-- 电站下拉框 -->
|
||||
@ -329,7 +330,7 @@ const initForm = () => {
|
||||
// 下拉菜单
|
||||
// shuJuTianBaoStore.getBaseOption();
|
||||
shuJuTianBaoStore.getSelectForOption();
|
||||
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
||||
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
||||
}
|
||||
if (item.fieldProps?.required) {
|
||||
rules[item.name] = [
|
||||
@ -362,23 +363,23 @@ const triggerManualValuesChange = (changedKey: string, newValue: any) => {
|
||||
// };
|
||||
|
||||
const lyChange = (value: any) => {
|
||||
formData.hbrvcd = value;
|
||||
formData.rvcd = value;
|
||||
formData.rstcd = "";
|
||||
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
||||
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
||||
|
||||
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
||||
triggerManualValuesChange("hbrvcd", formData.hbrvcd);
|
||||
triggerManualValuesChange("rvcd", formData.rvcd);
|
||||
};
|
||||
|
||||
const stcdIdChange = (value: any) => {
|
||||
if (props.zhujianfujian == "fu") {
|
||||
formData.rstcd = value;
|
||||
shuJuTianBaoStore.getFpssOption(formData.hbrvcd, value);
|
||||
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
||||
// 【关键修改】手动触发 valuesChange
|
||||
triggerManualValuesChange("rstcd", formData.rstcd);
|
||||
} else {
|
||||
formData.stcd = value;
|
||||
shuJuTianBaoStore.getFpssOption(formData.hbrvcd, value);
|
||||
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
||||
// 【关键修改】手动触发 valuesChange
|
||||
triggerManualValuesChange("stcd", formData.stcd);
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@ const FPTabs: Array<any> =
|
||||
name: '基础信息',
|
||||
key: 'basicInfo',
|
||||
type: 'basic',
|
||||
url: '/bbi/siteBipc/getSiteBasicInfo',
|
||||
code: 'gyss.tabs.jcxx'
|
||||
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
|
||||
// code: 'gyss.tabs.jcxx'
|
||||
},
|
||||
// {
|
||||
// name: '实时视频',
|
||||
@ -1018,7 +1018,7 @@ const videoTabs: Array<any> = [
|
||||
name: '基础信息',
|
||||
key: 'basicInfo',
|
||||
type: 'basic',
|
||||
url: '/bbi/siteBipc/getSiteBasicInfo',
|
||||
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
|
||||
default: true, // 默认显示
|
||||
},
|
||||
{
|
||||
|
||||
@ -17,7 +17,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card_right">
|
||||
<div style="width: 100%;display:flex;align-items: center;">
|
||||
<div class="card_text_title"></div>
|
||||
<div class="card_text_title_zi">{{ currentTitle }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card_text_content">
|
||||
{{ currentDescription }}
|
||||
</div>
|
||||
@ -115,7 +119,9 @@ const jumpToSlide = (targetIndex: number) => {
|
||||
const currentDescription = computed(() => {
|
||||
return originalMediaData.value[currentIndex.value]?.description || '';
|
||||
});
|
||||
|
||||
const currentTitle = computed(() => {
|
||||
return originalMediaData.value[currentIndex.value]?.title || '';
|
||||
});
|
||||
// 页面加载时执行
|
||||
onMounted(() => {
|
||||
console.log('ArtsDetail mounted - props.index:', props.index, 'props.dataSource.length:', props.dataSource?.length);
|
||||
@ -223,6 +229,16 @@ watch(
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card_text_title_zi {
|
||||
font-size: 28px;
|
||||
// line-height: 36px;
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
position: relative;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
|
||||
.card_text_content {
|
||||
width: 100%;
|
||||
height: 96%;
|
||||
|
||||
@ -716,7 +716,6 @@ watch(
|
||||
formState.sfdb = ''
|
||||
formState.stnm = ''
|
||||
pieCode.value = []
|
||||
debugger
|
||||
// 重新加载数据
|
||||
nextTick(() => {
|
||||
handleSearch()
|
||||
|
||||
114
frontend/src/modules/guoyujiance/components/FPVDDetailMD.vue
Normal file
114
frontend/src/modules/guoyujiance/components/FPVDDetailMD.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<!-- SidePanelItem.vue -->
|
||||
<template>
|
||||
<!-- 数据表格 -->
|
||||
<BasicTable ref="tableRef" :scroll-y="400" :columns="columns" :list-url="vmsstbprptGetKendoList" :search-params="{}"
|
||||
:transform-data="customTransform">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<a @click="handleViewDetail(record)" class="text-link">
|
||||
查看详情
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||
import { vmsstbprptGetKendoList } from '@/api/gyss'
|
||||
import BasicTable from '@/components/BasicTable/index.vue'
|
||||
import { useModelStore } from "@/store/modules/model";
|
||||
|
||||
const modelStore = useModelStore();
|
||||
// 定义组件名(便于调试和递归)
|
||||
defineOptions({
|
||||
name: 'guoyusheshijiansheqingkuang'
|
||||
});
|
||||
const props = defineProps<{
|
||||
baseid: any,
|
||||
currentItem: any
|
||||
}>()
|
||||
const columns = ref([
|
||||
{
|
||||
key: 'stnm',
|
||||
dataIndex: 'stnm',
|
||||
title: '名称',
|
||||
},
|
||||
{
|
||||
key: 'ennm',
|
||||
dataIndex: 'ennm',
|
||||
title: '所属电站',
|
||||
},
|
||||
{
|
||||
key: 'stlc',
|
||||
dataIndex: 'stlc',
|
||||
title: '位置',
|
||||
},
|
||||
{
|
||||
key: 'action',
|
||||
title: '操作',
|
||||
width: 100,
|
||||
align: 'center' as const,
|
||||
fixed: 'right' as const
|
||||
}
|
||||
])
|
||||
const tableRef = ref()
|
||||
|
||||
// 自定义数据转换
|
||||
const customTransform = (res: any) => {
|
||||
return {
|
||||
records: res?.data?.data || [],
|
||||
total: res?.data?.total || 0
|
||||
}
|
||||
}
|
||||
// 查看详情
|
||||
const handleViewDetail = (record: any) => {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "stinfo_ai_video_point";
|
||||
modelStore.title = record.stnm + "详情信息";
|
||||
modelStore.params.stcd = record.stcd;
|
||||
}
|
||||
// 页面加载时执行
|
||||
onMounted(() => {
|
||||
// const props = defineProps<{
|
||||
// baseid: any,
|
||||
// currentItem: any
|
||||
// }>()
|
||||
// 延迟初始化,确保容器已渲染
|
||||
const filter = {
|
||||
"logic": "and",
|
||||
"filters": [
|
||||
{
|
||||
"field": "sttpCode",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": props.currentItem.sttp
|
||||
},
|
||||
props.baseid != 'all' ? {
|
||||
"field": "baseId",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": props.baseid,
|
||||
} : null
|
||||
].filter(Boolean)
|
||||
}
|
||||
tableRef.value?.getList(filter)
|
||||
});
|
||||
|
||||
// 组件卸载时清理
|
||||
onUnmounted(() => {
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-link {
|
||||
color: #2f6b98;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,8 +1,12 @@
|
||||
<!-- SidePanelItem.vue -->
|
||||
<template>
|
||||
<SidePanelItem title="过鱼监测">
|
||||
<div class="facility-grid">
|
||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card">
|
||||
<div v-if="loading" class="loading-container">
|
||||
<a-spin tip="加载中..." />
|
||||
</div>
|
||||
<div v-else class="facility-grid">
|
||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card"
|
||||
@click="handleCardClick(facility)">
|
||||
<div style="width: 70px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
||||
<div class="facility-icon">
|
||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
||||
@ -17,51 +21,76 @@
|
||||
</div>
|
||||
</div>
|
||||
</SidePanelItem>
|
||||
|
||||
<!-- 详情弹框 -->
|
||||
<a-modal v-model:open="modalVisible" title="详情" width="1536px" :footer="null" destroy-on-close>
|
||||
<div class="modal-content">
|
||||
<FPVDDetailMD :baseid="baseid" :currentItem="selectedFacility" />
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
|
||||
import { vmsstbprptGetKendoList } from '@/api/gyss'
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import FPVDDetailMD from './components/FPVDDetailMD.vue'
|
||||
// 定义组件名(便于调试和递归)
|
||||
defineOptions({
|
||||
name: 'guoyusheshijiansheqingkuang'
|
||||
});
|
||||
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
// 设施数据
|
||||
const facilities = ref([
|
||||
{
|
||||
name: '视频监控',
|
||||
count: 56,
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-shipinjiankongshebei'
|
||||
, sttp: 'VD_FP'
|
||||
},
|
||||
{
|
||||
name: 'AI摄像头',
|
||||
count: 1722,
|
||||
icon: 'icon iconfont icon-jiankong'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-jiankong', sttp: 'VD_WVD'
|
||||
},
|
||||
{
|
||||
name: '声纳',
|
||||
count: 135,
|
||||
icon: 'icon iconfont icon-dwsjhQianzhidangqiang'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-dwsjhQianzhidangqiang', sttp: 'VD_SN'
|
||||
},
|
||||
{
|
||||
name: '水质设备',
|
||||
count: 135,
|
||||
count: 5,
|
||||
icon: 'icon iconfont icon-shuizhijiancezhan'
|
||||
},
|
||||
{
|
||||
name: '水文设备',
|
||||
count: 56,
|
||||
count: 8,
|
||||
icon: 'icon iconfont icon-guojiashuizhizhan'
|
||||
},
|
||||
{
|
||||
name: '气象设备',
|
||||
count: 1722,
|
||||
count: 4,
|
||||
icon: 'icon iconfont icon-qixiangzhan'
|
||||
},
|
||||
|
||||
]);
|
||||
const baseid = ref('all');
|
||||
const loading = ref(false);
|
||||
const modalVisible = ref(false);
|
||||
const selectedFacility = ref<any>(null);
|
||||
const title = ref('');
|
||||
// 处理卡片点击事件
|
||||
const handleCardClick = (facility: any) => {
|
||||
selectedFacility.value = facility;
|
||||
title.value = facility.name;
|
||||
if (facility.sttp) {
|
||||
modalVisible.value = true;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
// 页面加载时执行
|
||||
onMounted(() => {
|
||||
@ -73,6 +102,104 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
|
||||
});
|
||||
const getdata = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
let params = {
|
||||
"filter": {
|
||||
"logic": "and",
|
||||
"filters": [
|
||||
{
|
||||
"field": "sttpCode",
|
||||
"operator": "in",
|
||||
"dataType": "string",
|
||||
"value": [
|
||||
"VD_FP",
|
||||
"VD_WVD",
|
||||
"VD_SN"
|
||||
]
|
||||
},
|
||||
baseid.value != 'all' ? {
|
||||
"field": "baseId",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": baseid.value
|
||||
} : null
|
||||
].filter(Boolean),
|
||||
},
|
||||
"group": [
|
||||
{
|
||||
"dir": "desc",
|
||||
"field": "sttpCode"
|
||||
}
|
||||
],
|
||||
"groupResultFlat": true
|
||||
}
|
||||
let res = await vmsstbprptGetKendoList(params)
|
||||
|
||||
// 处理返回数据,将 count_sttpCode 匹配到 facilities 的 count
|
||||
if (res?.data?.data) {
|
||||
const countData = res.data.data;
|
||||
|
||||
// 遍历返回的统计数据
|
||||
countData.forEach((item: any) => {
|
||||
// 在 facilities 中找到对应的设施
|
||||
const facility = facilities.value.find(f => f.sttp === item.sttpCode);
|
||||
if (facility) {
|
||||
// 更新 count 值
|
||||
facility.count = item.count_sttpCode || 0;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
facilities.value = [
|
||||
{
|
||||
name: '视频监控',
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-shipinjiankongshebei'
|
||||
, sttp: 'VD_FP'
|
||||
},
|
||||
{
|
||||
name: 'AI摄像头',
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-jiankong', sttp: 'VD_WVD'
|
||||
},
|
||||
{
|
||||
name: '声纳',
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-dwsjhQianzhidangqiang', sttp: 'VD_SN'
|
||||
},
|
||||
{
|
||||
name: '水质设备',
|
||||
count: 5,
|
||||
icon: 'icon iconfont icon-shuizhijiancezhan'
|
||||
},
|
||||
{
|
||||
name: '水文设备',
|
||||
count: 8,
|
||||
icon: 'icon iconfont icon-guojiashuizhizhan'
|
||||
},
|
||||
{
|
||||
name: '气象设备',
|
||||
count: 4,
|
||||
icon: 'icon iconfont icon-qixiangzhan'
|
||||
},
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
baseid.value = newVal.wbsCode;
|
||||
getdata()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -131,4 +258,11 @@ onUnmounted(() => {
|
||||
color: #2f6b98;
|
||||
// font-weight: 600;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 200px;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="gyss-container">
|
||||
<!-- 搜索表单 -->
|
||||
<a-form layout="inline" class="search-form">
|
||||
<a-form-item label="设施类型">
|
||||
<a-select v-model:value="filterOpts.dwtp" placeholder="请选择设施类型" style="width: 150px"
|
||||
:options="facilityTypeOptions" />
|
||||
</a-form-item>
|
||||
<a-form-item label="所属基地">
|
||||
<a-select v-model:value="filterOpts.baseId" placeholder="请选择所属基地" style="width: 200px" show-search
|
||||
:filter-option="filterOption" :options="jdInfoOpt" />
|
||||
</a-form-item>
|
||||
<a-form-item label="建设状态">
|
||||
<a-select v-model:value="filterOpts.bldstt" placeholder="请选择建设状态" style="width: 150px"
|
||||
:options="buildStateOptions" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-input v-model:value="filterOpts.searchContent" placeholder="请输入设施名称" style="width: 200px"
|
||||
allow-clear />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||||
<a-tooltip title="重置">
|
||||
<a-button @click="handleReset">重置</a-button>
|
||||
</a-tooltip>
|
||||
<!-- TODO: 导出功能 - 需要实现 ExportBtnFile 组件 -->
|
||||
<!-- <ExportBtnFile
|
||||
:table-ref="tableRef"
|
||||
:export-url="exportUrl"
|
||||
file-name="过鱼设施建设及接入情况"
|
||||
/> -->
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<BasicTable ref="tableRef" :scroll-y="400" :columns="columns" :list-url="vmsstbprptGetKendoList"
|
||||
:enable-sort="true" :search-params="searchParams" :transform-data="customTransform"
|
||||
@sort-change="handleSortChange">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'ennm'">
|
||||
<a @click="handleViewDetail(record, 'dz')" class="text-link">
|
||||
{{ record.ennm }}
|
||||
</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a @click="handleViewDetail(record, 'other')" class="text-link">
|
||||
查看详情
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, nextTick } from 'vue'
|
||||
import BasicTable from '@/components/BasicTable/index.vue'
|
||||
// TODO: API 接口 - 需要在 @/api/gyss 中实现
|
||||
import { vmsstbprptGetKendoList } from '@/api/gyss'
|
||||
import { useModelStore } from "@/store/modules/model";
|
||||
|
||||
const modelStore = useModelStore();
|
||||
// ==================== Props 定义 ====================
|
||||
const props = defineProps<{
|
||||
data?: any
|
||||
jdId?: any
|
||||
jrzt?: string
|
||||
}>()
|
||||
|
||||
// ==================== 状态管理 ====================
|
||||
const tableRef = ref()
|
||||
const mapModal = ref(false)
|
||||
const modaldata = ref<any>({})
|
||||
|
||||
// 筛选条件
|
||||
const filterOpts = ref({
|
||||
dwtp: '', // 设施类型
|
||||
baseId: 'all', // 所属基地
|
||||
bldstt: '', // 建设状态
|
||||
bonusing: '', // 接入状态(预留)
|
||||
searchContent: '' // 搜索文本
|
||||
})
|
||||
|
||||
// 排序状态
|
||||
const sortState = ref<{ field: string; order: string } | null>(null)
|
||||
|
||||
// ==================== 基地列表数据(硬编码)====================
|
||||
const jdInfoOpt = ref<any[]>([
|
||||
{ value: 'all', label: '当前全部' },
|
||||
{ value: '01', label: '金沙江干流' },
|
||||
{ value: '02', label: '雅砻江干流' },
|
||||
{ value: '03', label: '大渡河干流' },
|
||||
{ value: '04', label: '乌江干流' },
|
||||
{ value: '05', label: '长江上游干流' },
|
||||
{ value: '10', label: '湘西' },
|
||||
{ value: '08', label: '黄河上游干流' },
|
||||
{ value: '09', label: '黄河中游干流' },
|
||||
{ value: '06', label: '南盘江-红水河' },
|
||||
{ value: '12', label: '东北' },
|
||||
{ value: '07', label: '澜沧江干流' },
|
||||
{ value: '13', label: '怒江干流' },
|
||||
{ value: '11', label: '闽浙赣' },
|
||||
{ value: 'other', label: '其他' }
|
||||
])
|
||||
|
||||
// ==================== 常量配置 ====================
|
||||
// 设施类型选项
|
||||
const facilityTypeOptions = [
|
||||
{ label: '全部', value: '' },
|
||||
{ label: '鱼道', value: 'FP_1' },
|
||||
{ label: '集运鱼系统', value: 'FP_3' },
|
||||
{ label: '升鱼机', value: 'FP_4' },
|
||||
{ label: '其他', value: 'FP_5' }
|
||||
]
|
||||
|
||||
// 建设状态选项
|
||||
const buildStateOptions = [
|
||||
{ label: '全部', value: '' },
|
||||
{ label: '在建', value: '1' },
|
||||
{ label: '已建', value: '2' }
|
||||
]
|
||||
// ==================== 表格列定义 ====================
|
||||
const columns = [
|
||||
{
|
||||
key: 'stnm',
|
||||
title: '设施名称',
|
||||
dataIndex: 'stnm',
|
||||
width: 200,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'baseName',
|
||||
title: '所在基地名称',
|
||||
dataIndex: 'baseName',
|
||||
width: 150,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'ennm',
|
||||
title: '所属电站名称',
|
||||
dataIndex: 'ennm',
|
||||
width: 150,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'ststdt',
|
||||
title: '开工日期',
|
||||
dataIndex: 'ststdt',
|
||||
width: 120,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'jcdt',
|
||||
title: '建成日期',
|
||||
dataIndex: 'jcdt',
|
||||
width: 120,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'bldsttCcodeName',
|
||||
title: '建设状态',
|
||||
dataIndex: 'bldsttCcodeName',
|
||||
width: 100,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'dtinName',
|
||||
title: '接入状态',
|
||||
dataIndex: 'dtinName',
|
||||
width: 100,
|
||||
sorter: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'action',
|
||||
title: '操作',
|
||||
width: 100,
|
||||
align: 'center' as const,
|
||||
fixed: 'right' as const
|
||||
}
|
||||
]
|
||||
|
||||
// ==================== 计算属性 ====================
|
||||
// 搜索参数(包含排序)
|
||||
const searchParams = computed(() => {
|
||||
const params: any = {
|
||||
group: [],
|
||||
groupResultFlat: false,
|
||||
select: []
|
||||
}
|
||||
|
||||
if (sortState.value) {
|
||||
// 用户自定义排序
|
||||
params.sort = [{
|
||||
field: sortState.value.field,
|
||||
dir: sortState.value.order === 'ascend' ? 'asc' : 'desc'
|
||||
}]
|
||||
} else {
|
||||
// 默认排序
|
||||
params.sort = null
|
||||
}
|
||||
|
||||
return params
|
||||
})
|
||||
|
||||
// ==================== 方法定义 ====================
|
||||
// 下拉框过滤
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
|
||||
// 构建过滤条件
|
||||
const buildFilter = () => {
|
||||
const filters: any[] = [
|
||||
{
|
||||
field: 'sttpFullPath',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: 'ENV,ENVP,FP,FP'
|
||||
},
|
||||
filterOpts.value.baseId !== 'all' && {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: filterOpts.value.baseId
|
||||
},
|
||||
filterOpts.value.bldstt && {
|
||||
field: 'bldsttCcode',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: filterOpts.value.bldstt
|
||||
},
|
||||
filterOpts.value.searchContent && {
|
||||
logic: 'or',
|
||||
filters: [
|
||||
{
|
||||
field: 'stnm',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: filterOpts.value.searchContent
|
||||
},
|
||||
{
|
||||
field: 'ennm',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: filterOpts.value.searchContent
|
||||
}
|
||||
]
|
||||
},
|
||||
filterOpts.value.dwtp && {
|
||||
field: 'sttpCode',
|
||||
operator: filterOpts.value.dwtp === 'FP_5' ? 'in' : 'eq',
|
||||
dataType: 'string',
|
||||
value: filterOpts.value.dwtp === 'FP_5' ? ['FP_5', 'FP_2'] : filterOpts.value.dwtp
|
||||
},
|
||||
// TODO: 接入状态筛选(当前已注释)
|
||||
// filterOpts.value.bonusing && {
|
||||
// field: 'dtin',
|
||||
// operator: 'eq',
|
||||
// dataType: 'string',
|
||||
// value: filterOpts.value.bonusing
|
||||
// }
|
||||
].filter(Boolean)
|
||||
|
||||
return {
|
||||
logic: 'and',
|
||||
filters
|
||||
}
|
||||
}
|
||||
|
||||
// 处理排序变化
|
||||
const handleSortChange = (info: { field: string; order: string | null }) => {
|
||||
// debugger
|
||||
if (info.field && info.order) {
|
||||
sortState.value = info
|
||||
} else {
|
||||
sortState.value = null // 恢复默认排序
|
||||
}
|
||||
nextTick(() => {
|
||||
handleSearch()
|
||||
})
|
||||
}
|
||||
|
||||
// 查询
|
||||
const handleSearch = () => {
|
||||
console.log('【搜索】', filterOpts.value)
|
||||
const filter = buildFilter()
|
||||
tableRef.value?.getList(filter)
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
console.log('【重置】')
|
||||
filterOpts.value = {
|
||||
dwtp: '',
|
||||
baseId: 'all',
|
||||
bldstt: '',
|
||||
bonusing: '',
|
||||
searchContent: ''
|
||||
}
|
||||
sortState.value = null // 重置排序状态
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleViewDetail = (record: any, type: string) => {
|
||||
if (type === 'dz') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "ENG";
|
||||
modelStore.title = record.ennm + " 详情信息";
|
||||
modelStore.params.stcd = record.rstcd;
|
||||
} else {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "fp_point";
|
||||
modelStore.title = record.stnm + "详情信息";
|
||||
modelStore.params.stcd = record.stcd;
|
||||
}
|
||||
// console.log('【查看详情】', record)
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const handleCloseModal = () => {
|
||||
mapModal.value = false
|
||||
modaldata.value = {}
|
||||
}
|
||||
|
||||
// 自定义数据转换
|
||||
const customTransform = (res: any) => {
|
||||
return {
|
||||
records: res?.data?.data || [],
|
||||
total: res?.data?.total || 0
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 生命周期 ====================
|
||||
onMounted(() => {
|
||||
// 基地列表已在上方硬编码定义(jdInfoOpt),无需从缓存获取
|
||||
filterOpts.value.dwtp = props.data.key
|
||||
// 初始加载数据
|
||||
handleSearch()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyss-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search-form {
|
||||
padding: 16px 0px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-wrapper) {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.text-link {
|
||||
color: #2f6b98;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,9 +1,11 @@
|
||||
<!-- SidePanelItem.vue -->
|
||||
<template>
|
||||
<SidePanelItem title="过鱼设施">
|
||||
<a-spin :spinning="loading" tip="加载中...">
|
||||
<div class="facility-grid">
|
||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card">
|
||||
<div style="width: 70px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card"
|
||||
@click="handleFacilityClick(facility)">
|
||||
<div style="width: 60px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
||||
<div class="facility-icon">
|
||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
||||
</div>
|
||||
@ -16,43 +18,118 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</SidePanelItem>
|
||||
<!-- 弹框 -->
|
||||
<a-modal v-model:open="modalVisible" :title="'过鱼设施'" :footer="null" width="1536px" @cancel="handleCloseModal">
|
||||
<ModalPage v-if="currentFacility" :data="currentFacility" :jdId="'all'" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import { buildGetKendoListCust } from '@/api/gyss';
|
||||
import ModalPage from './ModalPage/index.vue'
|
||||
// 定义组件名(便于调试和递归)
|
||||
defineOptions({
|
||||
name: 'guoyusheshijiansheqingkuang'
|
||||
name: 'qixidibaohugongzuokaizhanQK'
|
||||
});
|
||||
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
// loading状态
|
||||
const loading = ref(false);
|
||||
// 设施数据
|
||||
const facilities = ref([
|
||||
{
|
||||
name: '鱼道',
|
||||
count: 56,
|
||||
icon: 'icon iconfont icon-map-gyssYudao'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-map-gyssYudao',
|
||||
key: 'FP_1'
|
||||
},
|
||||
{
|
||||
name: '集运鱼系统',
|
||||
count: 1722,
|
||||
icon: 'icon iconfont icon-map-gyssJiyunyuxitong'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-map-gyssJiyunyuxitong',
|
||||
key: 'FP_3'
|
||||
},
|
||||
{
|
||||
name: '升鱼机',
|
||||
count: 135,
|
||||
icon: 'icon iconfont icon-map-gyssShengyuji'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-map-gyssShengyuji',
|
||||
key: 'FP_4'
|
||||
},
|
||||
{
|
||||
name: '其他',
|
||||
count: 135,
|
||||
icon: 'icon iconfont icon-map-gyssQita'
|
||||
count: 0,
|
||||
icon: 'icon iconfont icon-map-gyssQita',
|
||||
key: 'FP_5'
|
||||
},
|
||||
|
||||
]);
|
||||
const baseid = ref('')
|
||||
// 弹框相关状态
|
||||
const modalVisible = ref(false);
|
||||
const currentFacility = ref<any>(null);
|
||||
//获取页面数据
|
||||
const getData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
let params = {
|
||||
"filter": {
|
||||
"logic": "and",
|
||||
"filters": []
|
||||
}
|
||||
}
|
||||
const res = await buildGetKendoListCust(params); //适配监控-VD
|
||||
let data = res?.data?.data || res?.data || [];
|
||||
|
||||
// 重置所有设施的count为0
|
||||
facilities.value.forEach(facility => {
|
||||
facility.count = 0;
|
||||
});
|
||||
|
||||
// 遍历接口返回的所有数据
|
||||
data.forEach(item => {
|
||||
const matchedFacility = facilities.value.find(facility => facility.key === item.sttpCode);
|
||||
if (matchedFacility) {
|
||||
// 如果在facilities中找到对应的key,累加到该设施
|
||||
matchedFacility.count += Number(item.built) + Number(item.building) || 0;
|
||||
} else {
|
||||
// 如果没有找到对应的key,累加到FP_5(其他)
|
||||
const otherFacility = facilities.value.find(facility => facility.key === 'FP_5');
|
||||
if (otherFacility) {
|
||||
otherFacility.count += Number(item.built) + Number(item.building) || 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
// 点击处理函数
|
||||
const handleFacilityClick = (facility: any) => {
|
||||
currentFacility.value = facility;
|
||||
modalVisible.value = true;
|
||||
|
||||
|
||||
};
|
||||
// 关闭弹框
|
||||
const handleCloseModal = () => {
|
||||
modalVisible.value = false;
|
||||
currentFacility.value = null;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
baseid.value = newVal.wbsCode;
|
||||
getData()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
// 页面加载时执行
|
||||
onMounted(() => {
|
||||
// 延迟初始化,确保容器已渲染
|
||||
@ -96,7 +173,7 @@ onUnmounted(() => {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
// margin-right: 8px;
|
||||
background: rgb(47, 107, 152);
|
||||
background: #5389b5;
|
||||
border-radius: 50%;
|
||||
|
||||
.anticon {
|
||||
|
||||
@ -1,128 +1,187 @@
|
||||
<!-- SidePanelItem.vue -->
|
||||
<template>
|
||||
<SidePanelItem title="过鱼设施介绍">
|
||||
<div class="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
||||
<!-- Loading 和空状态容器 -->
|
||||
<a-spin :spinning="loading" class="carousel-container-wrapper">
|
||||
<div v-if="hasData" class="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
||||
<!-- 跑马灯轨道容器 -->
|
||||
<div class="carousel-track" :class="{ 'no-transition': isTransitioning }"
|
||||
:style="{ transform: `translateX(-${currentIndex * 100}%)` }">
|
||||
<!-- 遍历所有媒体项(包含克隆项) -->
|
||||
<div v-for="(item, index) in renderMediaData" :key="index" class="carousel-item">
|
||||
<div v-for="(item, index) in renderMediaData" :key="index" class="carousel-item"
|
||||
@click="handleItemClick(originalMediaData)">
|
||||
<!-- 图片 -->
|
||||
<img :src="item.url" alt="" />
|
||||
<img :src="item.url" :alt="item.stnm" loading="lazy" />
|
||||
<!-- 说明文字(随媒体项移动) -->
|
||||
<div class="text">{{ item.text }}</div>
|
||||
<div class="text">{{ item.stnm }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 面板指示器(固定在底部右侧) -->
|
||||
<div class="pagination-dots-fixed">
|
||||
<span
|
||||
v-for="(dot, index) in originalMediaData"
|
||||
:key="index"
|
||||
class="dot"
|
||||
:class="{ active: getCurrentRealIndex() === index }"
|
||||
@click="goToSlide(index)"
|
||||
></span>
|
||||
<span v-for="(dot, index) in originalMediaData" :key="index" class="dot"
|
||||
:class="{ active: currentRealIndex === index }" @click="goToSlide(index)"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 暂无数据状态 -->
|
||||
|
||||
<!-- 独立的文字说明区域(随跑马灯切换而变化) -->
|
||||
<div class="description-text">
|
||||
<div v-if="hasData" class="description-text" @click="handleItemClick(originalMediaData)">
|
||||
{{ currentDescription }}
|
||||
</div>
|
||||
<a-empty v-else description="暂无数据" :image="simpleImage" />
|
||||
</a-spin>
|
||||
</SidePanelItem>
|
||||
<!-- 设施详情弹框 -->
|
||||
<a-modal v-model:open="modalVisible" :title="'设施类型介绍'" width="1536px" :footer="null">
|
||||
<!-- 你在这里编写弹框内容 -->
|
||||
<div v-if="currentItem">
|
||||
<ArtsDetail :dataSource='currentItem' :index="getCurrentRealIndex()" />
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
|
||||
// 定义组件名(便于调试和递归)
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import { vmsstbprptGetKendoList } from '@/api/gyss';
|
||||
import ArtsDetail from '@/components/carouselIntroduce/ArtsDetail.vue';
|
||||
import { Empty } from 'ant-design-vue';
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
interface MediaItem {
|
||||
url: string;
|
||||
stnm: string;
|
||||
introduce: string;
|
||||
}
|
||||
|
||||
interface CarouselConfig {
|
||||
autoPlayInterval: number;
|
||||
transitionDuration: number;
|
||||
}
|
||||
|
||||
// ==================== 常量配置 ====================
|
||||
const CAROUSEL_CONFIG: CarouselConfig = {
|
||||
autoPlayInterval: 4000, // 自动轮播间隔 4秒
|
||||
transitionDuration: 500 // 过渡动画时长 500ms
|
||||
};
|
||||
|
||||
// ==================== Store 和基础配置 ====================
|
||||
defineOptions({
|
||||
name: 'ZhiWuYuanJianSheJiJieRuQingKuangBar'
|
||||
});
|
||||
|
||||
// 媒体类型定义
|
||||
interface MediaItem {
|
||||
type: 'image' | 'video';
|
||||
url: string;
|
||||
text: string;
|
||||
description: string;
|
||||
}
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
const baseid = ref('all'); // 默认值为 'all'
|
||||
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||
// 弹框控制
|
||||
const modalVisible = ref(false);
|
||||
const currentItem = ref<any>(null);
|
||||
// ==================== 数据状态 ====================
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 是否有数据
|
||||
const hasData = ref(false);
|
||||
// 空状态图片
|
||||
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
// 原始媒体数据(3条测试数据)
|
||||
const originalMediaData = ref<MediaItem[]>([
|
||||
{
|
||||
type: 'image',
|
||||
url: 'https://211.99.26.225:12125/?20240328104745462272538202651107&view=jpg&token=bearer 50b652db-035b-43a9-becd-48b7d54aa941',
|
||||
text: '铜街子鱼道',
|
||||
description: '鱼道布置在河床右岸,全长 1388.32m,由鱼道进口、进口段、绕过木阀闸段、坝后开挖段、过坝段、出口明渠段、鱼道出口组成。鱼道布置 1 个进口和 1 个出口,其中进口位于新华电站尾水渠下游约15m 处。出口位于库区右岸,距离坝轴线约 150m。'
|
||||
},
|
||||
{
|
||||
type: 'video',
|
||||
url: 'https://211.99.26.225:12125/?20240328104800052128627215562160&view=jpg&token=bearer 50b652db-035b-43a9-becd-48b7d54aa941', // 视频URL示例,您可替换为真实地址
|
||||
text: '枕头坝一级鱼道',
|
||||
description: '枕头坝一级鱼道建筑物主要由鱼道进口、梯身、鱼道出口等组成。全长1300m、池室坡度i=0.033、鱼道净宽2.4m、池室长度为3m,每隔10个水池设立一个长6m的休息池,池室隔墙厚度为0.20m,高3.00m;设置3个进口,进口断面尺寸为2.40×3.00m(宽×高)。'
|
||||
},
|
||||
{
|
||||
type: 'image',
|
||||
url: 'https://211.99.26.225:12125/?20240328104800052128627215562160&view=jpg&token=bearer 50b652db-035b-43a9-becd-48b7d54aa941',
|
||||
text: '沙坪二级鱼道',
|
||||
description: '沙坪二级鱼道位于泄洪闸与厂房之间,鱼道上下游方向长 224.42m,宽 10.0m~14.0m,最大高度 29.85m~37.00m。鱼道由诱鱼系统、入口、池室、休息池、观察室和出口等组成,其中诱鱼系统和入口布置于下游厂房尾水侧,出口布置于上游泄洪闸进口侧。鱼道采取连续“绕弯”方式布置,全长 597m,平均坡降为 3.85%。沙坪二级鱼道位于泄洪闸与厂房之间,鱼道上下游方向长 224.42m,宽 10.0m~14.0m,最大高度 29.85m~37.00m。鱼道由诱鱼系统、入口、池室、休息池、观察室和出口等组成,其中诱鱼系统和入口布置于下游厂房尾水侧,出口布置于上游泄洪闸进口侧。鱼道采取连续“绕弯”方式布置,全长 597m,平均坡降为 3.85%。'
|
||||
}
|
||||
]);
|
||||
|
||||
// 克隆首尾项后的渲染数组(用于无缝循环)
|
||||
// 结构:[最后一项克隆, 原始数据..., 第一项克隆]
|
||||
const renderMediaData = ref<MediaItem[]>([]);
|
||||
// 原始媒体数据
|
||||
const originalMediaData = ref<MediaItem[]>([]);
|
||||
|
||||
// 当前显示索引(指向renderMediaData)
|
||||
const currentIndex = ref(1); // 从1开始,跳过克隆的首项
|
||||
|
||||
// 定时器引用
|
||||
let timer: any = null;
|
||||
// 是否正在切换动画中(用于禁用transition)
|
||||
const isTransitioning = ref(false);
|
||||
|
||||
// 鼠标悬停状态
|
||||
const isHovering = ref(false);
|
||||
|
||||
// 是否正在切换动画中(用于禁用transition)
|
||||
const isTransitioning = ref(false);
|
||||
// 定时器引用
|
||||
let autoPlayTimer: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
// 初始化渲染数组(克隆首尾项)
|
||||
const initRenderData = () => {
|
||||
// ==================== 计算属性 ====================
|
||||
/**
|
||||
* 克隆首尾项后的渲染数组(用于无缝循环)
|
||||
* 结构:[最后一项克隆, 原始数据..., 第一项克隆]
|
||||
*/
|
||||
const renderMediaData = computed<MediaItem[]>(() => {
|
||||
const length = originalMediaData.value.length;
|
||||
if (length === 0) return;
|
||||
if (length === 0) return [];
|
||||
|
||||
renderMediaData.value = [
|
||||
return [
|
||||
originalMediaData.value[length - 1], // 克隆最后一项
|
||||
...originalMediaData.value, // 原始数据
|
||||
originalMediaData.value[0] // 克隆第一项
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
// 启动自动轮播
|
||||
/**
|
||||
* 获取当前真实的索引(排除克隆项的影响)
|
||||
*/
|
||||
const currentRealIndex = computed(() => {
|
||||
const realLength = originalMediaData.value.length;
|
||||
if (realLength === 0) return 0;
|
||||
|
||||
let realIndex = currentIndex.value - 1; // 减去克隆的首项偏移
|
||||
|
||||
// 处理边界情况(无缝循环时的克隆项)
|
||||
if (realIndex < 0) realIndex = realLength - 1;
|
||||
if (realIndex >= realLength) realIndex = 0;
|
||||
|
||||
return realIndex;
|
||||
});
|
||||
|
||||
/**
|
||||
* 计算当前显示的描述文字
|
||||
*/
|
||||
const currentDescription = computed(() => {
|
||||
return originalMediaData.value[currentRealIndex.value]?.introduce || '';
|
||||
});
|
||||
|
||||
// ==================== 核心方法 ====================
|
||||
/**
|
||||
* 启动自动轮播
|
||||
*/
|
||||
const startAutoPlay = () => {
|
||||
if (timer) clearInterval(timer);
|
||||
timer = setInterval(() => {
|
||||
stopAutoPlay(); // 先清除旧的定时器
|
||||
autoPlayTimer = setInterval(() => {
|
||||
if (!isHovering.value && !isTransitioning.value) {
|
||||
nextSlide();
|
||||
}
|
||||
}, 4000);
|
||||
}, CAROUSEL_CONFIG.autoPlayInterval);
|
||||
};
|
||||
|
||||
// 切换到下一张
|
||||
/**
|
||||
* 停止自动轮播
|
||||
*/
|
||||
const stopAutoPlay = () => {
|
||||
if (autoPlayTimer) {
|
||||
clearInterval(autoPlayTimer);
|
||||
autoPlayTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 切换到下一张
|
||||
*/
|
||||
const nextSlide = () => {
|
||||
currentIndex.value++;
|
||||
|
||||
// 延迟检查是否需要无缝跳转
|
||||
// 延迟检查是否需要无缝跳转(与transition时间一致)
|
||||
setTimeout(() => {
|
||||
checkSeamlessJump();
|
||||
}, 500); // 与transition时间一致
|
||||
handleSeamlessLoop();
|
||||
}, CAROUSEL_CONFIG.transitionDuration);
|
||||
};
|
||||
|
||||
// 检查是否需要无缝跳转(克隆项处理)
|
||||
const checkSeamlessJump = () => {
|
||||
/**
|
||||
* 处理无缝循环(克隆项处理)
|
||||
*/
|
||||
const handleSeamlessLoop = () => {
|
||||
const realLength = originalMediaData.value.length;
|
||||
if (realLength === 0) return;
|
||||
|
||||
// 如果到达克隆的最后一项(索引 = realLength + 1)
|
||||
if (currentIndex.value >= realLength + 1) {
|
||||
@ -141,33 +200,114 @@ const checkSeamlessJump = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理鼠标进入
|
||||
/**
|
||||
* 处理鼠标进入
|
||||
*/
|
||||
const handleMouseEnter = () => {
|
||||
isHovering.value = true;
|
||||
};
|
||||
|
||||
// 处理鼠标离开
|
||||
/**
|
||||
* 处理鼠标离开
|
||||
*/
|
||||
const handleMouseLeave = () => {
|
||||
isHovering.value = false;
|
||||
};
|
||||
|
||||
// 计算当前显示的描述文字
|
||||
const currentDescription = computed(() => {
|
||||
const realIndex = getCurrentRealIndex();
|
||||
return originalMediaData.value[realIndex]?.description || '';
|
||||
});
|
||||
/**
|
||||
* 跳转到指定幻灯片
|
||||
*/
|
||||
const goToSlide = (targetIndex: number) => {
|
||||
if (isTransitioning.value) return;
|
||||
|
||||
// 页面加载时执行
|
||||
// 计算目标索引(考虑克隆项偏移)
|
||||
currentIndex.value = targetIndex + 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取轮播图数据
|
||||
*/
|
||||
const getCarouselData = async () => {
|
||||
loading.value = true;
|
||||
hasData.value = false;
|
||||
|
||||
try {
|
||||
const params = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'sttpFullPath',
|
||||
operator: 'contains',
|
||||
dataType: 'string',
|
||||
value: 'ENV,ENVP,FP,FP'
|
||||
},
|
||||
{
|
||||
field: 'logo',
|
||||
operator: 'isnotnull',
|
||||
dataType: 'string'
|
||||
},
|
||||
baseid.value !== 'all' ? {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: baseid.value
|
||||
} : null
|
||||
].filter(Boolean)
|
||||
},
|
||||
select: ['introduce', 'logo', 'stnm', 'precis'],
|
||||
sort: [{ field: 'rstcdStepSort', dir: 'asc' }]
|
||||
};
|
||||
|
||||
const res = await vmsstbprptGetKendoList(params);
|
||||
const data = res?.data?.data || [];
|
||||
|
||||
if (data.length > 0) {
|
||||
originalMediaData.value = data.map((item: any) => ({
|
||||
url: item.logo ? `${baseUrl}/?${item.logo}&view=jpg` : '',
|
||||
introduce: item.introduce || '',
|
||||
stnm: item.stnm || ''
|
||||
}));
|
||||
|
||||
// 重置索引到第一项(跳过克隆的首项)
|
||||
currentIndex.value = 1;
|
||||
hasData.value = true;
|
||||
} else {
|
||||
// 无数据时清空
|
||||
originalMediaData.value = [];
|
||||
hasData.value = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取轮播图数据失败:', error);
|
||||
originalMediaData.value = [];
|
||||
hasData.value = false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== 生命周期 ====================
|
||||
onMounted(() => {
|
||||
initRenderData();
|
||||
startAutoPlay();
|
||||
});
|
||||
|
||||
// 组件卸载时清理
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer);
|
||||
stopAutoPlay();
|
||||
});
|
||||
|
||||
// ==================== 监听器 ====================
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
if (newVal?.wbsCode) {
|
||||
baseid.value = newVal.wbsCode;
|
||||
} else {
|
||||
baseid.value = 'all';
|
||||
}
|
||||
getCarouselData();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
// 获取当前真实的索引(排除克隆项的影响)
|
||||
const getCurrentRealIndex = () => {
|
||||
const realLength = originalMediaData.value.length;
|
||||
@ -179,13 +319,15 @@ const getCurrentRealIndex = () => {
|
||||
|
||||
return realIndex;
|
||||
};
|
||||
|
||||
// 跳转到指定幻灯片
|
||||
const goToSlide = (targetIndex: number) => {
|
||||
if (isTransitioning.value) return;
|
||||
|
||||
// 计算目标索引(考虑克隆项偏移)
|
||||
currentIndex.value = targetIndex + 1;
|
||||
// 处理项目点击事件
|
||||
const handleItemClick = (item: any) => {
|
||||
console.log('轮播图项目被点击:', item, getCurrentRealIndex());
|
||||
currentItem.value = item.map((item: any) => ({
|
||||
url: item.url || '',
|
||||
description: item.introduce || '',
|
||||
title: item.stnm || ''
|
||||
}));
|
||||
modalVisible.value = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -193,8 +335,6 @@ const goToSlide = (targetIndex: number) => {
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 228px;
|
||||
// border: 1px solid #7fd6ff;
|
||||
// border-radius: 5px;
|
||||
position: relative;
|
||||
overflow: hidden; // 隐藏超出容器的内容
|
||||
|
||||
@ -216,9 +356,9 @@ const goToSlide = (targetIndex: number) => {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
flex-shrink: 0; // 防止被压缩
|
||||
cursor: pointer;
|
||||
|
||||
img,
|
||||
video {
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; // 保持比例填充
|
||||
@ -268,12 +408,11 @@ const goToSlide = (targetIndex: number) => {
|
||||
|
||||
// 独立的文字说明区域
|
||||
.description-text {
|
||||
// padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
// min-height: 40px;
|
||||
transition: all 0.3s ease;
|
||||
margin-bottom: 20px;
|
||||
// margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
// 多行文本溢出省略
|
||||
display: -webkit-box;
|
||||
|
||||
@ -401,7 +401,6 @@ const getChartData = async (startDate: string, endDate: string, stcd: string) =>
|
||||
|
||||
// 调用实际的API获取数据
|
||||
const res = await sdrvwtsGetKendoList(params);
|
||||
debugger
|
||||
console.log('API返回结果:', res);
|
||||
|
||||
let data = res?.data?.data || [];
|
||||
|
||||
@ -45,7 +45,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
||||
const res = await getSelectForDropdown({});
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
const list = [
|
||||
{ hbrvcd: 'all', hbrvnm: '当前全部', baseid: '01' },
|
||||
{ rvcd: 'all', rvnm: '当前全部', baseid: '01' },
|
||||
...res.data
|
||||
];
|
||||
// 直接赋值给 ref,触发响应式更新
|
||||
@ -58,15 +58,15 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
||||
}
|
||||
};
|
||||
// 获取电站列表
|
||||
const getEngOption = async (hbrvcd: string) => {
|
||||
const getEngOption = async (rvcd: string) => {
|
||||
try {
|
||||
engLoading.value = true;
|
||||
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
||||
const param = rvcd === 'all' ? {} : { rvcd };
|
||||
const res = await getEngInfoDropdown(param);
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 直接赋值给 ref
|
||||
engOption.value = res.data;
|
||||
getFpssOption(hbrvcd, '');
|
||||
getFpssOption(rvcd, '');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取电站列表失败:', error);
|
||||
@ -75,10 +75,10 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
||||
}
|
||||
};
|
||||
// 获取过鱼设施列表
|
||||
const getFpssOption = async (hbrvcd: string, rstcd: string) => {
|
||||
const getFpssOption = async (rvcd: string, rstcd: string) => {
|
||||
try {
|
||||
fpssLoading.value = true;
|
||||
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
||||
const param = rvcd === 'all' ? {} : { rvcd };
|
||||
const res = await getFpssDropdown({...param, rstcd: rstcd});
|
||||
fpssOption.value = res.data;
|
||||
} catch (error) {
|
||||
|
||||
@ -5,6 +5,17 @@ import GuoYuSheShiJieShao from "@/modules/guoyusheshijieshao/index.vue"
|
||||
import GuoYuSheShiJianSheQingKuang from "@/modules/guoyusheshijiansheqingkuang/index.vue"
|
||||
import GuoYuJianCeTJ from "@/modules/guoyujiance/index.vue"
|
||||
import GYZLLB from "@/modules/GYZLLB/index.vue"
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import { ref,watch} from 'vue';
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
const baseid = ref('')
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
baseid.value = newVal.wbsCode;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -14,8 +25,8 @@ import GYZLLB from "@/modules/GYZLLB/index.vue"
|
||||
</div>
|
||||
<div class="rightContent">
|
||||
<RightDrawer>
|
||||
<!-- <GuoYuSheShiJieShao /> -->
|
||||
<GuoYuSheShiJianSheQingKuang />
|
||||
<GuoYuSheShiJieShao v-if="baseid != 'all'" />
|
||||
<GuoYuSheShiJianSheQingKuang v-if="baseid == 'all'" />
|
||||
<GuoYuJianCeTJ />
|
||||
<GYZLLB title="过鱼总量" />
|
||||
</RightDrawer>
|
||||
|
||||
@ -129,12 +129,12 @@
|
||||
</a-form-item>
|
||||
|
||||
<!-- 流域(多选,数组,必填) -->
|
||||
<a-form-item name="hbrvcdCode" label="流 域" required>
|
||||
<a-select v-model:value="organizationData.hbrvcdCode" mode="multiple" placeholder="请选择流域"
|
||||
<a-form-item name="rvcdCode" label="流 域" required>
|
||||
<a-select v-model:value="organizationData.rvcdCode" mode="multiple" placeholder="请选择流域"
|
||||
style="width: 100%" show-search :filter-option="filterOption" @change="onRvcdChange">
|
||||
<a-select-option v-for="item in basinList" :key="item.hbrvcd" :value="item.hbrvcd"
|
||||
:label="item.hbrvnm">
|
||||
{{ item.hbrvnm }}
|
||||
<a-select-option v-for="item in basinList" :key="item.rvcd" :value="item.rvcd"
|
||||
:label="item.rvnm">
|
||||
{{ item.rvnm }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
@ -142,7 +142,7 @@
|
||||
<!-- 电站(多选,数组,必填,依赖流域) -->
|
||||
<a-form-item name="stationCode" label="电 站" required>
|
||||
<a-select v-model:value="organizationData.stationCode" mode="multiple" placeholder="请先选择流域"
|
||||
:disabled="organizationData.hbrvcdCode.length === 0" style="width: 100%" show-search
|
||||
:disabled="organizationData.rvcdCode.length === 0" style="width: 100%" show-search
|
||||
:filter-option="filterOption">
|
||||
<a-select-option v-for="item in stationList" :key="item.stcd" :value="item.stcd"
|
||||
:label="item.ennm">
|
||||
@ -199,7 +199,7 @@ let smsTimer: any = null;
|
||||
const organizationData = reactive({
|
||||
groupCode: '', // 集团(单选,字符串)
|
||||
companyCode: '', // 公司(单选,字符串)
|
||||
hbrvcdCode: [], // 流域(多选,数组)
|
||||
rvcdCode: [], // 流域(多选,数组)
|
||||
stationCode: [] // 电站(多选,数组)
|
||||
});
|
||||
|
||||
@ -208,7 +208,7 @@ const organizationFormRef = ref();
|
||||
|
||||
// ==================== 组织表单验证规则 ====================
|
||||
const organizationRules = {
|
||||
hbrvcdCode: [
|
||||
rvcdCode: [
|
||||
{
|
||||
validator: (rule: any, value: any[]) => {
|
||||
if (!value || value.length === 0) {
|
||||
@ -434,8 +434,8 @@ const onRvcdChange = () => {
|
||||
// 清空电站选择
|
||||
organizationData.stationCode = [];
|
||||
// 获取当前选中的所有流域ID,加载对应的电站列表
|
||||
if (organizationData.hbrvcdCode && organizationData.hbrvcdCode.length > 0) {
|
||||
onBasinChange({ hbrvcds: organizationData.hbrvcdCode });
|
||||
if (organizationData.rvcdCode && organizationData.rvcdCode.length > 0) {
|
||||
onBasinChange({ rvcds: organizationData.rvcdCode });
|
||||
} else {
|
||||
// 如果没有选择流域,清空电站列表
|
||||
stationList.value = [];
|
||||
@ -490,7 +490,7 @@ const handleModalCancel = () => {
|
||||
// 重置组织表单数据
|
||||
organizationData.groupCode = '';
|
||||
organizationData.companyCode = '';
|
||||
organizationData.hbrvcdCode = [];
|
||||
organizationData.rvcdCode = [];
|
||||
organizationData.stationCode = [];
|
||||
// 清除表单验证状态
|
||||
organizationFormRef.value?.clearValidate();
|
||||
@ -539,8 +539,8 @@ const onRegister = async () => {
|
||||
}
|
||||
|
||||
// 可选字段:流域(如果有值才传,数组转逗号分隔字符串)
|
||||
if (organizationData.hbrvcdCode && organizationData.hbrvcdCode.length > 0) {
|
||||
registerParams.hbrvcdCode = organizationData.hbrvcdCode.join(',');
|
||||
if (organizationData.rvcdCode && organizationData.rvcdCode.length > 0) {
|
||||
registerParams.rvcdCode = organizationData.rvcdCode.join(',');
|
||||
}
|
||||
|
||||
// 可选字段:电站(如果有值才传,数组转逗号分隔字符串)
|
||||
|
||||
@ -46,7 +46,7 @@ const basicSearchRef = ref<any>();
|
||||
const btnLoading = ref<boolean>(false);
|
||||
|
||||
const initSearchData = {
|
||||
hbrvcd: "all",
|
||||
rvcd: "all",
|
||||
stcd: null,
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@ const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "waterStation",
|
||||
name: "hbrvcd",
|
||||
name: "rvcd",
|
||||
label: "流域",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
@ -72,7 +72,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
||||
searchData.value = { ...searchData.value, ...allValues };
|
||||
if (
|
||||
Object.keys(changedValues)[0] == "rstcd" ||
|
||||
Object.keys(changedValues)[0] == "hbrvcd"
|
||||
Object.keys(changedValues)[0] == "rvcd"
|
||||
) {
|
||||
const formInstance = basicSearchRef.value?.formData;
|
||||
formInstance.stcd = null;
|
||||
|
||||
@ -340,11 +340,11 @@ const handleDetailSearchFinish = (values: any) => {
|
||||
dataType: "date",
|
||||
value: values.strdt[1] + " 23:59:59",
|
||||
},
|
||||
values.hbrvcd !== "all" && {
|
||||
values.rvcd !== "all" && {
|
||||
field: "basinCode",
|
||||
operator: "eq",
|
||||
dataType: "string",
|
||||
value: values.hbrvcd,
|
||||
value: values.rvcd,
|
||||
},
|
||||
values.rstcd && {
|
||||
field: "stationCode",
|
||||
|
||||
@ -35,7 +35,7 @@ const localTypeDate = ref<string>(null);
|
||||
const basicSearchRef = ref<any>();
|
||||
|
||||
const initSearchData = {
|
||||
hbrvcd: "all",
|
||||
rvcd: "all",
|
||||
stcd: null,
|
||||
rstcd: null,
|
||||
ftp: null,
|
||||
@ -52,7 +52,7 @@ const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "waterStation",
|
||||
name: "hbrvcd",
|
||||
name: "rvcd",
|
||||
label: "流域",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
@ -121,7 +121,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
||||
if (
|
||||
Object.keys(changedValues)[0] == "rstcd" ||
|
||||
Object.keys(changedValues)[0] == "baseId" ||
|
||||
Object.keys(changedValues)[0] == "hbrvcd"
|
||||
Object.keys(changedValues)[0] == "rvcd"
|
||||
) {
|
||||
const formInstance = basicSearchRef.value?.formData;
|
||||
formInstance.stcd = null;
|
||||
|
||||
@ -290,11 +290,11 @@ const handleSearchFinish = (values: any) => {
|
||||
dataType: "string",
|
||||
value: values.rstcd,
|
||||
},
|
||||
values.hbrvcd !== "all" && {
|
||||
field: "hbrvcd",
|
||||
values.rvcd !== "all" && {
|
||||
field: "rvcd",
|
||||
operator: "eq",
|
||||
dataType: "string",
|
||||
value: values.hbrvcd,
|
||||
value: values.rvcd,
|
||||
},
|
||||
].filter(Boolean);
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="流域" name="hbrvcd">
|
||||
<a-form-item label="流域" name="rvcd">
|
||||
<a-select
|
||||
v-model:value="formData.hbrvcd"
|
||||
v-model:value="formData.rvcd"
|
||||
:loading="hbrvcdLoading"
|
||||
placeholder="请选择流域"
|
||||
:disabled="isView"
|
||||
@ -31,11 +31,11 @@
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in hbrvcdOption"
|
||||
:key="opt.hbrvcd"
|
||||
:value="opt.hbrvcd"
|
||||
:label="opt.hbrvnm"
|
||||
:key="opt.rvcd"
|
||||
:value="opt.rvcd"
|
||||
:label="opt.rvnm"
|
||||
>
|
||||
{{ opt.hbrvnm }}
|
||||
{{ opt.rvnm }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
@ -67,7 +67,7 @@
|
||||
v-model:value="formData.rstcd"
|
||||
:loading="engLoading"
|
||||
placeholder="请选择电站名称"
|
||||
:disabled="isView || !formData.hbrvcd"
|
||||
:disabled="isView || !formData.rvcd"
|
||||
show-search
|
||||
allowClear
|
||||
:filter-option="filterOption"
|
||||
@ -363,7 +363,7 @@ const getHbrvcdDropdownSelect = async () => {
|
||||
const res = await getSelectForDropdown({});
|
||||
let list = res.data || [];
|
||||
if (list && list.length > 0) {
|
||||
list = list.filter((item: any) => item.hbrvcd !== "all");
|
||||
list = list.filter((item: any) => item.rvcd !== "all");
|
||||
}
|
||||
hbrvcdOption.value = list;
|
||||
} catch (error) {
|
||||
@ -378,16 +378,16 @@ const getHbrvcdDropdownSelect = async () => {
|
||||
// await getEngInfoDropdownSelect(baseId);
|
||||
// await getFpssDropdownSelect(formData.rstcd, baseId);
|
||||
// };
|
||||
const hbrvcdChange = async (hbrvcd: string) => {
|
||||
const hbrvcdChange = async (rvcd: string) => {
|
||||
formData.rstcd = undefined;
|
||||
formData.stcd = undefined;
|
||||
await getEngInfoDropdownSelect(hbrvcd);
|
||||
// await getFpssDropdownSelect(formData.rstcd, hbrvcd);
|
||||
await getEngInfoDropdownSelect(rvcd);
|
||||
// await getFpssDropdownSelect(formData.rstcd, rvcd);
|
||||
};
|
||||
const getEngInfoDropdownSelect = async (hbrvcd: string) => {
|
||||
const getEngInfoDropdownSelect = async (rvcd: string) => {
|
||||
try {
|
||||
engLoading.value = true;
|
||||
const res = await getEngInfoDropdown({ hbrvcd });
|
||||
const res = await getEngInfoDropdown({ rvcd });
|
||||
engOption.value = res.data;
|
||||
} catch (error) {
|
||||
console.error("获取电站列表失败", error);
|
||||
@ -397,12 +397,12 @@ const getEngInfoDropdownSelect = async (hbrvcd: string) => {
|
||||
};
|
||||
const engChange = async (rstcd: string) => {
|
||||
formData.stcd = undefined;
|
||||
await getFpssDropdownSelect(rstcd, formData.hbrvcd);
|
||||
await getFpssDropdownSelect(rstcd, formData.rvcd);
|
||||
};
|
||||
const getFpssDropdownSelect = async (rstcd: string, hbrvcd: string) => {
|
||||
const getFpssDropdownSelect = async (rstcd: string, rvcd: string) => {
|
||||
try {
|
||||
fpssLoading.value = true;
|
||||
const res = await getFpssDropdown({ rstcd, hbrvcd });
|
||||
const res = await getFpssDropdown({ rstcd, rvcd });
|
||||
fpssOption.value = res.data;
|
||||
} catch (error) {
|
||||
console.error("获取流量列表失败", error);
|
||||
@ -431,7 +431,7 @@ const weightError = ref<string>("");
|
||||
// 表单数据模型
|
||||
const defaultFormData = reactive({
|
||||
id: undefined,
|
||||
hbrvcd: undefined,
|
||||
rvcd: undefined,
|
||||
stcd: undefined,
|
||||
rstcd: undefined,
|
||||
strdt: undefined,
|
||||
@ -456,7 +456,7 @@ const filterOption = (inputValue: string, option: any) => {
|
||||
};
|
||||
// 验证规则
|
||||
const rules: Record<string, Rule[]> = {
|
||||
hbrvcd: [{ required: true, message: "请选择流域", trigger: "change" }],
|
||||
rvcd: [{ required: true, message: "请选择流域", trigger: "change" }],
|
||||
rstcd: [{ required: true, message: "请选择电站", trigger: "change" }],
|
||||
stcd: [{ required: true, message: "请选择过鱼设施", trigger: "change" }],
|
||||
strdt: [{ required: true, message: "请选择过鱼时间", trigger: "change" }],
|
||||
@ -817,8 +817,8 @@ watch(
|
||||
// 弹窗打开时,初始化数据
|
||||
// getBaseDropdownSelect();// 基地
|
||||
getHbrvcdDropdownSelect(); // 流域
|
||||
getEngInfoDropdownSelect(formData.hbrvcd);
|
||||
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
|
||||
getEngInfoDropdownSelect(formData.rvcd);
|
||||
getFpssDropdownSelect(formData.rstcd, formData.rvcd);
|
||||
initForm();
|
||||
}
|
||||
},
|
||||
|
||||
@ -116,7 +116,7 @@ const localTypeDate = ref<string>(null);
|
||||
const basicSearchRef = ref<any>();
|
||||
|
||||
const initSearchData = {
|
||||
hbrvcd: "all",
|
||||
rvcd: "all",
|
||||
// baseId: "all",
|
||||
stcd: null,
|
||||
rstcd: null,
|
||||
@ -133,7 +133,7 @@ const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "waterStation",
|
||||
name: "hbrvcd",
|
||||
name: "rvcd",
|
||||
label: "流域",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
@ -205,7 +205,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
||||
if (
|
||||
Object.keys(changedValues)[0] == "rstcd" ||
|
||||
Object.keys(changedValues)[0] == "baseId" ||
|
||||
Object.keys(changedValues)[0] == "hbrvcd"
|
||||
Object.keys(changedValues)[0] == "rvcd"
|
||||
) {
|
||||
const formInstance = basicSearchRef.value?.formData;
|
||||
formInstance.stcd = null;
|
||||
|
||||
@ -73,9 +73,9 @@
|
||||
</a-select>
|
||||
</template> -->
|
||||
<!-- 流域名称 -->
|
||||
<template v-if="column.dataIndex === 'hbrvnm'">
|
||||
<template v-if="column.dataIndex === 'rvnm'">
|
||||
<a-select
|
||||
v-model:value="editingData.hbrvcd"
|
||||
v-model:value="editingData.rvcd"
|
||||
placeholder="请选择"
|
||||
show-search
|
||||
allowClear
|
||||
@ -83,14 +83,15 @@
|
||||
:loading="rowStates[index]?.hbrvcdLoading"
|
||||
style="width: 100%"
|
||||
@change="(val) => handleHbrvcdChange(val, index, 'input')"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto', minWidth: '300px' }"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in hbrvcdOptions"
|
||||
:key="opt.hbrvcd"
|
||||
:value="opt.hbrvcd"
|
||||
:label="opt.hbrvnm"
|
||||
:key="opt.rvcd"
|
||||
:value="opt.rvcd"
|
||||
:label="opt.rvnm"
|
||||
>
|
||||
{{ opt.hbrvnm }}
|
||||
{{ opt.rvnm }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
@ -105,7 +106,7 @@
|
||||
:filter-option="filterOption"
|
||||
:loading="rowStates[index]?.engLoading"
|
||||
style="width: 100%"
|
||||
:disabled="!editingData.hbrvcd"
|
||||
:disabled="!editingData.rvcd"
|
||||
@change="(val) => handleEngChange(val, index, 'input')"
|
||||
>
|
||||
<a-select-option
|
||||
@ -316,9 +317,9 @@ const modalColumns = ref([
|
||||
fixed: "left",
|
||||
},
|
||||
{
|
||||
dataIndex: "hbrvnm",
|
||||
key: "hbrvnm",
|
||||
dataIndexKey: "hbrvcd",
|
||||
dataIndex: "rvnm",
|
||||
key: "rvnm",
|
||||
dataIndexKey: "rvcd",
|
||||
title: "流域",
|
||||
width: 140,
|
||||
},
|
||||
@ -418,11 +419,11 @@ const loadHbrvcdOptions = async () => {
|
||||
const res = await getSelectForDropdown({});
|
||||
let list = res.data || [];
|
||||
if (list && list.length > 0) {
|
||||
list = list.filter((item: any) => item.hbrvcd !== "all");
|
||||
list = list.filter((item: any) => item.rvcd !== "all");
|
||||
}
|
||||
hbrvcdOptions.value = list;
|
||||
} catch (e) {
|
||||
console.error("Load hbrvcd options failed", e);
|
||||
console.error("Load rvcd options failed", e);
|
||||
}
|
||||
};
|
||||
|
||||
@ -442,15 +443,15 @@ const ensureRowState = (index: number) => {
|
||||
|
||||
// --- 级联逻辑 (操作 editingData) ---
|
||||
// const handleBaseChange = async (
|
||||
// hbrvcd: string,
|
||||
// rvcd: string,
|
||||
// index: number,
|
||||
// type: string = "start"
|
||||
// ) => {
|
||||
// const state = ensureRowState(index);
|
||||
// editingData.value.baseName = hbrvcdOptions.value.find(
|
||||
// (item: any) => item.hbrvcd == hbrvcd
|
||||
// (item: any) => item.rvcd == rvcd
|
||||
// )?.basename;
|
||||
// delWarning(hbrvcd, "hbrvcd");
|
||||
// delWarning(rvcd, "rvcd");
|
||||
// // 清空后续字段
|
||||
// if (type != "start") {
|
||||
// editingData.value.rstcd = undefined;
|
||||
@ -462,7 +463,7 @@ const ensureRowState = (index: number) => {
|
||||
// }
|
||||
// state.engLoading = true;
|
||||
// try {
|
||||
// const res = await getEngInfoDropdown({ hbrvcd });
|
||||
// const res = await getEngInfoDropdown({ rvcd });
|
||||
// state.engOptions = res.data || [];
|
||||
// } catch (e) {
|
||||
// message.error("获取电站列表失败");
|
||||
@ -471,17 +472,17 @@ const ensureRowState = (index: number) => {
|
||||
// }
|
||||
// };
|
||||
const handleHbrvcdChange = async (
|
||||
hbrvcd: string,
|
||||
rvcd: string,
|
||||
index: number,
|
||||
type = "start"
|
||||
) => {
|
||||
const state = ensureRowState(index);
|
||||
editingData.value.hbrvnm = hbrvcdOptions.value.find(
|
||||
(item: any) => item.hbrvcd == hbrvcd
|
||||
)?.hbrvnm;
|
||||
delWarning(hbrvcd, "hbrvcd");
|
||||
if (hbrvcd == null) {
|
||||
delWarning(null, "hbrvcd");
|
||||
editingData.value.rvnm = hbrvcdOptions.value.find(
|
||||
(item: any) => item.rvcd == rvcd
|
||||
)?.rvnm;
|
||||
delWarning(rvcd, "rvcd");
|
||||
if (rvcd == null) {
|
||||
delWarning(null, "rvcd");
|
||||
delWarning(null, "stcd");
|
||||
}
|
||||
// 清空后续字段
|
||||
@ -495,7 +496,7 @@ const handleHbrvcdChange = async (
|
||||
}
|
||||
state.engLoading = true;
|
||||
try {
|
||||
const res = await getEngInfoDropdown({ hbrvcd });
|
||||
const res = await getEngInfoDropdown({ rvcd });
|
||||
state.engOptions = res.data || [];
|
||||
} catch (e) {
|
||||
message.error("获取电站列表失败");
|
||||
@ -521,7 +522,7 @@ const handleEngChange = async (rstcd: string, index: number, type = "start") =>
|
||||
}
|
||||
state.fpssLoading = true;
|
||||
try {
|
||||
const res = await getFpssDropdown({ rstcd, hbrvcd: editingData.value.hbrvcd });
|
||||
const res = await getFpssDropdown({ rstcd, rvcd: editingData.value.rvcd });
|
||||
state.fpssOptions = res.data || [];
|
||||
} catch (e) {
|
||||
message.error("获取设施列表失败");
|
||||
@ -572,9 +573,9 @@ const startEdit = (index: number) => {
|
||||
processStringToMinMax(editingData.value);
|
||||
|
||||
editingRowIndex.value = index;
|
||||
if (editingData.value.warnings.includes("hbrvcd")) {
|
||||
editingData.value.hbrvcd = null;
|
||||
editingData.value.hbrvnm = null;
|
||||
if (editingData.value.warnings.includes("rvcd")) {
|
||||
editingData.value.rvcd = null;
|
||||
editingData.value.rvnm = null;
|
||||
editingData.value.rstcd = null;
|
||||
editingData.value.stcd = null;
|
||||
delWarning(null, "rstcd");
|
||||
@ -590,7 +591,7 @@ const startEdit = (index: number) => {
|
||||
}
|
||||
|
||||
// 3. 预加载下拉选项 (基于 editingData 的值)
|
||||
if (editingData.value.hbrvcd == "" || editingData.value.hbrvcd == undefined) {
|
||||
if (editingData.value.rvcd == "" || editingData.value.rvcd == undefined) {
|
||||
if (editingData.value.rstcd) {
|
||||
handleHbrvcdChange("", index, "start").then(() => {
|
||||
handleEngChange(editingData.value.rstcd, index, "start");
|
||||
@ -598,8 +599,8 @@ const startEdit = (index: number) => {
|
||||
} else {
|
||||
handleEngChange("", index, "start");
|
||||
}
|
||||
} else if (editingData.value.hbrvcd != "" && editingData.value.hbrvcd != undefined) {
|
||||
handleHbrvcdChange(editingData.value.hbrvcd, index, "start").then(() => {
|
||||
} else if (editingData.value.rvcd != "" && editingData.value.rvcd != undefined) {
|
||||
handleHbrvcdChange(editingData.value.rvcd, index, "start").then(() => {
|
||||
handleEngChange(editingData.value.rstcd, index, "start");
|
||||
});
|
||||
}
|
||||
|
||||
@ -584,7 +584,7 @@ const handleModalOk = () => {
|
||||
// message.warning("请检查流域,流域填写有误!");
|
||||
// return;
|
||||
// }
|
||||
if (fileTableData.value[i].warnings.includes("hbrvcd")) {
|
||||
if (fileTableData.value[i].warnings.includes("rvcd")) {
|
||||
message.warning("请检查流域,流域填写有误!");
|
||||
return;
|
||||
}
|
||||
@ -850,11 +850,11 @@ const handleSearchFinish = (values: any) => {
|
||||
dataType: "string",
|
||||
value: values.rstcd,
|
||||
},
|
||||
values.hbrvcd !== "all" && {
|
||||
field: "hbrvcd",
|
||||
values.rvcd !== "all" && {
|
||||
field: "rvcd",
|
||||
operator: "eq",
|
||||
dataType: "string",
|
||||
value: values.hbrvcd,
|
||||
value: values.rvcd,
|
||||
},
|
||||
// values.baseId !== "all" && {
|
||||
// field: "baseId",
|
||||
|
||||
@ -37,7 +37,7 @@ const localTypeDate = ref<string>(null);
|
||||
const basicSearchRef = ref<any>();
|
||||
|
||||
const initSearchData = {
|
||||
hbrvcd: "all",
|
||||
rvcd: "rvcd",
|
||||
stcd: null,
|
||||
rstcd: null,
|
||||
strdt: [
|
||||
@ -51,7 +51,7 @@ const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "waterStation",
|
||||
name: "hbrvcd",
|
||||
name: "rvcd",
|
||||
label: "流域",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
@ -81,7 +81,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
||||
searchData.value = { ...searchData.value, ...allValues };
|
||||
if (
|
||||
Object.keys(changedValues)[0] == "rstcd" ||
|
||||
Object.keys(changedValues)[0] == "hbrvcd"
|
||||
Object.keys(changedValues)[0] == "rvcd"
|
||||
) {
|
||||
const formInstance = basicSearchRef.value?.formData;
|
||||
formInstance.stcd = null;
|
||||
|
||||
@ -366,11 +366,11 @@ const handleSearchFinish = (values: any) => {
|
||||
dataType: "string",
|
||||
value: values.status,
|
||||
},
|
||||
values.hbrvcd !== "all" && {
|
||||
field: "hbrvcd",
|
||||
values.rvcd !== "all" && {
|
||||
field: "rvcd",
|
||||
operator: "eq",
|
||||
dataType: "string",
|
||||
value: values.hbrvcd,
|
||||
value: values.rvcd,
|
||||
},
|
||||
values.stcd && {
|
||||
field: "stcd",
|
||||
@ -585,11 +585,11 @@ const handleDetailSearchFinish = (values: any) => {
|
||||
dataType: "string",
|
||||
value: values.rstcd,
|
||||
},
|
||||
values.hbrvcd !== "all" && {
|
||||
field: "hbrvcd",
|
||||
values.rvcd !== "all" && {
|
||||
field: "rvcd",
|
||||
operator: "eq",
|
||||
dataType: "string",
|
||||
value: values.hbrvcd,
|
||||
value: values.rvcd,
|
||||
},
|
||||
approvalId.value && {
|
||||
field: "approvalId", // 字段名
|
||||
|
||||
@ -61,7 +61,7 @@ const emit = defineEmits<{
|
||||
|
||||
// 模拟 initSearchData
|
||||
const initSearchData = {
|
||||
hbrvcd: "all",
|
||||
rvcd: "all",
|
||||
stcd: "",
|
||||
status: "",
|
||||
};
|
||||
@ -71,7 +71,7 @@ const searchData = ref<any>({ ...initSearchData });
|
||||
const searchList: any = computed(() => [
|
||||
{
|
||||
type: "waterStation",
|
||||
name: "hbrvcd",
|
||||
name: "rvcd",
|
||||
label: "流域",
|
||||
fieldProps: {
|
||||
allowClear: true,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user