Merge branch 'main' of http://121.37.111.42:3000/zhengsl/WholeProcessPlatform into main_hzz
This commit is contained in:
commit
c34db88aaf
@ -52,7 +52,7 @@ export function registerUser(data: any): AxiosPromise<any> {
|
|||||||
*/
|
*/
|
||||||
export function getBasinList(): AxiosPromise<any[]> {
|
export function getBasinList(): AxiosPromise<any[]> {
|
||||||
return request({
|
return request({
|
||||||
url: '/env/hbrv/regDropdown',
|
url: '/env/rvcd/regDropdown',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
// params: baseid ? { baseid } : {}
|
// 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) {
|
export function getSelectForDropdown(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/env/hbrv/selectForDropdown',
|
url: '/env/rvcd/selectForDropdown',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
@ -113,7 +113,7 @@ export function updatePassword (queryParams:any) {
|
|||||||
//获取过鱼设施权限树
|
//获取过鱼设施权限树
|
||||||
export function getFishtree(queryParams:any) {
|
export function getFishtree(queryParams:any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/env/tree/hbrvEng',
|
url: '/env/tree/rvcdEng',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: queryParams
|
params: queryParams
|
||||||
});
|
});
|
||||||
|
|||||||
@ -96,21 +96,22 @@
|
|||||||
</a-select> -->
|
</a-select> -->
|
||||||
<!-- 流域下拉框 -->
|
<!-- 流域下拉框 -->
|
||||||
<a-select
|
<a-select
|
||||||
:value="formData.hbrvcd"
|
:value="formData.rvcd"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
@change="lyChange"
|
@change="lyChange"
|
||||||
show-search
|
show-search
|
||||||
:loading="shuJuTianBaoStore.lyLoading"
|
:loading="shuJuTianBaoStore.lyLoading"
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
style="width: 135px"
|
style="width: 135px"
|
||||||
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto', minWidth: '360px' }"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in shuJuTianBaoStore.lyOption"
|
v-for="opt in shuJuTianBaoStore.lyOption"
|
||||||
:key="opt.hbrvcd"
|
:key="opt.rvcd"
|
||||||
:value="opt.hbrvcd"
|
:value="opt.rvcd"
|
||||||
:label="opt.hbrvnm"
|
:label="opt.rvnm"
|
||||||
>
|
>
|
||||||
{{ opt.hbrvnm }}
|
{{ opt.rvnm }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
<!-- 电站下拉框 -->
|
<!-- 电站下拉框 -->
|
||||||
@ -329,7 +330,7 @@ const initForm = () => {
|
|||||||
// 下拉菜单
|
// 下拉菜单
|
||||||
// shuJuTianBaoStore.getBaseOption();
|
// shuJuTianBaoStore.getBaseOption();
|
||||||
shuJuTianBaoStore.getSelectForOption();
|
shuJuTianBaoStore.getSelectForOption();
|
||||||
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
||||||
}
|
}
|
||||||
if (item.fieldProps?.required) {
|
if (item.fieldProps?.required) {
|
||||||
rules[item.name] = [
|
rules[item.name] = [
|
||||||
@ -362,23 +363,23 @@ const triggerManualValuesChange = (changedKey: string, newValue: any) => {
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
const lyChange = (value: any) => {
|
const lyChange = (value: any) => {
|
||||||
formData.hbrvcd = value;
|
formData.rvcd = value;
|
||||||
formData.rstcd = "";
|
formData.rstcd = "";
|
||||||
shuJuTianBaoStore.getEngOption(formData.hbrvcd);
|
shuJuTianBaoStore.getEngOption(formData.rvcd);
|
||||||
|
|
||||||
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
// 【关键修改】手动触发 valuesChange,因为 a-form-item-rest 阻断了自动监听
|
||||||
triggerManualValuesChange("hbrvcd", formData.hbrvcd);
|
triggerManualValuesChange("rvcd", formData.rvcd);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stcdIdChange = (value: any) => {
|
const stcdIdChange = (value: any) => {
|
||||||
if (props.zhujianfujian == "fu") {
|
if (props.zhujianfujian == "fu") {
|
||||||
formData.rstcd = value;
|
formData.rstcd = value;
|
||||||
shuJuTianBaoStore.getFpssOption(formData.hbrvcd, value);
|
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
||||||
// 【关键修改】手动触发 valuesChange
|
// 【关键修改】手动触发 valuesChange
|
||||||
triggerManualValuesChange("rstcd", formData.rstcd);
|
triggerManualValuesChange("rstcd", formData.rstcd);
|
||||||
} else {
|
} else {
|
||||||
formData.stcd = value;
|
formData.stcd = value;
|
||||||
shuJuTianBaoStore.getFpssOption(formData.hbrvcd, value);
|
shuJuTianBaoStore.getFpssOption(formData.rvcd, value);
|
||||||
// 【关键修改】手动触发 valuesChange
|
// 【关键修改】手动触发 valuesChange
|
||||||
triggerManualValuesChange("stcd", formData.stcd);
|
triggerManualValuesChange("stcd", formData.stcd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2002,7 +2002,7 @@ const StinfoAiVidoPointColumns: Array<any> = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '所属行政区',
|
name: '所属行政区',
|
||||||
filed: 'addvcdName ',
|
filed: 'addvcdName',
|
||||||
visible: true,
|
visible: true,
|
||||||
type: 'select',
|
type: 'select',
|
||||||
url: '',
|
url: '',
|
||||||
|
|||||||
@ -309,8 +309,8 @@ const FPTabs: Array<any> =
|
|||||||
name: '基础信息',
|
name: '基础信息',
|
||||||
key: 'basicInfo',
|
key: 'basicInfo',
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
url: '/bbi/siteBipc/getSiteBasicInfo',
|
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
|
||||||
code: 'gyss.tabs.jcxx'
|
// code: 'gyss.tabs.jcxx'
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// name: '实时视频',
|
// name: '实时视频',
|
||||||
@ -1025,8 +1025,8 @@ const videoTabs: Array<any> = [
|
|||||||
name: '基础信息',
|
name: '基础信息',
|
||||||
key: 'basicInfo',
|
key: 'basicInfo',
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
url: '/bbi/siteBipc/getSiteBasicInfo',
|
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
|
||||||
default: true // 默认显示
|
default: true, // 默认显示
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '实时视频',
|
name: '实时视频',
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
<div class="carousel-inner">
|
<div class="carousel-inner">
|
||||||
<div class="carousel-track" :style="trackStyle">
|
<div class="carousel-track" :style="trackStyle">
|
||||||
<div v-for="(item, index) in originalMediaData" :key="index" class="carousel-item">
|
<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" /> -->
|
<!-- <img :src="item.url" :alt="item.title" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -17,7 +17,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card_right">
|
<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">
|
<div class="card_text_content">
|
||||||
{{ currentDescription }}
|
{{ currentDescription }}
|
||||||
</div>
|
</div>
|
||||||
@ -52,7 +56,7 @@ const props = defineProps<{
|
|||||||
description: string;
|
description: string;
|
||||||
url: string;
|
url: string;
|
||||||
}>;
|
}>;
|
||||||
index:any
|
index: any
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
@ -115,7 +119,9 @@ const jumpToSlide = (targetIndex: number) => {
|
|||||||
const currentDescription = computed(() => {
|
const currentDescription = computed(() => {
|
||||||
return originalMediaData.value[currentIndex.value]?.description || '';
|
return originalMediaData.value[currentIndex.value]?.description || '';
|
||||||
});
|
});
|
||||||
|
const currentTitle = computed(() => {
|
||||||
|
return originalMediaData.value[currentIndex.value]?.title || '';
|
||||||
|
});
|
||||||
// 页面加载时执行
|
// 页面加载时执行
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('ArtsDetail mounted - props.index:', props.index, 'props.dataSource.length:', props.dataSource?.length);
|
console.log('ArtsDetail mounted - props.index:', props.index, 'props.dataSource.length:', props.dataSource?.length);
|
||||||
@ -223,6 +229,16 @@ watch(
|
|||||||
box-sizing: border-box;
|
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 {
|
.card_text_content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 96%;
|
height: 96%;
|
||||||
|
|||||||
@ -716,7 +716,6 @@ watch(
|
|||||||
formState.sfdb = ''
|
formState.sfdb = ''
|
||||||
formState.stnm = ''
|
formState.stnm = ''
|
||||||
pieCode.value = []
|
pieCode.value = []
|
||||||
debugger
|
|
||||||
// 重新加载数据
|
// 重新加载数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
handleSearch()
|
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 -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="过鱼监测">
|
<SidePanelItem title="过鱼监测">
|
||||||
<div class="facility-grid">
|
<div v-if="loading" class="loading-container">
|
||||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card">
|
<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 style="width: 70px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
||||||
<div class="facility-icon">
|
<div class="facility-icon">
|
||||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
||||||
@ -12,56 +16,81 @@
|
|||||||
<div class="facility-info">
|
<div class="facility-info">
|
||||||
<div class="facility-name">{{ facility.name }}</div>
|
<div class="facility-name">{{ facility.name }}</div>
|
||||||
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
|
<div style="font-size: 16px;"> <span class="facility-count">{{ facility.count
|
||||||
}}</span><span>个</span></div>
|
}}</span><span>个</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SidePanelItem>
|
</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>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.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({
|
defineOptions({
|
||||||
name: 'guoyusheshijiansheqingkuang'
|
name: 'guoyusheshijiansheqingkuang'
|
||||||
});
|
});
|
||||||
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
// 设施数据
|
// 设施数据
|
||||||
const facilities = ref([
|
const facilities = ref([
|
||||||
{
|
{
|
||||||
name: '视频监控',
|
name: '视频监控',
|
||||||
count: 56,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-shipinjiankongshebei'
|
icon: 'icon iconfont icon-shipinjiankongshebei'
|
||||||
|
, sttp: 'VD_FP'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'AI摄像头',
|
name: 'AI摄像头',
|
||||||
count: 1722,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-jiankong'
|
icon: 'icon iconfont icon-jiankong', sttp: 'VD_WVD'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '声纳',
|
name: '声纳',
|
||||||
count: 135,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-dwsjhQianzhidangqiang'
|
icon: 'icon iconfont icon-dwsjhQianzhidangqiang', sttp: 'VD_SN'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '水质设备',
|
name: '水质设备',
|
||||||
count: 135,
|
count: 5,
|
||||||
icon: 'icon iconfont icon-shuizhijiancezhan'
|
icon: 'icon iconfont icon-shuizhijiancezhan'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '水文设备',
|
name: '水文设备',
|
||||||
count: 56,
|
count: 8,
|
||||||
icon: 'icon iconfont icon-guojiashuizhizhan'
|
icon: 'icon iconfont icon-guojiashuizhizhan'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '气象设备',
|
name: '气象设备',
|
||||||
count: 1722,
|
count: 4,
|
||||||
icon: 'icon iconfont icon-qixiangzhan'
|
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(() => {
|
onMounted(() => {
|
||||||
@ -73,6 +102,104 @@ onMounted(() => {
|
|||||||
onUnmounted(() => {
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -131,4 +258,11 @@ onUnmounted(() => {
|
|||||||
color: #2f6b98;
|
color: #2f6b98;
|
||||||
// font-weight: 600;
|
// font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
</style>
|
</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,58 +1,135 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="过鱼设施">
|
<SidePanelItem title="过鱼设施">
|
||||||
<div class="facility-grid">
|
<a-spin :spinning="loading" tip="加载中...">
|
||||||
<div v-for="facility in facilities" :key="facility.name" class="facility-card">
|
<div class="facility-grid">
|
||||||
<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"
|
||||||
<div class="facility-icon">
|
@click="handleFacilityClick(facility)">
|
||||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
<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>
|
</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>
|
||||||
</div>
|
</a-spin>
|
||||||
</SidePanelItem>
|
</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>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.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({
|
defineOptions({
|
||||||
name: 'guoyusheshijiansheqingkuang'
|
name: 'qixidibaohugongzuokaizhanQK'
|
||||||
});
|
});
|
||||||
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
// loading状态
|
||||||
|
const loading = ref(false);
|
||||||
// 设施数据
|
// 设施数据
|
||||||
const facilities = ref([
|
const facilities = ref([
|
||||||
{
|
{
|
||||||
name: '鱼道',
|
name: '鱼道',
|
||||||
count: 56,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssYudao'
|
icon: 'icon iconfont icon-map-gyssYudao',
|
||||||
|
key: 'FP_1'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '集运鱼系统',
|
name: '集运鱼系统',
|
||||||
count: 1722,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssJiyunyuxitong'
|
icon: 'icon iconfont icon-map-gyssJiyunyuxitong',
|
||||||
|
key: 'FP_3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '升鱼机',
|
name: '升鱼机',
|
||||||
count: 135,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssShengyuji'
|
icon: 'icon iconfont icon-map-gyssShengyuji',
|
||||||
|
key: 'FP_4'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '其他',
|
name: '其他',
|
||||||
count: 135,
|
count: 0,
|
||||||
icon: 'icon iconfont icon-map-gyssQita'
|
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(() => {
|
onMounted(() => {
|
||||||
// 延迟初始化,确保容器已渲染
|
// 延迟初始化,确保容器已渲染
|
||||||
@ -96,7 +173,7 @@ onUnmounted(() => {
|
|||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
// margin-right: 8px;
|
// margin-right: 8px;
|
||||||
background: rgb(47, 107, 152);
|
background: #5389b5;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
.anticon {
|
.anticon {
|
||||||
|
|||||||
@ -1,128 +1,187 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
<!-- SidePanelItem.vue -->
|
||||||
<template>
|
<template>
|
||||||
<SidePanelItem title="过鱼设施介绍">
|
<SidePanelItem title="过鱼设施介绍">
|
||||||
<div class="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
<!-- Loading 和空状态容器 -->
|
||||||
<!-- 跑马灯轨道容器 -->
|
<a-spin :spinning="loading" class="carousel-container-wrapper">
|
||||||
<div class="carousel-track" :class="{ 'no-transition': isTransitioning }"
|
<div v-if="hasData" class="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
||||||
:style="{ transform: `translateX(-${currentIndex * 100}%)` }">
|
<!-- 跑马灯轨道容器 -->
|
||||||
<!-- 遍历所有媒体项(包含克隆项) -->
|
<div class="carousel-track" :class="{ 'no-transition': isTransitioning }"
|
||||||
<div v-for="(item, index) in renderMediaData" :key="index" class="carousel-item">
|
:style="{ transform: `translateX(-${currentIndex * 100}%)` }">
|
||||||
<!-- 图片 -->
|
<!-- 遍历所有媒体项(包含克隆项) -->
|
||||||
<img :src="item.url" alt="" />
|
<div v-for="(item, index) in renderMediaData" :key="index" class="carousel-item"
|
||||||
<!-- 说明文字(随媒体项移动) -->
|
@click="handleItemClick(originalMediaData)">
|
||||||
<div class="text">{{ item.text }}</div>
|
<!-- 图片 -->
|
||||||
|
<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>
|
</div>
|
||||||
|
<!-- 暂无数据状态 -->
|
||||||
|
|
||||||
<!-- 面板指示器(固定在底部右侧) -->
|
<!-- 独立的文字说明区域(随跑马灯切换而变化) -->
|
||||||
<div class="pagination-dots-fixed">
|
<div v-if="hasData" class="description-text" @click="handleItemClick(originalMediaData)">
|
||||||
<span
|
{{ currentDescription }}
|
||||||
v-for="(dot, index) in originalMediaData"
|
|
||||||
:key="index"
|
|
||||||
class="dot"
|
|
||||||
:class="{ active: getCurrentRealIndex() === index }"
|
|
||||||
@click="goToSlide(index)"
|
|
||||||
></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<a-empty v-else description="暂无数据" :image="simpleImage" />
|
||||||
|
</a-spin>
|
||||||
<!-- 独立的文字说明区域(随跑马灯切换而变化) -->
|
|
||||||
<div class="description-text">
|
|
||||||
{{ currentDescription }}
|
|
||||||
</div>
|
|
||||||
</SidePanelItem>
|
</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>
|
</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({
|
defineOptions({
|
||||||
name: 'ZhiWuYuanJianSheJiJieRuQingKuangBar'
|
name: 'ZhiWuYuanJianSheJiJieRuQingKuangBar'
|
||||||
});
|
});
|
||||||
|
|
||||||
// 媒体类型定义
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
interface MediaItem {
|
const baseid = ref('all'); // 默认值为 'all'
|
||||||
type: 'image' | 'video';
|
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||||
url: string;
|
// 弹框控制
|
||||||
text: string;
|
const modalVisible = ref(false);
|
||||||
description: string;
|
const currentItem = ref<any>(null);
|
||||||
}
|
// ==================== 数据状态 ====================
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(false);
|
||||||
|
// 是否有数据
|
||||||
|
const hasData = ref(false);
|
||||||
|
// 空状态图片
|
||||||
|
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||||
|
|
||||||
// 原始媒体数据(3条测试数据)
|
// 原始媒体数据
|
||||||
const originalMediaData = ref<MediaItem[]>([
|
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[]>([]);
|
|
||||||
|
|
||||||
// 当前显示索引(指向renderMediaData)
|
// 当前显示索引(指向renderMediaData)
|
||||||
const currentIndex = ref(1); // 从1开始,跳过克隆的首项
|
const currentIndex = ref(1); // 从1开始,跳过克隆的首项
|
||||||
|
|
||||||
// 定时器引用
|
// 是否正在切换动画中(用于禁用transition)
|
||||||
let timer: any = null;
|
const isTransitioning = ref(false);
|
||||||
|
|
||||||
// 鼠标悬停状态
|
// 鼠标悬停状态
|
||||||
const isHovering = 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;
|
const length = originalMediaData.value.length;
|
||||||
if (length === 0) return;
|
if (length === 0) return [];
|
||||||
|
|
||||||
renderMediaData.value = [
|
return [
|
||||||
originalMediaData.value[length - 1], // 克隆最后一项
|
originalMediaData.value[length - 1], // 克隆最后一项
|
||||||
...originalMediaData.value, // 原始数据
|
...originalMediaData.value, // 原始数据
|
||||||
originalMediaData.value[0] // 克隆第一项
|
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 = () => {
|
const startAutoPlay = () => {
|
||||||
if (timer) clearInterval(timer);
|
stopAutoPlay(); // 先清除旧的定时器
|
||||||
timer = setInterval(() => {
|
autoPlayTimer = setInterval(() => {
|
||||||
if (!isHovering.value && !isTransitioning.value) {
|
if (!isHovering.value && !isTransitioning.value) {
|
||||||
nextSlide();
|
nextSlide();
|
||||||
}
|
}
|
||||||
}, 4000);
|
}, CAROUSEL_CONFIG.autoPlayInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换到下一张
|
/**
|
||||||
|
* 停止自动轮播
|
||||||
|
*/
|
||||||
|
const stopAutoPlay = () => {
|
||||||
|
if (autoPlayTimer) {
|
||||||
|
clearInterval(autoPlayTimer);
|
||||||
|
autoPlayTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换到下一张
|
||||||
|
*/
|
||||||
const nextSlide = () => {
|
const nextSlide = () => {
|
||||||
currentIndex.value++;
|
currentIndex.value++;
|
||||||
|
|
||||||
// 延迟检查是否需要无缝跳转
|
// 延迟检查是否需要无缝跳转(与transition时间一致)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
checkSeamlessJump();
|
handleSeamlessLoop();
|
||||||
}, 500); // 与transition时间一致
|
}, CAROUSEL_CONFIG.transitionDuration);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 检查是否需要无缝跳转(克隆项处理)
|
/**
|
||||||
const checkSeamlessJump = () => {
|
* 处理无缝循环(克隆项处理)
|
||||||
|
*/
|
||||||
|
const handleSeamlessLoop = () => {
|
||||||
const realLength = originalMediaData.value.length;
|
const realLength = originalMediaData.value.length;
|
||||||
|
if (realLength === 0) return;
|
||||||
|
|
||||||
// 如果到达克隆的最后一项(索引 = realLength + 1)
|
// 如果到达克隆的最后一项(索引 = realLength + 1)
|
||||||
if (currentIndex.value >= realLength + 1) {
|
if (currentIndex.value >= realLength + 1) {
|
||||||
@ -141,33 +200,114 @@ const checkSeamlessJump = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理鼠标进入
|
/**
|
||||||
|
* 处理鼠标进入
|
||||||
|
*/
|
||||||
const handleMouseEnter = () => {
|
const handleMouseEnter = () => {
|
||||||
isHovering.value = true;
|
isHovering.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理鼠标离开
|
/**
|
||||||
|
* 处理鼠标离开
|
||||||
|
*/
|
||||||
const handleMouseLeave = () => {
|
const handleMouseLeave = () => {
|
||||||
isHovering.value = false;
|
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(() => {
|
onMounted(() => {
|
||||||
initRenderData();
|
|
||||||
startAutoPlay();
|
startAutoPlay();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 组件卸载时清理
|
|
||||||
onUnmounted(() => {
|
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 getCurrentRealIndex = () => {
|
||||||
const realLength = originalMediaData.value.length;
|
const realLength = originalMediaData.value.length;
|
||||||
@ -179,13 +319,15 @@ const getCurrentRealIndex = () => {
|
|||||||
|
|
||||||
return realIndex;
|
return realIndex;
|
||||||
};
|
};
|
||||||
|
// 处理项目点击事件
|
||||||
// 跳转到指定幻灯片
|
const handleItemClick = (item: any) => {
|
||||||
const goToSlide = (targetIndex: number) => {
|
console.log('轮播图项目被点击:', item, getCurrentRealIndex());
|
||||||
if (isTransitioning.value) return;
|
currentItem.value = item.map((item: any) => ({
|
||||||
|
url: item.url || '',
|
||||||
// 计算目标索引(考虑克隆项偏移)
|
description: item.introduce || '',
|
||||||
currentIndex.value = targetIndex + 1;
|
title: item.stnm || ''
|
||||||
|
}));
|
||||||
|
modalVisible.value = true;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -193,8 +335,6 @@ const goToSlide = (targetIndex: number) => {
|
|||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 228px;
|
height: 228px;
|
||||||
// border: 1px solid #7fd6ff;
|
|
||||||
// border-radius: 5px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden; // 隐藏超出容器的内容
|
overflow: hidden; // 隐藏超出容器的内容
|
||||||
|
|
||||||
@ -216,9 +356,9 @@ const goToSlide = (targetIndex: number) => {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-shrink: 0; // 防止被压缩
|
flex-shrink: 0; // 防止被压缩
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
img,
|
img {
|
||||||
video {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover; // 保持比例填充
|
object-fit: cover; // 保持比例填充
|
||||||
@ -268,13 +408,12 @@ const goToSlide = (targetIndex: number) => {
|
|||||||
|
|
||||||
// 独立的文字说明区域
|
// 独立的文字说明区域
|
||||||
.description-text {
|
.description-text {
|
||||||
// padding: 8px 12px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
// min-height: 40px;
|
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
margin-bottom: 20px;
|
// margin-bottom: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
// 多行文本溢出省略
|
// 多行文本溢出省略
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
|
|||||||
@ -401,7 +401,6 @@ const getChartData = async (startDate: string, endDate: string, stcd: string) =>
|
|||||||
|
|
||||||
// 调用实际的API获取数据
|
// 调用实际的API获取数据
|
||||||
const res = await sdrvwtsGetKendoList(params);
|
const res = await sdrvwtsGetKendoList(params);
|
||||||
debugger
|
|
||||||
console.log('API返回结果:', res);
|
console.log('API返回结果:', res);
|
||||||
|
|
||||||
let data = res?.data?.data || [];
|
let data = res?.data?.data || [];
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
const res = await getSelectForDropdown({});
|
const res = await getSelectForDropdown({});
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
const list = [
|
const list = [
|
||||||
{ hbrvcd: 'all', hbrvnm: '当前全部', baseid: '01' },
|
{ rvcd: 'all', rvnm: '当前全部', baseid: '01' },
|
||||||
...res.data
|
...res.data
|
||||||
];
|
];
|
||||||
// 直接赋值给 ref,触发响应式更新
|
// 直接赋值给 ref,触发响应式更新
|
||||||
@ -58,15 +58,15 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 获取电站列表
|
// 获取电站列表
|
||||||
const getEngOption = async (hbrvcd: string) => {
|
const getEngOption = async (rvcd: string) => {
|
||||||
try {
|
try {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
const param = rvcd === 'all' ? {} : { rvcd };
|
||||||
const res = await getEngInfoDropdown(param);
|
const res = await getEngInfoDropdown(param);
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
// 直接赋值给 ref
|
// 直接赋值给 ref
|
||||||
engOption.value = res.data;
|
engOption.value = res.data;
|
||||||
getFpssOption(hbrvcd, '');
|
getFpssOption(rvcd, '');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取电站列表失败:', 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 {
|
try {
|
||||||
fpssLoading.value = true;
|
fpssLoading.value = true;
|
||||||
const param = hbrvcd === 'all' ? {} : { hbrvcd };
|
const param = rvcd === 'all' ? {} : { rvcd };
|
||||||
const res = await getFpssDropdown({...param, rstcd: rstcd});
|
const res = await getFpssDropdown({...param, rstcd: rstcd});
|
||||||
fpssOption.value = res.data;
|
fpssOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -5,6 +5,17 @@ import GuoYuSheShiJieShao from "@/modules/guoyusheshijieshao/index.vue"
|
|||||||
import GuoYuSheShiJianSheQingKuang from "@/modules/guoyusheshijiansheqingkuang/index.vue"
|
import GuoYuSheShiJianSheQingKuang from "@/modules/guoyusheshijiansheqingkuang/index.vue"
|
||||||
import GuoYuJianCeTJ from "@/modules/guoyujiance/index.vue"
|
import GuoYuJianCeTJ from "@/modules/guoyujiance/index.vue"
|
||||||
import GYZLLB from "@/modules/GYZLLB/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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -14,8 +25,8 @@ import GYZLLB from "@/modules/GYZLLB/index.vue"
|
|||||||
</div>
|
</div>
|
||||||
<div class="rightContent">
|
<div class="rightContent">
|
||||||
<RightDrawer>
|
<RightDrawer>
|
||||||
<!-- <GuoYuSheShiJieShao /> -->
|
<GuoYuSheShiJieShao v-if="baseid != 'all'" />
|
||||||
<GuoYuSheShiJianSheQingKuang />
|
<GuoYuSheShiJianSheQingKuang v-if="baseid == 'all'" />
|
||||||
<GuoYuJianCeTJ />
|
<GuoYuJianCeTJ />
|
||||||
<GYZLLB title="过鱼总量" />
|
<GYZLLB title="过鱼总量" />
|
||||||
</RightDrawer>
|
</RightDrawer>
|
||||||
|
|||||||
@ -129,12 +129,12 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<!-- 流域(多选,数组,必填) -->
|
<!-- 流域(多选,数组,必填) -->
|
||||||
<a-form-item name="hbrvcdCode" label="流 域" required>
|
<a-form-item name="rvcdCode" label="流 域" required>
|
||||||
<a-select v-model:value="organizationData.hbrvcdCode" mode="multiple" placeholder="请选择流域"
|
<a-select v-model:value="organizationData.rvcdCode" mode="multiple" placeholder="请选择流域"
|
||||||
style="width: 100%" show-search :filter-option="filterOption" @change="onRvcdChange">
|
style="width: 100%" show-search :filter-option="filterOption" @change="onRvcdChange">
|
||||||
<a-select-option v-for="item in basinList" :key="item.hbrvcd" :value="item.hbrvcd"
|
<a-select-option v-for="item in basinList" :key="item.rvcd" :value="item.rvcd"
|
||||||
:label="item.hbrvnm">
|
:label="item.rvnm">
|
||||||
{{ item.hbrvnm }}
|
{{ item.rvnm }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@ -142,7 +142,7 @@
|
|||||||
<!-- 电站(多选,数组,必填,依赖流域) -->
|
<!-- 电站(多选,数组,必填,依赖流域) -->
|
||||||
<a-form-item name="stationCode" label="电 站" required>
|
<a-form-item name="stationCode" label="电 站" required>
|
||||||
<a-select v-model:value="organizationData.stationCode" mode="multiple" placeholder="请先选择流域"
|
<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">
|
:filter-option="filterOption">
|
||||||
<a-select-option v-for="item in stationList" :key="item.stcd" :value="item.stcd"
|
<a-select-option v-for="item in stationList" :key="item.stcd" :value="item.stcd"
|
||||||
:label="item.ennm">
|
:label="item.ennm">
|
||||||
@ -199,7 +199,7 @@ let smsTimer: any = null;
|
|||||||
const organizationData = reactive({
|
const organizationData = reactive({
|
||||||
groupCode: '', // 集团(单选,字符串)
|
groupCode: '', // 集团(单选,字符串)
|
||||||
companyCode: '', // 公司(单选,字符串)
|
companyCode: '', // 公司(单选,字符串)
|
||||||
hbrvcdCode: [], // 流域(多选,数组)
|
rvcdCode: [], // 流域(多选,数组)
|
||||||
stationCode: [] // 电站(多选,数组)
|
stationCode: [] // 电站(多选,数组)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ const organizationFormRef = ref();
|
|||||||
|
|
||||||
// ==================== 组织表单验证规则 ====================
|
// ==================== 组织表单验证规则 ====================
|
||||||
const organizationRules = {
|
const organizationRules = {
|
||||||
hbrvcdCode: [
|
rvcdCode: [
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: any[]) => {
|
validator: (rule: any, value: any[]) => {
|
||||||
if (!value || value.length === 0) {
|
if (!value || value.length === 0) {
|
||||||
@ -434,8 +434,8 @@ const onRvcdChange = () => {
|
|||||||
// 清空电站选择
|
// 清空电站选择
|
||||||
organizationData.stationCode = [];
|
organizationData.stationCode = [];
|
||||||
// 获取当前选中的所有流域ID,加载对应的电站列表
|
// 获取当前选中的所有流域ID,加载对应的电站列表
|
||||||
if (organizationData.hbrvcdCode && organizationData.hbrvcdCode.length > 0) {
|
if (organizationData.rvcdCode && organizationData.rvcdCode.length > 0) {
|
||||||
onBasinChange({ hbrvcds: organizationData.hbrvcdCode });
|
onBasinChange({ rvcds: organizationData.rvcdCode });
|
||||||
} else {
|
} else {
|
||||||
// 如果没有选择流域,清空电站列表
|
// 如果没有选择流域,清空电站列表
|
||||||
stationList.value = [];
|
stationList.value = [];
|
||||||
@ -490,7 +490,7 @@ const handleModalCancel = () => {
|
|||||||
// 重置组织表单数据
|
// 重置组织表单数据
|
||||||
organizationData.groupCode = '';
|
organizationData.groupCode = '';
|
||||||
organizationData.companyCode = '';
|
organizationData.companyCode = '';
|
||||||
organizationData.hbrvcdCode = [];
|
organizationData.rvcdCode = [];
|
||||||
organizationData.stationCode = [];
|
organizationData.stationCode = [];
|
||||||
// 清除表单验证状态
|
// 清除表单验证状态
|
||||||
organizationFormRef.value?.clearValidate();
|
organizationFormRef.value?.clearValidate();
|
||||||
@ -539,8 +539,8 @@ const onRegister = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 可选字段:流域(如果有值才传,数组转逗号分隔字符串)
|
// 可选字段:流域(如果有值才传,数组转逗号分隔字符串)
|
||||||
if (organizationData.hbrvcdCode && organizationData.hbrvcdCode.length > 0) {
|
if (organizationData.rvcdCode && organizationData.rvcdCode.length > 0) {
|
||||||
registerParams.hbrvcdCode = organizationData.hbrvcdCode.join(',');
|
registerParams.rvcdCode = organizationData.rvcdCode.join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 可选字段:电站(如果有值才传,数组转逗号分隔字符串)
|
// 可选字段:电站(如果有值才传,数组转逗号分隔字符串)
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const basicSearchRef = ref<any>();
|
|||||||
const btnLoading = ref<boolean>(false);
|
const btnLoading = ref<boolean>(false);
|
||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd: "all",
|
rvcd: "all",
|
||||||
stcd: null,
|
stcd: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ const searchData = ref<any>({ ...initSearchData });
|
|||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "hbrvcd",
|
name: "rvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
@ -72,7 +72,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
|||||||
searchData.value = { ...searchData.value, ...allValues };
|
searchData.value = { ...searchData.value, ...allValues };
|
||||||
if (
|
if (
|
||||||
Object.keys(changedValues)[0] == "rstcd" ||
|
Object.keys(changedValues)[0] == "rstcd" ||
|
||||||
Object.keys(changedValues)[0] == "hbrvcd"
|
Object.keys(changedValues)[0] == "rvcd"
|
||||||
) {
|
) {
|
||||||
const formInstance = basicSearchRef.value?.formData;
|
const formInstance = basicSearchRef.value?.formData;
|
||||||
formInstance.stcd = null;
|
formInstance.stcd = null;
|
||||||
|
|||||||
@ -347,11 +347,11 @@ const handleDetailSearchFinish = (values: any) => {
|
|||||||
dataType: 'date',
|
dataType: 'date',
|
||||||
value: values.strdt[1] + ' 23:59:59'
|
value: values.strdt[1] + ' 23:59:59'
|
||||||
},
|
},
|
||||||
values.hbrvcd !== 'all' && {
|
values.rvcd !== "all" && {
|
||||||
field: 'basinCode',
|
field: "basinCode",
|
||||||
operator: 'eq',
|
operator: "eq",
|
||||||
dataType: 'string',
|
dataType: "string",
|
||||||
value: values.hbrvcd
|
value: values.rvcd,
|
||||||
},
|
},
|
||||||
values.rstcd && {
|
values.rstcd && {
|
||||||
field: 'stationCode',
|
field: 'stationCode',
|
||||||
|
|||||||
@ -35,7 +35,7 @@ const localTypeDate = ref<string>(null);
|
|||||||
const basicSearchRef = ref<any>();
|
const basicSearchRef = ref<any>();
|
||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd: "all",
|
rvcd: "all",
|
||||||
stcd: null,
|
stcd: null,
|
||||||
rstcd: null,
|
rstcd: null,
|
||||||
ftp: null,
|
ftp: null,
|
||||||
@ -52,7 +52,7 @@ const searchData = ref<any>({ ...initSearchData });
|
|||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "hbrvcd",
|
name: "rvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
@ -121,7 +121,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
|||||||
if (
|
if (
|
||||||
Object.keys(changedValues)[0] == "rstcd" ||
|
Object.keys(changedValues)[0] == "rstcd" ||
|
||||||
Object.keys(changedValues)[0] == "baseId" ||
|
Object.keys(changedValues)[0] == "baseId" ||
|
||||||
Object.keys(changedValues)[0] == "hbrvcd"
|
Object.keys(changedValues)[0] == "rvcd"
|
||||||
) {
|
) {
|
||||||
const formInstance = basicSearchRef.value?.formData;
|
const formInstance = basicSearchRef.value?.formData;
|
||||||
formInstance.stcd = null;
|
formInstance.stcd = null;
|
||||||
|
|||||||
@ -308,12 +308,12 @@ const handleSearchFinish = (values: any) => {
|
|||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.rstcd
|
value: values.rstcd
|
||||||
},
|
},
|
||||||
values.hbrvcd !== 'all' && {
|
values.rvcd !== "all" && {
|
||||||
field: 'hbrvcd',
|
field: "rvcd",
|
||||||
operator: 'eq',
|
operator: "eq",
|
||||||
dataType: 'string',
|
dataType: "string",
|
||||||
value: values.hbrvcd
|
value: values.rvcd,
|
||||||
}
|
},
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
|
|||||||
@ -18,9 +18,9 @@
|
|||||||
>
|
>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="流域" name="hbrvcd">
|
<a-form-item label="流域" name="rvcd">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="formData.hbrvcd"
|
v-model:value="formData.rvcd"
|
||||||
:loading="hbrvcdLoading"
|
:loading="hbrvcdLoading"
|
||||||
placeholder="请选择流域"
|
placeholder="请选择流域"
|
||||||
:disabled="isView"
|
:disabled="isView"
|
||||||
@ -31,11 +31,11 @@
|
|||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in hbrvcdOption"
|
v-for="opt in hbrvcdOption"
|
||||||
:key="opt.hbrvcd"
|
:key="opt.rvcd"
|
||||||
:value="opt.hbrvcd"
|
:value="opt.rvcd"
|
||||||
:label="opt.hbrvnm"
|
:label="opt.rvnm"
|
||||||
>
|
>
|
||||||
{{ opt.hbrvnm }}
|
{{ opt.rvnm }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
v-model:value="formData.rstcd"
|
v-model:value="formData.rstcd"
|
||||||
:loading="engLoading"
|
:loading="engLoading"
|
||||||
placeholder="请选择电站名称"
|
placeholder="请选择电站名称"
|
||||||
:disabled="isView || !formData.hbrvcd"
|
:disabled="isView || !formData.rvcd"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@ -370,7 +370,7 @@ const getHbrvcdDropdownSelect = async () => {
|
|||||||
const res = await getSelectForDropdown({});
|
const res = await getSelectForDropdown({});
|
||||||
let list = res.data || [];
|
let list = res.data || [];
|
||||||
if (list && list.length > 0) {
|
if (list && list.length > 0) {
|
||||||
list = list.filter((item: any) => item.hbrvcd !== 'all');
|
list = list.filter((item: any) => item.rvcd !== "all");
|
||||||
}
|
}
|
||||||
hbrvcdOption.value = list;
|
hbrvcdOption.value = list;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -385,16 +385,16 @@ const getHbrvcdDropdownSelect = async () => {
|
|||||||
// await getEngInfoDropdownSelect(baseId);
|
// await getEngInfoDropdownSelect(baseId);
|
||||||
// await getFpssDropdownSelect(formData.rstcd, baseId);
|
// await getFpssDropdownSelect(formData.rstcd, baseId);
|
||||||
// };
|
// };
|
||||||
const hbrvcdChange = async (hbrvcd: string) => {
|
const hbrvcdChange = async (rvcd: string) => {
|
||||||
formData.rstcd = undefined;
|
formData.rstcd = undefined;
|
||||||
formData.stcd = undefined;
|
formData.stcd = undefined;
|
||||||
await getEngInfoDropdownSelect(hbrvcd);
|
await getEngInfoDropdownSelect(rvcd);
|
||||||
// await getFpssDropdownSelect(formData.rstcd, hbrvcd);
|
// await getFpssDropdownSelect(formData.rstcd, rvcd);
|
||||||
};
|
};
|
||||||
const getEngInfoDropdownSelect = async (hbrvcd: string) => {
|
const getEngInfoDropdownSelect = async (rvcd: string) => {
|
||||||
try {
|
try {
|
||||||
engLoading.value = true;
|
engLoading.value = true;
|
||||||
const res = await getEngInfoDropdown({ hbrvcd });
|
const res = await getEngInfoDropdown({ rvcd });
|
||||||
engOption.value = res.data;
|
engOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取电站列表失败', error);
|
console.error('获取电站列表失败', error);
|
||||||
@ -404,12 +404,12 @@ const getEngInfoDropdownSelect = async (hbrvcd: string) => {
|
|||||||
};
|
};
|
||||||
const engChange = async (rstcd: string) => {
|
const engChange = async (rstcd: string) => {
|
||||||
formData.stcd = undefined;
|
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 {
|
try {
|
||||||
fpssLoading.value = true;
|
fpssLoading.value = true;
|
||||||
const res = await getFpssDropdown({ rstcd, hbrvcd });
|
const res = await getFpssDropdown({ rstcd, rvcd });
|
||||||
fpssOption.value = res.data;
|
fpssOption.value = res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取流量列表失败', error);
|
console.error('获取流量列表失败', error);
|
||||||
@ -444,7 +444,7 @@ const weightError = ref<string>('');
|
|||||||
// 表单数据模型
|
// 表单数据模型
|
||||||
const defaultFormData = reactive({
|
const defaultFormData = reactive({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
hbrvcd: undefined,
|
rvcd: undefined,
|
||||||
stcd: undefined,
|
stcd: undefined,
|
||||||
rstcd: undefined,
|
rstcd: undefined,
|
||||||
strdt: undefined,
|
strdt: undefined,
|
||||||
@ -469,13 +469,13 @@ const filterOption = (inputValue: string, option: any) => {
|
|||||||
};
|
};
|
||||||
// 验证规则
|
// 验证规则
|
||||||
const rules: Record<string, Rule[]> = {
|
const rules: Record<string, Rule[]> = {
|
||||||
hbrvcd: [{ required: true, message: '请选择流域', trigger: 'change' }],
|
rvcd: [{ required: true, message: "请选择流域", trigger: "change" }],
|
||||||
rstcd: [{ required: true, message: '请选择电站', trigger: 'change' }],
|
rstcd: [{ required: true, message: "请选择电站", trigger: "change" }],
|
||||||
stcd: [{ required: true, message: '请选择过鱼设施', trigger: 'change' }],
|
stcd: [{ required: true, message: "请选择过鱼设施", trigger: "change" }],
|
||||||
strdt: [{ required: true, message: '请选择过鱼时间', trigger: 'change' }],
|
strdt: [{ required: true, message: "请选择过鱼时间", trigger: "change" }],
|
||||||
ftp: [{ required: true, message: '请选择鱼种类', trigger: 'change' }],
|
ftp: [{ required: true, message: "请选择鱼种类", trigger: "change" }],
|
||||||
direction: [{ required: true, message: '请选择游向', trigger: 'change' }],
|
direction: [{ required: true, message: "请选择游向", trigger: "change" }],
|
||||||
fcnt: [{ required: true, message: '请输入过鱼数量', trigger: 'change' }]
|
fcnt: [{ required: true, message: "请输入过鱼数量", trigger: "change" }],
|
||||||
};
|
};
|
||||||
|
|
||||||
// 计算是否为编辑模式
|
// 计算是否为编辑模式
|
||||||
@ -848,8 +848,8 @@ watch(
|
|||||||
// 弹窗打开时,初始化数据
|
// 弹窗打开时,初始化数据
|
||||||
// getBaseDropdownSelect();// 基地
|
// getBaseDropdownSelect();// 基地
|
||||||
getHbrvcdDropdownSelect(); // 流域
|
getHbrvcdDropdownSelect(); // 流域
|
||||||
getEngInfoDropdownSelect(formData.hbrvcd);
|
getEngInfoDropdownSelect(formData.rvcd);
|
||||||
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
|
getFpssDropdownSelect(formData.rstcd, formData.rvcd);
|
||||||
initForm();
|
initForm();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -138,7 +138,7 @@ const localTypeDate = ref<string>(null);
|
|||||||
const basicSearchRef = ref<any>();
|
const basicSearchRef = ref<any>();
|
||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd: 'all',
|
rvcd: "all",
|
||||||
// baseId: "all",
|
// baseId: "all",
|
||||||
stcd: null,
|
stcd: null,
|
||||||
rstcd: null,
|
rstcd: null,
|
||||||
@ -154,9 +154,9 @@ const initSearchData = {
|
|||||||
const searchData = ref<any>({ ...initSearchData });
|
const searchData = ref<any>({ ...initSearchData });
|
||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: 'waterStation',
|
type: "waterStation",
|
||||||
name: 'hbrvcd',
|
name: "rvcd",
|
||||||
label: '流域',
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true
|
allowClear: true
|
||||||
},
|
},
|
||||||
@ -225,9 +225,9 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
|||||||
searchData.value = { ...searchData.value, ...allValues };
|
searchData.value = { ...searchData.value, ...allValues };
|
||||||
// 同步更新本地 searchData,以便其他逻辑使用
|
// 同步更新本地 searchData,以便其他逻辑使用
|
||||||
if (
|
if (
|
||||||
Object.keys(changedValues)[0] == 'rstcd' ||
|
Object.keys(changedValues)[0] == "rstcd" ||
|
||||||
Object.keys(changedValues)[0] == 'baseId' ||
|
Object.keys(changedValues)[0] == "baseId" ||
|
||||||
Object.keys(changedValues)[0] == 'hbrvcd'
|
Object.keys(changedValues)[0] == "rvcd"
|
||||||
) {
|
) {
|
||||||
const formInstance = basicSearchRef.value?.formData;
|
const formInstance = basicSearchRef.value?.formData;
|
||||||
formInstance.stcd = null;
|
formInstance.stcd = null;
|
||||||
|
|||||||
@ -73,9 +73,9 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</template> -->
|
</template> -->
|
||||||
<!-- 流域名称 -->
|
<!-- 流域名称 -->
|
||||||
<template v-if="column.dataIndex === 'hbrvnm'">
|
<template v-if="column.dataIndex === 'rvnm'">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="editingData.hbrvcd"
|
v-model:value="editingData.rvcd"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
@ -83,14 +83,15 @@
|
|||||||
:loading="rowStates[index]?.hbrvcdLoading"
|
:loading="rowStates[index]?.hbrvcdLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(val) => handleHbrvcdChange(val, index, 'input')"
|
@change="(val) => handleHbrvcdChange(val, index, 'input')"
|
||||||
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto', minWidth: '300px' }"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in hbrvcdOptions"
|
v-for="opt in hbrvcdOptions"
|
||||||
:key="opt.hbrvcd"
|
:key="opt.rvcd"
|
||||||
:value="opt.hbrvcd"
|
:value="opt.rvcd"
|
||||||
:label="opt.hbrvnm"
|
:label="opt.rvnm"
|
||||||
>
|
>
|
||||||
{{ opt.hbrvnm }}
|
{{ opt.rvnm }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
@ -105,7 +106,7 @@
|
|||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
:loading="rowStates[index]?.engLoading"
|
:loading="rowStates[index]?.engLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="!editingData.hbrvcd"
|
:disabled="!editingData.rvcd"
|
||||||
@change="(val) => handleEngChange(val, index, 'input')"
|
@change="(val) => handleEngChange(val, index, 'input')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
@ -316,9 +317,9 @@ const modalColumns = ref([
|
|||||||
fixed: "left",
|
fixed: "left",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: "hbrvnm",
|
dataIndex: "rvnm",
|
||||||
key: "hbrvnm",
|
key: "rvnm",
|
||||||
dataIndexKey: "hbrvcd",
|
dataIndexKey: "rvcd",
|
||||||
title: "流域",
|
title: "流域",
|
||||||
width: 140,
|
width: 140,
|
||||||
},
|
},
|
||||||
@ -418,11 +419,11 @@ const loadHbrvcdOptions = async () => {
|
|||||||
const res = await getSelectForDropdown({});
|
const res = await getSelectForDropdown({});
|
||||||
let list = res.data || [];
|
let list = res.data || [];
|
||||||
if (list && list.length > 0) {
|
if (list && list.length > 0) {
|
||||||
list = list.filter((item: any) => item.hbrvcd !== "all");
|
list = list.filter((item: any) => item.rvcd !== "all");
|
||||||
}
|
}
|
||||||
hbrvcdOptions.value = list;
|
hbrvcdOptions.value = list;
|
||||||
} catch (e) {
|
} 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) ---
|
// --- 级联逻辑 (操作 editingData) ---
|
||||||
// const handleBaseChange = async (
|
// const handleBaseChange = async (
|
||||||
// hbrvcd: string,
|
// rvcd: string,
|
||||||
// index: number,
|
// index: number,
|
||||||
// type: string = "start"
|
// type: string = "start"
|
||||||
// ) => {
|
// ) => {
|
||||||
// const state = ensureRowState(index);
|
// const state = ensureRowState(index);
|
||||||
// editingData.value.baseName = hbrvcdOptions.value.find(
|
// editingData.value.baseName = hbrvcdOptions.value.find(
|
||||||
// (item: any) => item.hbrvcd == hbrvcd
|
// (item: any) => item.rvcd == rvcd
|
||||||
// )?.basename;
|
// )?.basename;
|
||||||
// delWarning(hbrvcd, "hbrvcd");
|
// delWarning(rvcd, "rvcd");
|
||||||
// // 清空后续字段
|
// // 清空后续字段
|
||||||
// if (type != "start") {
|
// if (type != "start") {
|
||||||
// editingData.value.rstcd = undefined;
|
// editingData.value.rstcd = undefined;
|
||||||
@ -462,7 +463,7 @@ const ensureRowState = (index: number) => {
|
|||||||
// }
|
// }
|
||||||
// state.engLoading = true;
|
// state.engLoading = true;
|
||||||
// try {
|
// try {
|
||||||
// const res = await getEngInfoDropdown({ hbrvcd });
|
// const res = await getEngInfoDropdown({ rvcd });
|
||||||
// state.engOptions = res.data || [];
|
// state.engOptions = res.data || [];
|
||||||
// } catch (e) {
|
// } catch (e) {
|
||||||
// message.error("获取电站列表失败");
|
// message.error("获取电站列表失败");
|
||||||
@ -471,17 +472,17 @@ const ensureRowState = (index: number) => {
|
|||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
const handleHbrvcdChange = async (
|
const handleHbrvcdChange = async (
|
||||||
hbrvcd: string,
|
rvcd: string,
|
||||||
index: number,
|
index: number,
|
||||||
type = "start"
|
type = "start"
|
||||||
) => {
|
) => {
|
||||||
const state = ensureRowState(index);
|
const state = ensureRowState(index);
|
||||||
editingData.value.hbrvnm = hbrvcdOptions.value.find(
|
editingData.value.rvnm = hbrvcdOptions.value.find(
|
||||||
(item: any) => item.hbrvcd == hbrvcd
|
(item: any) => item.rvcd == rvcd
|
||||||
)?.hbrvnm;
|
)?.rvnm;
|
||||||
delWarning(hbrvcd, "hbrvcd");
|
delWarning(rvcd, "rvcd");
|
||||||
if (hbrvcd == null) {
|
if (rvcd == null) {
|
||||||
delWarning(null, "hbrvcd");
|
delWarning(null, "rvcd");
|
||||||
delWarning(null, "stcd");
|
delWarning(null, "stcd");
|
||||||
}
|
}
|
||||||
// 清空后续字段
|
// 清空后续字段
|
||||||
@ -495,7 +496,7 @@ const handleHbrvcdChange = async (
|
|||||||
}
|
}
|
||||||
state.engLoading = true;
|
state.engLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getEngInfoDropdown({ hbrvcd });
|
const res = await getEngInfoDropdown({ rvcd });
|
||||||
state.engOptions = res.data || [];
|
state.engOptions = res.data || [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error("获取电站列表失败");
|
message.error("获取电站列表失败");
|
||||||
@ -521,7 +522,7 @@ const handleEngChange = async (rstcd: string, index: number, type = "start") =>
|
|||||||
}
|
}
|
||||||
state.fpssLoading = true;
|
state.fpssLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getFpssDropdown({ rstcd, hbrvcd: editingData.value.hbrvcd });
|
const res = await getFpssDropdown({ rstcd, rvcd: editingData.value.rvcd });
|
||||||
state.fpssOptions = res.data || [];
|
state.fpssOptions = res.data || [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error("获取设施列表失败");
|
message.error("获取设施列表失败");
|
||||||
@ -572,9 +573,9 @@ const startEdit = (index: number) => {
|
|||||||
processStringToMinMax(editingData.value);
|
processStringToMinMax(editingData.value);
|
||||||
|
|
||||||
editingRowIndex.value = index;
|
editingRowIndex.value = index;
|
||||||
if (editingData.value.warnings.includes("hbrvcd")) {
|
if (editingData.value.warnings.includes("rvcd")) {
|
||||||
editingData.value.hbrvcd = null;
|
editingData.value.rvcd = null;
|
||||||
editingData.value.hbrvnm = null;
|
editingData.value.rvnm = null;
|
||||||
editingData.value.rstcd = null;
|
editingData.value.rstcd = null;
|
||||||
editingData.value.stcd = null;
|
editingData.value.stcd = null;
|
||||||
delWarning(null, "rstcd");
|
delWarning(null, "rstcd");
|
||||||
@ -590,7 +591,7 @@ const startEdit = (index: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 预加载下拉选项 (基于 editingData 的值)
|
// 3. 预加载下拉选项 (基于 editingData 的值)
|
||||||
if (editingData.value.hbrvcd == "" || editingData.value.hbrvcd == undefined) {
|
if (editingData.value.rvcd == "" || editingData.value.rvcd == undefined) {
|
||||||
if (editingData.value.rstcd) {
|
if (editingData.value.rstcd) {
|
||||||
handleHbrvcdChange("", index, "start").then(() => {
|
handleHbrvcdChange("", index, "start").then(() => {
|
||||||
handleEngChange(editingData.value.rstcd, index, "start");
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
@ -598,8 +599,8 @@ const startEdit = (index: number) => {
|
|||||||
} else {
|
} else {
|
||||||
handleEngChange("", index, "start");
|
handleEngChange("", index, "start");
|
||||||
}
|
}
|
||||||
} else if (editingData.value.hbrvcd != "" && editingData.value.hbrvcd != undefined) {
|
} else if (editingData.value.rvcd != "" && editingData.value.rvcd != undefined) {
|
||||||
handleHbrvcdChange(editingData.value.hbrvcd, index, "start").then(() => {
|
handleHbrvcdChange(editingData.value.rvcd, index, "start").then(() => {
|
||||||
handleEngChange(editingData.value.rstcd, index, "start");
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -613,8 +613,8 @@ const handleModalOk = () => {
|
|||||||
// message.warning("请检查流域,流域填写有误!");
|
// message.warning("请检查流域,流域填写有误!");
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
if (fileTableData.value[i].warnings.includes('hbrvcd')) {
|
if (fileTableData.value[i].warnings.includes("rvcd")) {
|
||||||
message.warning('请检查流域,流域填写有误!');
|
message.warning("请检查流域,流域填写有误!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fileTableData.value[i].warnings.includes('rstcd')) {
|
if (fileTableData.value[i].warnings.includes('rstcd')) {
|
||||||
@ -880,12 +880,12 @@ const handleSearchFinish = (values: any) => {
|
|||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.rstcd
|
value: values.rstcd
|
||||||
},
|
},
|
||||||
values.hbrvcd !== 'all' && {
|
values.rvcd !== "all" && {
|
||||||
field: 'hbrvcd',
|
field: "rvcd",
|
||||||
operator: 'eq',
|
operator: "eq",
|
||||||
dataType: 'string',
|
dataType: "string",
|
||||||
value: values.hbrvcd
|
value: values.rvcd,
|
||||||
}
|
},
|
||||||
// values.baseId !== "all" && {
|
// values.baseId !== "all" && {
|
||||||
// field: "baseId",
|
// field: "baseId",
|
||||||
// operator: "eq",
|
// operator: "eq",
|
||||||
|
|||||||
@ -37,7 +37,7 @@ const localTypeDate = ref<string>(null);
|
|||||||
const basicSearchRef = ref<any>();
|
const basicSearchRef = ref<any>();
|
||||||
|
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd: "all",
|
rvcd: "rvcd",
|
||||||
stcd: null,
|
stcd: null,
|
||||||
rstcd: null,
|
rstcd: null,
|
||||||
strdt: [
|
strdt: [
|
||||||
@ -51,7 +51,7 @@ const searchData = ref<any>({ ...initSearchData });
|
|||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "hbrvcd",
|
name: "rvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
@ -81,7 +81,7 @@ const onValuesChange = (changedValues: any, allValues: any) => {
|
|||||||
searchData.value = { ...searchData.value, ...allValues };
|
searchData.value = { ...searchData.value, ...allValues };
|
||||||
if (
|
if (
|
||||||
Object.keys(changedValues)[0] == "rstcd" ||
|
Object.keys(changedValues)[0] == "rstcd" ||
|
||||||
Object.keys(changedValues)[0] == "hbrvcd"
|
Object.keys(changedValues)[0] == "rvcd"
|
||||||
) {
|
) {
|
||||||
const formInstance = basicSearchRef.value?.formData;
|
const formInstance = basicSearchRef.value?.formData;
|
||||||
formInstance.stcd = null;
|
formInstance.stcd = null;
|
||||||
|
|||||||
@ -378,11 +378,11 @@ const handleSearchFinish = (values: any) => {
|
|||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.status
|
value: values.status
|
||||||
},
|
},
|
||||||
values.hbrvcd !== 'all' && {
|
values.rvcd !== "all" && {
|
||||||
field: 'hbrvcd',
|
field: "rvcd",
|
||||||
operator: 'eq',
|
operator: "eq",
|
||||||
dataType: 'string',
|
dataType: "string",
|
||||||
value: values.hbrvcd
|
value: values.rvcd,
|
||||||
},
|
},
|
||||||
values.stcd && {
|
values.stcd && {
|
||||||
field: 'stcd',
|
field: 'stcd',
|
||||||
@ -616,11 +616,11 @@ const handleDetailSearchFinish = (values: any) => {
|
|||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.rstcd
|
value: values.rstcd
|
||||||
},
|
},
|
||||||
values.hbrvcd !== 'all' && {
|
values.rvcd !== "all" && {
|
||||||
field: 'hbrvcd',
|
field: "rvcd",
|
||||||
operator: 'eq',
|
operator: "eq",
|
||||||
dataType: 'string',
|
dataType: "string",
|
||||||
value: values.hbrvcd
|
value: values.rvcd,
|
||||||
},
|
},
|
||||||
approvalId.value && {
|
approvalId.value && {
|
||||||
field: 'approvalId', // 字段名
|
field: 'approvalId', // 字段名
|
||||||
|
|||||||
@ -61,7 +61,7 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
// 模拟 initSearchData
|
// 模拟 initSearchData
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd: "all",
|
rvcd: "all",
|
||||||
stcd: "",
|
stcd: "",
|
||||||
status: "",
|
status: "",
|
||||||
};
|
};
|
||||||
@ -71,7 +71,7 @@ const searchData = ref<any>({ ...initSearchData });
|
|||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "hbrvcd",
|
name: "rvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user