This commit is contained in:
扈兆增 2026-06-08 09:33:20 +08:00
commit c34db88aaf
29 changed files with 1184 additions and 295 deletions

View File

@ -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 } : {}
});

View 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
});
}

View File

@ -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
});

View File

@ -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
});

View File

@ -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);
}

View File

@ -2002,7 +2002,7 @@ const StinfoAiVidoPointColumns: Array<any> = [
},
{
name: '所属行政区',
filed: 'addvcdName ',
filed: 'addvcdName',
visible: true,
type: 'select',
url: '',

View File

@ -309,8 +309,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: '实时视频',
@ -1025,8 +1025,8 @@ const videoTabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo',
default: true // 默认显示
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true, // 默认显示
},
{
name: '实时视频',

View File

@ -8,7 +8,7 @@
<div class="carousel-inner">
<div class="carousel-track" :style="trackStyle">
<div v-for="(item, index) in originalMediaData" :key="index" class="carousel-item">
<a-image :src="item.url" />
<a-image :src="item.url" />
<!-- <img :src="item.url" :alt="item.title" /> -->
</div>
</div>
@ -17,7 +17,11 @@
</div>
</div>
<div class="card_right">
<div class="card_text_title"></div>
<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>
@ -52,7 +56,7 @@ const props = defineProps<{
description: string;
url: string;
}>;
index:any
index: any
}>();
interface MediaItem {
@ -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%;

View File

@ -716,7 +716,6 @@ watch(
formState.sfdb = ''
formState.stnm = ''
pieCode.value = []
debugger
//
nextTick(() => {
handleSearch()

View 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>

View File

@ -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>
@ -12,56 +16,81 @@
<div class="facility-info">
<div class="facility-name">{{ facility.name }}</div>
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
}}</span><span></span></div>
}}</span><span></span></div>
</div>
</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>

View File

@ -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>

View File

