feat(iot): 优化设备管理功能

- 添加设备状态切换功能
- 优化设备状态展示样式
- 实现设备在线状态切换
- 重构产品编辑组件,优化图片上传逻辑
This commit is contained in:
Kven 2025-03-19 22:16:05 +08:00
parent bdd99287cf
commit eed0d9c99a
3 changed files with 104 additions and 53 deletions

View File

@ -72,6 +72,11 @@ export function queryProductByName(data: any) {
}); });
} }
// 设备状态
export function toggleDeviceStatus(id: number) {
return axios.patch(`/api/rest/device/toggle/${id}`)
}
// 新增 // 新增
export function createDevice(data: DeviceCreateRecord) { export function createDevice(data: DeviceCreateRecord) {
return axios.post(`/api/rest/device`, data); return axios.post(`/api/rest/device`, data);

View File

@ -171,11 +171,18 @@
<span>{{ record.id }}</span> <span>{{ record.id }}</span>
</template> </template>
<template #state="{ record }"> <template #state="{ record }">
{{ record.state == "UNACTIVATED" ? '未激活' : '激活'}} <a-tag v-if="record.state == 'UNACTIVATED'" color="red">未激活</a-tag>
<a-tag v-else-if="record.state == 'ACTIVATED'" color="green">激活</a-tag>
<a-tag v-else-if="record.state == 'DISCARDED'" color="red">已报废</a-tag>
<a-tag v-else color="red">已锁定</a-tag>
</template> </template>
<template #online="{ record }"> <template #online="{ record }">
<a-tag v-if="record.online == true" color="green">在线</a-tag> <a-switch
<a-tag v-else color="red">离线</a-tag> v-model="record.online"
:checked-value="true"
:unchecked-value="false"
@change="handleToggleEventStatus(record)"
/>
</template> </template>
<template #operations="{ record }"> <template #operations="{ record }">
<a-button <a-button
@ -235,8 +242,9 @@
import useTableOption from '@/hooks/table-option'; import useTableOption from '@/hooks/table-option';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { deleteDevice, DeviceRecord, queryDeviceList, queryProductByName } from '@/api/device'; import { deleteDevice, DeviceRecord, queryDeviceList, queryProductByName, toggleDeviceStatus } from '@/api/device';
import DeviceEdit from '@/views/iot/device/components/device-edit.vue'; import DeviceEdit from '@/views/iot/device/components/device-edit.vue';
import { enableEvent } from '@/api/tsl';
const generateFormModel = () => { const generateFormModel = () => {
return { return {
@ -257,6 +265,24 @@
]); ]);
const formModel = ref(generateFormModel()); const formModel = ref(generateFormModel());
const router = useRouter(); const router = useRouter();
const stateOptions = computed(() => [
{
label: '未激活',
value: 'UNACTIVATED',
},
{
label: '激活',
value: 'ACTIVATED',
},
{
label: '已报废',
value: 'DISCARDED',
},
{
label: '已锁定',
value: 'LOCKED',
},
])
const { const {
cloneColumns, cloneColumns,
showColumns, showColumns,
@ -365,6 +391,22 @@
search(); search();
}; };
//
const handleToggleEventStatus = async (record: any) => {
try {
const res = await toggleDeviceStatus(record.id);
if (res.status === 200) {
Message.success({
content: '状态更新成功',
duration: 5 * 1000,
});
search();
}
} catch (error) {
console.error('状态更新失败:', error);
}
};
// //
const onSizeChange = (Size: number) => { const onSizeChange = (Size: number) => {
pagination.value.size = Size; pagination.value.size = Size;

View File

@ -77,31 +77,31 @@
<a-form-item field="remark" label="备注"> <a-form-item field="remark" label="备注">
<a-textarea v-model="formData.remark" placeholder="请输入备注" /> <a-textarea v-model="formData.remark" placeholder="请输入备注" />
</a-form-item> </a-form-item>
<!-- &lt;!&ndash; 上传预览图 &ndash;&gt;--> <!-- 上传预览图 -->
<!-- <a-form-item--> <a-form-item
<!-- label="预览图"--> label="预览图"
<!-- >--> >
<!-- <a-upload--> <a-upload
<!-- show-file-list--> show-file-list
<!-- :file-list="previewList"--> :file-list="previewList"
<!-- :limit="1"--> :limit="1"
<!-- list-type="picture-card"--> list-type="picture-card"
<!-- :custom-request="(option: any) => customRequest(option, 'preview')"--> :custom-request="(option: any) => customRequest(option, 'preview')"
<!-- @before-remove="beforeRemove"--> @before-remove="beforeRemove"
<!-- />--> />
<!-- </a-form-item>--> </a-form-item>
<!-- &lt;!&ndash; 上传图标 &ndash;&gt;--> <!-- 上传图标 -->
<!-- <a-form-item--> <a-form-item
<!-- label="图标"--> label="图标"
<!-- >--> >
<!-- <a-upload--> <a-upload
<!-- show-file-list--> show-file-list
<!-- :file-list="iconList"--> :file-list="iconList"
<!-- :limit="1"--> :limit="1"
<!-- :custom-request="(option: any) => customRequest(option, 'icon')"--> :custom-request="(option: any) => customRequest(option, 'icon')"
<!-- @before-remove="beforeRemove"--> @before-remove="beforeRemove"
<!-- />--> />
<!-- </a-form-item>--> </a-form-item>
<!-- 参数 --> <!-- 参数 -->
<a-form-item field="params" label="参数"> <a-form-item field="params" label="参数">
<div style="width: 100%"> <div style="width: 100%">
@ -145,9 +145,7 @@
<template #footer> <template #footer>
<a-button class="editor-button" @click="handleCancel">取消</a-button> <a-button class="editor-button" @click="handleCancel">取消</a-button>
<a-button class="editor-button" type="primary" @click="handleSubmit" <a-button class="editor-button" type="primary" @click="handleSubmit">确定</a-button>
>确定</a-button
>
</template> </template>
</a-modal> </a-modal>
</template> </template>
@ -255,22 +253,17 @@
paramsData.value = res.data.params; paramsData.value = res.data.params;
}; };
// // //
// const previewList = computed(() => { const previewList = computed(() => {
// return { const { preview }= formData.value;
// name: formData.value.preview?.fileName, return preview?.url ? [{ name: preview.fileName, url: preview.url, uid: preview.id }] : [];
// url: formData.value.preview?.url, });
// uid: formData.value.preview?.id,
// } //
// }); const iconList = computed(() => {
// // const { icon } = formData.value;
// const iconList = computed(() => { return icon?.url ? [{ name: icon.fileName, url: icon.url, uid: icon.id }] : [];
// return { });
// name: formData.value.icon?.fileName,
// url: formData.value.icon?.url,
// uid: formData.value.icon?.id,
// }
// });
// //
const customRequest = async (option: any,type: string) => { const customRequest = async (option: any,type: string) => {
const { fileItem, onSuccess, onError } = option; const { fileItem, onSuccess, onError } = option;
@ -295,12 +288,23 @@
}; };
// //
const beforeRemove = async (file: any) => { const beforeRemove = async (file: any) => {
if (!file.uid) { try {
const res = await deleteAttachment(file.response.id); const fileId = file.uid || file.response?.id;
return res.status === 200; if (!fileId) {
Message.error('无法获取图片 ID');
}
//
const res = await deleteAttachment(fileId);
if (res.status === 200) {
//
Message.success('删除成功');
} else {
Message.error('删除失败');
}
}
catch (error) {
Message.error('删除图片失败,请稍后重试');
} }
const res = await deleteAttachment(file.uid);
return res.status === 200;
}; };
// //