diff --git a/frontend/src/api/select/index.ts b/frontend/src/api/select/index.ts index da23bfb..a43e8ed 100644 --- a/frontend/src/api/select/index.ts +++ b/frontend/src/api/select/index.ts @@ -16,6 +16,14 @@ export function getEngInfoDropdown(data:any) { data }); } +// 更新导入任务 +export function updateImportTask(data:any) { + return request({ + url: '/data/importTask/update', + method: 'post', + data + }); +} //过鱼设施下拉列表 export function getFpssDropdown(params:any) { return request({ @@ -31,6 +39,14 @@ export function getFishDictoryDropdown() { method: 'get' }); } +// 类似鱼类名称下拉列表 +export function getSimilarFishDictoryDropdown(params:any) { + return request({ + url: '/env/fishDictory/similar', + method: 'get', + params + }); +} // 上传文件 export function uploadFile(data:any) { return request({ diff --git a/frontend/src/components/BasicSearch/index.vue b/frontend/src/components/BasicSearch/index.vue index a03b9ec..1cb5ec0 100644 --- a/frontend/src/components/BasicSearch/index.vue +++ b/frontend/src/components/BasicSearch/index.vue @@ -83,6 +83,7 @@ :loading="shuJuTianBaoStore.baseLoading" :filter-option="filterOption" style="width: 135px" + > + - - - + +
+ - - + + +
diff --git a/frontend/src/store/modules/shuJuTianBao.ts b/frontend/src/store/modules/shuJuTianBao.ts index 49f2bd4..e430125 100644 --- a/frontend/src/store/modules/shuJuTianBao.ts +++ b/frontend/src/store/modules/shuJuTianBao.ts @@ -1,7 +1,6 @@ import { defineStore } from 'pinia'; import { ref } from 'vue'; // 使用 ref 更简单直观 import { getBaseDropdown, getEngInfoDropdown, getFpssDropdown } from '@/api/select'; -import { set } from 'lodash'; export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => { // 1. 直接使用 ref 定义状态,确保响应式 @@ -19,10 +18,6 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => { const res = await getBaseDropdown({}); if (res.data && Array.isArray(res.data)) { const list = [...res.data]; - list.unshift({ - baseid: 'all', - basename: '当前全部' - }); // 直接赋值给 ref,触发响应式更新 baseOption.value = list; } @@ -53,6 +48,7 @@ export const useShuJuTianBaoStore = defineStore('shuJuTianBao', () => { try { fpssLoading.value = true; const res = await getFpssDropdown({ baseId, rstcd }); + console.log(res.data) fpssOption.value = res.data; } catch (error) { console.log(error); diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index cdc9fd2..589c32b 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -84,18 +84,87 @@ export function parseTime(time :any, cFormat :any) { }) return time_str } -export function downloadFile(obj :any, name :any, suffix :any) { - const url = window.URL.createObjectURL(new Blob([obj])) - const link = document.createElement('a') - link.style.display = 'none' - link.href = url - const fileName = parseTime(new Date(),'') + '-' + name + '.' + suffix - link.setAttribute('download', fileName) - document.body.appendChild(link) - link.click() - document.body.removeChild(link) +export function downloadFile(obj: any, name: any, suffix: any) { + try { + const url = window.URL.createObjectURL(new Blob([obj])); + const link = document.createElement('a'); + link.style.display = 'none'; + link.href = url; + + // 优化文件名生成逻辑,避免多余的中横线 + const timeStamp = parseTime(new Date(), '{y}{m}{d}{h}{i}{s}') || ''; + const separator = timeStamp ? '-' : ''; + const fileName = `${timeStamp}${separator}${name}.${suffix}`; + + link.setAttribute('download', fileName); + document.body.appendChild(link); + link.click(); + + // 延迟移除,确保下载触发 + setTimeout(() => { + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + }, 100); + } catch (error) { + console.error('Download failed:', error); + } } +/** + * 通过 URL 下载文件 + * @param url 文件地址 + * @param fileName 文件名(可选,如果不传则尝试从 URL 解析或使用默认名) + */ +export function downloadFileByUrl(url: string, fileName?: string) { + if (!url) return; + // 如果没有提供文件名,尝试从 URL 中提取 + let name = fileName; + if (!name) { + const urlParts = url.split('/'); + name = urlParts[urlParts.length - 1] || 'download_file'; + // 去除查询参数 + name = name.split('?')[0]; + } + + // 方法 1: 使用 fetch 获取 Blob (推荐,可重命名且强制下载) + // 注意:如果 URL 跨域且服务器未配置 CORS,fetch 会失败 + fetch(url) + .then((response) => { + if (!response.ok) throw new Error('Network response was not ok'); + return response.blob(); + }) + .then((blob) => { + const blobUrl = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.style.display = 'none'; + link.href = blobUrl; + link.setAttribute('download', name); + document.body.appendChild(link); + link.click(); + + // 清理 + setTimeout(() => { + document.body.removeChild(link); + window.URL.revokeObjectURL(blobUrl); + }, 100); + }) + .catch((error) => { + console.warn('Fetch download failed (possibly CORS), falling back to direct link:', error); + + // 方法 2: 回退方案 - 直接使用 a 标签跳转 + // 这种方式对于 PDF/图片等浏览器支持预览的文件,可能会直接在新标签页打开而不是下载 + const link = document.createElement('a'); + link.href = url; + link.target = '_blank'; + // 如果同源,download 属性生效;如果跨域,大多数浏览器会忽略 download 属性并直接打开 + if (fileName) { + link.setAttribute('download', fileName); + } + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }); +} const modules = import.meta.glob('@/assets/legend/*.svg', { eager: true }); // 图例图标映射 export const iconMap: Record = {}; diff --git a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue index 75b4218..71074fc 100644 --- a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue +++ b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoForm.vue @@ -258,7 +258,7 @@ 上传视频 (MP4) - 点击预览视频 + 点击预览视频 @@ -307,7 +307,9 @@ const getBaseDropdownSelect = async () => { try { baseLoading.value = true; const res = await getBaseDropdown({}); - baseOption.value = res.data; + let list = res.data || []; + if (list.length > 0) list.shift(); + baseOption.value = list; } catch (error) { console.error("获取流域列表失败:", error); } finally { @@ -642,7 +644,6 @@ const handleOk = async () => { // 先执行手动验证 const isBodyLenValid = validateBodyLength(); const isWeightValid = validateWeight(); - console.log(isBodyLenValid, isWeightValid); if (!isBodyLenValid || !isWeightValid) { message.error("请检查体长或体重填写是否正确"); return; @@ -749,7 +750,6 @@ const handleOk = async () => { vdpth: finalVideoPaths.join(","), }; if (!formData.id) submitValues.tm = dayjs().format("YYYY-MM-DD HH:mm:ss"); - console.log(submitValues); // return; emit("ok", submitValues); } catch (error) { diff --git a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoSearch.vue b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoSearch.vue index 820165a..7d4b81f 100644 --- a/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoSearch.vue +++ b/frontend/src/views/shuJuTianBao/guoYuSheShiShuJuTianBao/guoYuSheShiShuJuTianBaoSearch.vue @@ -9,7 +9,7 @@ @values-change="onValuesChange" >