添加增值放流
This commit is contained in:
parent
9c34ab5afe
commit
a9fde1edc5
@ -22,6 +22,16 @@ export function getIdUrl(params: any) {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
export function postIdUrl(data: any) {
|
||||||
|
return request({
|
||||||
|
url: import.meta.env.VITE_APP_ATTACHMENT_URL + '/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// 全景影像
|
// 全景影像
|
||||||
export function getPanoramaList(data: any) {
|
export function getPanoramaList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
@ -175,11 +185,118 @@ export function getMonitorDataOnline(data: any) {
|
|||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 没接
|
||||||
// 运行状态
|
export function getMonitorDataFpq(data: any) {
|
||||||
export function getRunState(data: any) {
|
|
||||||
return request({
|
return request({
|
||||||
url: '/wmp-env-server/env/fp/query/qgc/sdfpssr/GetKendoListCust',
|
url: '/fp/msstbprpt/GetKendoList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行状态
|
||||||
|
export function getRunState(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/fp/query/qgc/sdfpssr/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRunStateSecondPlan(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/fp/run/secondPlan/qgc/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 综合分析
|
||||||
|
|
||||||
|
export function getFishZHFX(data: any) {
|
||||||
|
return request({
|
||||||
|
url: 'fp/run/fish/select',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRunStateAnalysis(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/fp/run/analysis/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ai运行识别 没接
|
||||||
|
export function getAIYXSB(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/api/dec-lygk-base-server/base/msstbprpt/getStInfoByStcd',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ai运行识别 视频/表格 没接
|
||||||
|
export function getAIComList(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/env/ai/com/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ai运行识别 日历 没接
|
||||||
|
export function getAIComCalendar(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/env/ai/com/qgc/aiRecord/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ai运行 日历点击 没接
|
||||||
|
export function getAIComCalendarClick(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/env/ai/com/qgc/aiFile/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鱼类增殖站 - 运行数据 -获取年
|
||||||
|
export function getFishProgressionYear(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/fb/fbrdmr/getFbRelatedYrByStcd',
|
||||||
|
method: 'get',
|
||||||
|
params: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//鱼类增殖站 - 运行数据 -获取鱼
|
||||||
|
export function getFishProgressionFish(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/env/fishDic/stcd/GetKendoList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//增值放流情况 获取年 没接
|
||||||
|
export function getNormalAddedSituationYear(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/fb/msfbrdm/fbFlData/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//增值放流情况 列表 没接
|
||||||
|
|
||||||
|
export function getNormalAddedSituation(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/fb/msfbrdm/qgc/GetKendoListCust',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 科研情况 没接
|
||||||
|
export function getNormalResearchSituation(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/wmp-env-server/base/researchb/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
frontend/src/assets/images/videFm.jpg
Normal file
BIN
frontend/src/assets/images/videFm.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
@ -0,0 +1,250 @@
|
|||||||
|
<template>
|
||||||
|
<div class="attachment-preview" v-loading="loading">
|
||||||
|
<!-- 左侧媒体展示 -->
|
||||||
|
<div class="viewer-main">
|
||||||
|
<div
|
||||||
|
v-if="activeMedia.type === 'image' && activeMedia.src"
|
||||||
|
class="media-display"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="activeMedia.src"
|
||||||
|
style="width: 100%; height: 100%; object-fit: contain"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="activeMedia.type === 'video' && activeMedia.src"
|
||||||
|
class="media-display"
|
||||||
|
>
|
||||||
|
<LiveVideoBox
|
||||||
|
:videoData="{ url: activeMedia.src }"
|
||||||
|
height="100%"
|
||||||
|
:showTitle="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else class="media-empty">
|
||||||
|
<a-empty description="请选择右侧附件" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧列表 -->
|
||||||
|
<div class="viewer-sidebar">
|
||||||
|
<div class="sidebar-list" v-if="attachmentList.length > 0">
|
||||||
|
<div
|
||||||
|
v-for="item in attachmentList"
|
||||||
|
:key="item.fid"
|
||||||
|
class="sidebar-item"
|
||||||
|
:class="{ active: activeFid === item.fid }"
|
||||||
|
@click="handleSelectAttachment(item)"
|
||||||
|
>
|
||||||
|
<div class="item-thumb">
|
||||||
|
<img v-if="item.isImage && item.thumbUrl" :src="item.thumbUrl" />
|
||||||
|
<div v-else-if="item.isVideo" class="thumb-placeholder">
|
||||||
|
<img :src="videoCover" />
|
||||||
|
</div>
|
||||||
|
<span v-else class="no-media">无媒体</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-empty v-else description="暂无附件" class="sidebar-empty" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch, onMounted } from 'vue';
|
||||||
|
import LiveVideoBox from '@/views/shiPinJianKong/components/LiveVideoBox.vue';
|
||||||
|
import { postIdUrl } from '@/api/mapModal';
|
||||||
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
fid: string; // 逗号分隔的 fid 字符串
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const attachmentList = ref<any[]>([]);
|
||||||
|
const activeFid = ref('');
|
||||||
|
const activeMedia = ref<{ type: string; src: string }>({ type: '', src: '' });
|
||||||
|
|
||||||
|
// 获取附件列表
|
||||||
|
const fetchAttachmentList = async () => {
|
||||||
|
if (!props.fid) return;
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const fids = props.fid
|
||||||
|
.split(',')
|
||||||
|
.map((f: string) => f.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
// 调用 postIdUrl 获取附件详情
|
||||||
|
let mediaMap: Record<string, any> = {};
|
||||||
|
if (fids.length > 0) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('id', fids.join(','));
|
||||||
|
const mediaRes: any = await postIdUrl(formData);
|
||||||
|
mediaMap = mediaRes?.data || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建附件列表
|
||||||
|
const list: any[] = [];
|
||||||
|
fids.forEach((fid: string) => {
|
||||||
|
const m = mediaMap[fid];
|
||||||
|
const ext = m?.ext || '';
|
||||||
|
const isVideo = ext === '.mp4';
|
||||||
|
const isImage = ext === '.jpg';
|
||||||
|
|
||||||
|
list.push({
|
||||||
|
fid,
|
||||||
|
media: m || null,
|
||||||
|
thumbUrl: isImage ? m?.fullpath || '' : '',
|
||||||
|
isVideo,
|
||||||
|
isImage
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
attachmentList.value = list;
|
||||||
|
|
||||||
|
// 默认选中第一条
|
||||||
|
if (attachmentList.value.length > 0 && !activeFid.value) {
|
||||||
|
handleSelectAttachment(attachmentList.value[0]);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取附件列表失败:', error);
|
||||||
|
attachmentList.value = [];
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 选择附件
|
||||||
|
const handleSelectAttachment = (item: any) => {
|
||||||
|
activeFid.value = item.fid;
|
||||||
|
const { media, isVideo, isImage } = item;
|
||||||
|
|
||||||
|
if (isImage && media?.fullpath) {
|
||||||
|
activeMedia.value = { type: 'image', src: media.fullpath };
|
||||||
|
} else if (isVideo && media?.fullpath) {
|
||||||
|
activeMedia.value = { type: 'video', src: media.fullpath };
|
||||||
|
} else {
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听 fid 变化
|
||||||
|
watch(
|
||||||
|
() => props.fid,
|
||||||
|
() => {
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
attachmentList.value = [];
|
||||||
|
fetchAttachmentList();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 组件挂载时自动加载数据
|
||||||
|
onMounted(() => {
|
||||||
|
fetchAttachmentList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
fetchAttachmentList
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.attachment-preview {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.viewer-main {
|
||||||
|
flex: 0 0 80%;
|
||||||
|
background: #000;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.media-display {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-empty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer-sidebar {
|
||||||
|
flex: 0 0 20%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.sidebar-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.sidebar-item {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #e6f7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-thumb {
|
||||||
|
width: 100%;
|
||||||
|
height: 110px;
|
||||||
|
background: #1a1a1a;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-media {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-empty {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,407 @@
|
|||||||
|
<template>
|
||||||
|
<div class="media-viewer" v-loading="loading">
|
||||||
|
<!-- 左侧媒体展示 -->
|
||||||
|
<div class="viewer-main">
|
||||||
|
<div
|
||||||
|
v-if="activeMedia.type === 'image' && activeMedia.src"
|
||||||
|
class="media-display"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="activeMedia.src"
|
||||||
|
style="width: 100%; height: 100%; object-fit: contain"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="activeMedia.type === 'video' && activeMedia.src"
|
||||||
|
class="media-display"
|
||||||
|
>
|
||||||
|
<LiveVideoBox
|
||||||
|
:videoData="{ url: activeMedia.src }"
|
||||||
|
height="100%"
|
||||||
|
:showTitle="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else class="media-empty">
|
||||||
|
<a-empty description="请选择右侧数据" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧列表 -->
|
||||||
|
<div class="viewer-sidebar">
|
||||||
|
<div class="sidebar-list" v-if="mediaList.length > 0">
|
||||||
|
<div
|
||||||
|
v-for="item in mediaList"
|
||||||
|
:key="item.fid"
|
||||||
|
class="sidebar-item"
|
||||||
|
:class="{ active: activeRstcd === item.fid }"
|
||||||
|
@click="handleSelectMedia(item)"
|
||||||
|
>
|
||||||
|
<div class="item-thumb">
|
||||||
|
<img v-if="item.isImage && item.thumbUrl" :src="item.thumbUrl" />
|
||||||
|
<div v-else-if="item.isVideo" class="thumb-placeholder">
|
||||||
|
<img :src="videoCover" />
|
||||||
|
</div>
|
||||||
|
<span v-else class="no-media">无媒体</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-time">{{ item.ennm }} {{ item.tm }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-empty v-else description="暂无数据" class="sidebar-empty" />
|
||||||
|
<div class="sidebar-pagination">
|
||||||
|
<a-pagination
|
||||||
|
v-model:current="currentPage"
|
||||||
|
v-model:pageSize="currentPageSize"
|
||||||
|
:page-size-options="pageSizeOptions"
|
||||||
|
:total="total"
|
||||||
|
show-size-changer
|
||||||
|
size="small"
|
||||||
|
@change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch, onMounted } from 'vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import LiveVideoBox from '@/views/shiPinJianKong/components/LiveVideoBox.vue';
|
||||||
|
import { getAIComList, getAIComCalendarClick, postIdUrl } from '@/api/mapModal';
|
||||||
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
stcd: string;
|
||||||
|
type: string;
|
||||||
|
startDate: string;
|
||||||
|
endDate: string;
|
||||||
|
pageSizeOptions?: string[];
|
||||||
|
pageSize?: number;
|
||||||
|
dataType?: string; // 运行状态过滤:'2' 表示运行,'1' 表示未运行,不传则不过滤
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
pageSizeOptions: () => ['20', '50', '100'],
|
||||||
|
pageSize: 20,
|
||||||
|
dataType: ''
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
load: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const currentPage = ref(1);
|
||||||
|
const currentPageSize = ref(props.pageSize);
|
||||||
|
const total = ref(0);
|
||||||
|
const mediaList = ref<any[]>([]);
|
||||||
|
const activeRstcd = ref('');
|
||||||
|
const activeMedia = ref<{ type: string; src: string }>({ type: '', src: '' });
|
||||||
|
|
||||||
|
// 重置状态
|
||||||
|
const resetState = () => {
|
||||||
|
currentPage.value = 1;
|
||||||
|
activeRstcd.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
mediaList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取媒体列表
|
||||||
|
const fetchMediaList = async () => {
|
||||||
|
if (!props.stcd || !props.type) return;
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const skip = (currentPage.value - 1) * currentPageSize.value;
|
||||||
|
|
||||||
|
const filters: any[] = [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: props.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: props.startDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: props.endDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: props.type
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const params: any = {
|
||||||
|
take: currentPageSize.value,
|
||||||
|
skip,
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters
|
||||||
|
},
|
||||||
|
group: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// 日历模式需要 dataType 过滤
|
||||||
|
if (props.dataType) {
|
||||||
|
filters.push({
|
||||||
|
field: 'dataType',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: props.dataType
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 视频模式需要排序,日历模式不需要
|
||||||
|
params.sort = [
|
||||||
|
{ field: 'rstcdStepSort', dir: 'asc' },
|
||||||
|
{ field: 'tm', dir: 'desc' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
console.log(props.dataType);
|
||||||
|
|
||||||
|
// 日历点击使用 getAIComCalendarClick 接口,视频使用 getAIComList 接口
|
||||||
|
const apiFunc = props.dataType ? getAIComCalendarClick : getAIComList;
|
||||||
|
console.log(apiFunc);
|
||||||
|
const res: any = await apiFunc(params);
|
||||||
|
|
||||||
|
const rawData = res?.data?.data || [];
|
||||||
|
total.value = res?.data?.total || 0;
|
||||||
|
|
||||||
|
// 收集所有 fid
|
||||||
|
const allFids: string[] = [];
|
||||||
|
rawData.forEach((item: any) => {
|
||||||
|
if (item.fid) {
|
||||||
|
item.fid.split(',').forEach((f: string) => {
|
||||||
|
const trimmed = f.trim();
|
||||||
|
if (trimmed) allFids.push(trimmed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用 postIdUrl 获取媒体详情
|
||||||
|
let mediaMap: Record<string, any> = {};
|
||||||
|
if (allFids.length > 0) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('id', allFids.join(','));
|
||||||
|
const mediaRes: any = await postIdUrl(formData);
|
||||||
|
mediaMap = mediaRes?.data || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按 fid 展开为独立项
|
||||||
|
const flatList: any[] = [];
|
||||||
|
rawData.forEach((item: any) => {
|
||||||
|
const fids = item.fid
|
||||||
|
? item.fid
|
||||||
|
.split(',')
|
||||||
|
.map((f: string) => f.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
: [];
|
||||||
|
const tm = item.tm ? dayjs(item.tm).format('YYYY-MM-DD HH:mm:ss') : '-';
|
||||||
|
|
||||||
|
fids.forEach((fid: string) => {
|
||||||
|
const m = mediaMap[fid];
|
||||||
|
const ext = m?.ext || '';
|
||||||
|
const isVideo = ext === '.mp4';
|
||||||
|
const isImage = ext === '.jpg';
|
||||||
|
|
||||||
|
flatList.push({
|
||||||
|
...item,
|
||||||
|
fid,
|
||||||
|
media: m || null,
|
||||||
|
thumbUrl: isImage ? m?.fullpath || '' : '',
|
||||||
|
isVideo,
|
||||||
|
isImage,
|
||||||
|
tm
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
mediaList.value = flatList;
|
||||||
|
|
||||||
|
// 默认选中第一条
|
||||||
|
if (mediaList.value.length > 0 && !activeRstcd.value) {
|
||||||
|
handleSelectMedia(mediaList.value[0]);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取媒体列表失败:', error);
|
||||||
|
mediaList.value = [];
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
emit('load');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 选择媒体
|
||||||
|
const handleSelectMedia = (item: any) => {
|
||||||
|
activeRstcd.value = item.fid;
|
||||||
|
const { media, isVideo, isImage } = item;
|
||||||
|
|
||||||
|
if (isImage && media?.fullpath) {
|
||||||
|
activeMedia.value = { type: 'image', src: media.fullpath };
|
||||||
|
} else if (isVideo && media?.fullpath) {
|
||||||
|
activeMedia.value = { type: 'video', src: media.fullpath };
|
||||||
|
} else {
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页切换
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
currentPage.value = page;
|
||||||
|
activeRstcd.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
fetchMediaList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听参数变化
|
||||||
|
watch(
|
||||||
|
() => [
|
||||||
|
props.stcd,
|
||||||
|
props.type,
|
||||||
|
props.startDate,
|
||||||
|
props.endDate,
|
||||||
|
props.dataType
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
resetState();
|
||||||
|
fetchMediaList();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听 pageSize 变化
|
||||||
|
watch(
|
||||||
|
() => props.pageSize,
|
||||||
|
val => {
|
||||||
|
currentPageSize.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 组件挂载时自动加载数据
|
||||||
|
onMounted(() => {
|
||||||
|
fetchMediaList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
fetchMediaList,
|
||||||
|
resetState
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.media-viewer {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.viewer-main {
|
||||||
|
flex: 0 0 80%;
|
||||||
|
background: #000;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.media-display {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-empty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer-sidebar {
|
||||||
|
flex: 0 0 20%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.sidebar-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.sidebar-item {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #e6f7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-thumb {
|
||||||
|
width: 100%;
|
||||||
|
height: 110px;
|
||||||
|
background: #1a1a1a;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-media {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-time {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-empty {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-pagination {
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1225
frontend/src/components/MapModal/components/AIYXSB/index.vue
Normal file
1225
frontend/src/components/MapModal/components/AIYXSB/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -43,7 +43,9 @@
|
|||||||
:title="
|
:title="
|
||||||
!isEdit
|
!isEdit
|
||||||
? item.vlsr || String(item.value).length > 10
|
? item.vlsr || String(item.value).length > 10
|
||||||
? item.value
|
? item.vlsr
|
||||||
|
? '数据来源:' + item.vlsr
|
||||||
|
: item.value
|
||||||
: ''
|
: ''
|
||||||
: ''
|
: ''
|
||||||
"
|
"
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
type="daterange"
|
type="daterange"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:presets="DateSetting.RangeButton.year1"
|
||||||
/>
|
/>
|
||||||
<a-button class="ml-2" type="primary" @click="initData">查询</a-button>
|
<a-button class="ml-2" type="primary" @click="initData">查询</a-button>
|
||||||
</div>
|
</div>
|
||||||
@ -14,6 +15,9 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:scrollY="500"
|
:scrollY="500"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
:searchParams="{
|
||||||
|
sort: [{ field: 'yr', dir: 'desc' }]
|
||||||
|
}"
|
||||||
:list-url="getMonitorDataOnline"
|
:list-url="getMonitorDataOnline"
|
||||||
/>
|
/>
|
||||||
<!-- 图片预览弹框 -->
|
<!-- 图片预览弹框 -->
|
||||||
@ -48,8 +52,9 @@
|
|||||||
import { ref, onMounted, watch, computed, h } from 'vue';
|
import { ref, onMounted, watch, computed, h } from 'vue';
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import { getMonitorDataOnline } from '@/api/mapModal';
|
import { getMonitorDataFpq, getMonitorDataOnline } from '@/api/mapModal';
|
||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import { DateSetting } from '@/utils/enumeration';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@ -81,8 +86,36 @@ const openVideoPreview = (url: string) => {
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
isActive: { type: Boolean, default: false }
|
isActive: { type: Boolean, default: false }
|
||||||
});
|
});
|
||||||
|
const isCz = ref(false);
|
||||||
|
|
||||||
const columns = [
|
// 基础列(isCz为false时显示)
|
||||||
|
const baseColumns = [
|
||||||
|
{
|
||||||
|
title: '年份',
|
||||||
|
dataIndex: 'yr',
|
||||||
|
width: 120,
|
||||||
|
customRender: ({ text }: any) =>
|
||||||
|
text && text !== '-' ? dayjs(text).format('YYYY') : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '鱼种类',
|
||||||
|
dataIndex: 'ftp',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '鱼类规格(cm)',
|
||||||
|
dataIndex: 'fsz',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '过鱼数量(尾)',
|
||||||
|
dataIndex: 'fcnt',
|
||||||
|
width: 100
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 详细列(isCz为true时显示)
|
||||||
|
const detailColumns = [
|
||||||
{
|
{
|
||||||
title: '测站名称',
|
title: '测站名称',
|
||||||
dataIndex: 'stnm',
|
dataIndex: 'stnm',
|
||||||
@ -94,11 +127,11 @@ const columns = [
|
|||||||
dataIndex: 'tm',
|
dataIndex: 'tm',
|
||||||
width: 120,
|
width: 120,
|
||||||
customRender: ({ text }: any) =>
|
customRender: ({ text }: any) =>
|
||||||
text ? dayjs(text).format('YYYY-MM-DD') : '-'
|
text && text !== '-' ? dayjs(text).format('YYYY-MM-DD') : '-'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '鱼种类',
|
title: '鱼种类',
|
||||||
dataIndex: 'ftp',
|
dataIndex: 'ftpName',
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -114,8 +147,7 @@ const columns = [
|
|||||||
{
|
{
|
||||||
title: '鱼速度(m/s)',
|
title: '鱼速度(m/s)',
|
||||||
dataIndex: 'fishspeed',
|
dataIndex: 'fishspeed',
|
||||||
width: 100,
|
width: 100
|
||||||
customRender: ({ text }: any) => (text ? Number(text).toFixed(2) : '-')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '鱼游向',
|
title: '鱼游向',
|
||||||
@ -131,7 +163,6 @@ const columns = [
|
|||||||
return isNaN(num) ? '-' : num.toFixed(1);
|
return isNaN(num) ? '-' : num.toFixed(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '流速(m/s)',
|
title: '流速(m/s)',
|
||||||
dataIndex: 'speed',
|
dataIndex: 'speed',
|
||||||
@ -178,7 +209,6 @@ const columns = [
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
width: 100,
|
width: 100,
|
||||||
customRender: ({ text }: any) => {
|
customRender: ({ text }: any) => {
|
||||||
console.log(text);
|
|
||||||
const hasValidUrl =
|
const hasValidUrl =
|
||||||
text &&
|
text &&
|
||||||
text !== '-' &&
|
text !== '-' &&
|
||||||
@ -205,7 +235,61 @@ const columns = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 动态列
|
||||||
|
const columns = computed(() => {
|
||||||
|
return isCz.value ? detailColumns : baseColumns;
|
||||||
|
});
|
||||||
const initData = async () => {
|
const initData = async () => {
|
||||||
|
const params = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stCode',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{ field: 'sttpCode', operator: 'eq', dataType: 'string', value: 'FPQ' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
select: ['mway', 'stcd']
|
||||||
|
};
|
||||||
|
const params1 = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
select: ['mway', 'stcd']
|
||||||
|
};
|
||||||
|
isCz.value = false;
|
||||||
|
const res1 = await getMonitorDataFpq(params1);
|
||||||
|
const res = await getMonitorDataFpq(params);
|
||||||
|
let stcd = '';
|
||||||
|
console.log(res1);
|
||||||
|
if (res) {
|
||||||
|
if (res?.data?.data?.length > 0) {
|
||||||
|
stcd = res.data.data.map(item => item.stcd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res1) {
|
||||||
|
if (res1?.data?.data?.length > 0) {
|
||||||
|
if (res1?.data?.data[0].mway == '2') {
|
||||||
|
isCz.value = true;
|
||||||
|
} else if (res1?.data?.data[0].mway == '1') {
|
||||||
|
isCz.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(stcd);
|
||||||
const filter = {
|
const filter = {
|
||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
@ -225,10 +309,13 @@ const initData = async () => {
|
|||||||
field: 'stcd',
|
field: 'stcd',
|
||||||
operator: 'in',
|
operator: 'in',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: ['008640203900001049', '008640203900011009']
|
value: [modelStore.params.stcd]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
if (stcd != '') {
|
||||||
|
filter.filters[2].value = filter.filters[2].value.concat(stcd);
|
||||||
|
}
|
||||||
tableRef.value?.getList(filter);
|
tableRef.value?.getList(filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -10,14 +10,11 @@
|
|||||||
class="w-[160px]"
|
class="w-[160px]"
|
||||||
:loading="loadFtp"
|
:loading="loadFtp"
|
||||||
allowClear
|
allowClear
|
||||||
|
show-search
|
||||||
|
:fieldNames="{ label: 'name', value: 'id' }"
|
||||||
|
:filter-option="filterFtpOption"
|
||||||
|
:options="ftpList"
|
||||||
>
|
>
|
||||||
<a-select-option
|
|
||||||
v-for="item in ftpList"
|
|
||||||
:key="item.id"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
</a-select>
|
||||||
<span class="ml-2"> 游向:</span>
|
<span class="ml-2"> 游向:</span>
|
||||||
<a-select
|
<a-select
|
||||||
@ -35,10 +32,22 @@
|
|||||||
>
|
>
|
||||||
</a-select>
|
</a-select>
|
||||||
<span class="ml-2"> 过鱼目标:</span>
|
<span class="ml-2"> 过鱼目标:</span>
|
||||||
<a-tooltip title="暂无数据" placement="top">
|
<a-tooltip placement="top" :color="'#fff'">
|
||||||
|
<template #title>
|
||||||
|
<div v-if="planFtp" class="p-2">
|
||||||
|
<div
|
||||||
|
class="text-[#000] pb-2"
|
||||||
|
style="border-bottom: 1px solid #f5f5f5"
|
||||||
|
>
|
||||||
|
过鱼目标:
|
||||||
|
</div>
|
||||||
|
<div class="text-[#000] mt-2">{{ planFtp }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="text-[#000]">暂无数据</div>
|
||||||
|
</template>
|
||||||
<a-button size="small"><i class="iconfont icon-yulei"></i></a-button>
|
<a-button size="small"><i class="iconfont icon-yulei"></i></a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-button class="ml-2" type="primary" @click="initData">查询</a-button>
|
<a-button class="ml-2" type="primary" @click="queryBtn">查询</a-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-around mt-[20px] mb-[10px]">
|
<div class="flex justify-around mt-[20px] mb-[10px]">
|
||||||
<div>计划开始运行时间:暂无数据</div>
|
<div>计划开始运行时间:暂无数据</div>
|
||||||
@ -63,13 +72,32 @@
|
|||||||
<img :src="previewImageUrl" style="width: 100%; height: 600px" />
|
<img :src="previewImageUrl" style="width: 100%; height: 600px" />
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<!-- 视频播放弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="videoPreviewVisible"
|
||||||
|
title="视频预览"
|
||||||
|
:width="800"
|
||||||
|
:footer="null"
|
||||||
|
>
|
||||||
|
<div class="video-container">
|
||||||
|
<video
|
||||||
|
v-if="currentVideoUrl"
|
||||||
|
:src="currentVideoUrl"
|
||||||
|
controls
|
||||||
|
autoplay
|
||||||
|
class="video-player"
|
||||||
|
/>
|
||||||
|
<a-empty v-else description="暂无视频" />
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, watch, computed, h } from 'vue';
|
import { ref, onMounted, watch, nextTick, computed, h } from 'vue';
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
import BasicTable from '@/components/BasicTable/index.vue';
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
import { getRunState } from '@/api/mapModal';
|
import { getRunState, getRunStateSecondPlan } from '@/api/mapModal';
|
||||||
import { getDictItemsByCode } from '@/api/dict';
|
import { getDictItemsByCode } from '@/api/dict';
|
||||||
import { getFishDictoryDropdown } from '@/api/select';
|
import { getFishDictoryDropdown } from '@/api/select';
|
||||||
import { useModelStore } from '@/store/modules/model';
|
import { useModelStore } from '@/store/modules/model';
|
||||||
@ -94,11 +122,27 @@ const ftpList = ref([]);
|
|||||||
// 图片预览
|
// 图片预览
|
||||||
const imagePreviewVisible = ref(false);
|
const imagePreviewVisible = ref(false);
|
||||||
const previewImageUrl = ref('');
|
const previewImageUrl = ref('');
|
||||||
|
// 视频预览
|
||||||
|
const videoPreviewVisible = ref(false);
|
||||||
|
const currentVideoUrl = ref('');
|
||||||
|
|
||||||
|
// 鱼类搜索过滤
|
||||||
|
const filterFtpOption = (input: string, option: any) => {
|
||||||
|
console.log('filterOption', input, option);
|
||||||
|
if (!option.name) return false;
|
||||||
|
return option.name.indexOf(input) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
const openImagePreview = (url: string) => {
|
const openImagePreview = (url: string) => {
|
||||||
previewImageUrl.value = url;
|
previewImageUrl.value = url;
|
||||||
imagePreviewVisible.value = true;
|
imagePreviewVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openVideoPreview = (url: string) => {
|
||||||
|
currentVideoUrl.value = url;
|
||||||
|
videoPreviewVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
isActive: { type: Boolean, default: false }
|
isActive: { type: Boolean, default: false }
|
||||||
});
|
});
|
||||||
@ -116,7 +160,7 @@ const columns = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '游向',
|
title: '游向',
|
||||||
dataIndex: 'direction',
|
dataIndex: 'directionName',
|
||||||
width: 100,
|
width: 100,
|
||||||
customRender: ({ text }: any) => (text ? text : '-')
|
customRender: ({ text }: any) => (text ? text : '-')
|
||||||
},
|
},
|
||||||
@ -125,18 +169,18 @@ const columns = [
|
|||||||
dataIndex: 'strdt',
|
dataIndex: 'strdt',
|
||||||
width: 120,
|
width: 120,
|
||||||
customRender: ({ text }: any) =>
|
customRender: ({ text }: any) =>
|
||||||
text ? dayjs(text).format('YYYY-MM-DD') : '-'
|
text && text !== '-' ? dayjs(text).format('YYYY-MM-DD') : '-'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '结束时间',
|
title: '结束时间',
|
||||||
dataIndex: 'enddt',
|
dataIndex: 'enddt',
|
||||||
width: 120,
|
width: 120,
|
||||||
customRender: ({ text }: any) =>
|
customRender: ({ text }: any) =>
|
||||||
text ? dayjs(text).format('YYYY-MM-DD') : '-'
|
text && text !== '-' ? dayjs(text).format('YYYY-MM-DD') : '-'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '附件',
|
title: '图片',
|
||||||
dataIndex: 'firstimgurl',
|
dataIndex: 'picpth',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 100,
|
width: 100,
|
||||||
customRender: ({ text }: any) => {
|
customRender: ({ text }: any) => {
|
||||||
@ -161,12 +205,44 @@ const columns = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => '查看附件'
|
() => '查看图片'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '视频',
|
||||||
|
dataIndex: 'vdpth',
|
||||||
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
const hasValidUrl =
|
||||||
|
text &&
|
||||||
|
text !== '-' &&
|
||||||
|
text.trim() !== '' &&
|
||||||
|
text !== 'null' &&
|
||||||
|
text !== 'undefined';
|
||||||
|
return h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
disabled: !hasValidUrl,
|
||||||
|
style: {
|
||||||
|
color: !hasValidUrl ? '#ccc' : '#1890ff',
|
||||||
|
cursor: !hasValidUrl ? 'not-allowed' : 'pointer'
|
||||||
|
},
|
||||||
|
onClick: () => {
|
||||||
|
if (hasValidUrl) {
|
||||||
|
openVideoPreview(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => '查看视频'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
const initData = async () => {
|
const queryBtn = () => {
|
||||||
|
console.log('5');
|
||||||
const filter = {
|
const filter = {
|
||||||
logic: 'and',
|
logic: 'and',
|
||||||
filters: [
|
filters: [
|
||||||
@ -190,37 +266,107 @@ const initData = async () => {
|
|||||||
field: 'stcd',
|
field: 'stcd',
|
||||||
operator: 'in',
|
operator: 'in',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: ['008640203900011010']
|
value: [modelStore.params.stcd]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
if (searchParams.value.direction) {
|
||||||
|
filter.filters.push({
|
||||||
|
field: 'direction',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: searchParams.value.direction
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (searchParams.value.ftp) {
|
||||||
|
filter.filters.push({
|
||||||
|
field: 'ftp',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: searchParams.value.ftp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(filter);
|
||||||
|
nextTick(() => {
|
||||||
tableRef.value?.getList(filter);
|
tableRef.value?.getList(filter);
|
||||||
|
});
|
||||||
|
// const params = {
|
||||||
|
// filter: {
|
||||||
|
// logic: 'and',
|
||||||
|
// filters: [
|
||||||
|
// {
|
||||||
|
// field: 'stcd',
|
||||||
|
// operator: 'eq',
|
||||||
|
// dataType: 'string',
|
||||||
|
// value: modelStore.params.stcd
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// field: 'yr',
|
||||||
|
// operator: 'eq',
|
||||||
|
// dataType: 'string',
|
||||||
|
// value: searchParams.value.tm.format('YYYY')
|
||||||
|
// },
|
||||||
|
// { field: 'direction', operator: 'eq', dataType: 'string', value: '0' }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// getRunStateSecondPlan(params).then(res => {
|
||||||
|
// console.log(res);
|
||||||
|
// planFtp.value = res.data.ftp || '暂无数据';
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
const initData = async () => {
|
||||||
|
queryBtn();
|
||||||
|
hasLoaded.value = true;
|
||||||
};
|
};
|
||||||
const getOptions = async () => {
|
const getOptions = async () => {
|
||||||
loadDirection.value = true;
|
loadDirection.value = true;
|
||||||
getDictItemsByCode({ dictCode: 'direction' }).then(res => {
|
getDictItemsByCode({ dictCode: 'direction' }).then(res => {
|
||||||
|
if (res) {
|
||||||
direction.value = res.data || [];
|
direction.value = res.data || [];
|
||||||
loadDirection.value = false;
|
loadDirection.value = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
loadFtp.value = true;
|
loadFtp.value = true;
|
||||||
getFishDictoryDropdown().then(res => {
|
getFishDictoryDropdown()
|
||||||
|
.then(res => {
|
||||||
ftpList.value = res.data || [];
|
ftpList.value = res.data || [];
|
||||||
loadFtp.value = false;
|
loadFtp.value = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loadFtp.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.isActive,
|
() => props.isActive,
|
||||||
active => {
|
active => {
|
||||||
if (active) {
|
console.log('active', active);
|
||||||
|
if (active && !hasLoaded.value) {
|
||||||
getOptions();
|
getOptions();
|
||||||
initData();
|
initData();
|
||||||
|
hasLoaded.value = true;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.fish-facility-monitor-data {
|
.fish-facility-monitor-data {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 400px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-player {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 600px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,11 +1,584 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="fish-zhfx">
|
||||||
<h2>综合分析</h2>
|
<!-- 搜索条件 -->
|
||||||
|
<div class="search-bar mb-4">
|
||||||
|
<span>年份:</span>
|
||||||
|
<a-date-picker
|
||||||
|
v-model:value="searchParams.tm"
|
||||||
|
picker="year"
|
||||||
|
style="width: 160px"
|
||||||
|
/>
|
||||||
|
<span class="ml-4">鱼类:</span>
|
||||||
|
<a-select
|
||||||
|
v-model:value="searchParams.ftp"
|
||||||
|
placeholder="请选择"
|
||||||
|
class="w-[160px]"
|
||||||
|
:loading="loadFtp"
|
||||||
|
:fieldNames="{ label: 'name', value: 'id' }"
|
||||||
|
:filter-option="filterFtpOption"
|
||||||
|
:options="ftpList"
|
||||||
|
allowClear
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
<a-button class="ml-4" type="primary" @click="handleSearch">
|
||||||
|
查询
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图表和表格 -->
|
||||||
|
<a-spin :spinning="isLoading" tip="加载中...">
|
||||||
|
<div class="content-body">
|
||||||
|
<!-- 左侧图表 -->
|
||||||
|
<div class="chart-wrapper">
|
||||||
|
<div ref="chartRef" class="chart-container"></div>
|
||||||
|
<a-empty
|
||||||
|
v-if="!chartData || chartData.length === 0"
|
||||||
|
description="暂无数据"
|
||||||
|
class="chart-empty"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧表格 -->
|
||||||
|
<div class="table-wrapper">
|
||||||
|
<BasicTable
|
||||||
|
:scrollY="480"
|
||||||
|
:scrollX="tableScrollX"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:data="tableData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts"></script>
|
|
||||||
<style scoped>
|
<script setup lang="ts">
|
||||||
.fish-facility-monitor-data {
|
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||||
padding: 20px;
|
import dayjs from 'dayjs';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { getFishZHFX, getRunStateAnalysis } from '@/api/mapModal';
|
||||||
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isActive: { type: Boolean, default: false }
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const tableData = ref<any[]>([]);
|
||||||
|
const chartData = ref<any[]>([]);
|
||||||
|
const chartColumns = ref<any[]>([]);
|
||||||
|
const chartRef = ref<HTMLElement>();
|
||||||
|
const hasLoaded = ref(false);
|
||||||
|
let chartInstance: echarts.ECharts | null = null;
|
||||||
|
|
||||||
|
// 搜索参数
|
||||||
|
const searchParams = ref({
|
||||||
|
tm: dayjs(),
|
||||||
|
ftp: null
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鱼类列表
|
||||||
|
const loadFtp = ref(false);
|
||||||
|
const ftpList = ref([]);
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const tableColumns = ref<any[]>([]);
|
||||||
|
const tableScrollX = ref(0);
|
||||||
|
|
||||||
|
// 鱼类搜索过滤
|
||||||
|
const filterFtpOption = (input: string, option: any) => {
|
||||||
|
if (!option.name) return false;
|
||||||
|
return option.name.indexOf(input) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取鱼类字典
|
||||||
|
const getFtpOptions = async () => {
|
||||||
|
loadFtp.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(searchParams.value.tm)
|
||||||
|
.startOf('year')
|
||||||
|
.format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(searchParams.value.tm)
|
||||||
|
.endOf('year')
|
||||||
|
.format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const res = await getFishZHFX(params);
|
||||||
|
ftpList.value = res?.data?.data || [];
|
||||||
|
if (ftpList.value.length > 0) {
|
||||||
|
searchParams.value.ftp = ftpList.value[0].id;
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取鱼类列表失败:', error);
|
||||||
|
} finally {
|
||||||
|
loadFtp.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化图表
|
||||||
|
const initChart = () => {
|
||||||
|
if (!chartRef.value) return;
|
||||||
|
if (chartInstance) chartInstance.dispose();
|
||||||
|
chartInstance = echarts.init(chartRef.value);
|
||||||
|
updateChart(chartData.value, chartColumns.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新图表
|
||||||
|
const updateChart = (data: any[], columns: any[]) => {
|
||||||
|
if (!chartInstance) return;
|
||||||
|
if (!data || data.length === 0) {
|
||||||
|
chartInstance.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤掉时间列
|
||||||
|
const dataColumns = columns.filter(
|
||||||
|
col => col.dataIndex !== 'dt' && col.visible !== false
|
||||||
|
);
|
||||||
|
|
||||||
|
const sorted = [...data].sort(
|
||||||
|
(a, b) => new Date(a.dt).getTime() - new Date(b.dt).getTime()
|
||||||
|
);
|
||||||
|
|
||||||
|
const xAxisData = sorted.map(item => dayjs(item.dt).format('YYYY-MM-DD'));
|
||||||
|
|
||||||
|
// 颜色配置
|
||||||
|
const colorList = [
|
||||||
|
'#009DFF',
|
||||||
|
'#FEB157',
|
||||||
|
'#76513C',
|
||||||
|
'#A0FF8A',
|
||||||
|
'#7399C6',
|
||||||
|
'#FEB157',
|
||||||
|
'#35A9FF',
|
||||||
|
'#FFAF55',
|
||||||
|
'#FF8760',
|
||||||
|
'#FE5658'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 获取去除括号后的列名
|
||||||
|
const getCleanTitle = (title: string) => {
|
||||||
|
return title?.replace(/[()()℃尾]/g, '').trim() || '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Y轴名称与列名的映射关系
|
||||||
|
const yAxisColumnMap: Record<string, string[]> = {
|
||||||
|
'数量(尾)': ['数量', 'fcnt'],
|
||||||
|
'水温(℃)': ['水温', '出库水温', '入库水温'],
|
||||||
|
'(mg/L)': ['化学需氧量', '氨氮', '总氮', '总磷'],
|
||||||
|
水位: ['水位', '坝上水位', '坝下水位'],
|
||||||
|
流量: ['入库流量', '出库流量', '流量']
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据列名动态查找对应的Y轴索引
|
||||||
|
const getYAxisIndex = (col: any): number => {
|
||||||
|
// 数量(尾) 通过 dataIndex === 'fcnt' 匹配
|
||||||
|
if (col.dataIndex === 'fcnt') return 0;
|
||||||
|
|
||||||
|
const cleanTitle = getCleanTitle(col.title);
|
||||||
|
|
||||||
|
// 遍历Y轴映射,找到匹配的Y轴
|
||||||
|
const yAxisNames = Object.keys(yAxisColumnMap);
|
||||||
|
for (let i = 0; i < yAxisNames.length; i++) {
|
||||||
|
const yAxisName = yAxisNames[i];
|
||||||
|
// 跳过数量(尾),已经通过dataIndex匹配
|
||||||
|
if (yAxisName === '数量(尾)') continue;
|
||||||
|
|
||||||
|
const columnNames = yAxisColumnMap[yAxisName];
|
||||||
|
|
||||||
|
// 检查当前列名是否属于这个Y轴
|
||||||
|
if (
|
||||||
|
columnNames.some(
|
||||||
|
name => cleanTitle.includes(name) || name.includes(cleanTitle)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认第一个Y轴
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Y轴配置
|
||||||
|
const yAxisConfig = [
|
||||||
|
// 左侧3个Y轴
|
||||||
|
{
|
||||||
|
name: '数量(尾)',
|
||||||
|
type: 'value',
|
||||||
|
position: 'left',
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#FF6B35' } },
|
||||||
|
axisLabel: { color: '#FF6B35' },
|
||||||
|
nameTextStyle: { color: '#FF6B35' },
|
||||||
|
splitLine: { show: true, lineStyle: { color: '#e5e5e5' } }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '水温(℃)',
|
||||||
|
type: 'value',
|
||||||
|
position: 'left',
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#56C2E3' } },
|
||||||
|
axisLabel: { color: '#56C2E3' },
|
||||||
|
nameTextStyle: { color: '#56C2E3' },
|
||||||
|
splitLine: { show: false },
|
||||||
|
offset: 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '(mg/L)',
|
||||||
|
type: 'value',
|
||||||
|
position: 'left',
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#FF9500' } },
|
||||||
|
axisLabel: { color: '#FF9500' },
|
||||||
|
nameTextStyle: { color: '#FF9500' },
|
||||||
|
splitLine: { show: false },
|
||||||
|
offset: 100
|
||||||
|
},
|
||||||
|
// 右侧2个Y轴
|
||||||
|
{
|
||||||
|
name: '水位(m)',
|
||||||
|
type: 'value',
|
||||||
|
position: 'right',
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#73C0DE' } },
|
||||||
|
axisLabel: { color: '#73C0DE' },
|
||||||
|
nameTextStyle: { color: '#73C0DE' },
|
||||||
|
splitLine: { show: false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '流量(m³/s)',
|
||||||
|
type: 'value',
|
||||||
|
position: 'right',
|
||||||
|
axisLine: { show: true, lineStyle: { color: '#91CC75' } },
|
||||||
|
axisLabel: { color: '#91CC75' },
|
||||||
|
nameTextStyle: { color: '#91CC75' },
|
||||||
|
splitLine: { show: false },
|
||||||
|
offset: 70
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 构建series
|
||||||
|
const series = dataColumns.map((col, index) => {
|
||||||
|
const isBar = col.dataIndex === 'fcnt';
|
||||||
|
const yAxisIndex = getYAxisIndex(col);
|
||||||
|
|
||||||
|
const colData = sorted.map(item => {
|
||||||
|
return item[col.dataIndex];
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: col.title,
|
||||||
|
type: isBar ? 'bar' : 'line',
|
||||||
|
yAxisIndex,
|
||||||
|
data: colData,
|
||||||
|
smooth: !isBar,
|
||||||
|
symbol: isBar ? undefined : 'circle',
|
||||||
|
symbolSize: isBar ? undefined : 4,
|
||||||
|
itemStyle: { color: colorList[index % colorList.length] },
|
||||||
|
lineStyle: { width: 2 },
|
||||||
|
barMaxWidth: 30
|
||||||
|
};
|
||||||
|
});
|
||||||
|
console.log(sorted[0]);
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||||
|
textStyle: { color: '#fff', fontSize: 12 },
|
||||||
|
axisPointer: { type: 'cross' },
|
||||||
|
formatter: (params: any) => {
|
||||||
|
if (!params || params.length === 0) return '';
|
||||||
|
const dataIndex = params[0].dataIndex;
|
||||||
|
const fullTime = xAxisData[dataIndex] || '';
|
||||||
|
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||||
|
params.forEach((param: any) => {
|
||||||
|
if (param.value == null) return;
|
||||||
|
html += `
|
||||||
|
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||||
|
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||||
|
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
|
||||||
|
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${param.value}</strong></span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
type: 'scroll',
|
||||||
|
top: 10,
|
||||||
|
data: dataColumns.map(col => col.title),
|
||||||
|
textStyle: { fontSize: 12 }
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: 120,
|
||||||
|
right: 120,
|
||||||
|
top: 80,
|
||||||
|
bottom: 60
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData,
|
||||||
|
axisLine: { lineStyle: { color: '#000000' } },
|
||||||
|
axisTick: { show: false },
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: 12
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: yAxisConfig,
|
||||||
|
series,
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
type: 'inside',
|
||||||
|
xAxisIndex: [0],
|
||||||
|
throttle: 50,
|
||||||
|
start: 0,
|
||||||
|
end: 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
toolbox: {
|
||||||
|
show: true,
|
||||||
|
feature: {
|
||||||
|
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||||
|
},
|
||||||
|
right: 20,
|
||||||
|
top: 10
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
chartInstance.setOption(option, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const fetchData = async () => {
|
||||||
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
|
const filterParams = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(searchParams.value.tm)
|
||||||
|
.startOf('year')
|
||||||
|
.format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(searchParams.value.tm)
|
||||||
|
.endOf('year')
|
||||||
|
.format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ftp',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
// value: '重口裂腹鱼'
|
||||||
|
value: searchParams.value.ftp
|
||||||
|
}
|
||||||
|
].filter(Boolean)
|
||||||
|
},
|
||||||
|
sort: [{ field: 'dt', dir: 'asc' }]
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await getRunStateAnalysis(filterParams);
|
||||||
|
console.log(res);
|
||||||
|
const result = res?.data?.data[0] || {};
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
// 设置表格列
|
||||||
|
const columns = result.columns || [];
|
||||||
|
chartColumns.value = columns;
|
||||||
|
tableColumns.value = columns
|
||||||
|
.filter((col: any) => col.visible !== false)
|
||||||
|
.map((col: any) => ({
|
||||||
|
title: col.title,
|
||||||
|
dataIndex: col.dataIndex,
|
||||||
|
width: 120,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (col.dataType === 'date' && text) {
|
||||||
|
return dayjs(text).format('YYYY-MM-DD');
|
||||||
|
}
|
||||||
|
return text != null ? text : '-';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
tableScrollX.value = tableColumns.value.reduce(
|
||||||
|
(sum, col) => sum + (col.width || 100),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置数据
|
||||||
|
const dataSource = result.dataSource || [];
|
||||||
|
console.log(dataSource);
|
||||||
|
tableData.value = [...dataSource].reverse();
|
||||||
|
chartData.value = dataSource;
|
||||||
|
nextTick(() => updateChart(dataSource, columns));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取数据失败:', error);
|
||||||
|
tableData.value = [];
|
||||||
|
chartData.value = [];
|
||||||
|
if (chartInstance) chartInstance.clear();
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = () => fetchData();
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
const initData = () => {
|
||||||
|
nextTick(() => initChart());
|
||||||
|
fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听isActive
|
||||||
|
watch(
|
||||||
|
() => props.isActive,
|
||||||
|
active => {
|
||||||
|
if (active) {
|
||||||
|
getFtpOptions();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听stcd变化
|
||||||
|
watch(
|
||||||
|
() => modelStore.params.stcd,
|
||||||
|
(newStcd, oldStcd) => {
|
||||||
|
if (newStcd && newStcd !== oldStcd) {
|
||||||
|
fetchData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 图表resize
|
||||||
|
let resizeObserver: ResizeObserver | null = null;
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.isActive,
|
||||||
|
active => {
|
||||||
|
if (active && chartRef.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (chartInstance) chartInstance.resize();
|
||||||
|
}, 200);
|
||||||
|
if (!resizeObserver) {
|
||||||
|
resizeObserver = new ResizeObserver(() => {
|
||||||
|
if (chartInstance) chartInstance.resize();
|
||||||
|
});
|
||||||
|
resizeObserver.observe(chartRef.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleResize = () => {
|
||||||
|
if (chartInstance) chartInstance.resize();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (chartInstance) {
|
||||||
|
chartInstance.dispose();
|
||||||
|
chartInstance = null;
|
||||||
|
}
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
if (resizeObserver) {
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
resizeObserver = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fish-zhfx {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 600px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-body {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
height: 600px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.chart-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: 10px;
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-empty {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 500px;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-x: auto;
|
||||||
|
border-left: 1px solid #dcdfe6;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -0,0 +1,282 @@
|
|||||||
|
<template>
|
||||||
|
<div class="normal-added-situation">
|
||||||
|
<!-- 搜索条件 -->
|
||||||
|
<div class="search-bar mb-4">
|
||||||
|
<span>年份:</span>
|
||||||
|
<a-date-picker
|
||||||
|
v-model:value="searchParams.tm"
|
||||||
|
picker="year"
|
||||||
|
style="width: 160px"
|
||||||
|
format="YYYY"
|
||||||
|
value-format="YYYY"
|
||||||
|
/>
|
||||||
|
<span class="ml-4">鱼类:</span>
|
||||||
|
<a-select
|
||||||
|
v-model:value="searchParams.ftp"
|
||||||
|
placeholder="请选择"
|
||||||
|
class="w-[160px]"
|
||||||
|
:loading="loadFtp"
|
||||||
|
:fieldNames="{ label: 'name', value: 'id' }"
|
||||||
|
:filter-option="filterFtpOption"
|
||||||
|
:options="ftpList"
|
||||||
|
allowClear
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
<a-button class="ml-4" type="primary" @click="handleSearch">
|
||||||
|
查询
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<BasicTable
|
||||||
|
ref="tableRef"
|
||||||
|
:scrollY="500"
|
||||||
|
:scrollX="tableScrollX"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:list-url="getNormalAddedSituation"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import {
|
||||||
|
getNormalAddedSituationYear,
|
||||||
|
getNormalAddedSituation
|
||||||
|
} from '@/api/mapModal';
|
||||||
|
import { getFishDictoryDropdown } from '@/api/select';
|
||||||
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isActive: { type: Boolean, default: false }
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasLoaded = ref(false);
|
||||||
|
const tableRef = ref();
|
||||||
|
|
||||||
|
// 搜索参数
|
||||||
|
const searchParams = ref({
|
||||||
|
tm: null as string | null,
|
||||||
|
ftp: null
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鱼类列表
|
||||||
|
const loadFtp = ref(false);
|
||||||
|
const ftpList = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const tableColumns = ref([
|
||||||
|
{
|
||||||
|
title: '养殖鱼类',
|
||||||
|
dataIndex: 'ftpName',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '计划养殖规模(万尾)',
|
||||||
|
dataIndex: 'fcntjh',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (text == null || text === '-') return '-';
|
||||||
|
return (Number(text) / 10000).toFixed(4);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '实际完成数量(万尾)',
|
||||||
|
dataIndex: 'fcntjc',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (text == null || text === '-') return '-';
|
||||||
|
return (Number(text) / 10000).toFixed(4);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '放流去向',
|
||||||
|
dataIndex: 'directionVoList',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (text?.length > 0) {
|
||||||
|
return text[0].flstnm + ':' + Number(text[0].flfnct) / 10000;
|
||||||
|
} else {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '平均规格',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: '全长(cm)',
|
||||||
|
dataIndex: 'fsz',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (text == null || text === '-') return '-';
|
||||||
|
return Number(text).toFixed(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '体重(kg)',
|
||||||
|
dataIndex: 'fwet',
|
||||||
|
width: 150,
|
||||||
|
customRender: ({ text }: any) => {
|
||||||
|
if (text == null || text === '-') return '-';
|
||||||
|
return Number(text).toFixed(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// customRender: ({ text }: any) => {
|
||||||
|
// if (text?.length > 0) {
|
||||||
|
// return text[0].flstnm + ':' + Number(text[0].flfnct) / 10000;
|
||||||
|
// } else {
|
||||||
|
// return '-';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const tableScrollX = ref(300);
|
||||||
|
|
||||||
|
// 鱼类搜索过滤
|
||||||
|
const filterFtpOption = (input: string, option: any) => {
|
||||||
|
if (!option.name) return false;
|
||||||
|
return option.name.indexOf(input) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取年份列表(仅用于设置默认年份)
|
||||||
|
const getYearList = async () => {
|
||||||
|
if (!modelStore.params.stcd) return;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
group: [{ dir: 'desc', field: 'yr' }],
|
||||||
|
groupResultFlat: true
|
||||||
|
};
|
||||||
|
const res: any = await getNormalAddedSituationYear(params);
|
||||||
|
const yearData = res?.data?.data || [];
|
||||||
|
if (yearData.length > 0) {
|
||||||
|
searchParams.value.tm = yearData[0].yr;
|
||||||
|
getFtpOptions();
|
||||||
|
} else {
|
||||||
|
if (tableRef.value) {
|
||||||
|
tableRef.value.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取年份列表失败:', error);
|
||||||
|
if (tableRef.value) {
|
||||||
|
tableRef.value.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取鱼类字典
|
||||||
|
const getFtpOptions = async () => {
|
||||||
|
loadFtp.value = true;
|
||||||
|
getFishDictoryDropdown()
|
||||||
|
.then(res => {
|
||||||
|
ftpList.value = res.data || [];
|
||||||
|
loadFtp.value = false;
|
||||||
|
refreshTable();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loadFtp.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 刷新表格
|
||||||
|
const refreshTable = () => {
|
||||||
|
const year = searchParams.value.tm;
|
||||||
|
const startDate = `${year}-01-01 00:00:00`;
|
||||||
|
const endDate = `${year}-12-31 23:59:59`;
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'startTime',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: startDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'endTime',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: endDate
|
||||||
|
},
|
||||||
|
...(searchParams.value.ftp
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
field: 'ftp',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: searchParams.value.ftp
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: [])
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
tableRef.value?.getList(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const handleSearch = () => {
|
||||||
|
refreshTable();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听isActive
|
||||||
|
watch(
|
||||||
|
() => props.isActive,
|
||||||
|
active => {
|
||||||
|
if (active && !hasLoaded.value) {
|
||||||
|
getYearList();
|
||||||
|
hasLoaded.value = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听stcd变化
|
||||||
|
watch(
|
||||||
|
() => modelStore.params.stcd,
|
||||||
|
(newStcd, oldStcd) => {
|
||||||
|
if (newStcd && newStcd !== oldStcd) {
|
||||||
|
hasLoaded.value = false;
|
||||||
|
ftpList.value = [];
|
||||||
|
searchParams.value = { tm: null, ftp: null };
|
||||||
|
getYearList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.normal-added-situation {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,695 @@
|
|||||||
|
<template>
|
||||||
|
<div class="normal-operation-data">
|
||||||
|
<div class="search-bar">
|
||||||
|
<div class="search-item select-item1">
|
||||||
|
<a-select
|
||||||
|
v-model:value="searchForm.firstKey"
|
||||||
|
class="search-control select-control"
|
||||||
|
placeholder="请选择一级"
|
||||||
|
:options="firstLevelOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-item input-item1">
|
||||||
|
<a-select
|
||||||
|
v-model:value="searchForm.secondKey"
|
||||||
|
class="search-control input-control"
|
||||||
|
placeholder="请选择二级"
|
||||||
|
:options="secondLevelOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="search-item select-item2">
|
||||||
|
<a-date-picker
|
||||||
|
v-model:value="searchForm.year"
|
||||||
|
class="search-control select-control"
|
||||||
|
picker="year"
|
||||||
|
format="YYYY"
|
||||||
|
value-format="YYYY"
|
||||||
|
placeholder="请选择年份"
|
||||||
|
:disabled="loadYear"
|
||||||
|
:allow-clear="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-for="field in dynamicFilters" :key="field.name">
|
||||||
|
<div
|
||||||
|
class="search-item"
|
||||||
|
:class="field.type === 'select' ? 'select-item' : 'input-item'"
|
||||||
|
:style="getFieldStyle(field)"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-if="field.type === 'select'"
|
||||||
|
v-model:value="extraFilters[field.name]"
|
||||||
|
class="search-control select-control"
|
||||||
|
:placeholder="`请搜索${field.label}`"
|
||||||
|
:options="getFieldOptions(field)"
|
||||||
|
:loading="getSelectLoading(field)"
|
||||||
|
:filter-option="filterSelectOption"
|
||||||
|
show-search
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
<a-input
|
||||||
|
v-else
|
||||||
|
v-model:value="extraFilters[field.name]"
|
||||||
|
class="search-control input-control"
|
||||||
|
:placeholder="field.placeholder || `请输入${field.label}`"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="search-actions">
|
||||||
|
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<BasicTable
|
||||||
|
ref="tableRef"
|
||||||
|
:key="currentTable?.key || 'empty-table'"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:list-url="getTableList"
|
||||||
|
:scrollY="500"
|
||||||
|
:scrollX="tableScrollX"
|
||||||
|
>
|
||||||
|
<template #fid="{ record }">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
class="!p-0"
|
||||||
|
:disabled="!hasAttachment(record?.fid)"
|
||||||
|
@click="handleViewAttachment(record)"
|
||||||
|
>
|
||||||
|
查看附件
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
v-model:open="attachmentModalVisible"
|
||||||
|
title="查看附件"
|
||||||
|
width="80vw"
|
||||||
|
:footer="null"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<div class="attachment-modal-body">
|
||||||
|
<AttachmentPreview :fid="currentAttachmentFid" />
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, h, reactive, ref, watch } from 'vue';
|
||||||
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
|
import AttachmentPreview from '../AIYXSB/AttachmentPreview.vue';
|
||||||
|
import { getFishProgressionFish, getFishProgressionYear } from '@/api/mapModal';
|
||||||
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
import {
|
||||||
|
operationStepList,
|
||||||
|
type OperationFilterOption,
|
||||||
|
type OperationFilterField,
|
||||||
|
type OperationTableItem
|
||||||
|
} from './operationConfig';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isActive: { type: Boolean, default: false }
|
||||||
|
});
|
||||||
|
|
||||||
|
const DEFAULT_YEAR = String(new Date().getFullYear());
|
||||||
|
const DEFAULT_TABLE_PAGE_SIZE = 20;
|
||||||
|
const DEFAULT_TABLE_SCROLL_X = 900;
|
||||||
|
const DEFAULT_SELECT_WIDTH = 150;
|
||||||
|
const DEFAULT_INPUT_WIDTH = 250;
|
||||||
|
const EMPTY_TABLE_RESPONSE = {
|
||||||
|
data: {
|
||||||
|
records: [],
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
|
const searchForm = reactive({
|
||||||
|
firstKey: operationStepList[0]?.key || '',
|
||||||
|
secondKey: '',
|
||||||
|
year: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const extraFilters = reactive<Record<string, string | undefined>>({});
|
||||||
|
const ftpList = ref<OperationFilterOption[]>([]);
|
||||||
|
const loadYear = ref(false);
|
||||||
|
const loadFtp = ref(false);
|
||||||
|
const tableRef = ref();
|
||||||
|
const attachmentModalVisible = ref(false);
|
||||||
|
const currentAttachmentFid = ref('');
|
||||||
|
const fieldOptionsMap = reactive<Record<string, OperationFilterOption[]>>({});
|
||||||
|
const selectLoadingMap = reactive<Record<string, boolean>>({});
|
||||||
|
|
||||||
|
const currentFirstLevel = computed(() =>
|
||||||
|
operationStepList.find(item => item.key === searchForm.firstKey)
|
||||||
|
);
|
||||||
|
|
||||||
|
const secondLevelTables = computed<OperationTableItem[]>(() => {
|
||||||
|
const groups = currentFirstLevel.value?.textList || [];
|
||||||
|
return groups.flatMap(group => group.proTable);
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentTable = computed<OperationTableItem | undefined>(() =>
|
||||||
|
secondLevelTables.value.find(item => item.key === searchForm.secondKey)
|
||||||
|
);
|
||||||
|
|
||||||
|
const dynamicFilters = computed<OperationFilterField[]>(
|
||||||
|
() => currentTable.value?.filter || []
|
||||||
|
);
|
||||||
|
|
||||||
|
const firstLevelOptions = computed(() =>
|
||||||
|
operationStepList.map(item => ({
|
||||||
|
label: item.title,
|
||||||
|
value: item.key
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
const secondLevelOptions = computed(() =>
|
||||||
|
secondLevelTables.value.map(item => ({
|
||||||
|
label: item.title,
|
||||||
|
value: item.key
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
const getDefaultSecondKey = () => secondLevelOptions.value[0]?.value || '';
|
||||||
|
|
||||||
|
const resolveFirstLevelKey = (value?: string) =>
|
||||||
|
operationStepList.some(item => item.key === value)
|
||||||
|
? String(value)
|
||||||
|
: operationStepList[0]?.key || '';
|
||||||
|
|
||||||
|
const resolveSecondLevelKey = (value?: string) =>
|
||||||
|
secondLevelTables.value.some(item => item.key === value)
|
||||||
|
? String(value)
|
||||||
|
: getDefaultSecondKey();
|
||||||
|
|
||||||
|
const formatDateText = (value: unknown) => {
|
||||||
|
if (value === undefined || value === null || value === '') {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
const text = String(value).trim();
|
||||||
|
if (!text || text === '-') {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
return text.length >= 10 ? text.slice(0, 10) : text;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderEllipsisCell = (value: unknown) => {
|
||||||
|
const content =
|
||||||
|
value === undefined || value === null || value === '' ? '-' : String(value);
|
||||||
|
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
title: content,
|
||||||
|
style: {
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeColumns = (columns: any[] = []): any[] =>
|
||||||
|
columns
|
||||||
|
.filter(column => column?.visible !== false)
|
||||||
|
.map(column => ({
|
||||||
|
title: column.title,
|
||||||
|
dataIndex: column.dataIndex,
|
||||||
|
key: column.key || column.dataIndex || column.title,
|
||||||
|
width: column.width,
|
||||||
|
fixed: column.fixed || undefined,
|
||||||
|
customRender:
|
||||||
|
column.dataType === 'date'
|
||||||
|
? ({ text }: { text: unknown }) =>
|
||||||
|
renderEllipsisCell(formatDateText(text))
|
||||||
|
: undefined,
|
||||||
|
children:
|
||||||
|
Array.isArray(column.children) && column.children.length > 0
|
||||||
|
? normalizeColumns(column.children)
|
||||||
|
: undefined
|
||||||
|
}));
|
||||||
|
|
||||||
|
const tableColumns = computed(() =>
|
||||||
|
normalizeColumns(currentTable.value?.columns)
|
||||||
|
);
|
||||||
|
|
||||||
|
const getLeafColumns = (columns: any[] = []): any[] =>
|
||||||
|
columns.flatMap(column => {
|
||||||
|
if (Array.isArray(column.children) && column.children.length > 0) {
|
||||||
|
return getLeafColumns(column.children);
|
||||||
|
}
|
||||||
|
return [column];
|
||||||
|
});
|
||||||
|
|
||||||
|
const estimateColumnMinWidth = (column: any) => {
|
||||||
|
if (typeof column.width === 'number') {
|
||||||
|
return column.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
const titleText = String(column.title || '');
|
||||||
|
const titleWidth = titleText.length * 16 + 36;
|
||||||
|
|
||||||
|
if (column.dataType === 'date') {
|
||||||
|
return Math.max(120, titleWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column.dataIndex === 'recorderName' || column.dataIndex === 'fid') {
|
||||||
|
return Math.max(110, titleWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(100, Math.min(220, titleWidth));
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableScrollX = computed(() => {
|
||||||
|
const leafColumns = getLeafColumns(tableColumns.value);
|
||||||
|
if (leafColumns.length === 0) {
|
||||||
|
return DEFAULT_TABLE_SCROLL_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
return leafColumns.reduce(
|
||||||
|
(total, column) => total + estimateColumnMinWidth(column),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getDefaultFieldWidth = (field: OperationFilterField) =>
|
||||||
|
field.type === 'select' ? DEFAULT_SELECT_WIDTH : DEFAULT_INPUT_WIDTH;
|
||||||
|
|
||||||
|
const getFieldCacheKey = (field: OperationFilterField) =>
|
||||||
|
`${currentTable.value?.key || 'default'}-${field.name}`;
|
||||||
|
|
||||||
|
const getFieldStyle = (field: OperationFilterField) => ({
|
||||||
|
flexBasis:
|
||||||
|
typeof field.width === 'number'
|
||||||
|
? `${field.width}px`
|
||||||
|
: field.width || `${getDefaultFieldWidth(field)}px`
|
||||||
|
});
|
||||||
|
|
||||||
|
const buildFishOptionItem = (item: any): OperationFilterOption => ({
|
||||||
|
label: item?.name || item?.label || '-',
|
||||||
|
value: item?.id ?? item?.value ?? '',
|
||||||
|
name: item?.name || item?.label || '-',
|
||||||
|
id: item?.id ?? item?.value ?? ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const buildDictOptionItem = (item: any): OperationFilterOption => ({
|
||||||
|
label:
|
||||||
|
item?.dictMeaning || item?.label || item?.text || item?.dictLabel || '-',
|
||||||
|
value: item?.dictValue ?? item?.value ?? item?.code ?? '',
|
||||||
|
name:
|
||||||
|
item?.dictMeaning || item?.label || item?.text || item?.dictLabel || '-',
|
||||||
|
id: item?.dictValue ?? item?.value ?? item?.code ?? ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const getFieldOptions = (field: OperationFilterField) => {
|
||||||
|
if (field.name === 'ftp') {
|
||||||
|
return ftpList.value;
|
||||||
|
}
|
||||||
|
return fieldOptionsMap[getFieldCacheKey(field)] || field.options || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSelectLoading = (field: OperationFilterField) => {
|
||||||
|
if (field.name === 'ftp') {
|
||||||
|
return loadFtp.value;
|
||||||
|
}
|
||||||
|
return !!selectLoadingMap[getFieldCacheKey(field)];
|
||||||
|
};
|
||||||
|
|
||||||
|
const filterSelectOption = (input: string, option: any) => {
|
||||||
|
const label = String(option?.label ?? option?.name ?? '');
|
||||||
|
return label.includes(input);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetExtraFilters = () => {
|
||||||
|
Object.keys(extraFilters).forEach(key => {
|
||||||
|
delete extraFilters[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
dynamicFilters.value.forEach(field => {
|
||||||
|
extraFilters[field.name] = undefined;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isEmptyFilterValue = (value: unknown) =>
|
||||||
|
value === undefined || value === null || String(value).trim() === '';
|
||||||
|
|
||||||
|
const hasAttachment = (fid: unknown) =>
|
||||||
|
!!fid && String(fid).trim() !== '' && String(fid).trim() !== '-';
|
||||||
|
|
||||||
|
const handleViewAttachment = (record: any) => {
|
||||||
|
if (!hasAttachment(record?.fid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentAttachmentFid.value = String(record.fid);
|
||||||
|
attachmentModalVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildInputFilter = (field: OperationFilterField, value: string) => {
|
||||||
|
const filterKeys = Array.isArray(field.key)
|
||||||
|
? field.key
|
||||||
|
: field.key
|
||||||
|
? [field.key]
|
||||||
|
: [field.name];
|
||||||
|
|
||||||
|
if (filterKeys.length > 1) {
|
||||||
|
return {
|
||||||
|
logic: 'or',
|
||||||
|
filters: filterKeys.map(item => ({
|
||||||
|
field: item,
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
field: filterKeys[0],
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildYearRangeFilters = () => {
|
||||||
|
if (!modelStore.params.stcd || !searchForm.year) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'data',
|
||||||
|
value: `${searchForm.year}-01-01 00:00:00`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'data',
|
||||||
|
value: `${searchForm.year}-12-31 23:59:59`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildTableFilter = () => {
|
||||||
|
const baseFilters = buildYearRangeFilters();
|
||||||
|
if (!baseFilters) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filters: any[] = [...baseFilters];
|
||||||
|
|
||||||
|
dynamicFilters.value.forEach(field => {
|
||||||
|
const fieldValue = extraFilters[field.name];
|
||||||
|
if (isEmptyFilterValue(fieldValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.type === 'select') {
|
||||||
|
filters.push({
|
||||||
|
field: field.name,
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: fieldValue
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.push(buildInputFilter(field, String(fieldValue).trim()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
logic: 'and',
|
||||||
|
filters
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const syncSecondLevel = () => {
|
||||||
|
searchForm.secondKey = resolveSecondLevelKey(searchForm.secondKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetDefaultCascade = () => {
|
||||||
|
searchForm.firstKey = resolveFirstLevelKey();
|
||||||
|
searchForm.secondKey = getDefaultSecondKey();
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshTable = () => {
|
||||||
|
const filter = buildTableFilter();
|
||||||
|
if (!filter || !currentTable.value?.url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tableRef.value?.getList(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadYearList = async () => {
|
||||||
|
loadYear.value = true;
|
||||||
|
try {
|
||||||
|
if (!modelStore.params.stcd) {
|
||||||
|
searchForm.year = DEFAULT_YEAR;
|
||||||
|
resetDefaultCascade();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res: any = await getFishProgressionYear({
|
||||||
|
stcd: modelStore.params.stcd
|
||||||
|
});
|
||||||
|
const records = res?.data?.data || [];
|
||||||
|
|
||||||
|
if (records.length === 0) {
|
||||||
|
searchForm.year = DEFAULT_YEAR;
|
||||||
|
resetDefaultCascade();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstItem = records[0];
|
||||||
|
searchForm.year = firstItem?.yr || DEFAULT_YEAR;
|
||||||
|
searchForm.firstKey = resolveFirstLevelKey(firstItem?.type);
|
||||||
|
syncSecondLevel();
|
||||||
|
searchForm.secondKey = resolveSecondLevelKey(firstItem?.subType);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取运行数据年份失败:', error);
|
||||||
|
searchForm.year = DEFAULT_YEAR;
|
||||||
|
resetDefaultCascade();
|
||||||
|
} finally {
|
||||||
|
loadYear.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadFtpOptions = async () => {
|
||||||
|
if (!modelStore.params.stcd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadFtp.value = true;
|
||||||
|
try {
|
||||||
|
const res: any = await getFishProgressionFish({
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
select: ['id', 'name']
|
||||||
|
});
|
||||||
|
const records = res?.data?.data || res?.data?.records || res?.data || [];
|
||||||
|
ftpList.value = records.map((item: any) => buildFishOptionItem(item));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取鱼类选项失败:', error);
|
||||||
|
ftpList.value = [];
|
||||||
|
} finally {
|
||||||
|
loadFtp.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadRemoteSelectOptions = async () => {
|
||||||
|
const remoteFields = dynamicFilters.value.filter(
|
||||||
|
field => field.type === 'select' && field.name !== 'ftp' && field.url
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
remoteFields.map(async field => {
|
||||||
|
const cacheKey = getFieldCacheKey(field);
|
||||||
|
selectLoadingMap[cacheKey] = true;
|
||||||
|
try {
|
||||||
|
const method = field.method || 'post';
|
||||||
|
const payload = field.params || {};
|
||||||
|
const res: any = await request({
|
||||||
|
url: field.url,
|
||||||
|
method,
|
||||||
|
...(method === 'get' ? { params: payload } : { data: payload })
|
||||||
|
});
|
||||||
|
const records =
|
||||||
|
res?.data?.data || res?.data?.records || res?.data || [];
|
||||||
|
fieldOptionsMap[cacheKey] = records
|
||||||
|
.filter(
|
||||||
|
(item: any) =>
|
||||||
|
item?.level === undefined || String(item.level) === '2'
|
||||||
|
)
|
||||||
|
.map((item: any) => buildDictOptionItem(item));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取下拉选项失败: ${field.label}`, error);
|
||||||
|
fieldOptionsMap[cacheKey] = [];
|
||||||
|
} finally {
|
||||||
|
selectLoadingMap[cacheKey] = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadBaseData = async () => {
|
||||||
|
if (!modelStore.params.stcd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await Promise.all([loadYearList(), loadFtpOptions()]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTableList = async (params: any) => {
|
||||||
|
if (!currentTable.value?.url) {
|
||||||
|
return EMPTY_TABLE_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return request({
|
||||||
|
url: currentTable.value.url,
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
current: params?.skip || 1,
|
||||||
|
size: params?.take || DEFAULT_TABLE_PAGE_SIZE,
|
||||||
|
filter: params?.filter,
|
||||||
|
sort: [
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
dir: 'desc'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
refreshTable();
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => searchForm.firstKey,
|
||||||
|
() => {
|
||||||
|
syncSecondLevel();
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => searchForm.secondKey,
|
||||||
|
async () => {
|
||||||
|
resetExtraFilters();
|
||||||
|
await loadRemoteSelectOptions();
|
||||||
|
refreshTable();
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.isActive,
|
||||||
|
async active => {
|
||||||
|
if (!active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await loadBaseData();
|
||||||
|
syncSecondLevel();
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => modelStore.params.stcd,
|
||||||
|
async (newStcd, oldStcd) => {
|
||||||
|
if (!props.isActive || !newStcd || newStcd === oldStcd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await loadBaseData();
|
||||||
|
syncSecondLevel();
|
||||||
|
resetExtraFilters();
|
||||||
|
await loadRemoteSelectOptions();
|
||||||
|
refreshTable();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.normal-operation-data {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-control {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-item {
|
||||||
|
flex-basis: 150px;
|
||||||
|
}
|
||||||
|
.select-item1 {
|
||||||
|
flex-basis: 160px;
|
||||||
|
}
|
||||||
|
.select-item2 {
|
||||||
|
flex-basis: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-item {
|
||||||
|
flex-basis: 250px;
|
||||||
|
}
|
||||||
|
.input-item1 {
|
||||||
|
flex-basis: 210px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-modal-body {
|
||||||
|
height: 60vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,522 @@
|
|||||||
|
import {
|
||||||
|
miaoZhongJiLu,
|
||||||
|
miaoZhongPeiYu,
|
||||||
|
qinYuPeiYuFangShi,
|
||||||
|
qinYuPeiYuShuiWen,
|
||||||
|
qinYuPeiYuShuiZi,
|
||||||
|
qinYuPeiYuTouWei,
|
||||||
|
qinYuSiWanJiLu,
|
||||||
|
qinYuXinXi,
|
||||||
|
taoTaiQinYu,
|
||||||
|
yuBingFangZhi,
|
||||||
|
yuLeiRenGo,
|
||||||
|
yuLeiShouJin,
|
||||||
|
yuleifuhua
|
||||||
|
} from './proliferationColumns';
|
||||||
|
|
||||||
|
export interface OperationFilterOption {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
name?: string;
|
||||||
|
id?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationFilterField {
|
||||||
|
type: 'select' | 'input';
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
placeholder?: string;
|
||||||
|
width?: string | number;
|
||||||
|
key?: string | string[];
|
||||||
|
url?: string;
|
||||||
|
method?: 'get' | 'post';
|
||||||
|
params?: Record<string, any>;
|
||||||
|
options?: OperationFilterOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationTableItem {
|
||||||
|
title: string;
|
||||||
|
key: string;
|
||||||
|
url: string;
|
||||||
|
columns: any[];
|
||||||
|
filter: OperationFilterField[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationTextGroup {
|
||||||
|
ctitle: string;
|
||||||
|
key: string;
|
||||||
|
proTable: OperationTableItem[];
|
||||||
|
disable?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationStepItem {
|
||||||
|
title: string;
|
||||||
|
key: string;
|
||||||
|
typeIcon?: string;
|
||||||
|
arrowIcon?: string;
|
||||||
|
textList: OperationTextGroup[];
|
||||||
|
stepIcon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const operationStepList: OperationStepItem[] = [
|
||||||
|
{
|
||||||
|
title: '亲鱼选配与培育',
|
||||||
|
typeIcon: 'fishStation2',
|
||||||
|
arrowIcon: 'arrowDownLine2',
|
||||||
|
key: '1',
|
||||||
|
textList: [
|
||||||
|
{
|
||||||
|
ctitle: '亲鱼选配',
|
||||||
|
key: '1-1',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '亲鱼信息',
|
||||||
|
key: '1-1',
|
||||||
|
url: '/wmp-env-server/fb/bsmfr/qgc/GetKendoListCust',
|
||||||
|
columns: qinYuXinXi,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'sex',
|
||||||
|
label: '性别',
|
||||||
|
width: 120,
|
||||||
|
url: '',
|
||||||
|
options: [
|
||||||
|
{ label: '雄鱼', value: 1 },
|
||||||
|
{ label: '雌鱼', value: 2 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'signnum',
|
||||||
|
label: '标记编号',
|
||||||
|
key: ['signnum', 'length'],
|
||||||
|
placeholder: '搜索标记编号、全长',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '亲鱼死亡记录',
|
||||||
|
key: '1-2',
|
||||||
|
url: '/wmp-env-server/fb/bsdeathr/qgc/GetKendoListCust',
|
||||||
|
columns: qinYuSiWanJiLu,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'signnum',
|
||||||
|
label: '标记编号',
|
||||||
|
key: ['spod', 'deathd', 'length'],
|
||||||
|
placeholder: '搜索死亡症状、死亡诊断、全长',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ctitle: '亲鱼培育',
|
||||||
|
key: '1-2',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '亲鱼培育方式',
|
||||||
|
key: '1-3',
|
||||||
|
url: '/wmp-env-server/fb/bsctmob/qgc/GetKendoListCust',
|
||||||
|
columns: qinYuPeiYuFangShi,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ctmo',
|
||||||
|
label: '培育方式',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'CTMO'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpnum',
|
||||||
|
label: '标记编号',
|
||||||
|
placeholder: '搜索鱼池名称、全长',
|
||||||
|
key: ['fpName', 'length'],
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '亲鱼培育水温观测记录',
|
||||||
|
key: '1-4',
|
||||||
|
url: '/wmp-env-server/fb/fbbwtr/GetKendoListCust',
|
||||||
|
columns: qinYuPeiYuShuiWen,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpName',
|
||||||
|
label: '鱼池名称',
|
||||||
|
placeholder: '搜索鱼池名称',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '亲鱼培育水质监测记录',
|
||||||
|
key: '1-5',
|
||||||
|
url: '/wmp-env-server/fb/fbcwqr/GetKendoListCust',
|
||||||
|
columns: qinYuPeiYuShuiZi,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpName',
|
||||||
|
label: '鱼池名称',
|
||||||
|
placeholder: '搜索鱼池名称',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '亲鱼培育投喂记录',
|
||||||
|
key: '1-6',
|
||||||
|
url: '/wmp-env-server/fb/bsrfir/qgc/GetKendoListCust',
|
||||||
|
columns: qinYuPeiYuTouWei,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftype',
|
||||||
|
label: '饲料种类',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'FEEDTP'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpName',
|
||||||
|
label: '鱼池名称',
|
||||||
|
placeholder: '搜索鱼池名称',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ctitle: '亲鱼补充与淘汰',
|
||||||
|
key: '1-3',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '淘汰亲鱼信息',
|
||||||
|
key: '1-7',
|
||||||
|
url: '/wmp-env-server/fb/outfishr/qgc/GetKendoListCust',
|
||||||
|
columns: taoTaiQinYu,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'sex',
|
||||||
|
label: '性别',
|
||||||
|
width: 120,
|
||||||
|
url: '',
|
||||||
|
options: [
|
||||||
|
{ label: '雄鱼', value: 1 },
|
||||||
|
{ label: '雌鱼', value: 2 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'length',
|
||||||
|
label: '全长',
|
||||||
|
placeholder: '搜索全长'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIcon: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '人工繁殖',
|
||||||
|
key: '2',
|
||||||
|
typeIcon: 'fishStation2',
|
||||||
|
arrowIcon: 'arrowDownLine2',
|
||||||
|
textList: [
|
||||||
|
{
|
||||||
|
ctitle: '亲本选择',
|
||||||
|
key: '2-1',
|
||||||
|
proTable: [],
|
||||||
|
disable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ctitle: '人工催产',
|
||||||
|
key: '2-2',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '鱼类人工催产记录',
|
||||||
|
key: '2-1',
|
||||||
|
url: '/wmp-env-server/fb/fishartinlr/qgc/GetKendoListCust',
|
||||||
|
columns: yuLeiRenGo,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'fpitocintype',
|
||||||
|
label: '催产剂种类',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'FPITOCINTYPE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'sex',
|
||||||
|
label: '性别',
|
||||||
|
width: 120,
|
||||||
|
url: '',
|
||||||
|
options: [
|
||||||
|
{ label: '雄鱼', value: 1 },
|
||||||
|
{ label: '雌鱼', value: 2 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ctitle: '人工授精',
|
||||||
|
key: '2-3',
|
||||||
|
proTable: [],
|
||||||
|
disable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ctitle: '孵化',
|
||||||
|
key: '2-4',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '鱼类受精卵孵化过程记录',
|
||||||
|
key: '2-2',
|
||||||
|
url: '/wmp-env-server/fb/fishhatchrecr/qgc/GetKendoListCust',
|
||||||
|
columns: yuLeiShouJin,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'fpitocintype',
|
||||||
|
label: '催产剂种类',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'FPITOCINTYPE'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '鱼类孵化过程巡查记录',
|
||||||
|
key: '2-3',
|
||||||
|
url: '/wmp-env-server/fb/fishhatchpror/qgc/GetKendoListCust',
|
||||||
|
columns: yuleifuhua,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'devno',
|
||||||
|
label: '孵化设施编号',
|
||||||
|
placeholder: '搜索孵化设施编号'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIcon: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '鱼苗和鱼种的培育',
|
||||||
|
key: '3',
|
||||||
|
typeIcon: 'fishStation2',
|
||||||
|
arrowIcon: 'arrowDownLine2',
|
||||||
|
textList: [
|
||||||
|
{
|
||||||
|
ctitle: '鱼苗和鱼种的培育',
|
||||||
|
key: '3-1',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '苗种培育水环境监测记录',
|
||||||
|
key: '3-1',
|
||||||
|
url: '/wmp-env-server/fb/scwemr/GetKendoListCust',
|
||||||
|
columns: miaoZhongPeiYu,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpName',
|
||||||
|
label: '鱼池名称',
|
||||||
|
placeholder: '搜索鱼池名称'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '苗种培育记录',
|
||||||
|
key: '3-2',
|
||||||
|
url: '/wmp-env-server/fb/fishbreedr/qgc/GetKendoListCust',
|
||||||
|
columns: miaoZhongJiLu,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftype',
|
||||||
|
label: '饲料种类',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'FEEDTP'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'farmno',
|
||||||
|
label: '鱼池编号',
|
||||||
|
placeholder: '搜索鱼池名称、摄食情况',
|
||||||
|
key: ['fpName', 'fin']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIcon: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '鱼病防治',
|
||||||
|
key: '4',
|
||||||
|
typeIcon: 'fishStation2',
|
||||||
|
arrowIcon: 'arrowDownLine2',
|
||||||
|
textList: [
|
||||||
|
{
|
||||||
|
ctitle: '鱼病防治',
|
||||||
|
key: '4-1',
|
||||||
|
proTable: [
|
||||||
|
{
|
||||||
|
title: '鱼病防治记录',
|
||||||
|
key: '4-1',
|
||||||
|
url: '/wmp-env-server/fb/fishdpacr/qgc/GetKendoListCust',
|
||||||
|
columns: yuBingFangZhi,
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'ftp',
|
||||||
|
label: '鱼类',
|
||||||
|
url: '',
|
||||||
|
options: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'method',
|
||||||
|
label: '用药方式',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'method'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'treateffect',
|
||||||
|
label: '治疗效果',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'TREATEFFECT'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'fishdrugtype',
|
||||||
|
label: '鱼药种类',
|
||||||
|
url: '/api/dec-modules-usm-springcloud-starter/usm/v1/dict/getRemoteDictTreeValue',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
dictCode: 'FISHDRUGTYPE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'fpName',
|
||||||
|
label: '鱼池名称',
|
||||||
|
placeholder: '搜索鱼池名称、发病症状',
|
||||||
|
key: ['fpName', 'symptoms']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
disable: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIcon: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,183 @@
|
|||||||
|
<template>
|
||||||
|
<div class="normal-research-situation">
|
||||||
|
<!-- 搜索条件 -->
|
||||||
|
<div class="search-bar mb-4">
|
||||||
|
<span>年份:</span>
|
||||||
|
<a-date-picker
|
||||||
|
v-model:value="searchParams.tm"
|
||||||
|
picker="year"
|
||||||
|
style="width: 160px"
|
||||||
|
format="YYYY"
|
||||||
|
value-format="YYYY"
|
||||||
|
/>
|
||||||
|
<a-button class="ml-4" type="primary" @click="handleSearch">
|
||||||
|
查询
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<BasicTable
|
||||||
|
ref="tableRef"
|
||||||
|
:scrollY="500"
|
||||||
|
:scrollX="tableScrollX"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:list-url="getNormalResearchSituation"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import {
|
||||||
|
getNormalAddedSituationYear,
|
||||||
|
getNormalResearchSituation
|
||||||
|
} from '@/api/mapModal';
|
||||||
|
import { useModelStore } from '@/store/modules/model';
|
||||||
|
import BasicTable from '@/components/BasicTable/index.vue';
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isActive: { type: Boolean, default: false }
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasLoaded = ref(false);
|
||||||
|
const tableRef = ref();
|
||||||
|
|
||||||
|
// 搜索参数
|
||||||
|
const searchParams = ref({
|
||||||
|
tm: null as string | null
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const tableColumns = ref([
|
||||||
|
{
|
||||||
|
title: '科研鱼类',
|
||||||
|
dataIndex: 'ftp',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '已开展工作',
|
||||||
|
dataIndex: 'wco',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '工作详情',
|
||||||
|
dataIndex: 'jd',
|
||||||
|
width: 150
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const tableScrollX = ref(450);
|
||||||
|
|
||||||
|
// 获取年份列表(仅用于设置默认年份)
|
||||||
|
const getYearList = async () => {
|
||||||
|
if (!modelStore.params.stcd) return;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
group: [{ dir: 'desc', field: 'yr' }],
|
||||||
|
groupResultFlat: true
|
||||||
|
};
|
||||||
|
const res: any = await getNormalAddedSituationYear(params);
|
||||||
|
const yearData = res?.data?.data || [];
|
||||||
|
if (yearData.length > 0) {
|
||||||
|
searchParams.value.tm = yearData[0].yr;
|
||||||
|
refreshTable();
|
||||||
|
} else {
|
||||||
|
if (tableRef.value) {
|
||||||
|
tableRef.value.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取年份列表失败:', error);
|
||||||
|
if (tableRef.value) {
|
||||||
|
tableRef.value.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 刷新表格
|
||||||
|
const refreshTable = () => {
|
||||||
|
const year = searchParams.value.tm;
|
||||||
|
const startDate = `${year}-01-01 00:00:00`;
|
||||||
|
const endDate = `${year}-12-31 23:59:59`;
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
dataType: 'string',
|
||||||
|
value: modelStore.params.stcd
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dt',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: startDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dt',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: endDate
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
tableRef.value?.getList(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const handleSearch = () => {
|
||||||
|
refreshTable();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听isActive
|
||||||
|
watch(
|
||||||
|
() => props.isActive,
|
||||||
|
active => {
|
||||||
|
if (active && !hasLoaded.value) {
|
||||||
|
getYearList();
|
||||||
|
hasLoaded.value = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听stcd变化
|
||||||
|
watch(
|
||||||
|
() => modelStore.params.stcd,
|
||||||
|
(newStcd, oldStcd) => {
|
||||||
|
if (newStcd && newStcd !== oldStcd) {
|
||||||
|
hasLoaded.value = false;
|
||||||
|
searchParams.value = { tm: null };
|
||||||
|
getYearList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.normal-research-situation {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
500
frontend/src/components/MapModal/components/columnList.ts
Normal file
500
frontend/src/components/MapModal/components/columnList.ts
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
export const yyccg: any[] = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: '出港时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const Gysyx: any[] = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'stnm',
|
||||||
|
title: '设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: '赶鱼栅运行时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const Syjyx: any[] = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'stnm',
|
||||||
|
title: '设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: window.__lyConfigs.baseId == '02' ? '升鱼斗运行时间' : '升鱼机运行时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const ZWyyh: any[] = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'stnm',
|
||||||
|
title: '设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: '运行时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const Ycyd: any[] = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'stnm',
|
||||||
|
title: '设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: '运行时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: '',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const dlmcolumns = [
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'stnm',
|
||||||
|
title: '设施名称',
|
||||||
|
dataIndex: 'stnm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
fixed: 'left',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'ennm',
|
||||||
|
title: '所属电站',
|
||||||
|
dataIndex: 'ennm',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
fixed: 'left',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
dataFormat: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'tm',
|
||||||
|
title: '操作时间',
|
||||||
|
dataIndex: 'tm',
|
||||||
|
dataFormat: 'YYYY-MM-DD',
|
||||||
|
dataType: 'date',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: 'left',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndexRaw: '',
|
||||||
|
key: 'aiVal',
|
||||||
|
title: '操作状态',
|
||||||
|
dataIndex: 'aiVal',
|
||||||
|
children: [],
|
||||||
|
visible: true,
|
||||||
|
sort: true,
|
||||||
|
fixed: 'left',
|
||||||
|
ellipsis: true,
|
||||||
|
wrap: false,
|
||||||
|
dictType: '',
|
||||||
|
dictCode: '',
|
||||||
|
dictDatas: {},
|
||||||
|
fromType: '',
|
||||||
|
selectMode: '',
|
||||||
|
unit: '',
|
||||||
|
remark: '',
|
||||||
|
rules: '',
|
||||||
|
ruleTips: '',
|
||||||
|
setting: {},
|
||||||
|
chartColor: '',
|
||||||
|
elementCode: '',
|
||||||
|
disabledDate: true,
|
||||||
|
multiLink: false,
|
||||||
|
render: (res: any) => (
|
||||||
|
res == "open" ? "开启" : res == "close" ? "关闭" : '-'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
]
|
||||||
@ -19,6 +19,7 @@
|
|||||||
7. 出库水温 综合分析 导出没做
|
7. 出库水温 综合分析 导出没做
|
||||||
8. 栖息地-流量监测 没有水位视频和流量视频 字段没数据
|
8. 栖息地-流量监测 没有水位视频和流量视频 字段没数据
|
||||||
9. 栖息地 水温、水质、流量没有数据没法测
|
9. 栖息地 水温、水质、流量没有数据没法测
|
||||||
|
10.鱼类增殖站 - 运行数据 要添加字典
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div v-if="modelStore.showStcdSelector" class="stcd-selector-wrapper">
|
<div v-if="modelStore.showStcdSelector" class="stcd-selector-wrapper">
|
||||||
@ -134,6 +135,11 @@
|
|||||||
v-show="currentActiveKey === 'FishZHFX'"
|
v-show="currentActiveKey === 'FishZHFX'"
|
||||||
:is-active="currentActiveKey === 'FishZHFX'"
|
:is-active="currentActiveKey === 'FishZHFX'"
|
||||||
/>
|
/>
|
||||||
|
<!-- AI运行识别 -->
|
||||||
|
<AIYXSB
|
||||||
|
v-show="currentActiveKey === 'AIYXSB'"
|
||||||
|
:is-active="currentActiveKey === 'AIYXSB'"
|
||||||
|
/>
|
||||||
<!-- 预警提示 -->
|
<!-- 预警提示 -->
|
||||||
<EarlyWarningAlert
|
<EarlyWarningAlert
|
||||||
v-show="currentActiveKey === 'tableTabs'"
|
v-show="currentActiveKey === 'tableTabs'"
|
||||||
@ -150,6 +156,22 @@
|
|||||||
v-show="currentActiveKey === 'WaterTemperatureRep'"
|
v-show="currentActiveKey === 'WaterTemperatureRep'"
|
||||||
:is-active="currentActiveKey === 'WaterTemperatureRep'"
|
:is-active="currentActiveKey === 'WaterTemperatureRep'"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 鱼类增殖站 - 运行数据 -->
|
||||||
|
<NormalOperationData
|
||||||
|
v-show="currentActiveKey === 'NormalOperationData'"
|
||||||
|
:is-active="currentActiveKey === 'NormalOperationData'"
|
||||||
|
/>
|
||||||
|
<!-- 增值放流情况 -->
|
||||||
|
<NormalAddedSituation
|
||||||
|
v-show="currentActiveKey === 'NormalAddedSituation'"
|
||||||
|
:is-active="currentActiveKey === 'NormalAddedSituation'"
|
||||||
|
/>
|
||||||
|
<!-- 科研情况 -->
|
||||||
|
<NormalResearchSituation
|
||||||
|
v-show="currentActiveKey === 'NormalResearchSituation'"
|
||||||
|
:is-active="currentActiveKey === 'NormalResearchSituation'"
|
||||||
|
/>
|
||||||
<!-- 查看报告 -->
|
<!-- 查看报告 -->
|
||||||
<Attachment
|
<Attachment
|
||||||
v-show="currentActiveKey === 'attachment'"
|
v-show="currentActiveKey === 'attachment'"
|
||||||
@ -181,10 +203,16 @@ import MonitorInfo from './components/MonitorInfo.vue'; // 电站运行过程线
|
|||||||
import WaterTemperature from './components/WaterTemperature.vue'; // 水温
|
import WaterTemperature from './components/WaterTemperature.vue'; // 水温
|
||||||
import VerticalWaterTemperature from './components/VerticalWaterTemperature.vue'; // 垂向水温
|
import VerticalWaterTemperature from './components/VerticalWaterTemperature.vue'; // 垂向水温
|
||||||
import WaterQuality from './components/WaterQuality.vue'; // 水质
|
import WaterQuality from './components/WaterQuality.vue'; // 水质
|
||||||
|
import AIYXSB from './components/AIYXSB/index.vue'; // AI运行识别
|
||||||
import EarlyWarningAlert from './components/EarlyWarningAlert.vue'; // 预警提示
|
import EarlyWarningAlert from './components/EarlyWarningAlert.vue'; // 预警提示
|
||||||
import FlowMeasure from './components/FlowMeasure.vue'; // 流量监测
|
import FlowMeasure from './components/FlowMeasure.vue'; // 流量监测
|
||||||
import FishFacilityMonitorData from './components/FishFacilityMonitorData.vue'; // 在线监测数据
|
import FishFacilityMonitorData from './components/FishFacilityMonitorData.vue'; // 在线监测数据
|
||||||
import FishFacilityRunState from './components/FishFacilityRunState.vue'; // 运行情况
|
import FishFacilityRunState from './components/FishFacilityRunState.vue'; // 运行情况
|
||||||
|
// 鱼类增殖站
|
||||||
|
import NormalOperationData from './components/NormalOperationData/index.vue'; // 运行数据
|
||||||
|
import NormalAddedSituation from './components/NormalAddedSituation.vue'; // 增值放流情况
|
||||||
|
import NormalResearchSituation from './components/NormalResearchSituation.vue'; // 科研情况
|
||||||
|
|
||||||
import FishZHFX from './components/FishZHFX.vue'; // 鱼类繁殖适宜性分析
|
import FishZHFX from './components/FishZHFX.vue'; // 鱼类繁殖适宜性分析
|
||||||
import EcologicalFlow from './components/EcologicalFlow.vue'; // 生态流量
|
import EcologicalFlow from './components/EcologicalFlow.vue'; // 生态流量
|
||||||
import Attachment from './components/Attachment.vue'; // 查看报告/批复文件
|
import Attachment from './components/Attachment.vue'; // 查看报告/批复文件
|
||||||
@ -400,8 +428,7 @@ watch(
|
|||||||
let params = newVal;
|
let params = newVal;
|
||||||
if (['VD', 'WTRV', 'ZQ', 'WQ'].includes(params?.sttpCode)) {
|
if (['VD', 'WTRV', 'ZQ', 'WQ'].includes(params?.sttpCode)) {
|
||||||
params.sttp = params.sttpCode;
|
params.sttp = params.sttpCode;
|
||||||
}else
|
} else if (['ENG_ALARM'].includes(params?.sttpMap)) {
|
||||||
if (['ENG_ALARM'].includes(params?.sttpMap)) {
|
|
||||||
params.sttp = params.sttpMap;
|
params.sttp = params.sttpMap;
|
||||||
}
|
}
|
||||||
tabsConfig.value = handleTabs({ ...params });
|
tabsConfig.value = handleTabs({ ...params });
|
||||||
|
|||||||
@ -358,6 +358,51 @@ namespace DateSetting {
|
|||||||
value: [getStartTime().subtract(10, 'year'), getStartTime()]
|
value: [getStartTime().subtract(10, 'year'), getStartTime()]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
year1: [
|
||||||
|
{
|
||||||
|
label: '近七天',
|
||||||
|
// 注意:如果项目配置了 isoWeek 插件且希望周一为起始,可使用 startOf('isoWeek')
|
||||||
|
value: [dayjs().subtract(6, 'day').startOf('day'), dayjs().endOf('day')]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '本月',
|
||||||
|
value: [dayjs().startOf('month'), dayjs().endOf('month')]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最近一个月',
|
||||||
|
value: [
|
||||||
|
dayjs().subtract(1, 'month').startOf('month'),
|
||||||
|
dayjs().subtract(1, 'month').endOf('month')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最近三个月',
|
||||||
|
value: [
|
||||||
|
dayjs().subtract(3, 'month').startOf('month'),
|
||||||
|
dayjs().endOf('month')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最近六个月',
|
||||||
|
value: [
|
||||||
|
dayjs().subtract(6, 'month').startOf('month'),
|
||||||
|
dayjs().endOf('month')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最近一年',
|
||||||
|
value: [getStartTime().subtract(1, 'year'), getStartTime()]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '最近两年',
|
||||||
|
value: [getStartTime().subtract(2, 'year'), getStartTime()]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '近三年',
|
||||||
|
value: [getStartTime().subtract(3, 'year'), getStartTime()]
|
||||||
|
}
|
||||||
|
],
|
||||||
future: [
|
future: [
|
||||||
{
|
{
|
||||||
label: '未来一周',
|
label: '未来一周',
|
||||||
|
|||||||
@ -369,7 +369,7 @@ const handleSearchFinish = (values: any) => {
|
|||||||
},
|
},
|
||||||
values.stcd && {
|
values.stcd && {
|
||||||
field: 'stcd',
|
field: 'stcd',
|
||||||
operator: 'eq',
|
operator: 'contains',
|
||||||
dataType: 'string',
|
dataType: 'string',
|
||||||
value: values.stcd
|
value: values.stcd
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user