@ -1,58 +1,135 @@
<!-- SidePanelItem.vue -->
<template>
<SidePanelItem title="过鱼设施">
<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 class="facility-icon">
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
<a-spin :spinning="loading" tip="加载中...">
<div class="facility-grid">
<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>
</div>
<div class="facility-info">
<div class="facility-name">{{ facility.name }}</div>
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
}}</span><span></span></div>
</div>
</div>
<div class="facility-info">
<div class="facility-name">{{ facility.name }}</div>
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
}}</span><span></span></div>
</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 || [];
// count0
facilities.value.forEach(facility => {
facility.count = 0;
});
//
data.forEach(item => {
const matchedFacility = facilities.value.find(facility => facility.key === item.sttpCode);
if (matchedFacility) {
// facilitieskey
matchedFacility.count += Number(item.built) + Number(item.building) || 0;
} else {
// keyFP_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 {

View File

@ -1,128 +1,187 @@
<!-- SidePanelItem.vue -->
<template>
<SidePanelItem title="过鱼设施介绍">
<div 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">
<!-- 图片 -->
<img :src="item.url" alt="" />
<!-- 说明文字随媒体项移动 -->
<div class="text">{{ item.text }}</div>
<!-- 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"
@click="handleItemClick(originalMediaData)">
<!-- 图片 -->
<img :src="item.url" :alt="item.stnm" loading="lazy" />
<!-- 说明文字随媒体项移动 -->
<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: currentRealIndex === index }" @click="goToSlide(index)"></span>
</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>
<!-- 独立的文字说明区域随跑马灯切换而变化 -->
<div v-if="hasData" class="description-text" @click="handleItemClick(originalMediaData)">
{{ currentDescription }}
</div>
</div>
<!-- 独立的文字说明区域随跑马灯切换而变化 -->
<div class="description-text">
{{ 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.0m14.0m,最大高度 29.85m37.00m。鱼道由诱鱼系统、入口、池室、休息池、观察室和出口等组成,其中诱鱼系统和入口布置于下游厂房尾水侧,出口布置于上游泄洪闸进口侧。鱼道采取连续“绕弯”方式布置,全长 597m平均坡降为 3.85%。沙坪二级鱼道位于泄洪闸与厂房之间,鱼道上下游方向长 224.42m,宽 10.0m14.0m,最大高度 29.85m37.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;

View File

@ -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 || [];

View File

@ -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) {

View File

@ -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>

View File

@ -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(',');
}
//

View File

@ -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;

View File

@ -347,11 +347,11 @@ const handleDetailSearchFinish = (values: any) => {
dataType: 'date',
value: values.strdt[1] + ' 23:59:59'
},
values.hbrvcd !== 'all' && {
field: 'basinCode',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
values.rvcd !== "all" && {
field: "basinCode",
operator: "eq",
dataType: "string",
value: values.rvcd,
},
values.rstcd && {
field: 'stationCode',

View File

@ -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;

View File

@ -308,12 +308,12 @@ const handleSearchFinish = (values: any) => {
dataType: 'string',
value: values.rstcd
},
values.hbrvcd !== 'all' && {
field: 'hbrvcd',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
}
values.rvcd !== "all" && {
field: "rvcd",
operator: "eq",
dataType: "string",
value: values.rvcd,
},
].filter(Boolean);
const filter = {

View File

@ -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"
@ -370,7 +370,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) {
@ -385,16 +385,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);
@ -404,12 +404,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);
@ -444,7 +444,7 @@ const weightError = ref<string>('');
//
const defaultFormData = reactive({
id: undefined,
hbrvcd: undefined,
rvcd: undefined,
stcd: undefined,
rstcd: undefined,
strdt: undefined,
@ -469,13 +469,13 @@ const filterOption = (inputValue: string, option: any) => {
};
//
const rules: Record<string, Rule[]> = {
hbrvcd: [{ required: true, message: '请选择流域', trigger: 'change' }],
rstcd: [{ required: true, message: '请选择电站', trigger: 'change' }],
stcd: [{ required: true, message: '请选择过鱼设施', trigger: 'change' }],
strdt: [{ required: true, message: '请选择过鱼时间', trigger: 'change' }],
ftp: [{ required: true, message: '请选择鱼种类', trigger: 'change' }],
direction: [{ required: true, message: '请选择游向', trigger: 'change' }],
fcnt: [{ 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" }],
ftp: [{ required: true, message: "请选择鱼种类", trigger: "change" }],
direction: [{ required: true, message: "请选择游向", trigger: "change" }],
fcnt: [{ required: true, message: "请输入过鱼数量", trigger: "change" }],
};
//
@ -848,8 +848,8 @@ watch(
//
// getBaseDropdownSelect();//
getHbrvcdDropdownSelect(); //
getEngInfoDropdownSelect(formData.hbrvcd);
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
getEngInfoDropdownSelect(formData.rvcd);
getFpssDropdownSelect(formData.rstcd, formData.rvcd);
initForm();
}
},

View File

@ -138,7 +138,7 @@ const localTypeDate = ref<string>(null);
const basicSearchRef = ref<any>();
const initSearchData = {
hbrvcd: 'all',
rvcd: "all",
// baseId: "all",
stcd: null,
rstcd: null,
@ -154,9 +154,9 @@ const initSearchData = {
const searchData = ref<any>({ ...initSearchData });
const searchList: any = computed(() => [
{
type: 'waterStation',
name: 'hbrvcd',
label: '流域',
type: "waterStation",
name: "rvcd",
label: "流域",
fieldProps: {
allowClear: true
},
@ -225,9 +225,9 @@ const onValuesChange = (changedValues: any, allValues: any) => {
searchData.value = { ...searchData.value, ...allValues };
// searchData便使
if (
Object.keys(changedValues)[0] == 'rstcd' ||
Object.keys(changedValues)[0] == 'baseId' ||
Object.keys(changedValues)[0] == 'hbrvcd'
Object.keys(changedValues)[0] == "rstcd" ||
Object.keys(changedValues)[0] == "baseId" ||
Object.keys(changedValues)[0] == "rvcd"
) {
const formInstance = basicSearchRef.value?.formData;
formInstance.stcd = null;

View File

@ -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");
});
}

View File

@ -613,8 +613,8 @@ const handleModalOk = () => {
// message.warning("");
// return;
// }
if (fileTableData.value[i].warnings.includes('hbrvcd')) {
message.warning('请检查流域,流域填写有误!');
if (fileTableData.value[i].warnings.includes("rvcd")) {
message.warning("请检查流域,流域填写有误!");
return;
}
if (fileTableData.value[i].warnings.includes('rstcd')) {
@ -880,12 +880,12 @@ const handleSearchFinish = (values: any) => {
dataType: 'string',
value: values.rstcd
},
values.hbrvcd !== 'all' && {
field: 'hbrvcd',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
}
values.rvcd !== "all" && {
field: "rvcd",
operator: "eq",
dataType: "string",
value: values.rvcd,
},
// values.baseId !== "all" && {
// field: "baseId",
// operator: "eq",

View File

@ -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;

View File

@ -378,11 +378,11 @@ const handleSearchFinish = (values: any) => {
dataType: 'string',
value: values.status
},
values.hbrvcd !== 'all' && {
field: 'hbrvcd',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
values.rvcd !== "all" && {
field: "rvcd",
operator: "eq",
dataType: "string",
value: values.rvcd,
},
values.stcd && {
field: 'stcd',
@ -616,11 +616,11 @@ const handleDetailSearchFinish = (values: any) => {
dataType: 'string',
value: values.rstcd
},
values.hbrvcd !== 'all' && {
field: 'hbrvcd',
operator: 'eq',
dataType: 'string',
value: values.hbrvcd
values.rvcd !== "all" && {
field: "rvcd",
operator: "eq",
dataType: "string",
value: values.rvcd,
},
approvalId.value && {
field: 'approvalId', //

View File

@ -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,