fix: 新增功能修改及完善。
This commit is contained in:
@@ -47,9 +47,9 @@
|
||||
>删除</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:aquUser:export']">导出</el-button>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -64,8 +64,13 @@
|
||||
<el-table-column label="区县" align="center" prop="district" /> -->
|
||||
<el-table-column label="报警电话" align="center" prop="warnPhoneJson" />
|
||||
<el-table-column label="展示标题" align="center" prop="title" />
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" />
|
||||
<el-table-column label="修改时间" align="center" prop="updateTime" />
|
||||
<el-table-column label="操作" align="center" fixed="right" width="200" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看塘口" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleViewPonds(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:aquUser:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
@@ -78,7 +83,7 @@
|
||||
|
||||
<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="850px" append-to-body>
|
||||
<el-form ref="aquUserFormRef" :model="form" :rules="rules" :inline="true" label-width="120px">
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
@@ -137,12 +142,44 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 用户塘口信息对话框 -->
|
||||
<el-dialog :title="pondDialog.title" v-model="pondDialog.visible" width="1000px" append-to-body>
|
||||
<el-table :data="userPondList" border max-height="500px">
|
||||
<el-table-column label="塘口名称" align="center" prop="pondName" />
|
||||
<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="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.placeTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-if="userPondList.length === 0" class="text-center py-8 text-gray-500">
|
||||
该用户暂无塘口信息
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="pondDialog.visible = false">关 闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="AquUser" lang="ts">
|
||||
import { listAquUser, getAquUser, delAquUser, addAquUser, updateAquUser } from '@/api/fishery/aquUser';
|
||||
import { listPond } from '@/api/fishery/pond';
|
||||
import { AquUserVO, AquUserQuery, AquUserForm } from '@/api/fishery/aquUser/types';
|
||||
import { PondVO } from '@/api/fishery/pond/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@@ -163,6 +200,14 @@ const dialog = reactive<DialogOption>({
|
||||
title: ''
|
||||
});
|
||||
|
||||
// 塘口信息相关
|
||||
const pondDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const userPondList = ref<PondVO[]>([]);
|
||||
const currentUserId = ref<string | number>('');
|
||||
|
||||
const initFormData: AquUserForm = {
|
||||
id: undefined,
|
||||
userName: undefined,
|
||||
@@ -204,7 +249,7 @@ const data = reactive<PageData<AquUserForm, AquUserQuery>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询养殖用户列表 */
|
||||
/** 查询养殖账号列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listAquUser(queryParams.value);
|
||||
@@ -248,7 +293,7 @@ const handleSelectionChange = (selection: AquUserVO[]) => {
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加养殖用户';
|
||||
dialog.title = '添加养殖账号';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
@@ -258,7 +303,7 @@ const handleUpdate = async (row?: AquUserVO) => {
|
||||
const res = await getAquUser(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改养殖用户';
|
||||
dialog.title = '修改养殖账号';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
@@ -281,7 +326,7 @@ const submitForm = () => {
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: AquUserVO) => {
|
||||
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 delAquUser(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
@@ -298,6 +343,22 @@ const handleExport = () => {
|
||||
);
|
||||
};
|
||||
|
||||
/** 查看用户塘口信息 */
|
||||
const handleViewPonds = async (row: AquUserVO) => {
|
||||
currentUserId.value = row.id;
|
||||
pondDialog.title = `${row.userName} 的塘口信息`;
|
||||
|
||||
// 根据用户ID查询塘口列表
|
||||
const res = await listPond({
|
||||
pageNum: 1,
|
||||
pageSize: 1000,
|
||||
userId: row.id
|
||||
});
|
||||
|
||||
userPondList.value = res.rows || [];
|
||||
pondDialog.visible = true;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
1075
src/views/fishery/device/index.vue
Normal file
1075
src/views/fishery/device/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
459
src/views/fishery/deviceBindRecord/index.vue
Normal file
459
src/views/fishery/deviceBindRecord/index.vue
Normal file
@@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="90px">
|
||||
<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="deviceType">
|
||||
<el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable >
|
||||
<el-option v-for="dict in aqu_device_type" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="serialNum">
|
||||
<el-input v-model="queryParams.serialNum" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="绑定/解绑" prop="isBind">
|
||||
<el-select v-model="queryParams.isBind" placeholder="请选择绑定/解绑" clearable >
|
||||
<el-option v-for="dict in is_bind" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['fishery:deviceBindRecord:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['fishery:deviceBindRecord:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['fishery:deviceBindRecord:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['fishery:deviceBindRecord:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="deviceBindRecordList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="用户名" align="center" prop="userName"/>
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||
<el-table-column label="设备类型" align="center" prop="deviceType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="aqu_device_type" :value="scope.row.deviceType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设备编号" align="center" prop="serialNum" />
|
||||
|
||||
<el-table-column label="绑定/解绑" align="center" prop="isBind">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="is_bind" :value="scope.row.isBind"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作时间" align="center" prop="createTime" />
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:deviceBindRecord:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['fishery:deviceBindRecord:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<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="500px" append-to-body>
|
||||
<el-form ref="deviceBindRecordFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<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="deviceType">
|
||||
<el-select v-model="form.deviceType" placeholder="请选择设备类型" style="width: 100%">
|
||||
<el-option
|
||||
v-for="dict in aqu_device_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="serialNum">
|
||||
<el-input v-model="form.serialNum" placeholder="请输入设备编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="物联网IotId" prop="iotId">
|
||||
<el-input v-model="form.iotId" placeholder="请输入物联网IotId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="绑定/解绑" prop="isBind">
|
||||
<el-select v-model="form.isBind" placeholder="请选择绑定/解绑" style="width: 100%">
|
||||
<el-option
|
||||
v-for="dict in is_bind"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<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="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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="DeviceBindRecord" lang="ts">
|
||||
import { listDeviceBindRecord, getDeviceBindRecord, delDeviceBindRecord, addDeviceBindRecord, updateDeviceBindRecord } from '@/api/fishery/deviceBindRecord';
|
||||
import { DeviceBindRecordVO, DeviceBindRecordQuery, DeviceBindRecordForm } from '@/api/fishery/deviceBindRecord/types';
|
||||
import { listAquUser } from '@/api/fishery/aquUser';
|
||||
import { AquUserVO } from '@/api/fishery/aquUser/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { is_bind, aqu_device_type } = toRefs<any>(proxy?.useDict('is_bind', 'aqu_device_type'));
|
||||
|
||||
const deviceBindRecordList = ref<DeviceBindRecordVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
// 用户选择相关
|
||||
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 queryFormRef = ref<ElFormInstance>();
|
||||
const deviceBindRecordFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: DeviceBindRecordForm = {
|
||||
id: undefined,
|
||||
iotId: undefined,
|
||||
deviceType: undefined,
|
||||
serialNum: undefined,
|
||||
userId: undefined,
|
||||
isBind: undefined,
|
||||
}
|
||||
const data = reactive<PageData<DeviceBindRecordForm, DeviceBindRecordQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
iotId: undefined,
|
||||
deviceType: undefined,
|
||||
serialNum: undefined,
|
||||
userId: undefined,
|
||||
isBind: undefined,
|
||||
params: {
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: "主键id不能为空", trigger: "blur" }
|
||||
],
|
||||
iotId: [
|
||||
{ required: true, message: "物联网IotId不能为空", trigger: "blur" }
|
||||
],
|
||||
deviceType: [
|
||||
{ required: true, message: "设备类型不能为空", trigger: "change" }
|
||||
],
|
||||
serialNum: [
|
||||
{ required: true, message: "设备编号不能为空", trigger: "blur" }
|
||||
],
|
||||
userId: [
|
||||
{ required: true, message: "用户id不能为空", trigger: "blur" }
|
||||
],
|
||||
isBind: [
|
||||
{ required: true, message: "绑定/解绑不能为空", trigger: "change" }
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询设备绑定记录列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listDeviceBindRecord(queryParams.value);
|
||||
deviceBindRecordList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
selectedUser.value = null; // 清空用户选择
|
||||
deviceBindRecordFormRef.value?.resetFields();
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: DeviceBindRecordVO[]) => {
|
||||
ids.value = selection.map(item => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
selectedUser.value = null; // 清空用户选择
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加设备绑定记录";
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: DeviceBindRecordVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0]
|
||||
const res = await getDeviceBindRecord(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
|
||||
// 回显用户信息
|
||||
if (form.value.userId) {
|
||||
try {
|
||||
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 = "修改设备绑定记录";
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
deviceBindRecordFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateDeviceBindRecord(form.value).finally(() => buttonLoading.value = false);
|
||||
} else {
|
||||
await addDeviceBindRecord(form.value).finally(() => buttonLoading.value = false);
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: DeviceBindRecordVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除设备绑定记录编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
|
||||
await delDeviceBindRecord(_ids);
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
await getList();
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download('fishery/deviceBindRecord/export', {
|
||||
...queryParams.value
|
||||
}, `deviceBindRecord_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
|
||||
/** 获取用户列表 */
|
||||
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;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
@@ -35,9 +35,9 @@
|
||||
>删除</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:deviceThreshold:export']">导出</el-button>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -48,7 +48,8 @@
|
||||
<el-table-column label="阈值名称" align="center" prop="thresholdName" />
|
||||
<el-table-column label="最大值" align="center" prop="limitUpper" />
|
||||
<el-table-column label="最小值" align="center" prop="limitLower" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" />
|
||||
<el-table-column label="修改时间" align="center" prop="updateTime" />
|
||||
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
|
||||
153
src/views/fishery/deviceValidity/index.vue
Normal file
153
src/views/fishery/deviceValidity/index.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="90px">
|
||||
<el-form-item label="设备编号" prop="serialNum">
|
||||
<el-input v-model="queryParams.serialNum" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备类型" prop="deviceType">
|
||||
<el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable @change="handleQuery">
|
||||
<el-option
|
||||
v-for="dict in aqu_device_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</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="params.isExpired">
|
||||
<el-select v-model="queryParams.params.isExpired" placeholder="请选择是否过期" clearable @change="handleQuery">
|
||||
<el-option
|
||||
v-for="dict in is_expired"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="parseInt(dict.value)"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="deviceList">
|
||||
<el-table-column label="设备编号" align="center" prop="serialNum" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" />
|
||||
<el-table-column label="塘口名称" align="center" prop="pondName" />
|
||||
<el-table-column label="设备类型" align="center" prop="deviceType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="aqu_device_type" :value="scope.row.deviceType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户名" align="center" prop="userName" />
|
||||
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||
<el-table-column label="物联网卡号" align="center" prop="iccId" width="190"/>
|
||||
<el-table-column label="绑定时间" align="center" prop="bindTime">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.bindTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="到期时间" align="center" prop="deadTime">
|
||||
<template #default="scope">
|
||||
<span :style="{
|
||||
color: scope.row.expiredDays > 0 && scope.row.expiredDays < 60 ? 'red' :
|
||||
scope.row.expiredDays >= 60 ? '#E6A23C' : ''
|
||||
}">{{ parseTime(scope.row.deadTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="到期情况" align="center" prop="expiredDays">
|
||||
<template #default="scope">
|
||||
<span
|
||||
v-if="scope.row.expiredDays > 0"
|
||||
:style="{
|
||||
color: scope.row.expiredDays < 60 ? 'red' : '#E6A23C'
|
||||
}">已过期{{ scope.row.expiredDays }}天</span>
|
||||
<span v-else-if="scope.row.expiredDays < 0">剩余{{ Math.abs(scope.row.expiredDays) }}天</span>
|
||||
<span v-else>今天到期</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="DeviceValidity" lang="ts">
|
||||
import { listDevice } from '@/api/fishery/device';
|
||||
import { DeviceVO, DeviceQuery } from '@/api/fishery/device/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { aqu_device_type, is_expired } = toRefs<any>(proxy?.useDict('aqu_device_type', 'is_expired'));
|
||||
|
||||
const deviceList = ref<DeviceVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
|
||||
const data = reactive<PageData<{}, DeviceQuery>>({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
userId: undefined,
|
||||
serialNum: undefined,
|
||||
deviceName: undefined,
|
||||
deviceType: undefined,
|
||||
bindTime: undefined,
|
||||
pondId: undefined,
|
||||
iccId: undefined,
|
||||
category: undefined,
|
||||
params: {
|
||||
isExpired: 1,
|
||||
expiredFlag: 1
|
||||
}
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
/** 查询设备管理列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listDevice(queryParams.value);
|
||||
deviceList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
@@ -35,16 +35,16 @@
|
||||
>删除</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:fish: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="fishList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="主键Id" align="center" prop="id" v-if="true" />
|
||||
<!-- <el-table-column label="主键Id" align="center" prop="id" v-if="true" /> -->
|
||||
<el-table-column label="鱼类类型" align="center" prop="fishType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="fish_type" :value="scope.row.fishType" />
|
||||
|
||||
@@ -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