数据填报bug修改,添加预览视频图片公共组件,删除无用预览改为公共组件
This commit is contained in:
parent
0d5c79bd2e
commit
f289059628
@ -15,6 +15,6 @@ VITE_APP_BASE_URL = 'http://10.84.121.21:8093'
|
|||||||
|
|
||||||
|
|
||||||
# 开发环境导入预览地址
|
# 开发环境导入预览地址
|
||||||
VITE_APP_BASE_API_URL = 'http://172.16.21.14:8096'
|
VITE_APP_BASE_API_URL = 'http://10.84.121.21:8093'
|
||||||
## 开发环境预览 图片视频地址
|
## 开发环境预览 图片视频地址
|
||||||
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
|
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
|
||||||
|
|||||||
@ -32,5 +32,5 @@ module.exports = {
|
|||||||
// Vue文件脚本和样式标签缩进
|
// Vue文件脚本和样式标签缩进
|
||||||
vueIndentScriptAndStyle: false,
|
vueIndentScriptAndStyle: false,
|
||||||
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
|
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
|
||||||
endOfLine: 'lf'
|
endOfLine: 'lf',
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
frontend/dist.rar
Normal file
BIN
frontend/dist.rar
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
// 分页查询过鱼数据
|
// 分页查询过鱼数据
|
||||||
export function getFishDraftPage(data:any) {
|
export function getFishDraftPage(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/page',
|
url: '/data/fishDraft/page',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -9,7 +9,7 @@ export function getFishDraftPage(data:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//新增过鱼数据
|
//新增过鱼数据
|
||||||
export function addFishDraft(queryParams:any) {
|
export function addFishDraft(queryParams: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/saveDraft',
|
url: '/data/fishDraft/saveDraft',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -17,7 +17,7 @@ export function addFishDraft(queryParams:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//修改过鱼数据
|
//修改过鱼数据
|
||||||
export function editFishDraft(queryParams:any) {
|
export function editFishDraft(queryParams: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/updateDraft',
|
url: '/data/fishDraft/updateDraft',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -25,7 +25,7 @@ export function editFishDraft(queryParams:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//删除 过鱼数据
|
//删除 过鱼数据
|
||||||
export function delFishDraft(data:any) {
|
export function delFishDraft(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/batchRemoveDraft',
|
url: '/data/fishDraft/batchRemoveDraft',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -33,22 +33,22 @@ export function delFishDraft(data:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//提交过鱼数据
|
//提交过鱼数据
|
||||||
export function submitFishDraft(data:any) {
|
export function submitFishDraft(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/submitDrafts',
|
url: '/data/fishDraft/submitDrafts',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//提交全部过鱼数据
|
//提交全部过鱼数据
|
||||||
export function batchApproveAll() {
|
export function batchApproveAll() {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/submitDraftsAll',
|
url: '/data/fishDraft/submitDraftsAll',
|
||||||
method: 'post',
|
method: 'post'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//审批过鱼数据
|
//审批过鱼数据
|
||||||
export function successFishDraft(data:any) {
|
export function successFishDraft(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/batchApprove',
|
url: '/data/fishDraft/batchApprove',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -56,7 +56,7 @@ export function successFishDraft(data:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//驳回过鱼数据
|
//驳回过鱼数据
|
||||||
export function rejectFishDraft(data:any) {
|
export function rejectFishDraft(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/reject',
|
url: '/data/fishDraft/reject',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -64,7 +64,7 @@ export function rejectFishDraft(data:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 导入zip
|
// 导入zip
|
||||||
export function importFishZip(data:FormData) {
|
export function importFishZip(data: FormData) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/importZip',
|
url: '/data/fishDraft/importZip',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -73,7 +73,7 @@ export function importFishZip(data:FormData) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 取消导入任务
|
// 取消导入任务
|
||||||
export function cancelImportTask(data:any) {
|
export function cancelImportTask(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/cancelImport',
|
url: '/data/fishDraft/cancelImport',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -95,7 +95,7 @@ export function getLastImportResult() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export function deleteFile(params:any) {
|
export function deleteFile(params: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/deleteFile',
|
url: '/data/fishDraft/deleteFile',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@ -103,10 +103,18 @@ export function deleteFile(params:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 批量保存草稿
|
// 批量保存草稿
|
||||||
export function batchSaveDraft(data:any) {
|
export function batchSaveDraft(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/batchSaveDraft',
|
url: '/data/fishDraft/batchSaveDraft',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 批量删除 审批已驳回的
|
||||||
|
export function batchRemoveDraft(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/data/approvalMain/batchDelete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -34,8 +34,6 @@ interface Props {
|
|||||||
rowKey?: string;
|
rowKey?: string;
|
||||||
// 外部传入的搜索/过滤参数,变化时会自动触发刷新
|
// 外部传入的搜索/过滤参数,变化时会自动触发刷新
|
||||||
searchParams?: Record<string, any>;
|
searchParams?: Record<string, any>;
|
||||||
// 是否只加载一次,默认 false
|
|
||||||
isOneLoad?: boolean;
|
|
||||||
// 默认每页显示数量
|
// 默认每页显示数量
|
||||||
defaultPageSize?: number;
|
defaultPageSize?: number;
|
||||||
getCheckboxProps?: (record: any) => any;
|
getCheckboxProps?: (record: any) => any;
|
||||||
@ -46,7 +44,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
enableRowSelection: false,
|
enableRowSelection: false,
|
||||||
rowKey: "id",
|
rowKey: "id",
|
||||||
data: () => ([]),
|
data: () => ([]),
|
||||||
isOneLoad: true,
|
|
||||||
searchParams: () => ({}),
|
searchParams: () => ({}),
|
||||||
defaultPageSize: 20,
|
defaultPageSize: 20,
|
||||||
getCheckboxProps: undefined,
|
getCheckboxProps: undefined,
|
||||||
@ -143,7 +140,6 @@ const getList = async (filter?: Record<string, any>) => {
|
|||||||
totalCount = res?.data?.total || res?.total || 0;
|
totalCount = res?.data?.total || res?.total || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tableData.value = records;
|
tableData.value = records;
|
||||||
total.value = totalCount;
|
total.value = totalCount;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -10,10 +10,10 @@
|
|||||||
class="map-modal"
|
class="map-modal"
|
||||||
>
|
>
|
||||||
<a-tabs :active-key="currentActiveKey" @change="onTabChange">
|
<a-tabs :active-key="currentActiveKey" @change="onTabChange">
|
||||||
<a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.title">
|
<a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.name">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- 基本信息组件 -->
|
<!-- 基本信息组件 -->
|
||||||
<BasicInfo v-if="currentActiveKey === 'basicInfo'" :url="tab.url" />
|
<BasicInfo v-if="currentActiveKey === 'basicInfo'" :url="tab.url" />
|
||||||
<!-- 地图组件 -->
|
<!-- 地图组件 -->
|
||||||
<!-- <MapView v-else-if="currentActiveKey === 'mapView'" :data="modalData" /> -->
|
<!-- <MapView v-else-if="currentActiveKey === 'mapView'" :data="modalData" /> -->
|
||||||
<!-- 周边配套组件 -->
|
<!-- 周边配套组件 -->
|
||||||
@ -23,6 +23,14 @@
|
|||||||
/> -->
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
<template #rightExtra>
|
||||||
|
<a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'">
|
||||||
|
<a-button type="primary" :disabled="isEngConfig">
|
||||||
|
<i class="icon iconfont icon-topic mr-[5px]"></i>
|
||||||
|
电站专题
|
||||||
|
</a-button
|
||||||
|
></a-tooltip>
|
||||||
|
</template>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
@ -31,6 +39,13 @@
|
|||||||
import { ref, watch } from "vue";
|
import { ref, watch } from "vue";
|
||||||
// 导入预定义的 Tab 内容组件
|
// 导入预定义的 Tab 内容组件
|
||||||
import BasicInfo from "./components/BasicInfo.vue";
|
import BasicInfo from "./components/BasicInfo.vue";
|
||||||
|
import { useModelStore } from "@/store/modules/model";
|
||||||
|
import { handleTabs } from "./setting.config";
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
const tabsConfig = ref([]);
|
||||||
|
// 判断是否显示电站专题配置
|
||||||
|
const isEngConfig = ref(true);
|
||||||
// import MapView from './components/MapView.vue';
|
// import MapView from './components/MapView.vue';
|
||||||
// import SurroundingInfo from './components/SurroundingInfo.vue';
|
// import SurroundingInfo from './components/SurroundingInfo.vue';
|
||||||
|
|
||||||
@ -46,7 +61,6 @@ const props = defineProps<{
|
|||||||
visible: boolean;
|
visible: boolean;
|
||||||
title?: string;
|
title?: string;
|
||||||
activeKey?: string; // 外部控制的当前激活 tab
|
activeKey?: string; // 外部控制的当前激活 tab
|
||||||
tabsConfig?: TabItem[]; // Tab 配置列表,用于生成 Tab 头
|
|
||||||
data?: any; // 可选:传递给内部组件的数据
|
data?: any; // 可选:传递给内部组件的数据
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@ -71,7 +85,13 @@ watch(
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
watch(
|
||||||
|
() => modelStore.params,
|
||||||
|
(newVal) => {
|
||||||
|
tabsConfig.value = handleTabs(newVal);
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
// 监听内部 tab 切换
|
// 监听内部 tab 切换
|
||||||
const onTabChange = (key: string) => {
|
const onTabChange = (key: string) => {
|
||||||
currentActiveKey.value = key;
|
currentActiveKey.value = key;
|
||||||
|
|||||||
@ -12,95 +12,98 @@
|
|||||||
// import { Utility } from '@zebras/qgc-share/utils/Utility'
|
// import { Utility } from '@zebras/qgc-share/utils/Utility'
|
||||||
|
|
||||||
// // 水电站 √
|
// // 水电站 √
|
||||||
// const ENGTabs: Array<any> = [
|
const ENGTabs: Array<any> = [
|
||||||
// {
|
{
|
||||||
// name: '基础信息',
|
name: '基础信息',
|
||||||
// key: 'basicInfo',
|
key: 'basicInfo',
|
||||||
// type: 'basic',
|
type: 'basic',
|
||||||
// url: '/bbi/siteBipc/getSiteBasicInfo'
|
url: '/bbi/siteBipc/getSiteBasicInfo'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '阶段属性',
|
name: '阶段属性',
|
||||||
// key: 'basicFilter',
|
key: 'basicFilter',
|
||||||
// type: 'basicFilter',
|
type: 'basicFilter',
|
||||||
// url: '/eng/engBasisInfo/getEngBaseInfo'
|
url: '/eng/engBasisInfo/getEngBaseInfo'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '实时视频',
|
name: '实时视频',
|
||||||
// key: 'videoInfo',
|
key: 'videoInfo',
|
||||||
// type: 'video',
|
type: 'video',
|
||||||
// url: '/video/dataStcdFrame/getVideoMonitorList'
|
url: '/video/dataStcdFrame/getVideoMonitorList'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '全景影像',
|
name: '全景影像',
|
||||||
// key: 'panoramaInfo',
|
key: 'panoramaInfo',
|
||||||
// type: 'panorama'
|
type: 'panorama'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '监测数据',
|
name: '监测数据',
|
||||||
// key: 'monitorInfo',
|
key: 'monitorInfo',
|
||||||
// type: 'tabsWithTwo',
|
type: 'tabsWithTwo',
|
||||||
// code: 'dzxq.tabs.jcsj'
|
code: 'dzxq.tabs.jcsj'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '预警提示',
|
name: '预警提示',
|
||||||
// key: 'tableTabs',
|
key: 'tableTabs',
|
||||||
// type: 'tableTabs',
|
type: 'tableTabs',
|
||||||
// code: 'dzxq-yjts',
|
code: 'dzxq-yjts',
|
||||||
// tabs: [
|
tabs: [
|
||||||
// {
|
{
|
||||||
// name: '设计参数变更提示',
|
name: '设计参数变更提示',
|
||||||
// key: 'DesignParameterChangePrompt',
|
key: 'DesignParameterChangePrompt',
|
||||||
// type: 'table',
|
type: 'table',
|
||||||
// hiddenChart: true,
|
hiddenChart: true,
|
||||||
// tableUrl: '/dec-lygk-base-server/base/engWarning/GetKendoList'
|
tableUrl: '/dec-lygk-base-server/base/engWarning/GetKendoList'
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// name: '施工期环保措施落实预警',
|
name: '施工期环保措施落实预警',
|
||||||
// key: 'ImplementEarlyWarning',
|
key: 'ImplementEarlyWarning',
|
||||||
// type: 'table',
|
type: 'table',
|
||||||
// hiddenChart: true,
|
hiddenChart: true,
|
||||||
// tableUrl: '/dec-lygk-base-server/base/engWarning/sgqhbss/GetKendoListCust'
|
tableUrl:
|
||||||
// },
|
'/dec-lygk-base-server/base/engWarning/sgqhbss/GetKendoListCust'
|
||||||
// {
|
},
|
||||||
// name: '环保设施建设预警',
|
{
|
||||||
// key: 'ConstructionEarlyWarning',
|
name: '环保设施建设预警',
|
||||||
// type: 'table',
|
key: 'ConstructionEarlyWarning',
|
||||||
// hiddenChart: true,
|
type: 'table',
|
||||||
// tableUrl: '/dec-lygk-base-server/base/engWarning/hbssjs/GetKendoListCust'
|
hiddenChart: true,
|
||||||
// },
|
tableUrl:
|
||||||
// {
|
'/dec-lygk-base-server/base/engWarning/hbssjs/GetKendoListCust'
|
||||||
// name: '环保设施运行预警',
|
},
|
||||||
// key: 'RunEarlyWarning',
|
{
|
||||||
// type: 'table',
|
name: '环保设施运行预警',
|
||||||
// hiddenChart: true,
|
key: 'RunEarlyWarning',
|
||||||
// tableUrl: '/dec-lygk-base-server/base/engWarning/hbssyx/GetKendoListCust'
|
type: 'table',
|
||||||
// },
|
hiddenChart: true,
|
||||||
// {
|
tableUrl:
|
||||||
// name: '鱼类放流预警',
|
'/dec-lygk-base-server/base/engWarning/hbssyx/GetKendoListCust'
|
||||||
// key: 'ReleaseEarlyWarning',
|
},
|
||||||
// type: 'table',
|
{
|
||||||
// hiddenChart: true,
|
name: '鱼类放流预警',
|
||||||
// tableUrl: '/dec-lygk-base-server/base/engWarning/ylfl/GetKendoListCust'
|
key: 'ReleaseEarlyWarning',
|
||||||
// }
|
type: 'table',
|
||||||
// ]
|
hiddenChart: true,
|
||||||
// },
|
tableUrl: '/dec-lygk-base-server/base/engWarning/ylfl/GetKendoListCust'
|
||||||
// Session.getAppCode() === 'hbb' ? {
|
}
|
||||||
// name: '查看报告',
|
]
|
||||||
// key: 'attachment',
|
},
|
||||||
// type: 'attachment'
|
{
|
||||||
// } : null,
|
name: '查看报告',
|
||||||
// {
|
key: 'attachment',
|
||||||
// name: '批复文件',
|
type: 'attachment'
|
||||||
// key: 'approval',
|
},
|
||||||
// type: 'approval'
|
{
|
||||||
// },
|
name: '批复文件',
|
||||||
// // {
|
key: 'approval',
|
||||||
// // name: "特征曲线",
|
type: 'approval'
|
||||||
// // key: "characteristicCurve",
|
}
|
||||||
// // type: "characteristicCurve"
|
// {
|
||||||
// // }
|
// name: "特征曲线",
|
||||||
// ].filter(Boolean)
|
// key: "characteristicCurve",
|
||||||
|
// type: "characteristicCurve"
|
||||||
|
// }
|
||||||
|
].filter(Boolean);
|
||||||
// // 水电站生态流量 √
|
// // 水电站生态流量 √
|
||||||
// const ENGEQTabs: Array<any> = [
|
// const ENGEQTabs: Array<any> = [
|
||||||
// {
|
// {
|
||||||
@ -1076,15 +1079,15 @@
|
|||||||
// // }
|
// // }
|
||||||
// // ]
|
// // ]
|
||||||
|
|
||||||
// //其他配置
|
// 其他配置
|
||||||
// const CommonTabs: any = [
|
const CommonTabs: any = [
|
||||||
// {
|
{
|
||||||
// name: '基础信息',
|
name: '基础信息',
|
||||||
// key: 'basicInfo',
|
key: 'basicInfo',
|
||||||
// type: 'basic',
|
type: 'basic',
|
||||||
// url: '/bbi/siteBipc/getSiteBasicInfo'
|
url: '/bbi/siteBipc/getSiteBasicInfo'
|
||||||
// }
|
}
|
||||||
// ]
|
];
|
||||||
|
|
||||||
// // 气象站
|
// // 气象站
|
||||||
// const WeatherTabs: any = [
|
// const WeatherTabs: any = [
|
||||||
@ -1139,157 +1142,158 @@
|
|||||||
// ]
|
// ]
|
||||||
|
|
||||||
// //mway : 1-是人工 , 2-是自动 dtinType: 0-自建 1-国家 2-人工
|
// //mway : 1-是人工 , 2-是自动 dtinType: 0-自建 1-国家 2-人工
|
||||||
// const handleTabs = (modaldata: any) => {
|
const handleTabs = (modaldata: any) => {
|
||||||
// console.log('modaldata', modaldata)
|
console.log('modaldata', modaldata);
|
||||||
// if (!modaldata?.sttp) return
|
if (!modaldata?.sttp) return;
|
||||||
// let sttp = modaldata?.sttp ? modaldata?.sttp.toUpperCase() : ''
|
let sttp = modaldata?.sttp ? modaldata?.sttp.toUpperCase() : '';
|
||||||
// switch (sttp) {
|
switch (sttp) {
|
||||||
// case 'ENG':
|
case 'ENG':
|
||||||
// if (modaldata?.eqtp == 'QEC') {
|
return ENGTabs;
|
||||||
// const { page } = Utility.parseQueryString()
|
// if (modaldata?.eqtp == 'QEC') {
|
||||||
// if (page == 'shengTaiLiuLiangManZuQingKuangJiangJu') {
|
// const { page } = Utility.parseQueryString()
|
||||||
// return ENGEQTabsJuangJu
|
// if (page == 'shengTaiLiuLiangManZuQingKuangJiangJu') {
|
||||||
// } else {
|
// return ENGEQTabsJuangJu
|
||||||
// return ENGEQTabs
|
// } else {
|
||||||
// }
|
// return ENGEQTabs
|
||||||
// } else {
|
// }
|
||||||
// return Session.getAppCode() === 'hbb' ? ENGTabs.filter((e) => e.name !== '阶段属性') : ENGTabs
|
// } else {
|
||||||
// }
|
// return Session.getAppCode() === 'hbb' ? ENGTabs.filter((e) => e.name !== '阶段属性') : ENGTabs
|
||||||
// case 'ENG_ALARM':
|
// }
|
||||||
// return DZGJ
|
// case 'ENG_ALARM':
|
||||||
// case 'EQ':
|
// return DZGJ
|
||||||
// return EQTabs
|
// case 'EQ':
|
||||||
// case 'DW':
|
// return EQTabs
|
||||||
// case 'DW_1':
|
// case 'DW':
|
||||||
// case 'DW_2':
|
// case 'DW_1':
|
||||||
// case 'DW_3':
|
// case 'DW_2':
|
||||||
// case 'DW_4':
|
// case 'DW_3':
|
||||||
// case 'DW_5':
|
// case 'DW_4':
|
||||||
// return DWTabs
|
// case 'DW_5':
|
||||||
// case 'FP': //todo,后续再删除多余代码
|
// return DWTabs
|
||||||
// case 'FP_1': //todo,后续再删除多余代码
|
// case 'FP': //todo,后续再删除多余代码
|
||||||
// // case "FP_2": //todo,后续再删除多余代码
|
// case 'FP_1': //todo,后续再删除多余代码
|
||||||
// case 'FP_3': //todo,后续再删除多余代码
|
// // case "FP_2": //todo,后续再删除多余代码
|
||||||
// case 'FP_4': //todo,后续再删除多余代码
|
// case 'FP_3': //todo,后续再删除多余代码
|
||||||
// // case "FP_5": //todo,后续再删除多余代码
|
// case 'FP_4': //todo,后续再删除多余代码
|
||||||
// if (Session.getAppCode() === 'hbb') {
|
// // case "FP_5": //todo,后续再删除多余代码
|
||||||
// // mway为2的时侯显示在线监测数据
|
// if (Session.getAppCode() === 'hbb') {
|
||||||
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
// // mway为2的时侯显示在线监测数据
|
||||||
// return [
|
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
||||||
// ...FPTabs1 //建设情况
|
// return [
|
||||||
// ]
|
// ...FPTabs1 //建设情况
|
||||||
// } else {
|
// ]
|
||||||
// if (modaldata.mway != 2) {
|
// } else {
|
||||||
// return FPTabs.filter((item) => item.name !== '在线监测数据')
|
// if (modaldata.mway != 2) {
|
||||||
// } else {
|
// return FPTabs.filter((item) => item.name !== '在线监测数据')
|
||||||
// return [
|
// } else {
|
||||||
// ...FPTabs //有监测数据
|
// return [
|
||||||
// ]
|
// ...FPTabs //有监测数据
|
||||||
// }
|
// ]
|
||||||
// }
|
// }
|
||||||
// } else {
|
// }
|
||||||
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
// } else {
|
||||||
// return [
|
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
||||||
// ...FPTabs1
|
// return [
|
||||||
// // {
|
// ...FPTabs1
|
||||||
// // name: "系统运行记录",
|
// // {
|
||||||
// // key: "FishSystemRunState", //Normal1
|
// // name: "系统运行记录",
|
||||||
// // type: "FishSystemRunState", //Normal
|
// // key: "FishSystemRunState", //Normal1
|
||||||
// // tabs: []
|
// // type: "FishSystemRunState", //Normal
|
||||||
// // }
|
// // tabs: []
|
||||||
// ]
|
// // }
|
||||||
// } else {
|
// ]
|
||||||
// return [
|
// } else {
|
||||||
// ...FPTabs
|
// return [
|
||||||
// // {
|
// ...FPTabs
|
||||||
// // name: "系统运行记录",
|
// // {
|
||||||
// // key: "FishSystemRunState", //Normal1
|
// // name: "系统运行记录",
|
||||||
// // type: "FishSystemRunState", //Normal
|
// // key: "FishSystemRunState", //Normal1
|
||||||
// // tabs: []
|
// // type: "FishSystemRunState", //Normal
|
||||||
// // }
|
// // tabs: []
|
||||||
// ]
|
// // }
|
||||||
// }
|
// ]
|
||||||
// }
|
// }
|
||||||
// case 'FP_2': //todo,后续再删除多余代码
|
// }
|
||||||
// case 'FP_5': //todo,后续再删除多余代码
|
// case 'FP_2': //todo,后续再删除多余代码
|
||||||
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
// case 'FP_5': //todo,后续再删除多余代码
|
||||||
// return FPTabs1
|
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
||||||
// } else {
|
// return FPTabs1
|
||||||
// return FPTabs
|
// } else {
|
||||||
// }
|
// return FPTabs
|
||||||
// case 'ZQ':
|
// }
|
||||||
// return ZQTabs
|
// case 'ZQ':
|
||||||
// case 'FB':
|
// return ZQTabs
|
||||||
// if (modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
// case 'FB':
|
||||||
// return FBTabs1
|
// if (modaldata.bldstt == '1' || modaldata.bldstt == '0') {
|
||||||
// } else {
|
// return FBTabs1
|
||||||
// return FBTabs
|
// } else {
|
||||||
// }
|
// return FBTabs
|
||||||
// case 'FH':
|
// }
|
||||||
// return FHTabs
|
// case 'FH':
|
||||||
// case 'VD_FB':
|
// return FHTabs
|
||||||
// case 'VD_FP':
|
// case 'VD_FB':
|
||||||
// case 'VD_SG':
|
// case 'VD_FP':
|
||||||
// case 'VD_VP':
|
// case 'VD_SG':
|
||||||
// case 'VD_EQ':
|
// case 'VD_VP':
|
||||||
// case 'VD_DW':
|
// case 'VD_EQ':
|
||||||
// case 'VD_FH':
|
// case 'VD_DW':
|
||||||
// case 'VD_OTWE':
|
// case 'VD_FH':
|
||||||
// case 'VD_OTTE':
|
// case 'VD_OTWE':
|
||||||
// case 'VD_FBP':
|
// case 'VD_OTTE':
|
||||||
// case 'VD_FC':
|
// case 'VD_FBP':
|
||||||
// case 'VD_WQ':
|
// case 'VD_FC':
|
||||||
// case 'VD_TE':
|
// case 'VD_WQ':
|
||||||
// case 'VD_WE':
|
// case 'VD_TE':
|
||||||
// case 'VD_EQS':
|
// case 'VD_WE':
|
||||||
// case 'VD_WT':
|
// case 'VD_EQS':
|
||||||
// case 'VD_FBFM':
|
// case 'VD_WT':
|
||||||
// case 'VD_FBI':
|
// case 'VD_FBFM':
|
||||||
// case 'VD_PR':
|
// case 'VD_FBI':
|
||||||
// case 'VD_FPB':
|
// case 'VD_PR':
|
||||||
// case 'VD_GZFC':
|
// case 'VD_FPB':
|
||||||
// case 'VD_FPC':
|
// case 'VD_GZFC':
|
||||||
// case 'VD_VA':
|
// case 'VD_FPC':
|
||||||
// case 'VD':
|
// case 'VD_VA':
|
||||||
// return videoTabs
|
// case 'VD':
|
||||||
// case 'VD_SN':
|
// return videoTabs
|
||||||
// case 'VD_WVD':
|
// case 'VD_SN':
|
||||||
// return noLiveVideoTabs
|
// case 'VD_WVD':
|
||||||
// case 'VP':
|
// return noLiveVideoTabs
|
||||||
// return VPTabs
|
// case 'VP':
|
||||||
// case 'VA':
|
// return VPTabs
|
||||||
// return VATabs
|
// case 'VA':
|
||||||
// case 'WQFB':
|
// return VATabs
|
||||||
// return WQFBTabs
|
// case 'WQFB':
|
||||||
// case 'WQ':
|
// return WQFBTabs
|
||||||
// const _tabs = [...WQTabs]
|
// case 'WQ':
|
||||||
// if (modaldata?.dtinType == 2 || modaldata?.dtinType == 1) _tabs.splice(2, 1)//国家站 人工站把视频tab去除
|
// const _tabs = [...WQTabs]
|
||||||
// return _tabs
|
// if (modaldata?.dtinType == 2 || modaldata?.dtinType == 1) _tabs.splice(2, 1)//国家站 人工站把视频tab去除
|
||||||
// case 'WQDTA':
|
// return _tabs
|
||||||
// return WQDTATabs
|
// case 'WQDTA':
|
||||||
// case 'LL':
|
// return WQDTATabs
|
||||||
// return FLOWTabs
|
// case 'LL':
|
||||||
// case 'WT':
|
// return FLOWTabs
|
||||||
// case 'WTRV':
|
// case 'WT':
|
||||||
// if (modaldata.enfc == '1') {
|
// case 'WTRV':
|
||||||
// return WTTabs1
|
// if (modaldata.enfc == '1') {
|
||||||
// } else {
|
// return WTTabs1
|
||||||
// return WTTabs
|
// } else {
|
||||||
// }
|
// return WTTabs
|
||||||
// case 'WE':
|
// }
|
||||||
// return WETabs
|
// case 'WE':
|
||||||
// case 'MM':
|
// return WETabs
|
||||||
// return WeatherTabs
|
// case 'MM':
|
||||||
// case 'WARN':
|
// return WeatherTabs
|
||||||
// return WaterQualityMonitoring
|
// case 'WARN':
|
||||||
// case 'AI':
|
// return WaterQualityMonitoring
|
||||||
// return AIPrediction
|
// case 'AI':
|
||||||
// case 'AI_Basic':
|
// return AIPrediction
|
||||||
// return AIbasic
|
// case 'AI_Basic':
|
||||||
// default:
|
// return AIbasic
|
||||||
// return CommonTabs
|
default:
|
||||||
// }
|
return CommonTabs;
|
||||||
// }
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// const modalTabSetting = {
|
// const modalTabSetting = {
|
||||||
// footer: false,
|
// footer: false,
|
||||||
@ -1309,4 +1313,21 @@
|
|||||||
// className: 'map-tabs'
|
// className: 'map-tabs'
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// export { ENGTabs, DWTabs, WQTabs, FLOWTabs, EQTabs, FBTabs, WETabs, FPTabs, VPTabs, FHTabs, WTTabs, VATabs, WTTabs1, handleTabs, modalTabSetting, modalTabSettingLy }
|
export {
|
||||||
|
ENGTabs,
|
||||||
|
// DWTabs,
|
||||||
|
// WQTabs,
|
||||||
|
// FLOWTabs,
|
||||||
|
// EQTabs,
|
||||||
|
// FBTabs,
|
||||||
|
// WETabs,
|
||||||
|
// FPTabs,
|
||||||
|
// VPTabs,
|
||||||
|
// FHTabs,
|
||||||
|
// WTTabs,
|
||||||
|
// VATabs,
|
||||||
|
// WTTabs1,
|
||||||
|
handleTabs
|
||||||
|
// modalTabSetting,
|
||||||
|
// modalTabSettingLy
|
||||||
|
};
|
||||||
|
|||||||
315
frontend/src/components/previewMedia/index.vue
Normal file
315
frontend/src/components/previewMedia/index.vue
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 媒体预览 Modal -->
|
||||||
|
<a-modal
|
||||||
|
:open="visible"
|
||||||
|
:title="videoPreviewTitle"
|
||||||
|
:footer="null"
|
||||||
|
width="900px"
|
||||||
|
@cancel="closeMediaPreview"
|
||||||
|
:zIndex="2000"
|
||||||
|
>
|
||||||
|
<div class="flex h-[60vh] gap-4">
|
||||||
|
<!-- 左侧:混合列表 (图片+视频) -->
|
||||||
|
<div class="w-1/4 overflow-y-auto border-r pr-2 media-list-container">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in previewList"
|
||||||
|
:key="index"
|
||||||
|
class="mb-2 cursor-pointer list-item"
|
||||||
|
:class="{ select: index == currentMediaIndex }"
|
||||||
|
@click="currentMediaIndex = index"
|
||||||
|
>
|
||||||
|
<span class="file-name">{{ item.name }}</span>
|
||||||
|
<!-- 删除按钮 -->
|
||||||
|
<div
|
||||||
|
class="list-item-delete"
|
||||||
|
v-if="isDel"
|
||||||
|
@click.stop="handleDeleteMedia(item, index)"
|
||||||
|
>
|
||||||
|
<CloseCircleOutlined />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧:动态预览区域 -->
|
||||||
|
<div
|
||||||
|
class="w-3/4 flex flex-col items-center justify-center bg-gray-100 relative p-4"
|
||||||
|
>
|
||||||
|
<a-spin v-if="imageLoading" tip="图片加载中..." size="large" />
|
||||||
|
<!-- 图片预览 -->
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
currentMediaItem &&
|
||||||
|
currentMediaItem.url != '' &&
|
||||||
|
currentMediaItem.type === 'image'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-show="!imageLoading && !imageLoadError"
|
||||||
|
:src="currentMediaItem.url"
|
||||||
|
alt="preview"
|
||||||
|
class="max-w-full max-h-[50vh] object-contain"
|
||||||
|
@load="onImageLoad"
|
||||||
|
@error="onImageError"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 3. 加载失败提示 -->
|
||||||
|
<div
|
||||||
|
v-if="!imageLoading && imageLoadError"
|
||||||
|
class="text-gray-400 flex flex-col items-center"
|
||||||
|
>
|
||||||
|
<ExclamationCircleOutlined style="font-size: 24px; margin-bottom: 8px" />
|
||||||
|
<span>图片加载失败</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="
|
||||||
|
currentMediaItem &&
|
||||||
|
currentMediaItem.url == '' &&
|
||||||
|
currentMediaItem.type === 'image'
|
||||||
|
"
|
||||||
|
class="text-gray-400"
|
||||||
|
>
|
||||||
|
暂无图片预览
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 视频预览 -->
|
||||||
|
<video
|
||||||
|
v-else-if="
|
||||||
|
currentMediaItem &&
|
||||||
|
currentMediaItem.url != '' &&
|
||||||
|
currentMediaItem.type === 'video'
|
||||||
|
"
|
||||||
|
:src="currentMediaItem.url"
|
||||||
|
controls
|
||||||
|
autoplay
|
||||||
|
class="max-w-full max-h-[50vh]"
|
||||||
|
>
|
||||||
|
您的浏览器不支持视频播放
|
||||||
|
</video>
|
||||||
|
<div
|
||||||
|
v-else-if="
|
||||||
|
currentMediaItem &&
|
||||||
|
currentMediaItem.url == '' &&
|
||||||
|
currentMediaItem.type === 'video'
|
||||||
|
"
|
||||||
|
class="text-gray-400"
|
||||||
|
>
|
||||||
|
暂无视频预览
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部切换控制 -->
|
||||||
|
<div class="absolute bottom-4 flex gap-4 z-10">
|
||||||
|
<a-button
|
||||||
|
shape="circle"
|
||||||
|
:icon="h(LeftOutlined)"
|
||||||
|
@click="prevMedia"
|
||||||
|
:disabled="currentMediaIndex === 0"
|
||||||
|
/>
|
||||||
|
<span class="self-center text-gray-600 bg-white px-2 rounded shadow-sm">
|
||||||
|
{{ currentMediaIndex + 1 }} / {{ previewList.length }}
|
||||||
|
</span>
|
||||||
|
<a-button
|
||||||
|
shape="circle"
|
||||||
|
:icon="h(RightOutlined)"
|
||||||
|
@click="nextMedia"
|
||||||
|
:disabled="currentMediaIndex === previewList.length - 1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, nextTick, computed, watch, h } from "vue";
|
||||||
|
import { message, Modal } from "ant-design-vue"; // 假设使用 ant-design-vue
|
||||||
|
import {
|
||||||
|
LeftOutlined,
|
||||||
|
RightOutlined,
|
||||||
|
CloseCircleOutlined,
|
||||||
|
ExclamationCircleOutlined,
|
||||||
|
} from "@ant-design/icons-vue";
|
||||||
|
import { deleteFile } from "@/api/guoYuSheShiShuJuTianBao";
|
||||||
|
// 图片加载状态
|
||||||
|
const imageLoading = ref(false);
|
||||||
|
const imageLoadError = ref(false);
|
||||||
|
|
||||||
|
interface MediaItem {
|
||||||
|
id: string;
|
||||||
|
type: "image" | "video";
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
const props = defineProps<{
|
||||||
|
visible: boolean;
|
||||||
|
videoPreviewTitle: string;
|
||||||
|
previewList: MediaItem[];
|
||||||
|
previewListIndex: number;
|
||||||
|
taskId?: string;
|
||||||
|
isDel?: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:visible", "deleteMedia"]);
|
||||||
|
const currentMediaIndex = ref(props.previewListIndex);
|
||||||
|
|
||||||
|
// 计算当前选中的项
|
||||||
|
const currentMediaItem = computed(() => props.previewList[currentMediaIndex.value]);
|
||||||
|
|
||||||
|
const closeMediaPreview = () => {
|
||||||
|
emit("update:visible", false);
|
||||||
|
nextTick(() => {
|
||||||
|
currentMediaIndex.value = 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 【新增】统一切换逻辑
|
||||||
|
const prevMedia = () => {
|
||||||
|
if (currentMediaIndex.value > 0) {
|
||||||
|
currentMediaIndex.value--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 【新增】统一下一逻辑
|
||||||
|
const nextMedia = () => {
|
||||||
|
if (currentMediaIndex.value < props.previewList.length - 1) {
|
||||||
|
currentMediaIndex.value++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 【新增】统一删除逻辑
|
||||||
|
const handleDeleteMedia = (item: any, index: number) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "确认删除",
|
||||||
|
content: "确定要从预览列表中移除该项吗?",
|
||||||
|
zIndex: 2002,
|
||||||
|
onOk: async () => {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const params = {
|
||||||
|
id: item.id,
|
||||||
|
taskId: props.taskId,
|
||||||
|
type:
|
||||||
|
props.videoPreviewTitle == "图片预览"
|
||||||
|
? 1
|
||||||
|
: props.videoPreviewTitle == "视频预览"
|
||||||
|
? 2
|
||||||
|
: 0,
|
||||||
|
filename: item.name,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
let res: any = await deleteFile(params);
|
||||||
|
if (res && res?.code == 0) {
|
||||||
|
message.success("删除成功");
|
||||||
|
|
||||||
|
emit("deleteMedia", item, props.videoPreviewTitle, index);
|
||||||
|
if (props.previewList.length === 0) {
|
||||||
|
closeMediaPreview();
|
||||||
|
} else {
|
||||||
|
// 调整索引
|
||||||
|
if (index <= currentMediaIndex.value) {
|
||||||
|
currentMediaIndex.value = Math.max(0, currentMediaIndex.value - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
message.error("删除失败");
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
message.error("删除失败");
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
}).catch(() => console.log("Oops errors!"));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 【新增】图片加载完成回调
|
||||||
|
const onImageLoad = () => {
|
||||||
|
imageLoading.value = false;
|
||||||
|
imageLoadError.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 【新增】图片加载失败回调
|
||||||
|
const onImageError = () => {
|
||||||
|
imageLoading.value = false;
|
||||||
|
imageLoadError.value = true;
|
||||||
|
};
|
||||||
|
watch(
|
||||||
|
() => props.previewListIndex,
|
||||||
|
(newIndex) => {
|
||||||
|
currentMediaIndex.value = newIndex;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(newVisible) => {
|
||||||
|
if (newVisible) {
|
||||||
|
if (props.videoPreviewTitle == "图片预览") {
|
||||||
|
imageLoading.value = true;
|
||||||
|
imageLoadError.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(currentMediaIndex, (newIndex) => {
|
||||||
|
const item = props.previewList[newIndex];
|
||||||
|
if (item && item.type === "image") {
|
||||||
|
imageLoading.value = true;
|
||||||
|
imageLoadError.value = false;
|
||||||
|
} else {
|
||||||
|
imageLoading.value = false;
|
||||||
|
imageLoadError.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.media-list-container {
|
||||||
|
background-color: rgb(234, 241, 251);
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.select {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: rgb(37, 93, 138);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item-delete {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .list-item-delete {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -2,8 +2,12 @@
|
|||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { useTagsViewStore } from "@/store/modules/tagsView";
|
import { useTagsViewStore } from "@/store/modules/tagsView";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
import MapModal from "@/components/MapModal/index.vue";
|
||||||
|
import { useModelStore } from "@/store/modules/model";
|
||||||
// import GisView from "@/components/gis/GisView.vue";
|
// import GisView from "@/components/gis/GisView.vue";
|
||||||
|
|
||||||
|
const modelStore = useModelStore();
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
|
|
||||||
const router = useRoute();
|
const router = useRoute();
|
||||||
@ -22,6 +26,13 @@ const routeKey = computed(() => router.path + Math.random());
|
|||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<MapModal
|
||||||
|
v-model:visible="modelStore.modalVisible"
|
||||||
|
v-model:active-key="modelStore.currentTabKey"
|
||||||
|
:title="modelStore.title"
|
||||||
|
:tabs-config="modelStore.tabList"
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,23 @@ import { ref } from 'vue';
|
|||||||
|
|
||||||
export const useModelStore = defineStore('model', () => {
|
export const useModelStore = defineStore('model', () => {
|
||||||
// state
|
// state
|
||||||
const info = ref<{
|
const modalVisible = ref(false);
|
||||||
type: string;
|
const currentTabKey = ref("basicInfo");
|
||||||
|
const tabList = ref([]);
|
||||||
|
const title = ref('');
|
||||||
|
const isBasicEdit = ref(false);
|
||||||
|
|
||||||
|
const params = ref<{
|
||||||
|
sttp: string;
|
||||||
}>({
|
}>({
|
||||||
type: 'zh'
|
sttp: 'eng'
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
info,
|
params,
|
||||||
|
modalVisible,
|
||||||
|
currentTabKey,
|
||||||
|
tabList,
|
||||||
|
title,
|
||||||
|
isBasicEdit,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,10 +4,9 @@ import JidiSelectorMod from "@/modules/jidiSelectorMod.vue";
|
|||||||
import RightDrawer from "@/components/RightDrawer/index.vue";
|
import RightDrawer from "@/components/RightDrawer/index.vue";
|
||||||
import jidiInfoMod from "@/modules/jidiInfoMod/index.vue";
|
import jidiInfoMod from "@/modules/jidiInfoMod/index.vue";
|
||||||
import shuidianhuangjingjieruMod from "@/modules/shuidianhuangjingjieruMod/index.vue";
|
import shuidianhuangjingjieruMod from "@/modules/shuidianhuangjingjieruMod/index.vue";
|
||||||
import MapModal from "@/components/MapModal/index.vue";
|
|
||||||
import { useModelStore } from "@/store/modules/model";
|
import { useModelStore } from "@/store/modules/model";
|
||||||
|
|
||||||
const modelInfo = useModelStore();
|
const modelStore = useModelStore();
|
||||||
// import { getQgcStaticData } from "@/api/ecoFlow";
|
// import { getQgcStaticData } from "@/api/ecoFlow";
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// const params = {
|
// const params = {
|
||||||
@ -26,29 +25,23 @@ onMounted(() => {
|
|||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
const modalVisible = ref(false);
|
|
||||||
const currentTabKey = ref("basicInfo");
|
|
||||||
const projectData = ref({ id: 1, name: "测试项目" });
|
|
||||||
|
|
||||||
const tabList = [
|
|
||||||
{ key: "basicInfo", title: "基础信息", url: "" },
|
|
||||||
{ key: "mapView", title: "地图视图", url: "" },
|
|
||||||
{ key: "surrounding", title: "周边配套", url: "" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const showMapModal = () => {
|
const showMapModal = () => {
|
||||||
modalVisible.value = true;
|
modelStore.modalVisible = true;
|
||||||
currentTabKey.value = "basicInfo";
|
modelStore.params.sttp = "ENG";
|
||||||
modelInfo.info.type = "eng";
|
modelStore.title = "三峡 详情信息";
|
||||||
|
modelStore.currentTabKey = "basicInfo";
|
||||||
|
modelStore.isBasicEdit = true;
|
||||||
};
|
};
|
||||||
const showMapModal1 = () => {
|
const showMapModal1 = () => {
|
||||||
modalVisible.value = true;
|
modelStore.modalVisible = true;
|
||||||
currentTabKey.value = "basicInfo";
|
modelStore.params.sttp = "ENG";
|
||||||
modelInfo.info.type = "zh";
|
modelStore.title = "三峡222 详情信息";
|
||||||
};
|
modelStore.currentTabKey = "basicInfo";
|
||||||
|
modelStore.isBasicEdit = false;
|
||||||
const onTabChange = (key: string) => {
|
// modelStore.modalVisible = true;
|
||||||
console.log("Tab 切换为:", key);
|
// modelStore.params.sttp = "zh";
|
||||||
|
// modelStore.title = '三峡222 详情信息';
|
||||||
|
// modelStore.currentTabKey = "mapView";
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -60,16 +53,8 @@ const onTabChange = (key: string) => {
|
|||||||
<div class="rightContent">
|
<div class="rightContent">
|
||||||
<RightDrawer>
|
<RightDrawer>
|
||||||
<!-- <a-button @click="showMapModal">打开电站地图弹窗</a-button>
|
<!-- <a-button @click="showMapModal">打开电站地图弹窗</a-button>
|
||||||
<a-button @click="showMapModal1">打开地图弹窗1</a-button>
|
<a-button @click="showMapModal1">打开地图弹窗1</a-button> -->
|
||||||
|
|
||||||
<MapModal
|
|
||||||
v-model:visible="modalVisible"
|
|
||||||
v-model:active-key="currentTabKey"
|
|
||||||
title="三峡 详情信息"
|
|
||||||
:tabs-config="tabList"
|
|
||||||
:data="projectData"
|
|
||||||
@change="onTabChange"
|
|
||||||
/> -->
|
|
||||||
<jidiInfoMod />
|
<jidiInfoMod />
|
||||||
<shuidianhuangjingjieruMod />
|
<shuidianhuangjingjieruMod />
|
||||||
</RightDrawer>
|
</RightDrawer>
|
||||||
|
|||||||
@ -1,90 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="guoYuSheShiShuJuHistory-page">
|
<div class="guoYuSheShiShuJuHistory-page">
|
||||||
<GuoYuSheShiShuJuHistorySearch ref="searchRef" class="search-container" :guoyuStatus="guoyuStatus"
|
<GuoYuSheShiShuJuHistorySearch
|
||||||
:direction="direction" @reset="handleReset" @search-finish="handleSearchFinish" />
|
ref="searchRef"
|
||||||
|
class="search-container"
|
||||||
|
:guoyuStatus="guoyuStatus"
|
||||||
|
:direction="direction"
|
||||||
|
@reset="handleReset"
|
||||||
|
@search-finish="handleSearchFinish"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="table-container" ref="tableContainerRef">
|
<div class="table-container" ref="tableContainerRef">
|
||||||
<BasicTable ref="tableRef" :columns="columns" :scroll-y="tableScrollY" :list-url="getFishDraftPage"
|
<BasicTable
|
||||||
:search-params="{}" :transform-data="customTransform">
|
ref="tableRef"
|
||||||
|
:columns="columns"
|
||||||
|
:scroll-y="tableScrollY"
|
||||||
|
:list-url="getFishDraftPage"
|
||||||
|
:search-params="{}"
|
||||||
|
:transform-data="customTransform"
|
||||||
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
|
<template v-if="column.key === 'action' || column.dataIndex === 'action'">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<a-button type="link" size="small" @click="handleView(record)">查看</a-button>
|
<a-button type="link" size="small" @click="handleView(record)"
|
||||||
|
>查看</a-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 预览媒体组件 -->
|
||||||
|
<PreviewMedia
|
||||||
|
ref="previewMediaRef"
|
||||||
|
v-model:visible="mediaPreviewVisible"
|
||||||
|
:previewList="previewList"
|
||||||
|
:previewListIndex="previewListIndex"
|
||||||
|
:videoPreviewTitle="videoPreviewTitle"
|
||||||
|
/>
|
||||||
|
|
||||||
<a-modal v-model:open="mediaPreviewVisible" :title="videoPreviewTitle" :footer="null" width="900px"
|
<EditModal
|
||||||
@cancel="closeMediaPreview" :zIndex="2000">
|
ref="editModalRef"
|
||||||
<div class="flex h-[60vh] gap-4">
|
v-model:visible="editModalVisible"
|
||||||
<div class="w-1/4 overflow-y-auto border-r pr-2 media-list-container">
|
:is-view="true"
|
||||||
<div v-for="(item, index) in previewList" :key="index" class="mb-2 cursor-pointer list-item"
|
:direction="direction"
|
||||||
:class="{ select: index === currentMediaIndex }" @click="currentMediaIndex = index">
|
:initial-values="currentRecord"
|
||||||
<span class="file-name">{{ item.name }}</span>
|
@cancel="editModalCancel"
|
||||||
</div>
|
@preview-click="handlePreviewClick"
|
||||||
</div>
|
/>
|
||||||
|
|
||||||
<div class="w-3/4 flex flex-col items-center justify-center bg-gray-100 relative p-4">
|
|
||||||
<a-image v-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url != '' &&
|
|
||||||
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
|
||||||
" :src="currentMediaItem.url" class="max-w-full max-h-full object-contain" />
|
|
||||||
<div v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url == '' &&
|
|
||||||
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
|
||||||
" class="text-gray-400">
|
|
||||||
暂无图片预览
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<video v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url != '' &&
|
|
||||||
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
|
||||||
" :src="currentMediaItem.url" controls autoplay class="max-w-full max-h-[50vh]">
|
|
||||||
您的浏览器不支持视频播放
|
|
||||||
</video>
|
|
||||||
<div v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url == '' &&
|
|
||||||
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
|
||||||
" class="text-gray-400">
|
|
||||||
暂无视频预览
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="absolute bottom-4 flex gap-4 z-10">
|
|
||||||
<a-button shape="circle" :icon="h(LeftOutlined)" @click="prevMedia" :disabled="currentMediaIndex === 0" />
|
|
||||||
<span class="self-center text-gray-600 bg-white px-2 rounded shadow-sm">
|
|
||||||
{{ currentMediaIndex + 1 }} / {{ previewList.length }}
|
|
||||||
</span>
|
|
||||||
<a-button shape="circle" :icon="h(RightOutlined)" @click="nextMedia"
|
|
||||||
:disabled="currentMediaIndex === previewList.length - 1" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
|
|
||||||
<EditModal ref="editModalRef" v-model:visible="editModalVisible" :is-view="true" :direction="direction"
|
|
||||||
:initial-values="currentRecord" @cancel="editModalCancel" @preview-click="handlePreviewClick" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted, h, nextTick } from "vue";
|
import { ref, computed, onMounted, h, nextTick } from "vue";
|
||||||
import { message } from "ant-design-vue";
|
|
||||||
import { LeftOutlined, RightOutlined } from "@ant-design/icons-vue";
|
|
||||||
import BasicTable from "@/components/BasicTable/index.vue";
|
import BasicTable from "@/components/BasicTable/index.vue";
|
||||||
|
import PreviewMedia from "@/components/previewMedia/index.vue";
|
||||||
import GuoYuSheShiShuJuHistorySearch from "./guoYuSheShiShuJuHistorySearch.vue";
|
import GuoYuSheShiShuJuHistorySearch from "./guoYuSheShiShuJuHistorySearch.vue";
|
||||||
import EditModal from "../guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue";
|
import EditModal from "../guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue";
|
||||||
import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao";
|
import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao";
|
||||||
|
|
||||||
import { Tag } from "ant-design-vue";
|
import { Tag } from "ant-design-vue";
|
||||||
import { getDictItemsByCode } from "@/api/dict";
|
import { getDictItemsByCode } from "@/api/dict";
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||||
const baseUrlPreview = import.meta.env.VITE_APP_BASE_URL;
|
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -100,8 +77,6 @@ interface ColumnConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tableRef = ref<any>(null);
|
const tableRef = ref<any>(null);
|
||||||
const searchRef = ref<any>(null);
|
|
||||||
const editModalRef = ref<any>(null);
|
|
||||||
|
|
||||||
const direction = ref<any>([]);
|
const direction = ref<any>([]);
|
||||||
const guoyuStatus = ref<any>([]);
|
const guoyuStatus = ref<any>([]);
|
||||||
@ -174,17 +149,13 @@ const videoPreviewTitle = ref("视频预览");
|
|||||||
|
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
id: string;
|
id: string;
|
||||||
type: "image" | "video" | "formVideo" | "formImage";
|
type: "image" | "video";
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const previewList = ref<MediaItem[]>([]);
|
const previewList = ref<MediaItem[]>([]);
|
||||||
const currentMediaIndex = ref(0);
|
const previewListIndex = ref(0);
|
||||||
const tablePreviewRecord = ref<any>({});
|
|
||||||
|
|
||||||
const currentMediaItem = computed(() => previewList.value[currentMediaIndex.value]);
|
|
||||||
|
|
||||||
const columns = computed(() => {
|
const columns = computed(() => {
|
||||||
return [
|
return [
|
||||||
...baseColumnsConfig.map((col) => {
|
...baseColumnsConfig.map((col) => {
|
||||||
@ -231,59 +202,23 @@ const editModalCancel = () => {
|
|||||||
const handlePreviewClick = (record: any, type: string, index: number) => {
|
const handlePreviewClick = (record: any, type: string, index: number) => {
|
||||||
const mixedList: MediaItem[] = [];
|
const mixedList: MediaItem[] = [];
|
||||||
if (type === "image") {
|
if (type === "image") {
|
||||||
tablePreviewRecord.value = record;
|
|
||||||
videoPreviewTitle.value = "图片预览";
|
|
||||||
const nameList = record.picpthList;
|
|
||||||
nameList.forEach((item: any) => {
|
|
||||||
mixedList.push({
|
|
||||||
id: record.id,
|
|
||||||
type: "image",
|
|
||||||
name: item.name,
|
|
||||||
url:
|
|
||||||
baseUrlPreview +
|
|
||||||
"/data/fishDraft/previewFile?filename=" +
|
|
||||||
item.name +
|
|
||||||
"&taskId=" +
|
|
||||||
"" +
|
|
||||||
"&type=1",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else if (type === "video") {
|
|
||||||
tablePreviewRecord.value = record;
|
|
||||||
videoPreviewTitle.value = "视频预览";
|
|
||||||
const nameList = record.vdpthList;
|
|
||||||
nameList.forEach((item: any) => {
|
|
||||||
mixedList.push({
|
|
||||||
id: record.id,
|
|
||||||
type: "video",
|
|
||||||
name: item.name,
|
|
||||||
url:
|
|
||||||
baseUrlPreview +
|
|
||||||
"/data/fishDraft/previewFile?filename=" +
|
|
||||||
item.name +
|
|
||||||
"&taskId=" +
|
|
||||||
"" +
|
|
||||||
"&type=2",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else if (type === "formImage") {
|
|
||||||
videoPreviewTitle.value = "图片预览";
|
videoPreviewTitle.value = "图片预览";
|
||||||
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
id: record.id,
|
id: record.id,
|
||||||
type: "formImage",
|
type: "image",
|
||||||
name: item.name,
|
name: item.name,
|
||||||
url: item.url,
|
url: item.url,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (type === "formVideo") {
|
} else if (type === "video") {
|
||||||
videoPreviewTitle.value = "视频预览";
|
videoPreviewTitle.value = "视频预览";
|
||||||
const nameList = JSON.parse(JSON.stringify(record)).vdpthList;
|
const nameList = JSON.parse(JSON.stringify(record)).vdpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
id: record.id,
|
id: record.id,
|
||||||
type: "formVideo",
|
type: "video",
|
||||||
name: item.name,
|
name: item.name,
|
||||||
url: item.url,
|
url: item.url,
|
||||||
});
|
});
|
||||||
@ -291,32 +226,12 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mediaPreviewVisible.value = true;
|
mediaPreviewVisible.value = true;
|
||||||
currentMediaIndex.value = index;
|
previewListIndex.value = index;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
previewList.value = mixedList;
|
previewList.value = mixedList;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const prevMedia = () => {
|
|
||||||
if (currentMediaIndex.value > 0) {
|
|
||||||
currentMediaIndex.value--;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const nextMedia = () => {
|
|
||||||
if (currentMediaIndex.value < previewList.value.length - 1) {
|
|
||||||
currentMediaIndex.value++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeMediaPreview = () => {
|
|
||||||
mediaPreviewVisible.value = false;
|
|
||||||
nextTick(() => {
|
|
||||||
previewList.value = [];
|
|
||||||
currentMediaIndex.value = 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const customTransform = (res: any) => {
|
const customTransform = (res: any) => {
|
||||||
const rawRecords = res?.data?.records || [];
|
const rawRecords = res?.data?.records || [];
|
||||||
const modifiedRecords = rawRecords.map((item: any) => {
|
const modifiedRecords = rawRecords.map((item: any) => {
|
||||||
@ -349,13 +264,13 @@ const handleSearchFinish = (values: any) => {
|
|||||||
field: "strdt",
|
field: "strdt",
|
||||||
operator: "gte",
|
operator: "gte",
|
||||||
dataType: "date",
|
dataType: "date",
|
||||||
value: values.strdt[0] + ' 00:00:00',
|
value: values.strdt[0] + " 00:00:00",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "strdt",
|
field: "strdt",
|
||||||
operator: "lte",
|
operator: "lte",
|
||||||
dataType: "date",
|
dataType: "date",
|
||||||
value: values.strdt[1] + ' 23:59:59',
|
value: values.strdt[1] + " 23:59:59",
|
||||||
},
|
},
|
||||||
values.direction && {
|
values.direction && {
|
||||||
field: "direction",
|
field: "direction",
|
||||||
@ -367,7 +282,7 @@ const handleSearchFinish = (values: any) => {
|
|||||||
field: "status",
|
field: "status",
|
||||||
operator: "eq",
|
operator: "eq",
|
||||||
dataType: "string",
|
dataType: "string",
|
||||||
value: 'APPROVED',
|
value: "APPROVED",
|
||||||
},
|
},
|
||||||
values.stcd && {
|
values.stcd && {
|
||||||
field: "stcd",
|
field: "stcd",
|
||||||
@ -456,39 +371,4 @@ onMounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-list-container {
|
|
||||||
background-color: rgb(234, 241, 251);
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 36px;
|
|
||||||
line-height: 36px;
|
|
||||||
padding: 0 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-name {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.select {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: rgb(37, 93, 138);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
>
|
>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="流域" name="hbrvcd">
|
<a-form-item label="流域" name="hbrvcd">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="formData.hbrvcd"
|
v-model:value="formData.hbrvcd"
|
||||||
:loading="hbrvcdLoading"
|
:loading="hbrvcdLoading"
|
||||||
@ -413,7 +413,7 @@ const emit = defineEmits<{
|
|||||||
(e: "update:visible", value: boolean): void;
|
(e: "update:visible", value: boolean): void;
|
||||||
(e: "cancel"): void;
|
(e: "cancel"): void;
|
||||||
(e: "ok", values: any): void;
|
(e: "ok", values: any): void;
|
||||||
(e: "preview-click", record: any, type: string, index: number): void;
|
(e: "preview-click", record: any, type: string, index: number, action: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 表单引用
|
// 表单引用
|
||||||
@ -654,13 +654,12 @@ const initForm = () => {
|
|||||||
|
|
||||||
// 视频预览
|
// 视频预览
|
||||||
const handleVideoPreview = () => {
|
const handleVideoPreview = () => {
|
||||||
emit("preview-click", { vdpthList: videoFileList.value }, "formVideo", 0);
|
emit("preview-click", { vdpthList: videoFileList.value }, "video", 0, "preview");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 预览图片
|
// 预览图片
|
||||||
const handleImagePreview = async (file: any) => {
|
const handleImagePreview = async (file: any) => {
|
||||||
emit("preview-click", { picpthList: imageFileList.value }, "formImage", 0);
|
emit("preview-click", { picpthList: imageFileList.value }, "image", 0, "preview");
|
||||||
return Promise.reject();
|
|
||||||
};
|
};
|
||||||
// 确认操作
|
// 确认操作
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
@ -809,7 +808,7 @@ watch(
|
|||||||
if (newVisible) {
|
if (newVisible) {
|
||||||
// 弹窗打开时,初始化数据
|
// 弹窗打开时,初始化数据
|
||||||
// getBaseDropdownSelect();// 基地
|
// getBaseDropdownSelect();// 基地
|
||||||
getHbrvcdDropdownSelect();// 流域
|
getHbrvcdDropdownSelect(); // 流域
|
||||||
getEngInfoDropdownSelect(formData.hbrvcd);
|
getEngInfoDropdownSelect(formData.hbrvcd);
|
||||||
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
|
getFpssDropdownSelect(formData.rstcd, formData.hbrvcd);
|
||||||
initForm();
|
initForm();
|
||||||
@ -819,7 +818,7 @@ watch(
|
|||||||
);
|
);
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
localLoading
|
localLoading,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
row-key="id"
|
row-key="id"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record, index }">
|
<template #bodyCell="{ column, record, index }">
|
||||||
<!--
|
<!--
|
||||||
<template v-if="column.key === 'index' || column.dataIndex === 'index'">
|
<template v-if="column.key === 'index' || column.dataIndex === 'index'">
|
||||||
{{ index + 1 }}
|
{{ index + 1 }}
|
||||||
</template> -->
|
</template> -->
|
||||||
@ -144,14 +144,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 过鱼时间 -->
|
<!-- 过鱼时间 -->
|
||||||
<template v-else-if="column.dataIndex === 'strdt'">
|
<template v-else-if="column.dataIndex === 'strdtStr'">
|
||||||
<a-date-picker
|
<a-date-picker
|
||||||
v-model:value="editingData.strdt"
|
v-model:value="editingData.strdtStr"
|
||||||
show-time
|
show-time
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
@change="(val) => delWarning(val, 'strdt')"
|
@change="(val) => delWarning(val, 'strdtStr')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -251,7 +251,7 @@
|
|||||||
<div
|
<div
|
||||||
class="text"
|
class="text"
|
||||||
:class="{ text_warning: record.picpthsWarnings.includes(item.name) }"
|
:class="{ text_warning: record.picpthsWarnings.includes(item.name) }"
|
||||||
@click="emit('preview-click', record, 'image', index)"
|
@click="emit('preview-click', record, 'image', index, 'delete')"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
@ -263,7 +263,7 @@
|
|||||||
<div
|
<div
|
||||||
class="text"
|
class="text"
|
||||||
:class="{ text_warning: record.vdpthsWarnings.includes(item.name) }"
|
:class="{ text_warning: record.vdpthsWarnings.includes(item.name) }"
|
||||||
@click="emit('preview-click', record, 'video', index)"
|
@click="emit('preview-click', record, 'video', index, 'delete')"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
@ -307,7 +307,15 @@ const rowStates = reactive<Record<number, any>>({});
|
|||||||
const editingData = ref<any>(null);
|
const editingData = ref<any>(null);
|
||||||
|
|
||||||
const modalColumns = ref([
|
const modalColumns = ref([
|
||||||
{ dataIndex: "rowIndex", key: "rowIndex", title: "序号", width: 60, dataIndexKey: "rowIndex",align: "center",fixed: "left" },
|
{
|
||||||
|
dataIndex: "rowIndex",
|
||||||
|
key: "rowIndex",
|
||||||
|
title: "序号",
|
||||||
|
width: 60,
|
||||||
|
dataIndexKey: "rowIndex",
|
||||||
|
align: "center",
|
||||||
|
fixed: "left",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
dataIndex: "hbrvnm",
|
dataIndex: "hbrvnm",
|
||||||
key: "hbrvnm",
|
key: "hbrvnm",
|
||||||
@ -330,9 +338,9 @@ const modalColumns = ref([
|
|||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: "strdt",
|
dataIndex: "strdtStr",
|
||||||
key: "strdt",
|
key: "strdtStr",
|
||||||
dataIndexKey: "strdt",
|
dataIndexKey: "strdtStr",
|
||||||
title: "过鱼时间",
|
title: "过鱼时间",
|
||||||
width: 190,
|
width: 190,
|
||||||
},
|
},
|
||||||
@ -577,6 +585,10 @@ const startEdit = (index: number) => {
|
|||||||
editingData.value.stcd = null;
|
editingData.value.stcd = null;
|
||||||
delWarning(null, "stcd");
|
delWarning(null, "stcd");
|
||||||
}
|
}
|
||||||
|
if (editingData.value.warnings.includes("strdt")) {
|
||||||
|
editingData.value.strdt = null;
|
||||||
|
delWarning(null, "strdt");
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 预加载下拉选项 (基于 editingData 的值)
|
// 3. 预加载下拉选项 (基于 editingData 的值)
|
||||||
if (editingData.value.hbrvcd == "" || editingData.value.hbrvcd == undefined) {
|
if (editingData.value.hbrvcd == "" || editingData.value.hbrvcd == undefined) {
|
||||||
@ -652,6 +664,7 @@ const saveEdit = async (index: number) => {
|
|||||||
// 2. 创建新数组,替换对应索引的数据
|
// 2. 创建新数组,替换对应索引的数据
|
||||||
const newData = [...props.fileTableData];
|
const newData = [...props.fileTableData];
|
||||||
newData[index] = { ...editingData.value };
|
newData[index] = { ...editingData.value };
|
||||||
|
newData[index].strdt = newData[index].strdtStr;
|
||||||
emit("update:fileLoading", true);
|
emit("update:fileLoading", true);
|
||||||
try {
|
try {
|
||||||
const res: any = await revalidateAndUpdateRow({
|
const res: any = await revalidateAndUpdateRow({
|
||||||
@ -687,7 +700,7 @@ const handlePreviewDelete = async (index: number) => {
|
|||||||
});
|
});
|
||||||
if (res && res?.code == 0) {
|
if (res && res?.code == 0) {
|
||||||
message.success("删除成功");
|
message.success("删除成功");
|
||||||
|
|
||||||
props.getFileList();
|
props.getFileList();
|
||||||
editingRowIndex.value = null;
|
editingRowIndex.value = null;
|
||||||
editingData.value = null;
|
editingData.value = null;
|
||||||
|
|||||||
@ -185,142 +185,28 @@
|
|||||||
@ok="handleEditSubmit"
|
@ok="handleEditSubmit"
|
||||||
@preview-click="handlePreviewClick"
|
@preview-click="handlePreviewClick"
|
||||||
/>
|
/>
|
||||||
|
<!-- 预览媒体组件 -->
|
||||||
<!-- 媒体预览 Modal -->
|
<PreviewMedia
|
||||||
<a-modal
|
ref="previewMediaRef"
|
||||||
v-model:open="mediaPreviewVisible"
|
v-model:visible="mediaPreviewVisible"
|
||||||
:title="videoPreviewTitle"
|
:previewList="previewList"
|
||||||
:footer="null"
|
:previewListIndex="previewListIndex"
|
||||||
width="900px"
|
:videoPreviewTitle="videoPreviewTitle"
|
||||||
@cancel="closeMediaPreview"
|
:taskId="taskId"
|
||||||
:zIndex="2000"
|
:isDel="isPreviewMediaDelete"
|
||||||
>
|
@deleteMedia="handleDeleteMedia"
|
||||||
<div class="flex h-[60vh] gap-4">
|
/>
|
||||||
<!-- 左侧:混合列表 (图片+视频) -->
|
|
||||||
<div class="w-1/4 overflow-y-auto border-r pr-2 media-list-container">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in previewList"
|
|
||||||
:key="index"
|
|
||||||
class="mb-2 cursor-pointer list-item"
|
|
||||||
:class="{ select: index === currentMediaIndex }"
|
|
||||||
@click="currentMediaIndex = index"
|
|
||||||
>
|
|
||||||
<span class="file-name">{{ item.name }}</span>
|
|
||||||
<!-- 删除按钮 -->
|
|
||||||
<div
|
|
||||||
class="list-item-delete"
|
|
||||||
v-if="item.type != 'formVideo' && item.type != 'formImage'"
|
|
||||||
@click.stop="handleDeleteMedia(item, index)"
|
|
||||||
>
|
|
||||||
<CloseCircleOutlined />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧:动态预览区域 -->
|
|
||||||
<div
|
|
||||||
class="w-3/4 flex flex-col items-center justify-center bg-gray-100 relative p-4"
|
|
||||||
>
|
|
||||||
<a-spin v-if="imageLoading" tip="图片加载中..." size="large" />
|
|
||||||
<!-- 图片预览 -->
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url != '' &&
|
|
||||||
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
v-show="!imageLoading && !imageLoadError"
|
|
||||||
:src="currentMediaItem.url"
|
|
||||||
alt="preview"
|
|
||||||
class="max-w-full max-h-[50vh] object-contain"
|
|
||||||
@load="onImageLoad"
|
|
||||||
@error="onImageError"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 3. 加载失败提示 -->
|
|
||||||
<div
|
|
||||||
v-if="!imageLoading && imageLoadError"
|
|
||||||
class="text-gray-400 flex flex-col items-center"
|
|
||||||
>
|
|
||||||
<ExclamationCircleOutlined style="font-size: 24px; margin-bottom: 8px" />
|
|
||||||
<span>图片加载失败</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url == '' &&
|
|
||||||
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
|
||||||
"
|
|
||||||
class="text-gray-400"
|
|
||||||
>
|
|
||||||
暂无图片预览
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 视频预览 -->
|
|
||||||
<video
|
|
||||||
v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url != '' &&
|
|
||||||
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
|
||||||
"
|
|
||||||
:src="currentMediaItem.url"
|
|
||||||
controls
|
|
||||||
autoplay
|
|
||||||
class="max-w-full max-h-[50vh]"
|
|
||||||
>
|
|
||||||
您的浏览器不支持视频播放
|
|
||||||
</video>
|
|
||||||
<div
|
|
||||||
v-else-if="
|
|
||||||
currentMediaItem &&
|
|
||||||
currentMediaItem.url == '' &&
|
|
||||||
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
|
||||||
"
|
|
||||||
class="text-gray-400"
|
|
||||||
>
|
|
||||||
暂无视频预览
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 底部切换控制 -->
|
|
||||||
<div class="absolute bottom-4 flex gap-4 z-10">
|
|
||||||
<a-button
|
|
||||||
shape="circle"
|
|
||||||
:icon="h(LeftOutlined)"
|
|
||||||
@click="prevMedia"
|
|
||||||
:disabled="currentMediaIndex === 0"
|
|
||||||
/>
|
|
||||||
<span class="self-center text-gray-600 bg-white px-2 rounded shadow-sm">
|
|
||||||
{{ currentMediaIndex + 1 }} / {{ previewList.length }}
|
|
||||||
</span>
|
|
||||||
<a-button
|
|
||||||
shape="circle"
|
|
||||||
:icon="h(RightOutlined)"
|
|
||||||
@click="nextMedia"
|
|
||||||
:disabled="currentMediaIndex === previewList.length - 1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted, h, nextTick, watch } from "vue";
|
import { ref, computed, onMounted, h, nextTick, watch } from "vue";
|
||||||
import { message, Modal } from "ant-design-vue"; // 假设使用 ant-design-vue
|
import { message, Modal } from "ant-design-vue"; // 假设使用 ant-design-vue
|
||||||
import {
|
|
||||||
LeftOutlined,
|
|
||||||
RightOutlined,
|
|
||||||
CloseCircleOutlined,
|
|
||||||
ExclamationCircleOutlined,
|
|
||||||
} from "@ant-design/icons-vue"; // 引入图标组件
|
|
||||||
import BasicTable from "@/components/BasicTable/index.vue";
|
import BasicTable from "@/components/BasicTable/index.vue";
|
||||||
import GuoYuSheShiShuJuTianBaoSearch from "./guoYuSheShiShuJuTianBaoSearch.vue";
|
import GuoYuSheShiShuJuTianBaoSearch from "./guoYuSheShiShuJuTianBaoSearch.vue";
|
||||||
import GuoYuSheShiShuJuTianBaoTable from "./guoYuSheShiShuJuTianBaoTable.vue";
|
import GuoYuSheShiShuJuTianBaoTable from "./guoYuSheShiShuJuTianBaoTable.vue";
|
||||||
import EditModal from "./guoYuSheShiShuJuTianBaoForm.vue";
|
import EditModal from "./guoYuSheShiShuJuTianBaoForm.vue";
|
||||||
|
import PreviewMedia from "@/components/previewMedia/index.vue";
|
||||||
import { checkPerm } from "@/directive/permission";
|
import { checkPerm } from "@/directive/permission";
|
||||||
import {
|
import {
|
||||||
getFishDraftPage,
|
getFishDraftPage,
|
||||||
@ -335,11 +221,11 @@ import {
|
|||||||
checkImportStatus,
|
checkImportStatus,
|
||||||
batchSaveDraft,
|
batchSaveDraft,
|
||||||
getLastImportResult,
|
getLastImportResult,
|
||||||
deleteFile,
|
|
||||||
batchApproveAll,
|
batchApproveAll,
|
||||||
} from "@/api/guoYuSheShiShuJuTianBao";
|
} from "@/api/guoYuSheShiShuJuTianBao";
|
||||||
import { Tag } from "ant-design-vue"; // 确保导入 Tag
|
import { Tag } from "ant-design-vue"; // 确保导入 Tag
|
||||||
import { getDictItemsByCode } from "@/api/dict";
|
import { getDictItemsByCode } from "@/api/dict";
|
||||||
|
import { fr } from "element-plus/es/locale/index.mjs";
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||||
const baseUrlApi = import.meta.env.VITE_APP_BASE_API_URL;
|
const baseUrlApi = import.meta.env.VITE_APP_BASE_API_URL;
|
||||||
@ -358,9 +244,6 @@ interface ColumnConfig {
|
|||||||
}
|
}
|
||||||
const fileInputRef = ref<any>(null);
|
const fileInputRef = ref<any>(null);
|
||||||
const tableRef = ref<any>(null);
|
const tableRef = ref<any>(null);
|
||||||
// 图片加载状态
|
|
||||||
const imageLoading = ref(false);
|
|
||||||
const imageLoadError = ref(false);
|
|
||||||
// 字典项
|
// 字典项
|
||||||
const direction = ref<any>([]);
|
const direction = ref<any>([]);
|
||||||
const guoyuStatus = ref<any>([]);
|
const guoyuStatus = ref<any>([]);
|
||||||
@ -435,20 +318,18 @@ const isView = ref(false);
|
|||||||
const currentRecord = ref<FormData | null>(null);
|
const currentRecord = ref<FormData | null>(null);
|
||||||
|
|
||||||
const mediaPreviewVisible = ref(false);
|
const mediaPreviewVisible = ref(false);
|
||||||
|
const isPreviewMediaDelete = ref(false);
|
||||||
const videoPreviewTitle = ref("视频预览");
|
const videoPreviewTitle = ref("视频预览");
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
id: string;
|
id: string;
|
||||||
type: "image" | "video" | "formVideo" | "formImage";
|
type: "image" | "video";
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
const previewList = ref<MediaItem[]>([]);
|
const previewList = ref<MediaItem[]>([]);
|
||||||
const currentMediaIndex = ref(0);
|
const previewListIndex = ref(0);
|
||||||
const tablePreviewRecord = ref<any>({});
|
const tablePreviewRecord = ref<any>({});
|
||||||
|
|
||||||
// 计算当前选中的项
|
|
||||||
const currentMediaItem = computed(() => previewList.value[currentMediaIndex.value]);
|
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const fileTableData = ref<any[]>([]);
|
const fileTableData = ref<any[]>([]);
|
||||||
const batchData = ref<any[]>([]);
|
const batchData = ref<any[]>([]);
|
||||||
@ -810,6 +691,9 @@ const importBtn = async () => {
|
|||||||
if (visible.value) importBtn();
|
if (visible.value) importBtn();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
} else if (currentTask.status == "FAILED") {
|
||||||
|
message.error(currentTask.statusText);
|
||||||
|
fileLoading.value = false;
|
||||||
} else if (currentTask.status == "VALIDATED") {
|
} else if (currentTask.status == "VALIDATED") {
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
modalTableRef.value.editingRowIndex = null;
|
modalTableRef.value.editingRowIndex = null;
|
||||||
@ -839,13 +723,6 @@ const fileChange = (file: File) => {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
await importFishZip(formData);
|
await importFishZip(formData);
|
||||||
try {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (visible.value) importBtn();
|
|
||||||
}, 5000);
|
|
||||||
} catch (error) {
|
|
||||||
message.error("导入失败");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 获取文件列表
|
// 获取文件列表
|
||||||
@ -994,167 +871,95 @@ const handleSearchFinish = (values: any) => {
|
|||||||
tableRef.value?.getList(filter);
|
tableRef.value?.getList(filter);
|
||||||
};
|
};
|
||||||
// 处理预览点击 (由子组件触发)
|
// 处理预览点击 (由子组件触发)
|
||||||
const handlePreviewClick = (record: any, type: string, index: number) => {
|
const handlePreviewClick = (record: any, type: string, index: number, action: string) => {
|
||||||
const mixedList: MediaItem[] = [];
|
const mixedList: MediaItem[] = [];
|
||||||
if (type === "image") {
|
if (action === "delete") {
|
||||||
imageLoading.value = true;
|
isPreviewMediaDelete.value = true;
|
||||||
imageLoadError.value = false;
|
|
||||||
tablePreviewRecord.value = record;
|
tablePreviewRecord.value = record;
|
||||||
|
} else if (action === "preview") {
|
||||||
|
isPreviewMediaDelete.value = false;
|
||||||
|
}
|
||||||
|
if (type === "image") {
|
||||||
videoPreviewTitle.value = "图片预览";
|
videoPreviewTitle.value = "图片预览";
|
||||||
const nameList = record.picpthList;
|
const nameList = record.picpthList;
|
||||||
|
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
|
let url = "";
|
||||||
|
if (action === "preview") {
|
||||||
|
url = item.url;
|
||||||
|
} else if (action === "delete") {
|
||||||
|
url =
|
||||||
|
baseUrlApi +
|
||||||
|
"/data/fishDraft/previewFile?filename=" +
|
||||||
|
item.name +
|
||||||
|
"&taskId=" +
|
||||||
|
taskId.value +
|
||||||
|
"&type=1";
|
||||||
|
}
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
id: record.id,
|
id: record.id,
|
||||||
type: "image",
|
type: "image",
|
||||||
name: item.name,
|
name: item.name,
|
||||||
url:
|
url: url,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (type === "video") {
|
||||||
|
videoPreviewTitle.value = "视频预览";
|
||||||
|
const nameList = record.vdpthList;
|
||||||
|
nameList.forEach((item: any) => {
|
||||||
|
let url = "";
|
||||||
|
if (action === "preview") {
|
||||||
|
url = item.url;
|
||||||
|
} else if (action === "delete") {
|
||||||
|
url =
|
||||||
baseUrlApi +
|
baseUrlApi +
|
||||||
"/data/fishDraft/previewFile?filename=" +
|
"/data/fishDraft/previewFile?filename=" +
|
||||||
item.name +
|
item.name +
|
||||||
"&taskId=" +
|
"&taskId=" +
|
||||||
taskId.value +
|
taskId.value +
|
||||||
"&type=1",
|
"&type=2";
|
||||||
});
|
}
|
||||||
});
|
|
||||||
} else if (type === "video") {
|
|
||||||
tablePreviewRecord.value = record;
|
|
||||||
videoPreviewTitle.value = "视频预览";
|
|
||||||
const nameList = record.vdpthList;
|
|
||||||
nameList.forEach((item: any) => {
|
|
||||||
mixedList.push({
|
mixedList.push({
|
||||||
id: record.id,
|
id: record.id,
|
||||||
type: "video",
|
type: "video",
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
||||||
url:
|
url: url,
|
||||||
baseUrlApi +
|
|
||||||
"/data/fishDraft/previewFile?filename=" +
|
|
||||||
item.name +
|
|
||||||
"&taskId=" +
|
|
||||||
taskId.value +
|
|
||||||
"&type=2",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else if (type === "formImage") {
|
|
||||||
imageLoading.value = true;
|
|
||||||
imageLoadError.value = false;
|
|
||||||
videoPreviewTitle.value = "图片预览";
|
|
||||||
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
|
||||||
nameList.forEach((item: any) => {
|
|
||||||
mixedList.push({
|
|
||||||
id: record.id,
|
|
||||||
type: "formImage",
|
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
|
||||||
url: item.url,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else if (type === "formVideo") {
|
|
||||||
videoPreviewTitle.value = "视频预览";
|
|
||||||
const nameList = JSON.parse(JSON.stringify(record)).vdpthList;
|
|
||||||
nameList.forEach((item: any) => {
|
|
||||||
mixedList.push({
|
|
||||||
id: record.id,
|
|
||||||
type: "formVideo",
|
|
||||||
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
|
||||||
url: item.url,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaPreviewVisible.value = true;
|
mediaPreviewVisible.value = true;
|
||||||
currentMediaIndex.value = index;
|
previewListIndex.value = index;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
console.log(mixedList);
|
||||||
previewList.value = mixedList;
|
previewList.value = mixedList;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 【新增】统一切换逻辑
|
const handleDeleteMedia = (item: any, type: string, index: number) => {
|
||||||
const prevMedia = () => {
|
previewList.value.splice(index, 1);
|
||||||
if (currentMediaIndex.value > 0) {
|
if (type == "图片预览") {
|
||||||
currentMediaIndex.value--;
|
if (previewList.value.length == 0) {
|
||||||
|
tablePreviewRecord.value.picpthList = [];
|
||||||
|
tablePreviewRecord.value.picpthsWarnings = [];
|
||||||
|
} else {
|
||||||
|
tablePreviewRecord.value.picpthList.splice(index, 1);
|
||||||
|
tablePreviewRecord.value.picpthsWarnings = tablePreviewRecord.value.picpthsWarnings.filter(
|
||||||
|
(warningName: any) => warningName !== item.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (previewList.value.length == 0) {
|
||||||
|
tablePreviewRecord.value.vdpthList = [];
|
||||||
|
tablePreviewRecord.value.vdpthsWarnings = [];
|
||||||
|
} else {
|
||||||
|
tablePreviewRecord.value.vdpthList.splice(index, 1);
|
||||||
|
tablePreviewRecord.value.vdpthsWarnings = tablePreviewRecord.value.vdpthsWarnings.filter(
|
||||||
|
(warningName: any) => warningName !== item.name
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 【新增】统一下一逻辑
|
|
||||||
const nextMedia = () => {
|
|
||||||
if (currentMediaIndex.value < previewList.value.length - 1) {
|
|
||||||
currentMediaIndex.value++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 【新增】统一删除逻辑
|
|
||||||
const handleDeleteMedia = (item: any, index: number) => {
|
|
||||||
Modal.confirm({
|
|
||||||
title: "确认删除",
|
|
||||||
content: "确定要从预览列表中移除该项吗?",
|
|
||||||
zIndex: 2002,
|
|
||||||
onOk: async () => {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const params = {
|
|
||||||
id: item.id,
|
|
||||||
taskId: taskId.value,
|
|
||||||
type:
|
|
||||||
videoPreviewTitle.value == "图片预览"
|
|
||||||
? 1
|
|
||||||
: videoPreviewTitle.value == "视频预览"
|
|
||||||
? 2
|
|
||||||
: 0,
|
|
||||||
filename: item.name,
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
let res: any = await deleteFile(params);
|
|
||||||
if (res && res?.code == 0) {
|
|
||||||
message.success("删除成功");
|
|
||||||
previewList.value.splice(index, 1);
|
|
||||||
if (videoPreviewTitle.value == "图片预览") {
|
|
||||||
if (previewList.value.length == 0) {
|
|
||||||
tablePreviewRecord.value.picpthList = [];
|
|
||||||
tablePreviewRecord.value.picpthsWarnings = [];
|
|
||||||
} else {
|
|
||||||
tablePreviewRecord.value.picpthList.splice(index, 1);
|
|
||||||
tablePreviewRecord.value.picpthsWarnings = tablePreviewRecord.value.picpthsWarnings.filter(
|
|
||||||
(warningName: any) => warningName !== item.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (previewList.value.length == 0) {
|
|
||||||
tablePreviewRecord.value.vdpthList = [];
|
|
||||||
tablePreviewRecord.value.vdpthsWarnings = [];
|
|
||||||
} else {
|
|
||||||
tablePreviewRecord.value.vdpthList.splice(index, 1);
|
|
||||||
tablePreviewRecord.value.vdpthsWarnings = tablePreviewRecord.value.vdpthsWarnings.filter(
|
|
||||||
(warningName: any) => warningName !== item.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previewList.value.length === 0) {
|
|
||||||
mediaPreviewVisible.value = false;
|
|
||||||
} else {
|
|
||||||
// 调整索引
|
|
||||||
if (index <= currentMediaIndex.value) {
|
|
||||||
currentMediaIndex.value = Math.max(0, currentMediaIndex.value - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve(true);
|
|
||||||
} else {
|
|
||||||
message.error("删除失败");
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
message.error("删除失败");
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
}).catch(() => console.log("Oops errors!"));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeMediaPreview = () => {
|
|
||||||
mediaPreviewVisible.value = false;
|
|
||||||
nextTick(() => {
|
|
||||||
previewList.value = [];
|
|
||||||
currentMediaIndex.value = 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const tableContainerRef = ref<HTMLElement | null>(null);
|
const tableContainerRef = ref<HTMLElement | null>(null);
|
||||||
const tableScrollY = ref<number | undefined>(undefined);
|
const tableScrollY = ref<number | undefined>(undefined);
|
||||||
// 计算表格主体高度(减去表头、分页器、内边距等)
|
// 计算表格主体高度(减去表头、分页器、内边距等)
|
||||||
@ -1174,28 +979,6 @@ const observer = new ResizeObserver(() => {
|
|||||||
calcTableScrollY();
|
calcTableScrollY();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 【新增】图片加载完成回调
|
|
||||||
const onImageLoad = () => {
|
|
||||||
imageLoading.value = false;
|
|
||||||
imageLoadError.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 【新增】图片加载失败回调
|
|
||||||
const onImageError = () => {
|
|
||||||
imageLoading.value = false;
|
|
||||||
imageLoadError.value = true;
|
|
||||||
};
|
|
||||||
watch(currentMediaIndex, (newIndex) => {
|
|
||||||
const item = previewList.value[newIndex];
|
|
||||||
if (item && (item.type === "image" || item.type === "formImage")) {
|
|
||||||
imageLoading.value = true;
|
|
||||||
imageLoadError.value = false;
|
|
||||||
} else {
|
|
||||||
imageLoading.value = false;
|
|
||||||
imageLoadError.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- 生命周期 ---
|
// --- 生命周期 ---
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@ -1248,57 +1031,6 @@ onMounted(() => {
|
|||||||
/* 为绝对定位元素提供参考(如果需要) */
|
/* 为绝对定位元素提供参考(如果需要) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-list-container {
|
|
||||||
background-color: rgb(234, 241, 251);
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 36px;
|
|
||||||
line-height: 36px;
|
|
||||||
padding: 0 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-name {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.select {
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: rgb(37, 93, 138);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item-delete {
|
|
||||||
color: red;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
margin-left: 8px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover .list-item-delete {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttonStyle {
|
.buttonStyle {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="approval-detail-search">
|
<div class="approval-detail-search">
|
||||||
<BasicSearch ref="basicSearchRef" :searchList="searchList" :initial-values="initSearchData" :zhujianfujian="'fu'" @reset="handleReset"
|
<BasicSearch
|
||||||
@finish="onSearchFinish" @values-change="onValuesChange">
|
ref="basicSearchRef"
|
||||||
|
:searchList="searchList"
|
||||||
|
:initial-values="initSearchData"
|
||||||
|
:zhujianfujian="'fu'"
|
||||||
|
@reset="handleReset"
|
||||||
|
@finish="onSearchFinish"
|
||||||
|
@values-change="onValuesChange"
|
||||||
|
>
|
||||||
<template #ftp="{ onChange }">
|
<template #ftp="{ onChange }">
|
||||||
<fishSearch v-model="localTypeDate" width="200px" @update:modelValue="onChange" />
|
<fishSearch v-model="localTypeDate" width="200px" @update:modelValue="onChange" />
|
||||||
</template>
|
</template>
|
||||||
@ -62,10 +69,10 @@ const searchList: any = computed(() => [
|
|||||||
type: "RangePicker",
|
type: "RangePicker",
|
||||||
name: "strdt",
|
name: "strdt",
|
||||||
label: "过鱼时间",
|
label: "过鱼时间",
|
||||||
picker: "month",
|
picker: "date",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
format: "YYYY-MM",
|
format: "YYYY-MM-DD",
|
||||||
valueFormat: "YYYY-MM",
|
valueFormat: "YYYY-MM-DD",
|
||||||
allowClear: false,
|
allowClear: false,
|
||||||
},
|
},
|
||||||
presets: DateSetting.RangeButton.month,
|
presets: DateSetting.RangeButton.month,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,116 +1,121 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="guoYuSheShiShuJuTianBao-search">
|
<div class="guoYuSheShiShuJuTianBao-search">
|
||||||
<BasicSearch ref="basicSearchRef" :searchList="searchList" :initial-values="initSearchData" :zhujianfujian="'zhu'"
|
<BasicSearch
|
||||||
@finish="onSearchFinish" @values-change="onValuesChange" @reset="handleReset">
|
ref="basicSearchRef"
|
||||||
<template #actions>
|
:searchList="searchList"
|
||||||
<a-tooltip title="批量审批">
|
:initial-values="initSearchData"
|
||||||
<a-button :disabled="selectedCount === 0" @click="$emit('batch-approve')">
|
:zhujianfujian="'zhu'"
|
||||||
<template #icon>
|
@finish="onSearchFinish"
|
||||||
<CheckSquareOutlined />
|
@values-change="onValuesChange"
|
||||||
</template>
|
@reset="handleReset"
|
||||||
批量审批
|
>
|
||||||
</a-button>
|
<template #actions>
|
||||||
</a-tooltip>
|
<a-tooltip title="批量审批">
|
||||||
|
<a-button :disabled="selectedCount === 0" @click="$emit('batch-approve')">
|
||||||
<a-tooltip title="批量驳回">
|
<template #icon>
|
||||||
<a-button :disabled="selectedCount === 0" @click="$emit('batch-reject')">
|
<CheckSquareOutlined />
|
||||||
<template #icon>
|
|
||||||
<CloseCircleOutlined />
|
|
||||||
</template>
|
|
||||||
批量驳回
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</BasicSearch>
|
批量审批
|
||||||
</div>
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-tooltip title="批量驳回">
|
||||||
|
<a-button :disabled="selectedCount === 0" @click="$emit('batch-reject')">
|
||||||
|
<template #icon>
|
||||||
|
<CloseCircleOutlined />
|
||||||
|
</template>
|
||||||
|
批量驳回
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip title="批量删除">
|
||||||
|
<a-button :disabled="selectedCount === 0" @click="$emit('batch-delete')">
|
||||||
|
批量删除
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</BasicSearch>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, onMounted } from "vue";
|
import { ref, computed, onMounted } from "vue";
|
||||||
import BasicSearch from "@/components/BasicSearch/index.vue"; // 确保路径正确
|
import BasicSearch from "@/components/BasicSearch/index.vue"; // 确保路径正确
|
||||||
import { getDictItemsByCode } from '@/api/dict';
|
import { getDictItemsByCode } from "@/api/dict";
|
||||||
import {
|
import { CheckSquareOutlined, CloseCircleOutlined } from "@ant-design/icons-vue";
|
||||||
CheckSquareOutlined,
|
|
||||||
CloseCircleOutlined,
|
|
||||||
} from "@ant-design/icons-vue";
|
|
||||||
// --- Props & Emits ---
|
// --- Props & Emits ---
|
||||||
interface Props {
|
interface Props {
|
||||||
selectedCount?: number;
|
selectedCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
selectedCount: 0
|
selectedCount: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "reset", values: any): void;
|
(e: "reset", values: any): void;
|
||||||
(e: "searchFinish", values: any): void;
|
(e: "searchFinish", values: any): void;
|
||||||
(e: "batch-approve"): void;
|
(e: "batch-approve"): void;
|
||||||
(e: "batch-reject"): void;
|
(e: "batch-reject"): void;
|
||||||
|
(e: "batch-delete"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|
||||||
// 模拟 initSearchData
|
// 模拟 initSearchData
|
||||||
const initSearchData = {
|
const initSearchData = {
|
||||||
hbrvcd:'all',
|
hbrvcd: "all",
|
||||||
stcd:'',
|
stcd: "",
|
||||||
status: '',
|
status: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchData = ref<any>({ ...initSearchData });
|
const searchData = ref<any>({ ...initSearchData });
|
||||||
|
|
||||||
const searchList: any = computed(() => [
|
const searchList: any = computed(() => [
|
||||||
{
|
{
|
||||||
type: "waterStation",
|
type: "waterStation",
|
||||||
name: "hbrvcd",
|
name: "hbrvcd",
|
||||||
label: "流域",
|
label: "流域",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
|
||||||
options: [],
|
|
||||||
},
|
},
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: "Select",
|
type: "Select",
|
||||||
name: "status",
|
name: "status",
|
||||||
label: "审批状态",
|
label: "审批状态",
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
},
|
|
||||||
options: statusData.value,
|
|
||||||
},
|
},
|
||||||
|
options: statusData.value,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
// --- Methods ---
|
// --- Methods ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 2. 搜索表单逻辑
|
// 2. 搜索表单逻辑
|
||||||
const onSearchFinish = (values: any) => {
|
const onSearchFinish = (values: any) => {
|
||||||
console.log(values);
|
console.log(values);
|
||||||
|
|
||||||
emit("searchFinish", values);
|
emit("searchFinish", values);
|
||||||
};
|
};
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
emit("reset", initSearchData);
|
emit("reset", initSearchData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onValuesChange = (changedValues: any, allValues: any) => {
|
const onValuesChange = (changedValues: any, allValues: any) => {
|
||||||
// 同步更新本地 searchData,以便其他逻辑使用
|
// 同步更新本地 searchData,以便其他逻辑使用
|
||||||
searchData.value = { ...searchData.value, ...allValues };
|
searchData.value = { ...searchData.value, ...allValues };
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Lifecycle ---
|
// --- Lifecycle ---
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
emit("searchFinish", initSearchData);
|
emit("searchFinish", initSearchData);
|
||||||
getstatusData()
|
getstatusData();
|
||||||
});
|
});
|
||||||
const statusData = ref(false)
|
const statusData = ref(false);
|
||||||
const getstatusData = () => {
|
const getstatusData = () => {
|
||||||
getDictItemsByCode({ dictCode: "approvalStatus" }).then((res) => {
|
getDictItemsByCode({ dictCode: "approvalStatus" }).then((res) => {
|
||||||
statusData.value = res.data;
|
statusData.value = res.data;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user