鱼种类修改,导入修改,新增修改
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
10c3c33ad0
commit
7e383e35fe
@ -6,4 +6,7 @@ NODE_ENV='development'
|
|||||||
VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台'
|
VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台'
|
||||||
VITE_APP_PORT = 3000
|
VITE_APP_PORT = 3000
|
||||||
VITE_APP_BASE_API = '/dev-api'
|
VITE_APP_BASE_API = '/dev-api'
|
||||||
|
## 开发环境API地址
|
||||||
|
VITE_APP_BASE_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'
|
||||||
|
|||||||
@ -4,4 +4,7 @@ NODE_ENV='production'
|
|||||||
VITE_APP_TITLE = 'qgc-buji-web'
|
VITE_APP_TITLE = 'qgc-buji-web'
|
||||||
VITE_APP_PORT = 3000
|
VITE_APP_PORT = 3000
|
||||||
VITE_APP_BASE_API = '/prod-api'
|
VITE_APP_BASE_API = '/prod-api'
|
||||||
|
## 生产环境API地址
|
||||||
|
VITE_APP_BASE_URL = 'http://localhost:8093'
|
||||||
|
## 生产环境预览 图片视频地址
|
||||||
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
|
VITE_APP_PREVIEW_URL = 'https://211.99.26.225:12125'
|
||||||
|
|||||||
BIN
frontend/dist.rar
Normal file
BIN
frontend/dist.rar
Normal file
Binary file not shown.
@ -81,7 +81,7 @@ export function checkImportStatus() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询用户导入导入结果
|
// 查询用户导入结果
|
||||||
export function getLastImportResult() {
|
export function getLastImportResult() {
|
||||||
return request({
|
return request({
|
||||||
url: '/data/fishDraft/getLastImportResult',
|
url: '/data/fishDraft/getLastImportResult',
|
||||||
|
|||||||
@ -9,11 +9,11 @@ export function getBaseDropdown(data:any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//电站下拉列表
|
//电站下拉列表
|
||||||
export function getEngInfoDropdown(params:any) {
|
export function getEngInfoDropdown(data:any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/env/engInfo/dropdown',
|
url: '/env/engInfo/dropdown',
|
||||||
method: 'get',
|
method: 'post',
|
||||||
params
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//过鱼设施下拉列表
|
//过鱼设施下拉列表
|
||||||
@ -31,3 +31,12 @@ export function getFishDictoryDropdown() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 上传文件
|
||||||
|
export function uploadFile(data:any) {
|
||||||
|
return request({
|
||||||
|
url: import.meta.env.VITE_APP_PREVIEW_URL + '/upload',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -7,13 +7,12 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
placeholder="请选择鱼种类"
|
placeholder="鱼种类支持俗名查询"
|
||||||
:mode="multiple ? 'multiple' : undefined"
|
:mode="multiple ? 'multiple' : undefined"
|
||||||
show-search
|
show-search
|
||||||
:filter-option="false"
|
:filter-option="false"
|
||||||
class="custom-fish-select"
|
class="custom-fish-select"
|
||||||
:dropdownMatchSelectWidth="false"
|
:dropdownMatchSelectWidth="false"
|
||||||
:getPopupContainer="(triggerNode: HTMLElement) => triggerNode.parentNode"
|
|
||||||
@dropdownVisibleChange="handleDropdownVisibleChange"
|
@dropdownVisibleChange="handleDropdownVisibleChange"
|
||||||
:max-tag-count="multiple ? 1 : undefined"
|
:max-tag-count="multiple ? 1 : undefined"
|
||||||
:open="open"
|
:open="open"
|
||||||
@ -29,6 +28,23 @@
|
|||||||
|
|
||||||
<template #dropdownRender>
|
<template #dropdownRender>
|
||||||
<div class="custom-dropdown-container">
|
<div class="custom-dropdown-container">
|
||||||
|
<div class="w-[340px] h-[30px] flex items-center pl-[10px]" @click.stop @mousedown.prevent>
|
||||||
|
<div>查询方式:</div>
|
||||||
|
<div
|
||||||
|
class="text-[12px] font-bold mr-2 cursor-pointer"
|
||||||
|
:class="{ 'text-[#005293]': !isIntelligentQuery }"
|
||||||
|
@click="IntelligentQueryCLick(false)"
|
||||||
|
>
|
||||||
|
相似度
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-[12px] font-bold cursor-pointer"
|
||||||
|
:class="{ 'text-[#005293]': isIntelligentQuery }"
|
||||||
|
@click="IntelligentQueryCLick(true)"
|
||||||
|
>
|
||||||
|
智能查询
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 左侧:可滚动的选项列表 -->
|
<!-- 左侧:可滚动的选项列表 -->
|
||||||
<div class="dropdown-left-list">
|
<div class="dropdown-left-list">
|
||||||
<div
|
<div
|
||||||
@ -42,7 +58,7 @@
|
|||||||
@click.stop="handleSelectOption(opt)"
|
@click.stop="handleSelectOption(opt)"
|
||||||
@mouseenter="hoveredId = opt.id"
|
@mouseenter="hoveredId = opt.id"
|
||||||
>
|
>
|
||||||
<span class="item-name">{{ opt.name }}</span>
|
<span class="item-name" v-html="highlightText(opt.name)"></span>
|
||||||
<!-- 选中对勾 -->
|
<!-- 选中对勾 -->
|
||||||
<span v-if="isSelected(opt.id)" class="check-icon">✓</span>
|
<span v-if="isSelected(opt.id)" class="check-icon">✓</span>
|
||||||
</div>
|
</div>
|
||||||
@ -53,11 +69,14 @@
|
|||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<!-- 右侧:固定显示的别名/详情 -->
|
<!-- 右侧:固定显示的别名/详情 -->
|
||||||
<div class="dropdown-right-detail">
|
<div class="dropdown-right-detail" @click.stop @mousedown.prevent>
|
||||||
<div v-if="currentDetailData" class="detail-content">
|
<div v-if="currentDetailData" class="detail-content">
|
||||||
<div class="detail-title">{{ currentDetailData.name }}</div>
|
<div
|
||||||
|
class="detail-title"
|
||||||
|
v-html="highlightText(currentDetailData.name)"
|
||||||
|
></div>
|
||||||
<div class="detail-alias" :title="currentDetailData.alias">
|
<div class="detail-alias" :title="currentDetailData.alias">
|
||||||
{{ currentDetailData.alias || "暂无别名" }}
|
<div v-html="highlightText(currentDetailData.alias)"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="detail-placeholder">请选择或悬停查看</div>
|
<div v-else class="detail-placeholder">请选择或悬停查看</div>
|
||||||
@ -71,6 +90,7 @@
|
|||||||
import { ref, onMounted, computed, watch } from "vue";
|
import { ref, onMounted, computed, watch } from "vue";
|
||||||
import { getFishDictoryDropdown } from "@/api/select";
|
import { getFishDictoryDropdown } from "@/api/select";
|
||||||
import { useShuJuTianBaoStore } from "@/store/modules/shuJuTianBao";
|
import { useShuJuTianBaoStore } from "@/store/modules/shuJuTianBao";
|
||||||
|
import { message } from "ant-design-vue";
|
||||||
const shuJuTianBaoStore = useShuJuTianBaoStore();
|
const shuJuTianBaoStore = useShuJuTianBaoStore();
|
||||||
|
|
||||||
// --- Props & Emits ---
|
// --- Props & Emits ---
|
||||||
@ -94,6 +114,7 @@ const options = ref<any[]>([]);
|
|||||||
const searchKeyword = ref<string>("");
|
const searchKeyword = ref<string>("");
|
||||||
const hoveredId = ref<string | null>(null);
|
const hoveredId = ref<string | null>(null);
|
||||||
const open = ref(false); // 控制下拉框显隐
|
const open = ref(false); // 控制下拉框显隐
|
||||||
|
const isIntelligentQuery = ref(true); // 控制是否为智能查询
|
||||||
|
|
||||||
// --- Computed ---
|
// --- Computed ---
|
||||||
const filteredOptions = computed(() => {
|
const filteredOptions = computed(() => {
|
||||||
@ -128,6 +149,7 @@ const isSelected = (id: string) => {
|
|||||||
|
|
||||||
const handleSearch = (value: string) => {
|
const handleSearch = (value: string) => {
|
||||||
searchKeyword.value = value;
|
searchKeyword.value = value;
|
||||||
|
hoveredId.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDropdownVisibleChange = (val: boolean) => {
|
const handleDropdownVisibleChange = (val: boolean) => {
|
||||||
@ -139,6 +161,8 @@ const handleDropdownVisibleChange = (val: boolean) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectOption = (opt: any) => {
|
const handleSelectOption = (opt: any) => {
|
||||||
|
console.log(props.modelValue)
|
||||||
|
console.log(props.modelValue)
|
||||||
if (props.multiple) {
|
if (props.multiple) {
|
||||||
// --- 多选逻辑 ---
|
// --- 多选逻辑 ---
|
||||||
let newValues: string[] = Array.isArray(props.modelValue)
|
let newValues: string[] = Array.isArray(props.modelValue)
|
||||||
@ -165,11 +189,19 @@ const handleSelectOption = (opt: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const IntelligentQueryCLick = (val: boolean) => {
|
||||||
|
isIntelligentQuery.value = val;
|
||||||
|
if (val) {
|
||||||
|
message.success("智能查询已开启");
|
||||||
|
} else {
|
||||||
|
message.success("智能查询已关闭");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleChange = (val: any) => {
|
const handleChange = (val: any) => {
|
||||||
// 当 a-select 内部触发 change 时(例如删除 Tag)
|
// 当 a-select 内部触发 change 时(例如删除 Tag)
|
||||||
// 在单选模式下,如果用户通过键盘或删除操作改变了值,这里也会捕获
|
// 在单选模式下,如果用户通过键盘或删除操作改变了值,这里也会捕获
|
||||||
emit("update:modelValue", val, '');
|
emit("update:modelValue", val, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFishNameById = (id: string) => {
|
const getFishNameById = (id: string) => {
|
||||||
@ -210,6 +242,14 @@ const init = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 根据名字高亮显示匹配项
|
||||||
|
const highlightText = (text) => {
|
||||||
|
if (text == null) {
|
||||||
|
return "暂无别名";
|
||||||
|
}
|
||||||
|
const reg = new RegExp(searchKeyword.value, "g");
|
||||||
|
return text.replace(reg, `<span style="color: red;">${searchKeyword.value}</span>`);
|
||||||
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
init();
|
||||||
});
|
});
|
||||||
@ -226,7 +266,9 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.custom-dropdown-container {
|
.custom-dropdown-container {
|
||||||
|
width: 401px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -323,6 +365,9 @@ onMounted(() => {
|
|||||||
color: #666;
|
color: #666;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-placeholder {
|
.detail-placeholder {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
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 GisView from "@/components/gis/GisView.vue";
|
// import GisView from "@/components/gis/GisView.vue";
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ const routeKey = computed(() => router.path + Math.random());
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="app-main">
|
<section class="app-main">
|
||||||
<GisView />
|
<!-- <GisView /> -->
|
||||||
<div class="gi-panels">
|
<div class="gi-panels">
|
||||||
<router-view v-slot="{ Component, route }" :key="routeKey">
|
<router-view v-slot="{ Component, route }" :key="routeKey">
|
||||||
<transition name="router-fade" mode="out-in">
|
<transition name="router-fade" mode="out-in">
|
||||||
|
|||||||
@ -11,11 +11,9 @@ import Sidebar from "./Sidebar/index.vue";
|
|||||||
|
|
||||||
import { useTagsViewStore } from "@/store/modules/tagsView";
|
import { useTagsViewStore } from "@/store/modules/tagsView";
|
||||||
import { useUserStore } from "@/store/modules/user";
|
import { useUserStore } from "@/store/modules/user";
|
||||||
import Cookies from "js-cookie";
|
|
||||||
import {getPath,removePath } from '@/utils/auth';
|
import {getPath,removePath } from '@/utils/auth';
|
||||||
|
|
||||||
// const url = import.meta.env.VITE_APP_BASE_API;
|
// const url = import.meta.env.VITE_APP_BASE_API;
|
||||||
const username = Cookies.get("username");
|
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@ -67,7 +65,7 @@ onBeforeUnmount(() => {
|
|||||||
<span class="icon">
|
<span class="icon">
|
||||||
<UserOutlined />
|
<UserOutlined />
|
||||||
</span>
|
</span>
|
||||||
<span class="text">{{ username }}</span>
|
<span class="text">{{ userStore.username }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-space>
|
</a-space>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { UserInfo } from '@/api/user/types';
|
|||||||
export const useUserStore = defineStore('user', () => {
|
export const useUserStore = defineStore('user', () => {
|
||||||
// state
|
// state
|
||||||
const Token = ref<string>(getToken() || '');
|
const Token = ref<string>(getToken() || '');
|
||||||
|
const username = ref<string>('');
|
||||||
const nickname = ref<string>('');
|
const nickname = ref<string>('');
|
||||||
const avatar = ref<string>('');
|
const avatar = ref<string>('');
|
||||||
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
|
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
|
||||||
@ -47,6 +48,7 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
if (!data.roles || data.roles.length <= 0) {
|
if (!data.roles || data.roles.length <= 0) {
|
||||||
reject('getUserInfo: roles must be a non-null array!');
|
reject('getUserInfo: roles must be a non-null array!');
|
||||||
}
|
}
|
||||||
|
username.value = data.userInfo.username;
|
||||||
nickname.value = data.userInfo.nickname;
|
nickname.value = data.userInfo.nickname;
|
||||||
avatar.value = data.userInfo.avatar;
|
avatar.value = data.userInfo.avatar;
|
||||||
roles.value = data.roles;
|
roles.value = data.roles;
|
||||||
@ -85,6 +87,7 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
Token,
|
Token,
|
||||||
|
username,
|
||||||
nickname,
|
nickname,
|
||||||
avatar,
|
avatar,
|
||||||
roles,
|
roles,
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
v-model:value="formData.rstcd"
|
v-model:value="formData.rstcd"
|
||||||
:loading="engLoading"
|
:loading="engLoading"
|
||||||
placeholder="请选择电站名称"
|
placeholder="请选择电站名称"
|
||||||
:disabled="isView"
|
:disabled="isView || !formData.baseId"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@ -72,7 +72,7 @@
|
|||||||
v-model:value="formData.stcd"
|
v-model:value="formData.stcd"
|
||||||
:loading="fpssLoading"
|
:loading="fpssLoading"
|
||||||
placeholder="请选择过鱼设施"
|
placeholder="请选择过鱼设施"
|
||||||
:disabled="isView"
|
:disabled="isView || !formData.rstcd"
|
||||||
show-search
|
show-search
|
||||||
allowClear
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
@ -218,16 +218,47 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12" class="imgupload" :class="{'imgupload_hidden': isView}">
|
||||||
<a-form-item label="图片" name="picpth">
|
<a-form-item label="图片" name="picpth">
|
||||||
<!-- <a-input v-model:value="formData.picpth" placeholder="图片路径" /> -->
|
<a-upload
|
||||||
|
v-model:file-list="imageFileList"
|
||||||
|
list-type="picture-card"
|
||||||
|
:multiple="true"
|
||||||
|
accept=".png,.jpg,.jpeg"
|
||||||
|
:before-upload="beforeImageUpload"
|
||||||
|
@preview="handleImagePreview"
|
||||||
|
:disabled="isView"
|
||||||
|
:maxCount="5"
|
||||||
|
@remove="handleImageRemove"
|
||||||
|
>
|
||||||
|
<div v-if="!isView && imageFileList.length < 5">
|
||||||
|
<plus-outlined />
|
||||||
|
<div style="margin-top: 8px">上传</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="视频" name="vdpth">
|
<a-form-item label="视频" name="vdpth">
|
||||||
<!-- <a-input v-model:value="formData.vdpth" placeholder="视频路径" /> -->
|
<a-upload
|
||||||
|
v-if="!isView"
|
||||||
|
v-model:file-list="videoFileList"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="false"
|
||||||
|
accept=".mp4"
|
||||||
|
:before-upload="beforeVideoUpload"
|
||||||
|
:disabled="isView"
|
||||||
|
:maxCount="5"
|
||||||
|
@remove="handleVideoRemove"
|
||||||
|
>
|
||||||
|
<a-button :disabled="isView && videoFileList.length < 5">
|
||||||
|
<upload-outlined />
|
||||||
|
上传视频 (MP4)
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
<a-button v-else @click="handleVideoPreview"> 点击预览视频 </a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -238,10 +269,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, watch, computed } from "vue";
|
import { ref, reactive, watch, computed } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { message } from "ant-design-vue";
|
import { Upload, message } from "ant-design-vue";
|
||||||
|
import { UploadOutlined, PlusOutlined } from "@ant-design/icons-vue";
|
||||||
import type { Rule } from "ant-design-vue/es/form";
|
import type { Rule } from "ant-design-vue/es/form";
|
||||||
|
import type { UploadProps } from "ant-design-vue";
|
||||||
import fishSearch from "@/components/fishSearch/index.vue";
|
import fishSearch from "@/components/fishSearch/index.vue";
|
||||||
import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from "@/api/select";
|
import {
|
||||||
|
getBaseDropdown,
|
||||||
|
getEngInfoDropdown,
|
||||||
|
getFpssDropdown,
|
||||||
|
uploadFile,
|
||||||
|
} from "@/api/select";
|
||||||
|
|
||||||
// 定义 Props
|
// 定义 Props
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -257,6 +295,8 @@ const fpssLoading = ref(false);
|
|||||||
const baseOption = ref<any[]>([]);
|
const baseOption = ref<any[]>([]);
|
||||||
const engOption = ref<any[]>([]);
|
const engOption = ref<any[]>([]);
|
||||||
const fpssOption = ref<any[]>([]);
|
const fpssOption = ref<any[]>([]);
|
||||||
|
const imageFileList = ref<any[]>([]);
|
||||||
|
const videoFileList = ref<any[]>([]);
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
visible: false,
|
visible: false,
|
||||||
@ -315,6 +355,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;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 表单引用
|
// 表单引用
|
||||||
@ -420,7 +461,55 @@ const validateWeight = () => {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
// 图片上传前校验
|
||||||
|
const beforeImageUpload: UploadProps["beforeUpload"] = (file) => {
|
||||||
|
const isJpgOrPng =
|
||||||
|
file.type === "image/jpeg" ||
|
||||||
|
file.type === "image/png" ||
|
||||||
|
file.name.toLowerCase().endsWith(".jpg") ||
|
||||||
|
file.name.toLowerCase().endsWith(".jpeg") ||
|
||||||
|
file.name.toLowerCase().endsWith(".png");
|
||||||
|
if (!isJpgOrPng) {
|
||||||
|
message.error("只能上传 JPG/PNG/JPEG 格式的图片!");
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 5; // 限制5M,可根据需求调整
|
||||||
|
if (!isLt2M) {
|
||||||
|
message.error("图片大小不能超过 5MB!");
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
// 返回 false 阻止自动上传,我们手动处理
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 视频上传前校验
|
||||||
|
const beforeVideoUpload: UploadProps["beforeUpload"] = (file) => {
|
||||||
|
const isMp4 = file.type === "video/mp4" || file.name.toLowerCase().endsWith(".mp4");
|
||||||
|
if (!isMp4) {
|
||||||
|
message.error("只能上传 MP4 格式的视频!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isLt50M = file.size / 1024 / 1024 < 10; // 限制50M,可根据需求调整
|
||||||
|
if (!isLt50M) {
|
||||||
|
message.error("视频大小不能超过 10MB!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 返回 false 阻止自动上传
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 移除图片
|
||||||
|
const handleImageRemove = (file: any) => {
|
||||||
|
const index = imageFileList.value.indexOf(file);
|
||||||
|
const newFileList = imageFileList.value.slice();
|
||||||
|
newFileList.splice(index, 1);
|
||||||
|
imageFileList.value = newFileList;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 移除视频
|
||||||
|
const handleVideoRemove = (file: any) => {
|
||||||
|
videoFileList.value = [];
|
||||||
|
};
|
||||||
// 1. 定义一个初始化表单的函数
|
// 1. 定义一个初始化表单的函数
|
||||||
const initForm = () => {
|
const initForm = () => {
|
||||||
if (props.initialValues) {
|
if (props.initialValues) {
|
||||||
@ -453,7 +542,30 @@ const initForm = () => {
|
|||||||
formData.bodyLengthMin = undefined;
|
formData.bodyLengthMin = undefined;
|
||||||
formData.bodyLengthMax = undefined;
|
formData.bodyLengthMax = undefined;
|
||||||
}
|
}
|
||||||
|
if (values.picpth) {
|
||||||
|
const paths = Array.isArray(values.picpth)
|
||||||
|
? values.picpth
|
||||||
|
: values.picpth.split(",");
|
||||||
|
imageFileList.value = paths.map((path: string, index: number) => ({
|
||||||
|
uid: `-${index}`,
|
||||||
|
name: path.split("/").pop() || `image-${index}`,
|
||||||
|
status: "done",
|
||||||
|
path: path,
|
||||||
|
url: import.meta.env.VITE_APP_PREVIEW_URL + "/?" + path, // 这里需要是完整的可访问URL
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理视频回显
|
||||||
|
if (values.vdpth) {
|
||||||
|
const paths = Array.isArray(values.vdpth) ? values.vdpth : values.vdpth.split(",");
|
||||||
|
videoFileList.value = paths.map((path: string, index: number) => ({
|
||||||
|
uid: `-${index}`,
|
||||||
|
name: path.split("/").pop() || `image-${index}`,
|
||||||
|
status: "done",
|
||||||
|
path: path,
|
||||||
|
url: import.meta.env.VITE_APP_PREVIEW_URL + "/?" + path, // 这里需要是完整的可访问URL
|
||||||
|
}));
|
||||||
|
}
|
||||||
// 回填其他普通字段
|
// 回填其他普通字段
|
||||||
Object.keys(formData).forEach((key) => {
|
Object.keys(formData).forEach((key) => {
|
||||||
// 跳过已经特殊处理的字段
|
// 跳过已经特殊处理的字段
|
||||||
@ -498,6 +610,9 @@ const resetForm = () => {
|
|||||||
// 清空手动验证的错误信息
|
// 清空手动验证的错误信息
|
||||||
bodyLengthError.value = "";
|
bodyLengthError.value = "";
|
||||||
weightError.value = "";
|
weightError.value = "";
|
||||||
|
// 清空文件列表
|
||||||
|
imageFileList.value = [];
|
||||||
|
videoFileList.value = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// 取消操作
|
// 取消操作
|
||||||
@ -506,7 +621,21 @@ const handleCancel = () => {
|
|||||||
emit("cancel");
|
emit("cancel");
|
||||||
resetForm();
|
resetForm();
|
||||||
};
|
};
|
||||||
|
const handleVideoPreview = () => {
|
||||||
|
emit("preview-click", { vdpthList: videoFileList.value }, "formVideo", 0);
|
||||||
|
};
|
||||||
|
// ... 其他导入 ...
|
||||||
|
|
||||||
|
// 新增:自定义图片预览处理
|
||||||
|
const handleImagePreview = async (file: any) => {
|
||||||
|
if (!props.isView) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
emit("preview-click", { picpthList: imageFileList.value }, "formImage", 0);
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
// ... 其他现有代码 ...
|
||||||
// 确认操作
|
// 确认操作
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
try {
|
try {
|
||||||
@ -520,6 +649,70 @@ const handleOk = async () => {
|
|||||||
}
|
}
|
||||||
// 验证表单
|
// 验证表单
|
||||||
await formRef.value.validate();
|
await formRef.value.validate();
|
||||||
|
// 1. 处理图片上传
|
||||||
|
let uploadedPicPaths: any[] = [];
|
||||||
|
// 过滤出新生成的文件(没有 url 属性的通常是新选择的文件)
|
||||||
|
const newImageFiles = imageFileList.value.filter(
|
||||||
|
(file) => !file.url && file.originFileObj
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newImageFiles.length > 0) {
|
||||||
|
// 这里需要循环上传,或者使用 Promise.all 并行上传
|
||||||
|
// 伪代码:假设 uploadFile 返回 { data: { url: '...' } }
|
||||||
|
const uploadPromises = newImageFiles.map((file) => {
|
||||||
|
const formDataUpload = new FormData();
|
||||||
|
formDataUpload.append("file", file.originFileObj);
|
||||||
|
return uploadFile(formDataUpload); // 替换为真实的上传接口调用
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await Promise.all(uploadPromises);
|
||||||
|
uploadedPicPaths = results.map((item: any, index: number) => ({
|
||||||
|
path: item.message,
|
||||||
|
uid: `-${index}`,
|
||||||
|
name: item.fileMD5,
|
||||||
|
status: "done",
|
||||||
|
url: item.fullFilePath, // 这里需要是完整的可访问URL
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并已存在的图片路径(编辑模式下回显的)和新上传的
|
||||||
|
const existingPics = imageFileList.value
|
||||||
|
.filter((file) => file.path)
|
||||||
|
.map((file) => file.path);
|
||||||
|
const uploadedPicPaths1 = uploadedPicPaths
|
||||||
|
.filter((file) => file.path)
|
||||||
|
.map((file) => file.path);
|
||||||
|
const finalPicPaths = [...existingPics, ...uploadedPicPaths1];
|
||||||
|
|
||||||
|
// 2. 处理视频上传
|
||||||
|
let uploadedVideoPath = [];
|
||||||
|
const newVideoFiles = videoFileList.value.filter(
|
||||||
|
(file) => !file.url && file.originFileObj
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newVideoFiles.length > 0) {
|
||||||
|
const uploadPromises = newVideoFiles.map((file) => {
|
||||||
|
const formDataUpload = new FormData();
|
||||||
|
formDataUpload.append("file", file.originFileObj);
|
||||||
|
return uploadFile(formDataUpload); // 替换为真实的上传接口调用
|
||||||
|
});
|
||||||
|
const results = await Promise.all(uploadPromises);
|
||||||
|
uploadedVideoPath = results.map((item: any, index: number) => ({
|
||||||
|
path: item.message,
|
||||||
|
uid: `-${index}`,
|
||||||
|
name: item.fileMD5,
|
||||||
|
status: "done",
|
||||||
|
url: item.fullFilePath, // 这里需要是完整的可访问URL
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const existingVideos = videoFileList.value
|
||||||
|
.filter((file) => file.path)
|
||||||
|
.map((file) => file.path);
|
||||||
|
const uploadedVideoPaths1 = uploadedVideoPath
|
||||||
|
.filter((file) => file.path)
|
||||||
|
.map((file) => file.path);
|
||||||
|
const finalVideoPaths = [...existingVideos, ...uploadedVideoPaths1];
|
||||||
|
|
||||||
let fwet = "";
|
let fwet = "";
|
||||||
if (
|
if (
|
||||||
formData.weightMin == formData.weightMax &&
|
formData.weightMin == formData.weightMax &&
|
||||||
@ -528,7 +721,7 @@ const handleOk = async () => {
|
|||||||
) {
|
) {
|
||||||
fwet = formData.weightMin;
|
fwet = formData.weightMin;
|
||||||
} else if (formData.weightMin == undefined && formData.weightMax == undefined) {
|
} else if (formData.weightMin == undefined && formData.weightMax == undefined) {
|
||||||
fwet = "-";
|
fwet = "";
|
||||||
} else {
|
} else {
|
||||||
fwet = formData.weightMin + "~" + formData.weightMax;
|
fwet = formData.weightMin + "~" + formData.weightMax;
|
||||||
}
|
}
|
||||||
@ -543,7 +736,7 @@ const handleOk = async () => {
|
|||||||
formData.bodyLengthMin == undefined &&
|
formData.bodyLengthMin == undefined &&
|
||||||
formData.bodyLengthMax == undefined
|
formData.bodyLengthMax == undefined
|
||||||
) {
|
) {
|
||||||
fsz = "-";
|
fsz = "";
|
||||||
} else {
|
} else {
|
||||||
fsz = formData.bodyLengthMin + "~" + formData.bodyLengthMax;
|
fsz = formData.bodyLengthMin + "~" + formData.bodyLengthMax;
|
||||||
}
|
}
|
||||||
@ -552,9 +745,12 @@ const handleOk = async () => {
|
|||||||
...formData,
|
...formData,
|
||||||
fwet: fwet,
|
fwet: fwet,
|
||||||
fsz: fsz,
|
fsz: fsz,
|
||||||
|
picpth: finalPicPaths.join(","), // 根据后端要求,可能是数组或逗号分隔字符串
|
||||||
|
vdpth: finalVideoPaths.join(","),
|
||||||
};
|
};
|
||||||
if (!formData.id) submitValues.tm = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
if (!formData.id) submitValues.tm = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
console.log(submitValues);
|
console.log(submitValues);
|
||||||
|
// return;
|
||||||
emit("ok", submitValues);
|
emit("ok", submitValues);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Validate Failed:", error);
|
console.error("Validate Failed:", error);
|
||||||
@ -563,5 +759,52 @@ const handleOk = async () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
|
.imgupload {
|
||||||
|
/* 1. 控制上传触发按钮(那个加号框)的大小 */
|
||||||
|
:deep(.ant-upload-select-picture-card) {
|
||||||
|
width: 78px !important;
|
||||||
|
height: 78px !important;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. 控制已上传列表项容器的大小 */
|
||||||
|
:deep(.ant-upload-list-item-container) {
|
||||||
|
width: 78px !important;
|
||||||
|
height: 78px !important;
|
||||||
|
float: left; /* 确保浮动排列,避免换行问题 */
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. 控制列表项内部的具体内容(图片/缩略图) */
|
||||||
|
:deep(.ant-upload-list-item) {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
/* 删除预览按钮 */
|
||||||
|
.ant-upload-list-item-actions {
|
||||||
|
a {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.imgupload_hidden{
|
||||||
|
:deep(.ant-upload-list-item) {
|
||||||
|
/* 删除预览按钮 */
|
||||||
|
.ant-upload-list-item-actions {
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -78,7 +78,6 @@ import {
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import BasicSearch from "@/components/BasicSearch/index.vue"; // 确保路径正确
|
import BasicSearch from "@/components/BasicSearch/index.vue"; // 确保路径正确
|
||||||
import { DateSetting } from "@/utils/enumeration";
|
import { DateSetting } from "@/utils/enumeration";
|
||||||
import { checkPerm } from "@/directive/permission";
|
|
||||||
import fishSearch from "@/components/fishSearch/index.vue";
|
import fishSearch from "@/components/fishSearch/index.vue";
|
||||||
import { useShuJuTianBaoStore } from "@/store/modules/shuJuTianBao";
|
import { useShuJuTianBaoStore } from "@/store/modules/shuJuTianBao";
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
:columns="modalColumns"
|
:columns="modalColumns"
|
||||||
:scroll="{ y: 500, x: '100%' }"
|
:scroll="{ y: 500, x: '100%' }"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:row-key="(record, index) => index"
|
:row-key="(_record, index) => index"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record, index }">
|
<template #bodyCell="{ column, record, index }">
|
||||||
<!-- 1. 操作列 -->
|
<!-- 1. 操作列 -->
|
||||||
@ -29,28 +29,33 @@
|
|||||||
<template
|
<template
|
||||||
v-else-if="
|
v-else-if="
|
||||||
!isEditing(index) &&
|
!isEditing(index) &&
|
||||||
column.dataIndexKey &&
|
|
||||||
record._warnings &&
|
record._warnings &&
|
||||||
record._warnings.includes(column.dataIndexKey)
|
record._warnings.includes(column.dataIndexKey)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div style="color: red; display: flex; align-items: center">
|
<div style="color: red; display: flex; align-items: center">
|
||||||
<span>{{ record[column.dataIndex] }}</span>
|
<span v-if="record[column.dataIndex]">{{ record[column.dataIndex] }}</span>
|
||||||
|
<span v-else> 请添加{{ column.title }}</span>
|
||||||
<exclamation-circle-outlined style="margin-left: 4px" />
|
<exclamation-circle-outlined style="margin-left: 4px" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 3. 编辑状态下的单元格 (绑定到 editingData) -->
|
<!-- 3. 编辑状态下的单元格 (绑定到 editingData) -->
|
||||||
<template v-else-if="isEditing(index) && column.dataIndex != 'picpth' && column.dataIndex != 'vdpth'">
|
<template
|
||||||
|
v-else-if="
|
||||||
|
isEditing(index) && column.dataIndex != 'picpth' && column.dataIndex != 'vdpth'
|
||||||
|
"
|
||||||
|
>
|
||||||
<template v-if="column.dataIndex === 'baseName'">
|
<template v-if="column.dataIndex === 'baseName'">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="editingData.baseId"
|
v-model:value="editingData.baseId"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
show-search
|
show-search
|
||||||
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
:loading="rowStates[index]?.baseLoading"
|
:loading="rowStates[index]?.baseLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(val) => handleBaseChange(val, index)"
|
@change="(val) => handleBaseChange(val, index, 'input')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in baseOptions"
|
v-for="opt in baseOptions"
|
||||||
@ -69,11 +74,12 @@
|
|||||||
v-model:value="editingData.rstcd"
|
v-model:value="editingData.rstcd"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
show-search
|
show-search
|
||||||
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
:loading="rowStates[index]?.engLoading"
|
:loading="rowStates[index]?.engLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="!editingData.baseId"
|
:disabled="!editingData.baseId"
|
||||||
@change="(val) => handleEngChange(val, index)"
|
@change="(val) => handleEngChange(val, index, 'input')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="opt in rowStates[index]?.engOptions || []"
|
v-for="opt in rowStates[index]?.engOptions || []"
|
||||||
@ -92,6 +98,7 @@
|
|||||||
v-model:value="editingData.stcd"
|
v-model:value="editingData.stcd"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
show-search
|
show-search
|
||||||
|
allowClear
|
||||||
:filter-option="filterOption"
|
:filter-option="filterOption"
|
||||||
:loading="rowStates[index]?.fpssLoading"
|
:loading="rowStates[index]?.fpssLoading"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@ -117,6 +124,7 @@
|
|||||||
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')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -135,6 +143,7 @@
|
|||||||
v-model:value="editingData.direction"
|
v-model:value="editingData.direction"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@change="(val) => delWarning(val,'direction')"
|
||||||
>
|
>
|
||||||
<a-select-option
|
<a-select-option
|
||||||
v-for="item in direction"
|
v-for="item in direction"
|
||||||
@ -147,7 +156,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 数字输入框 -->
|
<!-- 数字输入框 -->
|
||||||
<template v-else-if="['fcnt', 'wt'].includes(column.dataIndex)">
|
<template v-else-if="['fcnt'].includes(column.dataIndex)">
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="editingData[column.dataIndex]"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="(val) => delWarning(val, column.dataIndex)"
|
||||||
|
:min="0"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="['wt'].includes(column.dataIndex)">
|
||||||
<a-input-number
|
<a-input-number
|
||||||
v-model:value="editingData[column.dataIndex]"
|
v-model:value="editingData[column.dataIndex]"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@ -157,7 +174,8 @@
|
|||||||
|
|
||||||
<!-- 是否鱼苗 -->
|
<!-- 是否鱼苗 -->
|
||||||
<template v-else-if="column.dataIndex === 'isfs'">
|
<template v-else-if="column.dataIndex === 'isfs'">
|
||||||
<a-radio-group v-model:value="editingData.isfs">
|
<a-radio-group v-model:value="editingData.isfs"
|
||||||
|
@change="(val) => delWarning(val,'isfs')">
|
||||||
<a-radio :value="1">是</a-radio>
|
<a-radio :value="1">是</a-radio>
|
||||||
<a-radio :value="0">否</a-radio>
|
<a-radio :value="0">否</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
@ -198,25 +216,29 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template
|
<template v-else-if="column.dataIndex === 'picpth'">
|
||||||
v-else-if="column.dataIndex === 'picpth'"
|
|
||||||
>
|
|
||||||
<div class="preview" v-for="(item, index) in record.picpthList">
|
<div class="preview" v-for="(item, index) in record.picpthList">
|
||||||
<div class="text" :class="{'text_warning': record.picpthsWarnings.includes(item.name)}" @click="emit('preview-click', record, 'image' ,index)">
|
<div
|
||||||
{{ item.name }}
|
class="text"
|
||||||
</div>
|
:class="{ text_warning: record.picpthsWarnings.includes(item.name) }"
|
||||||
</div>
|
@click="emit('preview-click', record, 'image', index)"
|
||||||
<div v-if="record.picpthList.length==0">暂无图片</div>
|
|
||||||
</template>
|
|
||||||
<template
|
|
||||||
v-else-if="column.dataIndex === 'vdpth'"
|
|
||||||
>
|
>
|
||||||
<div class="preview" v-for="(item, index) in record.vdpthList">
|
|
||||||
<div class="text" :class="{'text_warning': record.vdpthsWarnings.includes(item.name)}" @click="emit('preview-click', record, 'vdpth' ,index)">
|
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="record.vdpthList.length==0">暂无视频</div>
|
<div v-if="record.picpthList.length == 0">暂无图片</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.dataIndex === 'vdpth'">
|
||||||
|
<div class="preview" v-for="(item, index) in record.vdpthList">
|
||||||
|
<div
|
||||||
|
class="text"
|
||||||
|
:class="{ text_warning: record.vdpthsWarnings.includes(item.name) }"
|
||||||
|
@click="emit('preview-click', record, 'video', index)"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="record.vdpthList.length == 0">暂无视频</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
@ -228,8 +250,6 @@ import { message, Tag } from "ant-design-vue";
|
|||||||
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
||||||
import fishSearch from "@/components/fishSearch/index.vue";
|
import fishSearch from "@/components/fishSearch/index.vue";
|
||||||
import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from "@/api/select";
|
import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from "@/api/select";
|
||||||
import { CloseCircleOutlined } from "@ant-design/icons-vue";
|
|
||||||
import { es } from "element-plus/es/locale/index.mjs";
|
|
||||||
|
|
||||||
const props: any = defineProps({
|
const props: any = defineProps({
|
||||||
fileTableData: { type: Array, default: () => [] },
|
fileTableData: { type: Array, default: () => [] },
|
||||||
@ -269,12 +289,25 @@ const modalColumns = ref([
|
|||||||
title: "过鱼设施名称",
|
title: "过鱼设施名称",
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{ dataIndex: "strdt", key: "strdt", title: "过鱼时间", width: 190 },
|
{
|
||||||
{ dataIndex: "ftpName", key: "ftpName", title: "鱼种类", width: 120 },
|
dataIndex: "strdt",
|
||||||
|
key: "strdt",
|
||||||
|
dataIndexKey: "strdt",
|
||||||
|
title: "过鱼时间",
|
||||||
|
width: 190,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "ftpName",
|
||||||
|
key: "ftpName",
|
||||||
|
dataIndexKey: "ftp",
|
||||||
|
title: "鱼种类",
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
dataIndex: "isfs",
|
dataIndex: "isfs",
|
||||||
key: "isfs",
|
key: "isfs",
|
||||||
title: "是否鱼苗",
|
title: "是否鱼苗",
|
||||||
|
dataIndexKey: "isfs",
|
||||||
width: 130,
|
width: 130,
|
||||||
customRender: ({ text }: any) => {
|
customRender: ({ text }: any) => {
|
||||||
const isYes = text === 1 || text === "1";
|
const isYes = text === 1 || text === "1";
|
||||||
@ -285,13 +318,20 @@ const modalColumns = ref([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: "direction",
|
dataIndex: "direction",
|
||||||
|
dataIndexKey: "direction",
|
||||||
key: "direction",
|
key: "direction",
|
||||||
title: "游向",
|
title: "游向",
|
||||||
width: 120,
|
width: 120,
|
||||||
customRender: ({ text }: any) => props.direction.find((item: any) => item.itemCode === text)?.dictName || "-"
|
customRender: ({ text }: any) =>
|
||||||
,
|
props.direction.find((item: any) => item.itemCode === text)?.dictName || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: "fcnt",
|
||||||
|
key: "fcnt",
|
||||||
|
dataIndexKey: "fcnt",
|
||||||
|
title: "过鱼数量(尾)",
|
||||||
|
width: 120,
|
||||||
},
|
},
|
||||||
{ dataIndex: "fcnt", key: "fcnt", title: "过鱼数量(尾)", width: 120 },
|
|
||||||
{ dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 160 },
|
{ dataIndex: "fsz", key: "fsz", title: "体长(cm)", width: 160 },
|
||||||
{ dataIndex: "fwet", key: "fwet", title: "平均体重(g)", width: 160 },
|
{ dataIndex: "fwet", key: "fwet", title: "平均体重(g)", width: 160 },
|
||||||
{ dataIndex: "wt", key: "wt", title: "水温(℃)", width: 80 },
|
{ dataIndex: "wt", key: "wt", title: "水温(℃)", width: 80 },
|
||||||
@ -335,25 +375,23 @@ const ensureRowState = (index: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- 级联逻辑 (操作 editingData) ---
|
// --- 级联逻辑 (操作 editingData) ---
|
||||||
|
const handleBaseChange = async (
|
||||||
const handleBaseChange = async (baseId: string, index: number) => {
|
baseId: string,
|
||||||
console.log(baseId);
|
index: number,
|
||||||
|
type: string = "start"
|
||||||
|
) => {
|
||||||
|
const state = ensureRowState(index);
|
||||||
editingData.value.baseName = baseOptions.value.find(
|
editingData.value.baseName = baseOptions.value.find(
|
||||||
(item: any) => item.baseid == baseId
|
(item: any) => item.baseid == baseId
|
||||||
)?.basename;
|
)?.basename;
|
||||||
if (baseId && editingData.value._warnings) {
|
delWarning(baseId, "baseId");
|
||||||
editingData.value._warnings = editingData.value._warnings.filter(
|
|
||||||
(w: string) => w !== "baseName"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const state = ensureRowState(index);
|
|
||||||
// 清空后续字段
|
// 清空后续字段
|
||||||
|
if (type != "start") {
|
||||||
editingData.value.rstcd = undefined;
|
editingData.value.rstcd = undefined;
|
||||||
editingData.value.stcd = undefined;
|
editingData.value.stcd = undefined;
|
||||||
state.engOptions = [];
|
state.engOptions = [];
|
||||||
state.fpssOptions = [];
|
state.fpssOptions = [];
|
||||||
|
}
|
||||||
if (!baseId) return;
|
|
||||||
state.engLoading = true;
|
state.engLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getEngInfoDropdown({ baseId });
|
const res = await getEngInfoDropdown({ baseId });
|
||||||
@ -365,20 +403,16 @@ const handleBaseChange = async (baseId: string, index: number) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEngChange = async (rstcd: string, index: number) => {
|
const handleEngChange = async (rstcd: string, index: number, type: string = "start") => {
|
||||||
const state = ensureRowState(index);
|
const state = ensureRowState(index);
|
||||||
if (rstcd && editingData.value._warnings) {
|
|
||||||
editingData.value._warnings = editingData.value._warnings.filter(
|
|
||||||
(w: string) => w !== "ennm"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
editingData.value.ennm = state.engOptions.find(
|
editingData.value.ennm = state.engOptions.find(
|
||||||
(item: any) => item.stcd === rstcd
|
(item: any) => item.stcd === rstcd
|
||||||
)?.ennm;
|
)?.ennm;
|
||||||
|
delWarning(rstcd, "rstcd");
|
||||||
|
if (type != "start") {
|
||||||
editingData.value.stcd = undefined;
|
editingData.value.stcd = undefined;
|
||||||
state.fpssOptions = [];
|
state.fpssOptions = [];
|
||||||
|
}
|
||||||
if (!rstcd || !editingData.value.baseId) return;
|
|
||||||
state.fpssLoading = true;
|
state.fpssLoading = true;
|
||||||
try {
|
try {
|
||||||
const res = await getFpssDropdown({ rstcd, baseId: editingData.value.baseId });
|
const res = await getFpssDropdown({ rstcd, baseId: editingData.value.baseId });
|
||||||
@ -391,18 +425,35 @@ const handleEngChange = async (rstcd: string, index: number) => {
|
|||||||
};
|
};
|
||||||
const handleFpssChange = (stcd: string, index: number) => {
|
const handleFpssChange = (stcd: string, index: number) => {
|
||||||
const state = ensureRowState(index);
|
const state = ensureRowState(index);
|
||||||
if (stcd && editingData.value._warnings) {
|
delWarning(stcd, "stcd");
|
||||||
editingData.value._warnings = editingData.value._warnings.filter(
|
|
||||||
(w: string) => w !== "stnm"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
editingData.value.stnm = state.fpssOptions.find(
|
editingData.value.stnm = state.fpssOptions.find(
|
||||||
(item: any) => item.stcd === stcd
|
(item: any) => item.stcd === stcd
|
||||||
)?.stnm;
|
)?.stnm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- 编辑控制 ---
|
// 消除警告 / 添加警告
|
||||||
|
const delWarning = (val: any, key: string) => {
|
||||||
|
// 确保 _warnings 数组存在
|
||||||
|
if (!editingData.value._warnings) {
|
||||||
|
editingData.value._warnings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const warnings = editingData.value._warnings;
|
||||||
|
const hasWarning = warnings.includes(key);
|
||||||
|
|
||||||
|
if (val !== null && val !== undefined && val !== '') {
|
||||||
|
// 1. 如果有值,且存在警告,则移除警告
|
||||||
|
if (hasWarning) {
|
||||||
|
editingData.value._warnings = warnings.filter((w: string) => w !== key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 2. 如果值为空 (null/undefined/''),且不存在警告,则添加警告
|
||||||
|
if (!hasWarning) {
|
||||||
|
editingData.value._warnings.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// --- 编辑控制 ---
|
||||||
const isEditing = (index: number) => editingRowIndex.value === index;
|
const isEditing = (index: number) => editingRowIndex.value === index;
|
||||||
const startEdit = (index: number) => {
|
const startEdit = (index: number) => {
|
||||||
const originalRecord = props.fileTableData[index];
|
const originalRecord = props.fileTableData[index];
|
||||||
@ -416,11 +467,20 @@ const startEdit = (index: number) => {
|
|||||||
editingRowIndex.value = index;
|
editingRowIndex.value = index;
|
||||||
|
|
||||||
// 3. 预加载下拉选项 (基于 editingData 的值)
|
// 3. 预加载下拉选项 (基于 editingData 的值)
|
||||||
if (editingData.value.baseId && !editingData.value.rstcd) {
|
console.log(editingData.value.baseId);
|
||||||
handleBaseChange(editingData.value.baseId, index);
|
if (editingData.value.baseId == "" || editingData.value.baseId == undefined) {
|
||||||
} else if (editingData.value.baseId && editingData.value.rstcd) {
|
console.log(editingData.value.rstcd);
|
||||||
handleBaseChange(editingData.value.baseId, index).then(() => {
|
if (editingData.value.rstcd) {
|
||||||
handleEngChange(editingData.value.rstcd, index);
|
handleBaseChange("", index, "start").then(() => {
|
||||||
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleEngChange("", index, "start");
|
||||||
|
}
|
||||||
|
} else if (editingData.value.baseId != "" && editingData.value.baseId != undefined) {
|
||||||
|
console.log(2);
|
||||||
|
handleBaseChange(editingData.value.baseId, index, "start").then(() => {
|
||||||
|
handleEngChange(editingData.value.rstcd, index, "start");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -515,9 +575,9 @@ const handlePreviewDelete = (index: number) => {
|
|||||||
// 鱼种类编辑 修改名称
|
// 鱼种类编辑 修改名称
|
||||||
const handleFtpChange = (val: any, opt: any) => {
|
const handleFtpChange = (val: any, opt: any) => {
|
||||||
editingData.value.ftpName = opt.name;
|
editingData.value.ftpName = opt.name;
|
||||||
|
delWarning(val, "ftp");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// --- 辅助函数 ---
|
// --- 辅助函数 ---
|
||||||
const filterOption = (input: string, option: any) => {
|
const filterOption = (input: string, option: any) => {
|
||||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||||
|
|||||||
@ -128,6 +128,7 @@
|
|||||||
:loading="submitLoading"
|
:loading="submitLoading"
|
||||||
@cancel="editModalCancel"
|
@cancel="editModalCancel"
|
||||||
@ok="handleEditSubmit"
|
@ok="handleEditSubmit"
|
||||||
|
@preview-click="handlePreviewClick"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 媒体预览 Modal -->
|
<!-- 媒体预览 Modal -->
|
||||||
@ -137,6 +138,7 @@
|
|||||||
:footer="null"
|
:footer="null"
|
||||||
width="900px"
|
width="900px"
|
||||||
@cancel="closeMediaPreview"
|
@cancel="closeMediaPreview"
|
||||||
|
z-index="2000"
|
||||||
>
|
>
|
||||||
<div class="flex h-[60vh] gap-4">
|
<div class="flex h-[60vh] gap-4">
|
||||||
<!-- 左侧:混合列表 (图片+视频) -->
|
<!-- 左侧:混合列表 (图片+视频) -->
|
||||||
@ -149,9 +151,12 @@
|
|||||||
@click="currentMediaIndex = index"
|
@click="currentMediaIndex = index"
|
||||||
>
|
>
|
||||||
<span class="file-name">{{ item.name }}</span>
|
<span class="file-name">{{ item.name }}</span>
|
||||||
|
|
||||||
<!-- 删除按钮 -->
|
<!-- 删除按钮 -->
|
||||||
<div class="list-item-delete" @click.stop="handleDeleteMedia(item, index)">
|
<div
|
||||||
|
class="list-item-delete"
|
||||||
|
v-if="item.type != 'formVideo' && item.type != 'formImage'"
|
||||||
|
@click.stop="handleDeleteMedia(item, index)"
|
||||||
|
>
|
||||||
<CloseCircleOutlined />
|
<CloseCircleOutlined />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -166,17 +171,16 @@
|
|||||||
v-if="
|
v-if="
|
||||||
currentMediaItem &&
|
currentMediaItem &&
|
||||||
currentMediaItem.url != '' &&
|
currentMediaItem.url != '' &&
|
||||||
currentMediaItem.type === 'image'
|
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
||||||
"
|
"
|
||||||
:src="currentMediaItem.url"
|
:src="currentMediaItem.url"
|
||||||
class="max-w-full max-h-full object-contain"
|
class="max-w-full max-h-full object-contain"
|
||||||
:preview="{ visible: false }"
|
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else-if="
|
v-else-if="
|
||||||
currentMediaItem &&
|
currentMediaItem &&
|
||||||
currentMediaItem.url == '' &&
|
currentMediaItem.url == '' &&
|
||||||
currentMediaItem.type === 'image'
|
(currentMediaItem.type === 'image' || currentMediaItem.type === 'formImage')
|
||||||
"
|
"
|
||||||
class="text-gray-400"
|
class="text-gray-400"
|
||||||
>
|
>
|
||||||
@ -188,7 +192,7 @@
|
|||||||
v-else-if="
|
v-else-if="
|
||||||
currentMediaItem &&
|
currentMediaItem &&
|
||||||
currentMediaItem.url != '' &&
|
currentMediaItem.url != '' &&
|
||||||
currentMediaItem.type === 'video'
|
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
||||||
"
|
"
|
||||||
:src="currentMediaItem.url"
|
:src="currentMediaItem.url"
|
||||||
controls
|
controls
|
||||||
@ -201,7 +205,7 @@
|
|||||||
v-else-if="
|
v-else-if="
|
||||||
currentMediaItem &&
|
currentMediaItem &&
|
||||||
currentMediaItem.url == '' &&
|
currentMediaItem.url == '' &&
|
||||||
currentMediaItem.type === 'video'
|
(currentMediaItem.type === 'video' || currentMediaItem.type === 'formVideo')
|
||||||
"
|
"
|
||||||
class="text-gray-400"
|
class="text-gray-400"
|
||||||
>
|
>
|
||||||
@ -240,6 +244,7 @@ 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 { checkPerm } from "@/directive/permission";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getFishDraftPage,
|
getFishDraftPage,
|
||||||
@ -261,7 +266,7 @@ import { getDictItemsByCode } from "@/api/dict";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
// import { FileImageOutlined, VideoCameraOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
|
// import { FileImageOutlined, VideoCameraOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
|
||||||
// --- 类型定义 ---
|
// --- 类型定义 ---
|
||||||
interface FormData {
|
interface FormData {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -353,7 +358,7 @@ const submitLoading = ref(false);
|
|||||||
const mediaPreviewVisible = ref(false);
|
const mediaPreviewVisible = ref(false);
|
||||||
const videoPreviewTitle = ref("视频预览");
|
const videoPreviewTitle = ref("视频预览");
|
||||||
interface MediaItem {
|
interface MediaItem {
|
||||||
type: "image" | "video";
|
type: "image" | "video" | "formVideo" | "formImage";
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
@ -412,6 +417,7 @@ const columns = computed(() => {
|
|||||||
// --- 业务逻辑方法 ---
|
// --- 业务逻辑方法 ---
|
||||||
|
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
|
isView.value = false;
|
||||||
currentRecord.value = null;
|
currentRecord.value = null;
|
||||||
editModalVisible.value = true;
|
editModalVisible.value = true;
|
||||||
};
|
};
|
||||||
@ -552,13 +558,14 @@ const handleReject = (id: any) => {
|
|||||||
};
|
};
|
||||||
// 多选禁用
|
// 多选禁用
|
||||||
const getCheckboxProps = (record: any) => {
|
const getCheckboxProps = (record: any) => {
|
||||||
|
console.log(checkPerm(["sjtb:edit-review"]));
|
||||||
return {
|
return {
|
||||||
disabled: ['SUBMITTED', 'APPROVED'].includes(record.status),
|
disabled: ["SUBMITTED", "APPROVED"].includes(record.status),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const handleDataLoaded = (params: any, data: any) => {
|
const handleDataLoaded = (params: any, data: any) => {
|
||||||
console.log(params, data);
|
console.log(params, data);
|
||||||
return
|
return;
|
||||||
};
|
};
|
||||||
// 多选
|
// 多选
|
||||||
const handleSelectionChange = (keys: any) => {
|
const handleSelectionChange = (keys: any) => {
|
||||||
@ -652,10 +659,40 @@ const handleModalOk = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < fileTableData.value.length; i++) {
|
for (let i = 0; i < fileTableData.value.length; i++) {
|
||||||
// if (fileTableData.value[i]._warnings?.length > 0) {
|
if (fileTableData.value[i]._warnings?.length > 0) {
|
||||||
// message.warning("请检查数据,标红部分数据有误!");
|
if (fileTableData.value[i]._warnings.includes("baseId")) {
|
||||||
// return;
|
message.warning("请检查流域,流域填写有误!");
|
||||||
// }
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("rstcd")) {
|
||||||
|
message.warning("请检查电站,电站填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("stcd")) {
|
||||||
|
message.warning("请检查过鱼设施,过鱼设施填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("strdt")) {
|
||||||
|
message.warning("请检查过鱼时间,过鱼时间填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("ftp")) {
|
||||||
|
message.warning("请检查鱼种类,鱼种类填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("direction")) {
|
||||||
|
message.warning("请检查游向,游向填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("isfs")) {
|
||||||
|
message.warning("请检查是否鱼苗,是否鱼苗填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fileTableData.value[i]._warnings.includes("fcnt")) {
|
||||||
|
message.warning("请检查过鱼数量,过鱼数量填写有误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (fileTableData.value[i].picpthsWarnings?.length > 0) {
|
if (fileTableData.value[i].picpthsWarnings?.length > 0) {
|
||||||
message.warning("请检查图片,图片路径有误!");
|
message.warning("请检查图片,图片路径有误!");
|
||||||
return;
|
return;
|
||||||
@ -800,10 +837,16 @@ const fileTableaAnalysis = (res: any, type: string) => {
|
|||||||
let data = [];
|
let data = [];
|
||||||
let list = [];
|
let list = [];
|
||||||
if (type == "file") {
|
if (type == "file") {
|
||||||
list = res.data.failedRows;
|
list = res.data.failedRows.concat(res.data.successRows);
|
||||||
} else {
|
} else {
|
||||||
list = res.data.result.failedRowDetails;
|
list = res.data.result.failedRowDetails.concat(res.data.result.successRowDetails);
|
||||||
}
|
}
|
||||||
|
list.sort((a: any, b: any) => {
|
||||||
|
const keyA = a.rowIndex !== undefined && a.rowIndex !== null ? Number(a.rowIndex) : -1;
|
||||||
|
const keyB = b.rowIndex !== undefined && b.rowIndex !== null ? Number(b.rowIndex) : -1;
|
||||||
|
return keyA - keyB;
|
||||||
|
});
|
||||||
|
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
data.push({
|
data.push({
|
||||||
...item.data,
|
...item.data,
|
||||||
@ -827,7 +870,9 @@ const customTransform = (res: any) => {
|
|||||||
const modifiedRecords = rawRecords.map((item: any) => {
|
const modifiedRecords = rawRecords.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
picpthList: item.picpth ? item.picpth.split(",").map((item: string) => baseUrl + "/?" + item) || [] : [],
|
picpthList: item.picpth
|
||||||
|
? item.picpth.split(",").map((item: string) => baseUrl + "/?" + item) || []
|
||||||
|
: [],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@ -896,9 +941,10 @@ const handleSearchFinish = (values: any) => {
|
|||||||
};
|
};
|
||||||
// 处理预览点击 (由子组件触发)
|
// 处理预览点击 (由子组件触发)
|
||||||
const handlePreviewClick = (record: any, type: string, index: number) => {
|
const handlePreviewClick = (record: any, type: string, index: number) => {
|
||||||
|
console.log(record, type);
|
||||||
const mixedList: MediaItem[] = [];
|
const mixedList: MediaItem[] = [];
|
||||||
tablePreviewRecord.value = record;
|
|
||||||
if (type === "image") {
|
if (type === "image") {
|
||||||
|
tablePreviewRecord.value = record;
|
||||||
videoPreviewTitle.value = "图片预览";
|
videoPreviewTitle.value = "图片预览";
|
||||||
const nameList = record.picpthList;
|
const nameList = record.picpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
@ -908,7 +954,8 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else if (type === "video") {
|
||||||
|
tablePreviewRecord.value = record;
|
||||||
videoPreviewTitle.value = "视频预览";
|
videoPreviewTitle.value = "视频预览";
|
||||||
const nameList = record.vdpthList;
|
const nameList = record.vdpthList;
|
||||||
nameList.forEach((item: any) => {
|
nameList.forEach((item: any) => {
|
||||||
@ -918,10 +965,31 @@ const handlePreviewClick = (record: any, type: string, index: number) => {
|
|||||||
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
url: item.value ? `${baseUrl}/?${item.value}` : "",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} else if (type === "formImage") {
|
||||||
|
videoPreviewTitle.value = "图片预览";
|
||||||
|
const nameList = JSON.parse(JSON.stringify(record)).picpthList;
|
||||||
|
nameList.forEach((item: any) => {
|
||||||
|
mixedList.push({
|
||||||
|
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({
|
||||||
|
type: "formVideo",
|
||||||
|
name: item.name, // 视频通常没有单独的名称字段,可根据需要调整
|
||||||
|
url: item.url,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaPreviewVisible.value = true;
|
mediaPreviewVisible.value = true;
|
||||||
currentMediaIndex.value = index;
|
currentMediaIndex.value = index;
|
||||||
|
console.log(mixedList);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
previewList.value = mixedList;
|
previewList.value = mixedList;
|
||||||
});
|
});
|
||||||
@ -945,6 +1013,7 @@ const handleDeleteMedia = (item: any, index: number) => {
|
|||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "确认删除",
|
title: "确认删除",
|
||||||
content: "确定要从预览列表中移除该项吗?",
|
content: "确定要从预览列表中移除该项吗?",
|
||||||
|
zIndex: 2002,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
previewList.value.splice(index, 1);
|
previewList.value.splice(index, 1);
|
||||||
console.log(previewList.value);
|
console.log(previewList.value);
|
||||||
|
|||||||
@ -25,9 +25,9 @@ export default ({ mode }: ConfigEnv): UserConfig => {
|
|||||||
proxy: {
|
proxy: {
|
||||||
[env.VITE_APP_BASE_API]: {
|
[env.VITE_APP_BASE_API]: {
|
||||||
// 线上API地址
|
// 线上API地址
|
||||||
// target: 'http://localhost:8093/',
|
target: env.VITE_APP_BASE_URL,
|
||||||
// 本地API地址
|
// 本地API地址
|
||||||
target: 'http://10.84.121.21:8093',
|
// target: 'http://10.84.121.21:8093',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path =>
|
rewrite: path =>
|
||||||
path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user