fix: 新增功能修改及完善。
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="用户名称/手机号" prop="userName">
|
||||
<el-input v-model="queryParams.userId" placeholder="请输入用户id" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="塘口名称" prop="pondName">
|
||||
<el-input v-model="queryParams.pondName" placeholder="请输入塘口名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户信息" prop="params.userKeyword">
|
||||
<el-input v-model="queryParams.params.userKeyword" placeholder="请输入用户名或手机号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="投苗日期" prop="time">
|
||||
<el-date-picker
|
||||
v-model="queryParams.time"
|
||||
@@ -45,26 +45,34 @@
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:pond:export']">导出</el-button>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="pondList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="用户id" align="center" prop="userId" />
|
||||
|
||||
<el-table-column label="塘口名称" align="center" prop="pondName" />
|
||||
<el-table-column label="鱼品种列表" align="center" prop="fishKindIds" />
|
||||
<el-table-column label="面积" align="center" prop="area" />
|
||||
<el-table-column label="密度" align="center" prop="density" />
|
||||
<el-table-column label="投苗日期" align="center" prop="placeTime" width="180">
|
||||
<el-table-column label="用户名" align="center" prop="userName" />
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||
<el-table-column label="鱼品种列表" align="center" prop="fishKindNames" />
|
||||
<el-table-column label="面积(亩)" align="center" prop="area" />
|
||||
<el-table-column label="密度(尾/亩)" align="center" prop="density" />
|
||||
<el-table-column label="投苗日期" align="center" prop="placeTime" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.placeTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="夜间防止误关" align="center" prop="keepNightOpen" />
|
||||
<el-table-column label="夜间防止误关" align="center" prop="keepNightOpen">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="open_close" :value="scope.row.keepNightOpen" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160"/>
|
||||
<el-table-column label="修改时间" align="center" prop="updateTime" width="160"/>
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
@@ -79,30 +87,96 @@
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改塘口管理对话框 -->
|
||||
<!-- 添加或修改塘口对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="550px" append-to-body>
|
||||
<el-form ref="pondFormRef" :model="form" :rules="rules" label-width="110px">
|
||||
<el-form-item label="用户id" prop="userId">
|
||||
<el-input v-model="form.userId" placeholder="请输入用户id" />
|
||||
<el-form-item label="用户" prop="userId">
|
||||
<el-input
|
||||
:value="selectedUser ? `${selectedUser.userName} (${selectedUser.mobilePhone})` : ''"
|
||||
placeholder="请选择用户"
|
||||
readonly
|
||||
@click="openUserSelect"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
<template #append>
|
||||
<el-button icon="Search" @click="openUserSelect">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="塘口名称" prop="pondName">
|
||||
<el-input v-model="form.pondName" placeholder="请输入塘口名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="鱼品种列表" prop="fishKindIds">
|
||||
<el-input v-model="form.fishKindIds" placeholder="请输入鱼品种列表" />
|
||||
<div class="fish-selector">
|
||||
<el-input
|
||||
v-model="selectedFishNames"
|
||||
placeholder="请选择鱼品种"
|
||||
readonly
|
||||
@click="openFishSelect"
|
||||
style="cursor: pointer;"
|
||||
>
|
||||
<template #suffix>
|
||||
<div class="input-suffix">
|
||||
<span v-if="selectedFishList.length > 0" class="count-badge">
|
||||
{{ selectedFishList.length }}
|
||||
</span>
|
||||
<el-icon class="select-icon"><ArrowDown /></el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<!-- 简洁的已选择项目展示 -->
|
||||
<div v-if="selectedFishList.length > 0" class="selected-items">
|
||||
<div class="selected-summary">
|
||||
<span class="summary-text">已选择 {{ selectedFishList.length }} 个品种</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="clearAllFish"
|
||||
class="clear-btn"
|
||||
>
|
||||
清空
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="selected-list-compact">
|
||||
<span
|
||||
v-for="(fish, index) in selectedFishList.slice(0, 5)"
|
||||
:key="fish.id"
|
||||
class="fish-item"
|
||||
>
|
||||
{{ fish.fishName }}<span v-if="index < Math.min(4, selectedFishList.length - 1)">、</span>
|
||||
</span>
|
||||
<span v-if="selectedFishList.length > 5" class="more-indicator">
|
||||
... 及另外{{ selectedFishList.length - 5 }}个品种
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="面积" prop="area">
|
||||
<el-input v-model="form.area" placeholder="请输入面积" />
|
||||
<el-input v-model="form.area" placeholder="请输入面积">
|
||||
<template #append>亩</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密度" prop="density">
|
||||
<el-input v-model="form.density" placeholder="请输入密度" />
|
||||
<el-input v-model="form.density" placeholder="请输入密度">
|
||||
<template #append>尾/亩</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="投苗日期" prop="placeTime">
|
||||
<el-date-picker clearable v-model="form.placeTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择投苗日期">
|
||||
<el-date-picker clearable v-model="form.placeTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择投苗日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="夜间防止误关" prop="keepNightOpen">
|
||||
<el-input v-model="form.keepNightOpen" placeholder="请输入夜间防止误关" />
|
||||
<el-select v-model="form.keepNightOpen" placeholder="请选择夜间防止误关">
|
||||
<el-option
|
||||
v-for="dict in open_close"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
@@ -110,8 +184,198 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 鱼品种选择对话框 -->
|
||||
<el-dialog title="选择鱼品种" v-model="fishSelectVisible" width="1200px" append-to-body>
|
||||
<el-row :gutter="20">
|
||||
<!-- 左侧:鱼类搜索和列表 -->
|
||||
<el-col :span="16">
|
||||
<!-- Tab页签 -->
|
||||
<el-tabs v-model="activeTab" @tab-change="handleTabChange" class="mb-4">
|
||||
<el-tab-pane label="全部" name="all"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-for="dict in fish_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:name="dict.value"
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 搜索条件 -->
|
||||
<el-form :model="fishQueryParams" :inline="true" class="mb-4">
|
||||
<el-form-item label="鱼类名称">
|
||||
<el-input
|
||||
v-model="fishQueryParams.fishName"
|
||||
placeholder="请输入鱼类名称"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
@keyup.enter="handleFishQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleFishQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetFishQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 鱼品种表格 -->
|
||||
<el-table
|
||||
ref="fishTableRef"
|
||||
:data="fishList"
|
||||
@selection-change="handleSelectAllFish"
|
||||
height="350px"
|
||||
border
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="鱼类名称" align="center" prop="fishName" />
|
||||
<el-table-column label="鱼类类型" align="center" prop="fishType" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="fish_type" :value="scope.row.fishType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="80">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="quickAddFish(scope.row)"
|
||||
:disabled="selectedFishList.some(item => item.id === scope.row.id)"
|
||||
>
|
||||
添加
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 数据统计 -->
|
||||
<div class="mt-2 text-sm text-gray-500">
|
||||
当前显示 {{ fishList.length }} 条数据
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧:已选择的鱼类 -->
|
||||
<el-col :span="8">
|
||||
<div class="selected-fish-panel">
|
||||
<div class="panel-header">
|
||||
<h4>已选择的鱼类 ({{ selectedFishList.length }})</h4>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="clearAllFish"
|
||||
v-show="selectedFishList.length > 0"
|
||||
>
|
||||
清空
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="selected-list">
|
||||
<div
|
||||
v-for="fish in selectedFishList"
|
||||
:key="fish.id"
|
||||
class="selected-item"
|
||||
>
|
||||
<span class="fish-name">{{ fish.fishName }}</span>
|
||||
<dict-tag :options="fish_type" :value="fish.fishType" size="small" class="ml-2" />
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
icon="Close"
|
||||
circle
|
||||
@click="removeFish(fish.id)"
|
||||
class="ml-2"
|
||||
/>
|
||||
</div>
|
||||
<el-empty
|
||||
v-if="selectedFishList.length === 0"
|
||||
description="请选择鱼类"
|
||||
:image-size="100"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<span class="selected-count">已选择 {{ selectedFishList.length }} 个鱼类</span>
|
||||
<el-button type="primary" @click="confirmFishSelect" :disabled="selectedFishList.length === 0">确 定</el-button>
|
||||
<el-button @click="cancelFishSelect">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 用户选择对话框 -->
|
||||
<el-dialog title="选择用户" v-model="userSelectVisible" width="900px" append-to-body>
|
||||
<!-- 搜索条件 -->
|
||||
<el-form :model="userQueryParams" :inline="true" class="mb-4">
|
||||
<el-form-item label="用户名">
|
||||
<el-input
|
||||
v-model="userQueryParams.userName"
|
||||
placeholder="请输入用户名"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleUserQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号">
|
||||
<el-input
|
||||
v-model="userQueryParams.mobilePhone"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleUserQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleUserQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetUserQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 用户表格 -->
|
||||
<el-table
|
||||
:data="aquUserList"
|
||||
highlight-current-row
|
||||
height="400px"
|
||||
border
|
||||
>
|
||||
<el-table-column label="用户名" align="center" prop="userName" />
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||
<el-table-column label="省份" align="center" prop="province" />
|
||||
<el-table-column label="城市" align="center" prop="city" />
|
||||
<el-table-column label="区县" align="center" prop="district" />
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleUserSelect(scope.row)"
|
||||
>
|
||||
选择
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-show="userTotal > 0"
|
||||
:total="userTotal"
|
||||
v-model:page="userQueryParams.pageNum"
|
||||
v-model:limit="userQueryParams.pageSize"
|
||||
@pagination="handleUserPaginationChange"
|
||||
class="mt-4"
|
||||
/>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="cancelUserSelect">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@@ -120,12 +384,47 @@
|
||||
|
||||
<script setup name="Pond" lang="ts">
|
||||
import { listPond, getPond, delPond, addPond, updatePond } from '@/api/fishery/pond';
|
||||
import { listFish, getFish } from '@/api/fishery/fish';
|
||||
import { listAquUser } from '@/api/fishery/aquUser';
|
||||
import { PondVO, PondQuery, PondForm } from '@/api/fishery/pond/types';
|
||||
import { FishVO } from '@/api/fishery/fish/types';
|
||||
import { AquUserVO } from '@/api/fishery/aquUser/types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { fish_type,open_close } = toRefs<any>(proxy?.useDict('fish_type','open_close'));
|
||||
|
||||
const pondList = ref<PondVO[]>([]);
|
||||
const fishList = ref<FishVO[]>([]);
|
||||
const selectedFishList = ref<FishVO[]>([]);
|
||||
const originalSelectedFishList = ref<FishVO[]>([]); // 备份的选择列表,用于取消操作
|
||||
const fishSelectVisible = ref(false);
|
||||
|
||||
// 用户选择相关
|
||||
const aquUserList = ref<AquUserVO[]>([]);
|
||||
const selectedUser = ref<AquUserVO | null>(null);
|
||||
const userSelectVisible = ref(false);
|
||||
const userQueryParams = reactive<{
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
userName?: string;
|
||||
mobilePhone?: string;
|
||||
}>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
userName: undefined,
|
||||
mobilePhone: undefined
|
||||
});
|
||||
const userTotal = ref(0);
|
||||
const fishQueryParams = reactive<{
|
||||
fishType?: number;
|
||||
fishName?: string;
|
||||
}>({
|
||||
fishType: undefined,
|
||||
fishName: undefined
|
||||
});
|
||||
const fishTotal = ref(0); // 鱼类数据总数
|
||||
const activeTab = ref<string>('all'); // 当前激活的tab
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
@@ -136,6 +435,7 @@ const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const pondFormRef = ref<ElFormInstance>();
|
||||
const fishTableRef = ref<ElTableInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
@@ -173,13 +473,263 @@ const data = reactive<PageData<PondForm, PondQuery>>({
|
||||
fishKindIds: [{ required: true, message: '鱼品种列表不能为空', trigger: 'blur' }],
|
||||
area: [{ required: true, message: '面积不能为空', trigger: 'blur' }],
|
||||
density: [{ required: true, message: '密度不能为空', trigger: 'blur' }],
|
||||
keepNightOpen: [{ required: true, message: '夜间防止误关不能为空', trigger: 'blur' }]
|
||||
keepNightOpen: [{ required: true, message: '夜间防止误关不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询塘口管理列表 */
|
||||
// 鱼品种相关状态
|
||||
const selectedFishNames = computed(() => {
|
||||
const count = selectedFishList.value.length;
|
||||
if (count === 0) return '';
|
||||
// 简洁显示,不显示具体名称
|
||||
return `已选择 ${count} 个鱼类品种`;
|
||||
});
|
||||
|
||||
// 获取完整的鱼类名称列表(用于tooltip显示)
|
||||
const fullFishNames = computed(() => {
|
||||
return selectedFishList.value.map(fish => fish.fishName).join('、');
|
||||
});
|
||||
const parseFishIds = (fishKindIds: any): string[] => {
|
||||
if (!fishKindIds) return [];
|
||||
|
||||
try {
|
||||
// 解析JSON数组格式:"[29,31,34,4,2]"
|
||||
const parsed = JSON.parse(fishKindIds.toString());
|
||||
if (Array.isArray(parsed)) {
|
||||
return parsed.map(id => id.toString());
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('fishKindIds格式错误:', fishKindIds);
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
// 获取当前页面中已选中的项目
|
||||
const getCurrentPageSelection = () => {
|
||||
return fishList.value.filter(fish =>
|
||||
selectedFishList.value.some(selected => selected.id === fish.id)
|
||||
);
|
||||
};
|
||||
|
||||
/** 根据ID列表获取鱼类信息 */
|
||||
const getFishByIds = async (fishIds: string[]) => {
|
||||
if (fishIds.length === 0) return [];
|
||||
|
||||
try {
|
||||
// 方案1:如果鱼类数量不多,使用并发单个查询
|
||||
if (fishIds.length <= 20) {
|
||||
const promises = fishIds.map(id => getFish(id).catch(() => null));
|
||||
const results = await Promise.all(promises);
|
||||
return results.filter(res => res !== null).map(res => res.data);
|
||||
}
|
||||
|
||||
// 方案2:鱼类数量较多时,使用分批查询
|
||||
const allFishList: FishVO[] = [];
|
||||
let pageNum = 1;
|
||||
let hasMore = true;
|
||||
const foundIds = new Set<string>();
|
||||
|
||||
// 分批获取所有鱼类数据,直到找齐所需的鱼类
|
||||
while (hasMore && foundIds.size < fishIds.length) {
|
||||
const res = await listFish({
|
||||
pageNum: pageNum,
|
||||
pageSize: 100, // 每次获取100条
|
||||
fishType: undefined,
|
||||
fishName: undefined
|
||||
});
|
||||
|
||||
const fishData = res.rows || res.data || [];
|
||||
|
||||
// 筛选出需要的鱼类
|
||||
const neededFish = fishData.filter(fish => {
|
||||
const fishIdStr = fish.id.toString();
|
||||
if (fishIds.includes(fishIdStr) && !foundIds.has(fishIdStr)) {
|
||||
foundIds.add(fishIdStr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
allFishList.push(...neededFish);
|
||||
|
||||
// 判断是否还需要继续获取
|
||||
hasMore = fishData.length === 100 && foundIds.size < fishIds.length;
|
||||
pageNum++;
|
||||
|
||||
// 安全限制,避免无限循环
|
||||
if (pageNum > 50) break;
|
||||
}
|
||||
|
||||
return allFishList;
|
||||
} catch (error) {
|
||||
console.error('获取鱼类信息失败:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
const getFishList = async () => {
|
||||
const res = await listFish({
|
||||
pageNum: 1,
|
||||
pageSize: 1000, // 获取所有数据
|
||||
fishType: fishQueryParams.fishType,
|
||||
fishName: fishQueryParams.fishName
|
||||
});
|
||||
fishList.value = res.rows || res.data || [];
|
||||
fishTotal.value = res.total || 0;
|
||||
|
||||
// 数据加载完成后,设置当前页面的选中状态
|
||||
await nextTick();
|
||||
const currentPageSelection = getCurrentPageSelection();
|
||||
if (fishTableRef.value && currentPageSelection.length > 0) {
|
||||
// 清空当前选中状态
|
||||
fishTableRef.value.clearSelection();
|
||||
// 设置已选择的项目
|
||||
currentPageSelection.forEach(fish => {
|
||||
fishTableRef.value!.toggleRowSelection(fish, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** 鱼类分页改变 */
|
||||
const handleFishPaginationChange = () => {
|
||||
getFishList();
|
||||
};
|
||||
|
||||
/** 搜索鱼品种 */
|
||||
const handleFishQuery = () => {
|
||||
getFishList();
|
||||
};
|
||||
|
||||
/** 重置鱼品种搜索 */
|
||||
const resetFishQuery = () => {
|
||||
fishQueryParams.fishType = undefined;
|
||||
fishQueryParams.fishName = undefined;
|
||||
activeTab.value = 'all';
|
||||
getFishList();
|
||||
};
|
||||
|
||||
/** 切换tab */
|
||||
const handleTabChange = (tabName: string) => {
|
||||
activeTab.value = tabName;
|
||||
if (tabName === 'all') {
|
||||
fishQueryParams.fishType = undefined;
|
||||
} else {
|
||||
fishQueryParams.fishType = parseInt(tabName);
|
||||
}
|
||||
fishQueryParams.fishName = undefined; // 切换tab时清空名称搜索
|
||||
getFishList();
|
||||
};
|
||||
|
||||
/** 全选/反选鱼类 */
|
||||
const handleSelectAllFish = (selection: FishVO[]) => {
|
||||
// 先移除当前页面中的所有项目
|
||||
const currentPageIds = fishList.value.map(fish => fish.id);
|
||||
selectedFishList.value = selectedFishList.value.filter(fish => !currentPageIds.includes(fish.id));
|
||||
|
||||
// 再添加当前页面选中的项目
|
||||
selectedFishList.value.push(...selection);
|
||||
};
|
||||
|
||||
/** 快速添加单个鱼类 */
|
||||
const quickAddFish = (fish: FishVO) => {
|
||||
if (!selectedFishList.value.find(item => item.id === fish.id)) {
|
||||
selectedFishList.value.push(fish);
|
||||
}
|
||||
};
|
||||
|
||||
/** 移除已选择的鱼类 */
|
||||
const removeFish = (fishId: string | number) => {
|
||||
selectedFishList.value = selectedFishList.value.filter(fish => fish.id !== fishId);
|
||||
};
|
||||
|
||||
/** 清空所有已选择的鱼类 */
|
||||
const clearAllFish = async () => {
|
||||
selectedFishList.value = [];
|
||||
// 清空表格选中状态
|
||||
if (fishTableRef.value) {
|
||||
fishTableRef.value.clearSelection();
|
||||
}
|
||||
};
|
||||
|
||||
/** 打开鱼品种选择对话框 */
|
||||
const openFishSelect = () => {
|
||||
// 备份当前选择状态,用于取消操作
|
||||
originalSelectedFishList.value = [...selectedFishList.value];
|
||||
|
||||
// 仅重置搜索条件,不清空已选择的鱼类
|
||||
fishQueryParams.fishType = undefined;
|
||||
fishQueryParams.fishName = undefined;
|
||||
activeTab.value = 'all';
|
||||
getFishList();
|
||||
fishSelectVisible.value = true;
|
||||
};
|
||||
|
||||
/** 确认选择鱼品种 */
|
||||
const confirmFishSelect = () => {
|
||||
// 统一保存为JSON数组格式,新增和编辑都使用此格式
|
||||
const fishIds = selectedFishList.value.map(fish => fish.id);
|
||||
form.value.fishKindIds = JSON.stringify(fishIds);
|
||||
fishSelectVisible.value = false;
|
||||
};
|
||||
|
||||
/** 取消选择鱼品种 */
|
||||
const cancelFishSelect = () => {
|
||||
// 取消时恢复到原有选择状态
|
||||
selectedFishList.value = [...originalSelectedFishList.value];
|
||||
fishSelectVisible.value = false;
|
||||
};
|
||||
|
||||
/** 获取用户列表 */
|
||||
const getAquUserList = async () => {
|
||||
const res = await listAquUser(userQueryParams);
|
||||
aquUserList.value = res.rows || res.data || [];
|
||||
userTotal.value = res.total || 0;
|
||||
};
|
||||
|
||||
/** 打开用户选择对话框 */
|
||||
const openUserSelect = () => {
|
||||
// 重置搜索条件
|
||||
userQueryParams.pageNum = 1;
|
||||
userQueryParams.userName = undefined;
|
||||
userQueryParams.mobilePhone = undefined;
|
||||
getAquUserList();
|
||||
userSelectVisible.value = true;
|
||||
};
|
||||
|
||||
/** 搜索用户 */
|
||||
const handleUserQuery = () => {
|
||||
userQueryParams.pageNum = 1;
|
||||
getAquUserList();
|
||||
};
|
||||
|
||||
/** 重置用户搜索 */
|
||||
const resetUserQuery = () => {
|
||||
userQueryParams.pageNum = 1;
|
||||
userQueryParams.userName = undefined;
|
||||
userQueryParams.mobilePhone = undefined;
|
||||
getAquUserList();
|
||||
};
|
||||
|
||||
/** 用户分页改变 */
|
||||
const handleUserPaginationChange = () => {
|
||||
getAquUserList();
|
||||
};
|
||||
|
||||
/** 选择用户 */
|
||||
const handleUserSelect = (user: AquUserVO) => {
|
||||
selectedUser.value = user;
|
||||
form.value.userId = user.id;
|
||||
userSelectVisible.value = false;
|
||||
};
|
||||
|
||||
/** 取消选择用户 */
|
||||
const cancelUserSelect = () => {
|
||||
userSelectVisible.value = false;
|
||||
};
|
||||
|
||||
/** 查询塘口列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const timeRange = queryParams.value.time;
|
||||
@@ -189,8 +739,8 @@ const getList = async () => {
|
||||
st = dayjs(timeRange[0]).format('YYYY-MM-DD');
|
||||
et = dayjs(timeRange[1]).format('YYYY-MM-DD');
|
||||
}
|
||||
queryParams.value.startTime = st;
|
||||
queryParams.value.endTime = et;
|
||||
queryParams.value.params.startTime = st;
|
||||
queryParams.value.params.endTime = et;
|
||||
const res = await listPond(queryParams.value);
|
||||
pondList.value = res.rows;
|
||||
total.value = res.total;
|
||||
@@ -206,6 +756,8 @@ const cancel = () => {
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
// 注释掉清空选择列表,保持弹窗独立性
|
||||
// selectedFishList.value = [];
|
||||
pondFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
@@ -231,8 +783,10 @@ const handleSelectionChange = (selection: PondVO[]) => {
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
selectedFishList.value = []; // 新增时清空选择列表
|
||||
selectedUser.value = null; // 清空用户选择
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加塘口管理';
|
||||
dialog.title = '添加塘口';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
@@ -241,8 +795,41 @@ const handleUpdate = async (row?: PondVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getPond(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
|
||||
// 解析JSON数组格式的鱼类ID
|
||||
if (form.value.fishKindIds) {
|
||||
const fishIds = parseFishIds(form.value.fishKindIds);
|
||||
selectedFishList.value = await getFishByIds(fishIds);
|
||||
} else {
|
||||
selectedFishList.value = [];
|
||||
}
|
||||
|
||||
// 回显用户信息 - 优化加载逻辑
|
||||
if (form.value.userId) {
|
||||
try {
|
||||
// 先加载用户列表(使用较大的pageSize确保包含目标用户)
|
||||
const userRes = await listAquUser({
|
||||
pageNum: 1,
|
||||
pageSize: 1000
|
||||
});
|
||||
const userList = userRes.rows || userRes.data || [];
|
||||
const user = userList.find(u => u.id.toString() === form.value.userId.toString());
|
||||
if (user) {
|
||||
selectedUser.value = user;
|
||||
} else {
|
||||
console.warn('未找到用户ID:', form.value.userId);
|
||||
selectedUser.value = null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载用户信息失败:', error);
|
||||
selectedUser.value = null;
|
||||
}
|
||||
} else {
|
||||
selectedUser.value = null;
|
||||
}
|
||||
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改塘口管理';
|
||||
dialog.title = '修改塘口';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
@@ -265,7 +852,7 @@ const submitForm = () => {
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: PondVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除塘口管理编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await proxy?.$modal.confirm('是否确认删除塘口编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delPond(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
@@ -286,3 +873,154 @@ onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.selected-fish-panel {
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
height: 450px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.panel-header h4 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.selected-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.selected-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 6px;
|
||||
background-color: #f0f9ff;
|
||||
border: 1px solid #b3d8ff;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.fish-name {
|
||||
flex: 1;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
color: #606266;
|
||||
margin-right: auto;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 鱼品种选择器样式 */
|
||||
.fish-selector {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-suffix {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.count-badge {
|
||||
background: #409eff;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
padding: 2px 8px;
|
||||
font-size: 12px;
|
||||
min-width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select-icon {
|
||||
color: #c0c4cc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.selected-items {
|
||||
margin-top: 8px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.selected-summary {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.summary-text {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
color: #f56c6c;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.clear-btn:hover {
|
||||
color: #f78989;
|
||||
}
|
||||
|
||||
.selected-list-compact {
|
||||
padding: 10px 12px;
|
||||
line-height: 1.5;
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.fish-item {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.more-indicator {
|
||||
color: #909399;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.selected-fish-tags {
|
||||
max-height: 100px;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.selected-fish-tags .el-tag {
|
||||
margin-right: 6px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user