fix: 新增功能修改及完善。
@@ -1,5 +1,5 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 鱼测云后台管理系统
|
VITE_APP_TITLE = 水产养殖监测平台
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
VITE_APP_ENV = 'development'
|
VITE_APP_ENV = 'development'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "ruoyi-vue-plus",
|
"name": "ruoyi-vue-plus",
|
||||||
"version": "5.5.0-2.5.0",
|
"version": "5.5.0-2.5.0",
|
||||||
"description": "鱼测云后台管理系统",
|
"description": "水产养殖监测平台",
|
||||||
"author": "LionLi",
|
"author": "LionLi",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
BIN
public/favicon - 副本.ico
Normal file
|
After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 4.2 KiB |
63
src/api/fishery/device/index.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import { AxiosPromise } from 'axios';
|
||||||
|
import { DeviceVO, DeviceForm, DeviceQuery } from '@/api/fishery/device/types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备管理列表
|
||||||
|
* @param query
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const listDevice = (query?: DeviceQuery): AxiosPromise<DeviceVO[]> => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/device/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备管理详细
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getDevice = (id: string | number): AxiosPromise<DeviceVO> => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/device/' + id,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增设备管理
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addDevice = (data: DeviceForm) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/device',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改设备管理
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateDevice = (data: DeviceForm) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/device',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除设备管理
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const delDevice = (id: string | number | Array<string | number>) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/device/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
});
|
||||||
|
};
|
||||||
483
src/api/fishery/device/types.ts
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
export interface DeviceVO {
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
id: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网IotId
|
||||||
|
*/
|
||||||
|
iotId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备名称
|
||||||
|
*/
|
||||||
|
deviceName: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定时间
|
||||||
|
*/
|
||||||
|
bindTime: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务到期
|
||||||
|
*/
|
||||||
|
deadTime: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 塘口id
|
||||||
|
*/
|
||||||
|
pondId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧参数配置开关
|
||||||
|
*/
|
||||||
|
isOxygenUsed: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧
|
||||||
|
*/
|
||||||
|
valueDissolvedOxygen: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已触发溶解氧报警
|
||||||
|
*/
|
||||||
|
isOxygenWarnExist: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水温
|
||||||
|
*/
|
||||||
|
valueTemperature: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已触发温度报警
|
||||||
|
*/
|
||||||
|
isTempWarnExist: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 饱和度
|
||||||
|
*/
|
||||||
|
valueSaturability: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PH
|
||||||
|
*/
|
||||||
|
valuePh: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐度
|
||||||
|
*/
|
||||||
|
valueSalinity: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧电话告警开关
|
||||||
|
*/
|
||||||
|
oxyWarnCallOpen: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低溶氧告警免打扰
|
||||||
|
*/
|
||||||
|
oxyWarnCallNoDis: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次溶解氧电话告警时间
|
||||||
|
*/
|
||||||
|
oxyWarnCallLastTime: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧电话告警下限
|
||||||
|
*/
|
||||||
|
oxyWarnLower: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警开关
|
||||||
|
*/
|
||||||
|
tempWarnCallOpen: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度告警免打扰
|
||||||
|
*/
|
||||||
|
tempWarnCallNoDis: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次温度电话告警时间
|
||||||
|
*/
|
||||||
|
tempWarnCallLastTime: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警上限
|
||||||
|
*/
|
||||||
|
tempWarnUpper: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警下限
|
||||||
|
*/
|
||||||
|
tempWarnLower: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置的盐度补偿
|
||||||
|
*/
|
||||||
|
salinityCompensation: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入额定电压
|
||||||
|
*/
|
||||||
|
inputVoltage: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备告警状态码
|
||||||
|
*/
|
||||||
|
warnCode: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网卡号
|
||||||
|
*/
|
||||||
|
iccId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相位差
|
||||||
|
*/
|
||||||
|
phaseDifference: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 荧光值
|
||||||
|
*/
|
||||||
|
tfluorescence: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参比值
|
||||||
|
*/
|
||||||
|
treference: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线性系数补偿
|
||||||
|
*/
|
||||||
|
phaseCompensation: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相位差补偿
|
||||||
|
*/
|
||||||
|
phasedifCompensation: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度补偿
|
||||||
|
*/
|
||||||
|
temperatureCompensation: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电压告警开关
|
||||||
|
*/
|
||||||
|
voltageWarnOpen: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
remark: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备分类
|
||||||
|
*/
|
||||||
|
category: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量电话告警开关
|
||||||
|
*/
|
||||||
|
batteryWarnCallOpen: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量告警免打扰
|
||||||
|
*/
|
||||||
|
batteryWarnCallNoDis: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次电量电话告警时间
|
||||||
|
*/
|
||||||
|
batteryWarnCallLastTime: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量电话告警下限
|
||||||
|
*/
|
||||||
|
batteryWarnLower: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceForm extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
id?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网IotId
|
||||||
|
*/
|
||||||
|
iotId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备名称
|
||||||
|
*/
|
||||||
|
deviceName?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定时间
|
||||||
|
*/
|
||||||
|
bindTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务到期
|
||||||
|
*/
|
||||||
|
deadTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 塘口id
|
||||||
|
*/
|
||||||
|
pondId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧参数配置开关
|
||||||
|
*/
|
||||||
|
isOxygenUsed?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧
|
||||||
|
*/
|
||||||
|
valueDissolvedOxygen?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已触发溶解氧报警
|
||||||
|
*/
|
||||||
|
isOxygenWarnExist?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水温
|
||||||
|
*/
|
||||||
|
valueTemperature?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已触发温度报警
|
||||||
|
*/
|
||||||
|
isTempWarnExist?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 饱和度
|
||||||
|
*/
|
||||||
|
valueSaturability?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PH
|
||||||
|
*/
|
||||||
|
valuePh?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐度
|
||||||
|
*/
|
||||||
|
valueSalinity?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧电话告警开关
|
||||||
|
*/
|
||||||
|
oxyWarnCallOpen?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低溶氧告警免打扰
|
||||||
|
*/
|
||||||
|
oxyWarnCallNoDis?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次溶解氧电话告警时间
|
||||||
|
*/
|
||||||
|
oxyWarnCallLastTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 溶解氧电话告警下限
|
||||||
|
*/
|
||||||
|
oxyWarnLower?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警开关
|
||||||
|
*/
|
||||||
|
tempWarnCallOpen?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度告警免打扰
|
||||||
|
*/
|
||||||
|
tempWarnCallNoDis?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次温度电话告警时间
|
||||||
|
*/
|
||||||
|
tempWarnCallLastTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警上限
|
||||||
|
*/
|
||||||
|
tempWarnUpper?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度电话告警下限
|
||||||
|
*/
|
||||||
|
tempWarnLower?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置的盐度补偿
|
||||||
|
*/
|
||||||
|
salinityCompensation?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入额定电压
|
||||||
|
*/
|
||||||
|
inputVoltage?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备告警状态码
|
||||||
|
*/
|
||||||
|
warnCode?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网卡号
|
||||||
|
*/
|
||||||
|
iccId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相位差
|
||||||
|
*/
|
||||||
|
phaseDifference?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 荧光值
|
||||||
|
*/
|
||||||
|
tfluorescence?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参比值
|
||||||
|
*/
|
||||||
|
treference?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线性系数补偿
|
||||||
|
*/
|
||||||
|
phaseCompensation?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相位差补偿
|
||||||
|
*/
|
||||||
|
phasedifCompensation?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 温度补偿
|
||||||
|
*/
|
||||||
|
temperatureCompensation?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电压告警开关
|
||||||
|
*/
|
||||||
|
voltageWarnOpen?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
remark?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备分类
|
||||||
|
*/
|
||||||
|
category?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量电话告警开关
|
||||||
|
*/
|
||||||
|
batteryWarnCallOpen?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量告警免打扰
|
||||||
|
*/
|
||||||
|
batteryWarnCallNoDis?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次电量电话告警时间
|
||||||
|
*/
|
||||||
|
batteryWarnCallLastTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电量电话告警下限
|
||||||
|
*/
|
||||||
|
batteryWarnLower?: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceQuery extends PageQuery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备名称
|
||||||
|
*/
|
||||||
|
deviceName?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定时间
|
||||||
|
*/
|
||||||
|
bindTime?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 塘口id
|
||||||
|
*/
|
||||||
|
pondId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网卡号
|
||||||
|
*/
|
||||||
|
iccId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备分类
|
||||||
|
*/
|
||||||
|
category?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围参数
|
||||||
|
*/
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
63
src/api/fishery/deviceBindRecord/index.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import { AxiosPromise } from 'axios';
|
||||||
|
import { DeviceBindRecordVO, DeviceBindRecordForm, DeviceBindRecordQuery } from '@/api/fishery/deviceBindRecord/types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备绑定记录列表
|
||||||
|
* @param query
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const listDeviceBindRecord = (query?: DeviceBindRecordQuery): AxiosPromise<DeviceBindRecordVO[]> => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/deviceBindRecord/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备绑定记录详细
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const getDeviceBindRecord = (id: string | number): AxiosPromise<DeviceBindRecordVO> => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/deviceBindRecord/' + id,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增设备绑定记录
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const addDeviceBindRecord = (data: DeviceBindRecordForm) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/deviceBindRecord',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改设备绑定记录
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export const updateDeviceBindRecord = (data: DeviceBindRecordForm) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/deviceBindRecord',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除设备绑定记录
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const delDeviceBindRecord = (id: string | number | Array<string | number>) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishery/deviceBindRecord/' + id,
|
||||||
|
method: 'delete'
|
||||||
|
});
|
||||||
|
};
|
||||||
98
src/api/fishery/deviceBindRecord/types.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
export interface DeviceBindRecordVO {
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
id: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网IotId
|
||||||
|
*/
|
||||||
|
iotId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定/解绑
|
||||||
|
*/
|
||||||
|
isBind: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceBindRecordForm extends BaseEntity {
|
||||||
|
/**
|
||||||
|
* 主键id
|
||||||
|
*/
|
||||||
|
id?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网IotId
|
||||||
|
*/
|
||||||
|
iotId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定/解绑
|
||||||
|
*/
|
||||||
|
isBind?: number;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceBindRecordQuery extends PageQuery {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物联网IotId
|
||||||
|
*/
|
||||||
|
iotId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型
|
||||||
|
*/
|
||||||
|
deviceType?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号
|
||||||
|
*/
|
||||||
|
serialNum?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
userId?: string | number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定/解绑
|
||||||
|
*/
|
||||||
|
isBind?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围参数
|
||||||
|
*/
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 200 KiB |
BIN
src/assets/images/3.jpg
Normal file
|
After Width: | Height: | Size: 423 KiB |
BIN
src/assets/images/login-background - 副本.jpg
Normal file
|
After Width: | Height: | Size: 376 KiB |
|
Before Width: | Height: | Size: 423 KiB After Width: | Height: | Size: 358 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 149 KiB |
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
<div class="right-menu flex align-center">
|
<div class="right-menu flex align-center">
|
||||||
<template v-if="appStore.device !== 'mobile'">
|
<template v-if="appStore.device !== 'mobile'">
|
||||||
<!-- <el-select
|
<el-select
|
||||||
v-if="userId === 1 && tenantEnabled"
|
v-if="userId === 1 && tenantEnabled"
|
||||||
v-model="companyName"
|
v-model="companyName"
|
||||||
class="min-w-244px"
|
class="min-w-305px"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
reserve-keyword
|
reserve-keyword
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
>
|
>
|
||||||
<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
|
<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
|
||||||
<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
|
<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
|
||||||
</el-select> -->
|
</el-select>
|
||||||
|
|
||||||
<!-- <search-menu ref="searchMenuRef" />
|
<!-- <search-menu ref="searchMenuRef" />
|
||||||
<el-tooltip content="搜索" effect="dark" placement="bottom">
|
<el-tooltip content="搜索" effect="dark" placement="bottom">
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const title = ref('鱼测云后台管理系统');
|
const title = ref('水产养殖监测平台');
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const sideTheme = computed(() => settingsStore.sideTheme);
|
const sideTheme = computed(() => settingsStore.sideTheme);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-empty v-else :description="'消息为空'"></el-empty>
|
<el-empty v-else :description="'消息为空'"></el-empty>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="newsList.length > 0" class="foot-box" @click="onGoToGiteeClick">前往gitee</div>
|
<!-- <div v-if="newsList.length > 0" class="foot-box" @click="onGoToGiteeClick">前往gitee</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
6
src/types/components.d.ts
vendored
@@ -13,20 +13,16 @@ declare module 'vue' {
|
|||||||
Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default']
|
Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default']
|
||||||
DictTag: typeof import('./../components/DictTag/index.vue')['default']
|
DictTag: typeof import('./../components/DictTag/index.vue')['default']
|
||||||
Editor: typeof import('./../components/Editor/index.vue')['default']
|
Editor: typeof import('./../components/Editor/index.vue')['default']
|
||||||
ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
|
|
||||||
ElBadge: typeof import('element-plus/es')['ElBadge']
|
ElBadge: typeof import('element-plus/es')['ElBadge']
|
||||||
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
||||||
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
|
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
ElCard: typeof import('element-plus/es')['ElCard']
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
|
||||||
ElCol: typeof import('element-plus/es')['ElCol']
|
ElCol: typeof import('element-plus/es')['ElCol']
|
||||||
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
||||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||||
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
|
||||||
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||||
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||||
@@ -37,7 +33,6 @@ declare module 'vue' {
|
|||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
ElImage: typeof import('element-plus/es')['ElImage']
|
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElLink: typeof import('element-plus/es')['ElLink']
|
ElLink: typeof import('element-plus/es')['ElLink']
|
||||||
@@ -58,7 +53,6 @@ declare module 'vue' {
|
|||||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||||
ElTag: typeof import('element-plus/es')['ElTag']
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
ElText: typeof import('element-plus/es')['ElText']
|
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
ElTree: typeof import('element-plus/es')['ElTree']
|
ElTree: typeof import('element-plus/es')['ElTree']
|
||||||
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
|
||||||
|
|||||||
@@ -47,9 +47,9 @@
|
|||||||
>删除</el-button
|
>删除</el-button
|
||||||
>
|
>
|
||||||
</el-col>
|
</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-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>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
@@ -64,8 +64,13 @@
|
|||||||
<el-table-column label="区县" align="center" prop="district" /> -->
|
<el-table-column label="区县" align="center" prop="district" /> -->
|
||||||
<el-table-column label="报警电话" align="center" prop="warnPhoneJson" />
|
<el-table-column label="报警电话" align="center" prop="warnPhoneJson" />
|
||||||
<el-table-column label="展示标题" align="center" prop="title" />
|
<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">
|
<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-tooltip content="修改" placement="top">
|
||||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:aquUser:edit']"></el-button>
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['fishery:aquUser:edit']"></el-button>
|
||||||
</el-tooltip>
|
</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" />
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 添加或修改养殖用户对话框 -->
|
<!-- 添加或修改养殖账号对话框 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="850px" append-to-body>
|
<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 ref="aquUserFormRef" :model="form" :rules="rules" :inline="true" label-width="120px">
|
||||||
<el-form-item label="用户名" prop="userName">
|
<el-form-item label="用户名" prop="userName">
|
||||||
@@ -137,12 +142,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="AquUser" lang="ts">
|
<script setup name="AquUser" lang="ts">
|
||||||
import { listAquUser, getAquUser, delAquUser, addAquUser, updateAquUser } from '@/api/fishery/aquUser';
|
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 { AquUserVO, AquUserQuery, AquUserForm } from '@/api/fishery/aquUser/types';
|
||||||
|
import { PondVO } from '@/api/fishery/pond/types';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
@@ -163,6 +200,14 @@ const dialog = reactive<DialogOption>({
|
|||||||
title: ''
|
title: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 塘口信息相关
|
||||||
|
const pondDialog = reactive<DialogOption>({
|
||||||
|
visible: false,
|
||||||
|
title: ''
|
||||||
|
});
|
||||||
|
const userPondList = ref<PondVO[]>([]);
|
||||||
|
const currentUserId = ref<string | number>('');
|
||||||
|
|
||||||
const initFormData: AquUserForm = {
|
const initFormData: AquUserForm = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
userName: undefined,
|
userName: undefined,
|
||||||
@@ -204,7 +249,7 @@ const data = reactive<PageData<AquUserForm, AquUserQuery>>({
|
|||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data);
|
||||||
|
|
||||||
/** 查询养殖用户列表 */
|
/** 查询养殖账号列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await listAquUser(queryParams.value);
|
const res = await listAquUser(queryParams.value);
|
||||||
@@ -248,7 +293,7 @@ const handleSelectionChange = (selection: AquUserVO[]) => {
|
|||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
reset();
|
reset();
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '添加养殖用户';
|
dialog.title = '添加养殖账号';
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
@@ -258,7 +303,7 @@ const handleUpdate = async (row?: AquUserVO) => {
|
|||||||
const res = await getAquUser(_id);
|
const res = await getAquUser(_id);
|
||||||
Object.assign(form.value, res.data);
|
Object.assign(form.value, res.data);
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '修改养殖用户';
|
dialog.title = '修改养殖账号';
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
@@ -281,7 +326,7 @@ const submitForm = () => {
|
|||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (row?: AquUserVO) => {
|
const handleDelete = async (row?: AquUserVO) => {
|
||||||
const _ids = row?.id || ids.value;
|
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);
|
await delAquUser(_ids);
|
||||||
proxy?.$modal.msgSuccess('删除成功');
|
proxy?.$modal.msgSuccess('删除成功');
|
||||||
await getList();
|
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(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
|
|||||||
1075
src/views/fishery/device/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-button
|
||||||
>
|
>
|
||||||
</el-col>
|
</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-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>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,7 +48,8 @@
|
|||||||
<el-table-column label="阈值名称" align="center" prop="thresholdName" />
|
<el-table-column label="阈值名称" align="center" prop="thresholdName" />
|
||||||
<el-table-column label="最大值" align="center" prop="limitUpper" />
|
<el-table-column label="最大值" align="center" prop="limitUpper" />
|
||||||
<el-table-column label="最小值" align="center" prop="limitLower" />
|
<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">
|
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip content="修改" placement="top">
|
<el-tooltip content="修改" placement="top">
|
||||||
|
|||||||
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-button
|
||||||
>
|
>
|
||||||
</el-col>
|
</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-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>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" border :data="fishList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" border :data="fishList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<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">
|
<el-table-column label="鱼类类型" align="center" prop="fishType">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="fish_type" :value="scope.row.fishType" />
|
<dict-tag :options="fish_type" :value="scope.row.fishType" />
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
<div v-show="showSearch" class="mb-[10px]">
|
<div v-show="showSearch" class="mb-[10px]">
|
||||||
<el-card shadow="hover">
|
<el-card shadow="hover">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<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-form-item label="塘口名称" prop="pondName">
|
||||||
<el-input v-model="queryParams.pondName" placeholder="请输入塘口名称" clearable @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.pondName" placeholder="请输入塘口名称" clearable @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</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-form-item label="投苗日期" prop="time">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.time"
|
v-model="queryParams.time"
|
||||||
@@ -45,26 +45,34 @@
|
|||||||
>删除</el-button
|
>删除</el-button
|
||||||
>
|
>
|
||||||
</el-col>
|
</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-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>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" border :data="pondList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" border :data="pondList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<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="pondName" />
|
||||||
<el-table-column label="鱼品种列表" align="center" prop="fishKindIds" />
|
<el-table-column label="用户名" align="center" prop="userName" />
|
||||||
<el-table-column label="面积" align="center" prop="area" />
|
<el-table-column label="手机号" align="center" prop="mobilePhone" />
|
||||||
<el-table-column label="密度" align="center" prop="density" />
|
<el-table-column label="鱼品种列表" align="center" prop="fishKindNames" />
|
||||||
<el-table-column label="投苗日期" align="center" prop="placeTime" width="180">
|
<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">
|
<template #default="scope">
|
||||||
<span>{{ parseTime(scope.row.placeTime, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.placeTime, '{y}-{m}-{d}') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</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">
|
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip content="修改" placement="top">
|
<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" />
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 添加或修改塘口管理对话框 -->
|
<!-- 添加或修改塘口对话框 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="550px" append-to-body>
|
<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 ref="pondFormRef" :model="form" :rules="rules" label-width="110px">
|
||||||
<el-form-item label="用户id" prop="userId">
|
<el-form-item label="用户" prop="userId">
|
||||||
<el-input v-model="form.userId" placeholder="请输入用户id" />
|
<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>
|
||||||
<el-form-item label="塘口名称" prop="pondName">
|
<el-form-item label="塘口名称" prop="pondName">
|
||||||
<el-input v-model="form.pondName" placeholder="请输入塘口名称" />
|
<el-input v-model="form.pondName" placeholder="请输入塘口名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="鱼品种列表" prop="fishKindIds">
|
<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>
|
||||||
<el-form-item label="面积" prop="area">
|
<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>
|
||||||
<el-form-item label="密度" prop="density">
|
<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>
|
||||||
<el-form-item label="投苗日期" prop="placeTime">
|
<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-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="夜间防止误关" prop="keepNightOpen">
|
<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>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||||
@@ -110,8 +184,198 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-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>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -120,12 +384,47 @@
|
|||||||
|
|
||||||
<script setup name="Pond" lang="ts">
|
<script setup name="Pond" lang="ts">
|
||||||
import { listPond, getPond, delPond, addPond, updatePond } from '@/api/fishery/pond';
|
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 { 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';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
const { fish_type,open_close } = toRefs<any>(proxy?.useDict('fish_type','open_close'));
|
||||||
|
|
||||||
const pondList = ref<PondVO[]>([]);
|
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 buttonLoading = ref(false);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true);
|
||||||
@@ -136,6 +435,7 @@ const total = ref(0);
|
|||||||
|
|
||||||
const queryFormRef = ref<ElFormInstance>();
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
const pondFormRef = ref<ElFormInstance>();
|
const pondFormRef = ref<ElFormInstance>();
|
||||||
|
const fishTableRef = ref<ElTableInstance>();
|
||||||
|
|
||||||
const dialog = reactive<DialogOption>({
|
const dialog = reactive<DialogOption>({
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -173,13 +473,263 @@ const data = reactive<PageData<PondForm, PondQuery>>({
|
|||||||
fishKindIds: [{ required: true, message: '鱼品种列表不能为空', trigger: 'blur' }],
|
fishKindIds: [{ required: true, message: '鱼品种列表不能为空', trigger: 'blur' }],
|
||||||
area: [{ required: true, message: '面积不能为空', trigger: 'blur' }],
|
area: [{ required: true, message: '面积不能为空', trigger: 'blur' }],
|
||||||
density: [{ 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 { 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 () => {
|
const getList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const timeRange = queryParams.value.time;
|
const timeRange = queryParams.value.time;
|
||||||
@@ -189,8 +739,8 @@ const getList = async () => {
|
|||||||
st = dayjs(timeRange[0]).format('YYYY-MM-DD');
|
st = dayjs(timeRange[0]).format('YYYY-MM-DD');
|
||||||
et = dayjs(timeRange[1]).format('YYYY-MM-DD');
|
et = dayjs(timeRange[1]).format('YYYY-MM-DD');
|
||||||
}
|
}
|
||||||
queryParams.value.startTime = st;
|
queryParams.value.params.startTime = st;
|
||||||
queryParams.value.endTime = et;
|
queryParams.value.params.endTime = et;
|
||||||
const res = await listPond(queryParams.value);
|
const res = await listPond(queryParams.value);
|
||||||
pondList.value = res.rows;
|
pondList.value = res.rows;
|
||||||
total.value = res.total;
|
total.value = res.total;
|
||||||
@@ -206,6 +756,8 @@ const cancel = () => {
|
|||||||
/** 表单重置 */
|
/** 表单重置 */
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
form.value = { ...initFormData };
|
form.value = { ...initFormData };
|
||||||
|
// 注释掉清空选择列表,保持弹窗独立性
|
||||||
|
// selectedFishList.value = [];
|
||||||
pondFormRef.value?.resetFields();
|
pondFormRef.value?.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,8 +783,10 @@ const handleSelectionChange = (selection: PondVO[]) => {
|
|||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
reset();
|
reset();
|
||||||
|
selectedFishList.value = []; // 新增时清空选择列表
|
||||||
|
selectedUser.value = null; // 清空用户选择
|
||||||
dialog.visible = true;
|
dialog.visible = true;
|
||||||
dialog.title = '添加塘口管理';
|
dialog.title = '添加塘口';
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
@@ -241,8 +795,41 @@ const handleUpdate = async (row?: PondVO) => {
|
|||||||
const _id = row?.id || ids.value[0];
|
const _id = row?.id || ids.value[0];
|
||||||
const res = await getPond(_id);
|
const res = await getPond(_id);
|
||||||
Object.assign(form.value, res.data);
|
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.visible = true;
|
||||||
dialog.title = '修改塘口管理';
|
dialog.title = '修改塘口';
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
@@ -265,7 +852,7 @@ const submitForm = () => {
|
|||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (row?: PondVO) => {
|
const handleDelete = async (row?: PondVO) => {
|
||||||
const _ids = row?.id || ids.value;
|
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);
|
await delPond(_ids);
|
||||||
proxy?.$modal.msgSuccess('删除成功');
|
proxy?.$modal.msgSuccess('删除成功');
|
||||||
await getList();
|
await getList();
|
||||||
@@ -286,3 +873,154 @@ onMounted(() => {
|
|||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
</script>
|
</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>
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<span
|
<span
|
||||||
>Copyright © 2025 青岛星途瑞传感技术有限公司.All rights reserved
|
>Copyright © 2025 .All rights reserved
|
||||||
<a href="https://beian.miit.gov.cn/" target="_blank">鲁ICP备2024081187号</a>
|
<a href="https://beian.miit.gov.cn/" target="_blank">鲁ICP备2024081187号</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||