refactor:【antd】【iot】将 DeviceSaveReqVO 和 DeviceRespVO 合并到 Device,简化设备 API 接口
This commit is contained in:
@@ -3,49 +3,14 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace IotDeviceApi {
|
export namespace IotDeviceApi {
|
||||||
/** 设备新增/修改 Request VO */
|
/** 设备 */
|
||||||
// TODO @haohao:可以降低一些 VO 哈:DeviceSaveReqVO、DeviceRespVO 合并成 Device 就好,类似别的模块
|
export interface Device {
|
||||||
export interface DeviceSaveReqVO {
|
|
||||||
id?: number; // 设备编号
|
id?: number; // 设备编号
|
||||||
deviceName: string; // 设备名称
|
deviceName: string; // 设备名称
|
||||||
nickname?: string; // 备注名称
|
nickname?: string; // 备注名称
|
||||||
serialNumber?: string; // 设备序列号
|
serialNumber?: string; // 设备序列号
|
||||||
picUrl?: string; // 设备图片
|
picUrl?: string; // 设备图片
|
||||||
groupIds?: number[]; // 设备分组编号数组
|
groupIds?: number[]; // 设备分组编号数组
|
||||||
productId: number; // 产品编号(必填)
|
|
||||||
gatewayId?: number; // 网关设备 ID
|
|
||||||
config?: string; // 设备配置
|
|
||||||
locationType: number; // 定位类型(必填)
|
|
||||||
latitude?: number; // 设备位置的纬度
|
|
||||||
longitude?: number; // 设备位置的经度
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 设备更新分组 Request VO */
|
|
||||||
export interface DeviceUpdateGroupReqVO {
|
|
||||||
ids: number[]; // 设备编号列表(必填)
|
|
||||||
groupIds: number[]; // 分组编号列表(必填)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 设备分页 Request VO */
|
|
||||||
// TODO @haohao:可以不用 DevicePageReqVO,直接 PageParam 即可,简洁一点。这里的强类型,收益不大;
|
|
||||||
export interface DevicePageReqVO extends PageParam {
|
|
||||||
deviceName?: string; // 设备名称
|
|
||||||
nickname?: string; // 备注名称
|
|
||||||
productId?: number; // 产品编号
|
|
||||||
deviceType?: number; // 设备类型
|
|
||||||
status?: number; // 设备状态
|
|
||||||
groupId?: number; // 设备分组编号
|
|
||||||
gatewayId?: number; // 网关设备 ID
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 设备 Response VO */
|
|
||||||
export interface DeviceRespVO {
|
|
||||||
id: number; // 设备编号
|
|
||||||
deviceName: string; // 设备名称
|
|
||||||
nickname?: string; // 设备备注名称
|
|
||||||
serialNumber?: string; // 设备序列号
|
|
||||||
picUrl?: string; // 设备图片
|
|
||||||
groupIds?: number[]; // 设备分组编号数组
|
|
||||||
productId: number; // 产品编号
|
productId: number; // 产品编号
|
||||||
productKey?: string; // 产品标识
|
productKey?: string; // 产品标识
|
||||||
deviceType?: number; // 设备类型
|
deviceType?: number; // 设备类型
|
||||||
@@ -57,12 +22,18 @@ export namespace IotDeviceApi {
|
|||||||
deviceSecret?: string; // 设备密钥,用于设备认证
|
deviceSecret?: string; // 设备密钥,用于设备认证
|
||||||
authType?: string; // 认证类型(如一机一密、动态注册)
|
authType?: string; // 认证类型(如一机一密、动态注册)
|
||||||
config?: string; // 设备配置
|
config?: string; // 设备配置
|
||||||
locationType?: number; // 定位方式
|
locationType?: number; // 定位类型
|
||||||
latitude?: number; // 设备位置的纬度
|
latitude?: number; // 设备位置的纬度
|
||||||
longitude?: number; // 设备位置的经度
|
longitude?: number; // 设备位置的经度
|
||||||
createTime?: Date; // 创建时间
|
createTime?: Date; // 创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 设备更新分组 Request VO */
|
||||||
|
export interface DeviceUpdateGroupReqVO {
|
||||||
|
ids: number[]; // 设备编号列表(必填)
|
||||||
|
groupIds: number[]; // 分组编号列表(必填)
|
||||||
|
}
|
||||||
|
|
||||||
/** 设备认证信息 Response VO */
|
/** 设备认证信息 Response VO */
|
||||||
export interface DeviceAuthInfoRespVO {
|
export interface DeviceAuthInfoRespVO {
|
||||||
clientId: string; // 客户端 ID
|
clientId: string; // 客户端 ID
|
||||||
@@ -104,8 +75,8 @@ export namespace IotDeviceApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 查询设备分页 */
|
/** 查询设备分页 */
|
||||||
export function getDevicePage(params: IotDeviceApi.DevicePageReqVO) {
|
export function getDevicePage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<IotDeviceApi.DeviceRespVO>>(
|
return requestClient.get<PageResult<IotDeviceApi.Device>>(
|
||||||
'/iot/device/page',
|
'/iot/device/page',
|
||||||
{ params },
|
{ params },
|
||||||
);
|
);
|
||||||
@@ -113,18 +84,16 @@ export function getDevicePage(params: IotDeviceApi.DevicePageReqVO) {
|
|||||||
|
|
||||||
/** 查询设备详情 */
|
/** 查询设备详情 */
|
||||||
export function getDevice(id: number) {
|
export function getDevice(id: number) {
|
||||||
return requestClient.get<IotDeviceApi.DeviceRespVO>(
|
return requestClient.get<IotDeviceApi.Device>(`/iot/device/get?id=${id}`);
|
||||||
`/iot/device/get?id=${id}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增设备 */
|
/** 新增设备 */
|
||||||
export function createDevice(data: IotDeviceApi.DeviceSaveReqVO) {
|
export function createDevice(data: IotDeviceApi.Device) {
|
||||||
return requestClient.post<number>('/iot/device/create', data);
|
return requestClient.post<number>('/iot/device/create', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改设备 */
|
/** 修改设备 */
|
||||||
export function updateDevice(data: IotDeviceApi.DeviceSaveReqVO) {
|
export function updateDevice(data: IotDeviceApi.Device) {
|
||||||
return requestClient.put<boolean>('/iot/device/update', data);
|
return requestClient.put<boolean>('/iot/device/update', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +115,7 @@ export function deleteDeviceList(ids: number[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 导出设备 */
|
/** 导出设备 */
|
||||||
export function exportDeviceExcel(params: IotDeviceApi.DevicePageReqVO) {
|
export function exportDeviceExcel(params: PageParam) {
|
||||||
return requestClient.download('/iot/device/export-excel', { params });
|
return requestClient.download('/iot/device/export-excel', { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,22 +126,16 @@ export function getDeviceCount(productId: number) {
|
|||||||
|
|
||||||
/** 获取设备的精简信息列表 */
|
/** 获取设备的精简信息列表 */
|
||||||
export function getSimpleDeviceList(deviceType?: number, productId?: number) {
|
export function getSimpleDeviceList(deviceType?: number, productId?: number) {
|
||||||
return requestClient.get<IotDeviceApi.DeviceRespVO[]>(
|
return requestClient.get<IotDeviceApi.Device[]>('/iot/device/simple-list', {
|
||||||
'/iot/device/simple-list',
|
params: { deviceType, productId },
|
||||||
{
|
});
|
||||||
params: { deviceType, productId },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 根据产品编号,获取设备的精简信息列表 */
|
/** 根据产品编号,获取设备的精简信息列表 */
|
||||||
export function getDeviceListByProductId(productId: number) {
|
export function getDeviceListByProductId(productId: number) {
|
||||||
return requestClient.get<IotDeviceApi.DeviceRespVO[]>(
|
return requestClient.get<IotDeviceApi.Device[]>('/iot/device/simple-list', {
|
||||||
'/iot/device/simple-list',
|
params: { productId },
|
||||||
{
|
});
|
||||||
params: { productId },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取导入模板 */
|
/** 获取导入模板 */
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const router = useRouter();
|
|||||||
const id = Number(route.params.id);
|
const id = Number(route.params.id);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const product = ref<IotProductApi.Product>({} as IotProductApi.Product);
|
const product = ref<IotProductApi.Product>({} as IotProductApi.Product);
|
||||||
const device = ref<IotDeviceApi.DeviceRespVO>({} as IotDeviceApi.DeviceRespVO);
|
const device = ref<IotDeviceApi.Device>({} as IotDeviceApi.Device);
|
||||||
const activeTab = ref('info');
|
const activeTab = ref('info');
|
||||||
const thingModelList = ref<ThingModelData[]>([]);
|
const thingModelList = ref<ThingModelData[]>([]);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { IotDeviceMessageMethodEnum } from '#/views/iot/utils/constants';
|
|||||||
defineOptions({ name: 'DeviceDetailConfig' });
|
defineOptions({ name: 'DeviceDetailConfig' });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
device: IotDeviceApi.DeviceRespVO;
|
device: IotDeviceApi.Device;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -114,7 +114,7 @@ async function updateDeviceConfig() {
|
|||||||
await updateDevice({
|
await updateDevice({
|
||||||
id: props.device.id,
|
id: props.device.id,
|
||||||
config: JSON.stringify(config.value),
|
config: JSON.stringify(config.value),
|
||||||
} as IotDeviceApi.DeviceSaveReqVO);
|
} as IotDeviceApi.Device);
|
||||||
message.success({ content: '更新成功!' });
|
message.success({ content: '更新成功!' });
|
||||||
// 触发 success 事件
|
// 触发 success 事件
|
||||||
emit('success');
|
emit('success');
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import DeviceForm from '../../modules/form.vue';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
product: IotProductApi.Product;
|
product: IotProductApi.Product;
|
||||||
device: IotDeviceApi.DeviceRespVO;
|
device: IotDeviceApi.Device;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ function goToProductDetail(productId: number | undefined) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 打开编辑表单 */
|
/** 打开编辑表单 */
|
||||||
function openEditForm(row: IotDeviceApi.DeviceRespVO) {
|
function openEditForm(row: IotDeviceApi.Device) {
|
||||||
formModalApi.setData(row).open();
|
formModalApi.setData(row).open();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { getDeviceAuthInfo } from '#/api/iot/device/device';
|
|||||||
import { DictTag } from '#/components/dict-tag';
|
import { DictTag } from '#/components/dict-tag';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
device: IotDeviceApi.DeviceRespVO;
|
device: IotDeviceApi.Device;
|
||||||
product: IotProductApi.Product;
|
product: IotProductApi.Product;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import DataDefinition from '../../../../thingmodel/modules/components/data-defin
|
|||||||
import DeviceDetailsMessage from './message.vue';
|
import DeviceDetailsMessage from './message.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
device: IotDeviceApi.DeviceRespVO;
|
device: IotDeviceApi.Device;
|
||||||
product: IotProductApi.Product;
|
product: IotProductApi.Product;
|
||||||
thingModelList: ThingModelData[];
|
thingModelList: ThingModelData[];
|
||||||
}>();
|
}>();
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { PageParam } from '@vben/request';
|
||||||
|
|
||||||
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { IotDeviceApi } from '#/api/iot/device/device';
|
import type { IotDeviceApi } from '#/api/iot/device/device';
|
||||||
import type { IotProductApi } from '#/api/iot/product/product';
|
import type { IotProductApi } from '#/api/iot/product/product';
|
||||||
|
|
||||||
import { onMounted, reactive, ref, watch } from 'vue';
|
import { onMounted, ref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
import { DeviceTypeEnum, DICT_TYPE } from '@vben/constants';
|
import { DeviceTypeEnum, DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
|
||||||
|
|
||||||
import { Button, Input, Select, Space } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { getDevicePage } from '#/api/iot/device/device';
|
import { getDevicePage } from '#/api/iot/device/device';
|
||||||
@@ -25,10 +25,6 @@ const props = defineProps<Props>();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const products = ref<IotProductApi.Product[]>([]); // 产品列表
|
const products = ref<IotProductApi.Product[]>([]); // 产品列表
|
||||||
const queryParams = reactive({
|
|
||||||
deviceName: '',
|
|
||||||
status: undefined as number | undefined,
|
|
||||||
}); // 查询参数
|
|
||||||
|
|
||||||
function useGridColumns(): VxeTableGridOptions['columns'] {
|
function useGridColumns(): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
@@ -72,7 +68,35 @@ function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
/** 搜索表单 schema */
|
||||||
|
function useGridFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'deviceName',
|
||||||
|
label: 'DeviceName',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入 DeviceName',
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'status',
|
||||||
|
label: '设备状态',
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: getDictOptions(DICT_TYPE.IOT_DEVICE_STATE, 'number'),
|
||||||
|
placeholder: '请选择设备状态',
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.Device>({
|
||||||
|
formOptions: {
|
||||||
|
schema: useGridFormSchema(),
|
||||||
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useGridColumns(),
|
columns: useGridColumns(),
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@@ -82,11 +106,14 @@ const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
|||||||
},
|
},
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({
|
query: async (
|
||||||
page,
|
{
|
||||||
}: {
|
page,
|
||||||
page: { currentPage: number; pageSize: number };
|
}: {
|
||||||
}) => {
|
page: { currentPage: number; pageSize: number };
|
||||||
|
},
|
||||||
|
formValues?: { deviceName?: string; status?: number },
|
||||||
|
) => {
|
||||||
if (!props.deviceId) {
|
if (!props.deviceId) {
|
||||||
return { list: [], total: 0 };
|
return { list: [], total: 0 };
|
||||||
}
|
}
|
||||||
@@ -95,15 +122,15 @@ const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
|||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
gatewayId: props.deviceId,
|
gatewayId: props.deviceId,
|
||||||
deviceType: DeviceTypeEnum.GATEWAY_SUB,
|
deviceType: DeviceTypeEnum.GATEWAY_SUB,
|
||||||
deviceName: queryParams.deviceName || undefined,
|
deviceName: formValues?.deviceName || undefined,
|
||||||
status: queryParams.status,
|
status: formValues?.status,
|
||||||
} as IotDeviceApi.DevicePageReqVO);
|
} as PageParam);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
refresh: true,
|
refresh: true,
|
||||||
search: false,
|
search: true,
|
||||||
},
|
},
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@@ -111,18 +138,6 @@ const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 搜索操作 */
|
|
||||||
function handleQuery() {
|
|
||||||
gridApi.query();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 重置搜索 */
|
|
||||||
function resetQuery() {
|
|
||||||
queryParams.deviceName = '';
|
|
||||||
queryParams.status = undefined;
|
|
||||||
handleQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取产品名称 */
|
/** 获取产品名称 */
|
||||||
function getProductName(productId: number) {
|
function getProductName(productId: number) {
|
||||||
const product = products.value.find((p) => p.id === productId);
|
const product = products.value.find((p) => p.id === productId);
|
||||||
@@ -139,7 +154,7 @@ watch(
|
|||||||
() => props.deviceId,
|
() => props.deviceId,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
handleQuery();
|
gridApi.query();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -151,49 +166,13 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 如果设备ID存在,则查询列表
|
// 如果设备ID存在,则查询列表
|
||||||
if (props.deviceId) {
|
if (props.deviceId) {
|
||||||
handleQuery();
|
gridApi.query();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<!-- 搜索区域 -->
|
|
||||||
<!-- TODO @haohao:这个 search 能不能融合到 Grid 里; -->
|
|
||||||
<div class="mb-4 flex flex-wrap items-center gap-3">
|
|
||||||
<Input
|
|
||||||
v-model:value="queryParams.deviceName"
|
|
||||||
placeholder="请输入设备名称"
|
|
||||||
style="width: 200px"
|
|
||||||
allow-clear
|
|
||||||
@press-enter="handleQuery"
|
|
||||||
/>
|
|
||||||
<Select
|
|
||||||
v-model:value="queryParams.status"
|
|
||||||
allow-clear
|
|
||||||
placeholder="请选择设备状态"
|
|
||||||
style="width: 160px"
|
|
||||||
>
|
|
||||||
<Select.Option
|
|
||||||
v-for="dict in getDictOptions(DICT_TYPE.IOT_DEVICE_STATE, 'number')"
|
|
||||||
:key="dict.value"
|
|
||||||
:value="dict.value"
|
|
||||||
>
|
|
||||||
{{ dict.label }}
|
|
||||||
</Select.Option>
|
|
||||||
</Select>
|
|
||||||
<Space>
|
|
||||||
<Button type="primary" @click="handleQuery">
|
|
||||||
<IconifyIcon icon="ep:search" class="mr-5px" />
|
|
||||||
搜索
|
|
||||||
</Button>
|
|
||||||
<Button @click="resetQuery">
|
|
||||||
<IconifyIcon icon="ep:refresh-right" class="mr-5px" />
|
|
||||||
重置
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 子设备列表 -->
|
<!-- 子设备列表 -->
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #product="{ row }">
|
<template #product="{ row }">
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { PageParam } from '@vben/request';
|
||||||
|
|
||||||
import type { IotDeviceApi } from '#/api/iot/device/device';
|
import type { IotDeviceApi } from '#/api/iot/device/device';
|
||||||
import type { IotDeviceGroupApi } from '#/api/iot/device/group';
|
import type { IotDeviceGroupApi } from '#/api/iot/device/group';
|
||||||
import type { IotProductApi } from '#/api/iot/product/product';
|
import type { IotProductApi } from '#/api/iot/product/product';
|
||||||
@@ -68,7 +70,7 @@ const [DeviceImportFormModal, deviceImportFormModalApi] = useVbenModal({
|
|||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryParams = ref<Partial<IotDeviceApi.DevicePageReqVO>>({
|
const queryParams = ref<Partial<PageParam>>({
|
||||||
deviceName: '',
|
deviceName: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
productId: undefined,
|
productId: undefined,
|
||||||
@@ -118,7 +120,7 @@ async function handleExport() {
|
|||||||
...queryParams.value,
|
...queryParams.value,
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 999_999,
|
pageSize: 999_999,
|
||||||
} as IotDeviceApi.DevicePageReqVO);
|
} as PageParam);
|
||||||
downloadFileFromBlobPart({ fileName: '物联网设备.xls', source: data });
|
downloadFileFromBlobPart({ fileName: '物联网设备.xls', source: data });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,12 +149,12 @@ function handleCreate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 编辑设备 */
|
/** 编辑设备 */
|
||||||
function handleEdit(row: IotDeviceApi.DeviceRespVO) {
|
function handleEdit(row: IotDeviceApi.Device) {
|
||||||
deviceFormModalApi.setData(row).open();
|
deviceFormModalApi.setData(row).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除设备 */
|
/** 删除设备 */
|
||||||
async function handleDelete(row: IotDeviceApi.DeviceRespVO) {
|
async function handleDelete(row: IotDeviceApi.Device) {
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
content: $t('ui.actionMessage.deleting', [row.deviceName]),
|
content: $t('ui.actionMessage.deleting', [row.deviceName]),
|
||||||
duration: 0,
|
duration: 0,
|
||||||
@@ -203,12 +205,12 @@ function handleImport() {
|
|||||||
function handleRowCheckboxChange({
|
function handleRowCheckboxChange({
|
||||||
records,
|
records,
|
||||||
}: {
|
}: {
|
||||||
records: IotDeviceApi.DeviceRespVO[];
|
records: IotDeviceApi.Device[];
|
||||||
}) {
|
}) {
|
||||||
checkedIds.value = records.map((item) => item.id!);
|
checkedIds.value = records.map((item) => item.id!);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.Device>({
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
checkboxConfig: {
|
checkboxConfig: {
|
||||||
highlight: true,
|
highlight: true,
|
||||||
@@ -228,7 +230,7 @@ const [Grid, gridApi] = useVbenVxeGrid<IotDeviceApi.DeviceRespVO>({
|
|||||||
pageNo: page.currentPage,
|
pageNo: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
...queryParams.value,
|
...queryParams.value,
|
||||||
} as IotDeviceApi.DevicePageReqVO);
|
} as PageParam);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { PageParam } from '@vben/request';
|
||||||
|
|
||||||
import type { IotDeviceApi } from '#/api/iot/device/device';
|
import type { IotDeviceApi } from '#/api/iot/device/device';
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
@@ -46,9 +48,9 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const list = ref<IotDeviceApi.DeviceRespVO[]>([]);
|
const list = ref<IotDeviceApi.Device[]>([]);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const queryParams = ref<Partial<IotDeviceApi.DevicePageReqVO>>({
|
const queryParams = ref<Partial<PageParam>>({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
});
|
});
|
||||||
@@ -66,7 +68,7 @@ async function getList() {
|
|||||||
const data = await getDevicePage({
|
const data = await getDevicePage({
|
||||||
...queryParams.value,
|
...queryParams.value,
|
||||||
...props.searchParams,
|
...props.searchParams,
|
||||||
} as IotDeviceApi.DevicePageReqVO);
|
} as PageParam);
|
||||||
list.value = data.list || [];
|
list.value = data.list || [];
|
||||||
total.value = data.total || 0;
|
total.value = data.total || 0;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -192,7 +194,7 @@ onMounted(() => {
|
|||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
class="action-btn action-btn-detail"
|
class="action-btn action-btn-detail"
|
||||||
@click="emit('detail', item.id)"
|
@click="emit('detail', item.id!)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="lucide:eye" class="mr-1" />
|
<IconifyIcon icon="lucide:eye" class="mr-1" />
|
||||||
详情
|
详情
|
||||||
@@ -200,7 +202,7 @@ onMounted(() => {
|
|||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
class="action-btn action-btn-data"
|
class="action-btn action-btn-data"
|
||||||
@click="emit('model', item.id)"
|
@click="emit('model', item.id!)"
|
||||||
>
|
>
|
||||||
<IconifyIcon icon="lucide:database" class="mr-1" />
|
<IconifyIcon icon="lucide:database" class="mr-1" />
|
||||||
数据
|
数据
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { IotDeviceApi } from '#/api/iot/device/device';
|
import type { IotDeviceApi } from '#/api/iot/device/device';
|
||||||
import type { IotProductApi } from '#/api/iot/product/product';
|
import type { IotProductApi } from '#/api/iot/product/product';
|
||||||
|
|
||||||
import { computed, nextTick, onMounted, ref } from 'vue';
|
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import { useAdvancedFormSchema, useBasicFormSchema } from '../data';
|
|||||||
defineOptions({ name: 'IoTDeviceForm' });
|
defineOptions({ name: 'IoTDeviceForm' });
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formData = ref<IotDeviceApi.DeviceRespVO>();
|
const formData = ref<IotDeviceApi.Device>();
|
||||||
const products = ref<IotProductApi.Product[]>([]);
|
const products = ref<IotProductApi.Product[]>([]);
|
||||||
const activeKey = ref<string[]>([]);
|
const activeKey = ref<string[]>([]);
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
const data = {
|
const data = {
|
||||||
...basicValues,
|
...basicValues,
|
||||||
...advancedValues,
|
...advancedValues,
|
||||||
} as IotDeviceApi.DeviceSaveReqVO;
|
} as IotDeviceApi.Device;
|
||||||
try {
|
try {
|
||||||
await (formData.value?.id ? updateDevice(data) : createDevice(data));
|
await (formData.value?.id ? updateDevice(data) : createDevice(data));
|
||||||
// 关闭并提示
|
// 关闭并提示
|
||||||
@@ -115,11 +115,8 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const data = modalApi.getData<IotDeviceApi.DeviceRespVO>();
|
const data = modalApi.getData<IotDeviceApi.Device>();
|
||||||
if (!data || !data.id) {
|
if (!data || !data.id) {
|
||||||
// 新增:确保 Collapse 折叠
|
|
||||||
// TODO @haohao:是不是 activeKey 在上面的 112 到 115 就已经处理了哈;
|
|
||||||
activeKey.value = [];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 编辑模式:加载数据
|
// 编辑模式:加载数据
|
||||||
@@ -127,29 +124,29 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
try {
|
try {
|
||||||
formData.value = await getDevice(data.id);
|
formData.value = await getDevice(data.id);
|
||||||
await formApi.setValues(formData.value);
|
await formApi.setValues(formData.value);
|
||||||
// 如果存在高级字段数据,自动展开 Collapse
|
|
||||||
// TODO @haohao:默认不用展开哈;
|
|
||||||
if (
|
|
||||||
formData.value?.nickname ||
|
|
||||||
formData.value?.picUrl ||
|
|
||||||
formData.value?.groupIds?.length ||
|
|
||||||
formData.value?.serialNumber ||
|
|
||||||
formData.value?.locationType !== undefined
|
|
||||||
) {
|
|
||||||
activeKey.value = ['advanced'];
|
|
||||||
// 等待 Collapse 展开后表单挂载
|
|
||||||
await nextTick();
|
|
||||||
await nextTick();
|
|
||||||
if (advancedFormApi.isMounted) {
|
|
||||||
await advancedFormApi.setValues(formData.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 监听 Collapse 展开,自动设置高级表单的值 */
|
||||||
|
watch(
|
||||||
|
activeKey,
|
||||||
|
async (newKeys) => {
|
||||||
|
// 当用户手动展开 Collapse 且存在表单数据时,设置高级表单的值
|
||||||
|
if (newKeys.includes('advanced') && formData.value) {
|
||||||
|
// 等待表单挂载
|
||||||
|
await nextTick();
|
||||||
|
await nextTick();
|
||||||
|
if (advancedFormApi.isMounted) {
|
||||||
|
await advancedFormApi.setValues(formData.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: false },
|
||||||
|
);
|
||||||
|
|
||||||
/** 初始化产品列表 */
|
/** 初始化产品列表 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
products.value = await getSimpleProductList();
|
products.value = await getSimpleProductList();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { DeviceRespVO, IotDeviceApi } from '#/api/iot/device/device';
|
import type { IotDeviceApi } from '#/api/iot/device/device';
|
||||||
import type { OtaTask } from '#/api/iot/ota/task';
|
import type { OtaTask } from '#/api/iot/ota/task';
|
||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
@@ -57,7 +57,7 @@ const formRules = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const devices = ref<IotDeviceApi.DeviceRespVO[]>([]);
|
const devices = ref<IotDeviceApi.Device[]>([]);
|
||||||
|
|
||||||
/** 设备选项 */
|
/** 设备选项 */
|
||||||
const deviceOptions = computed(() => {
|
const deviceOptions = computed(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user