iot-fontend/src/views/iot/device/components/device-edit.vue

350 lines
9.0 KiB
Vue
Raw Normal View History

<template>
<a-button
v-permission="['iot:device:create']"
v-if="props.isCreate"
type="primary"
@click="handleClick"
>
<template #icon><icon-plus /></template>
新建
</a-button>
<a-button
v-permission="['iot:device:update']"
v-if="!props.isCreate"
type="outline"
size="small"
:style="{ marginRight: '10px', padding: '7px' }"
@click="handleClick"
>
<template #icon><icon-edit /></template>
编辑
</a-button>
<a-modal
width="900px"
height="500px"
:visible="visible"
@cancel="handleCancel"
>
<template #title>{{ modalTitle }}</template>
<a-form
ref="CreateRef"
:model="formData"
:style="{ width: '800px', height: '420px' }"
>
<!-- 产品名称 -->
<a-form-item
field="productName"
label="产品名称"
:rules="[{ required: true, message: '产品名称不能为空' }]"
:validate-trigger="['change']"
>
<a-select
v-model="formData.productName"
placeholder="请选择产品名称"
:loading="loading"
:filter-option="false"
allow-search
@search="handleSearch"
>
<a-option v-for="item of options" :key="item.id" :value="item.name">{{
item.name
}}</a-option>
</a-select>
</a-form-item>
<!-- 设备名称 -->
<a-form-item
field="name"
label="设备名称"
:rules="[{ required: true, message: '设备名称不能为空' }]"
:validate-trigger="['change']"
>
<a-input v-model="formData.name" placeholder="请输入设备名称" />
</a-form-item>
<!-- 硬件版本 -->
<a-form-item
field="hardwareVersion"
label="硬件版本"
:rules="[{ required: true, message: '硬件版本不能为空' }]"
:validate-trigger="['change']"
>
<a-input
v-model="formData.hardwareVersion"
placeholder="请输入硬件版本"
/>
</a-form-item>
<!-- 固件版本 -->
<a-form-item
field="firmwareVersion"
label="固件版本"
:rules="[{ required: true, message: '固件版本不能为空' }]"
:validate-trigger="['change']"
>
<a-input
v-model="formData.firmwareVersion"
placeholder="请输入固件版本"
/>
</a-form-item>
<a-form-item field="remark" label="备注">
<a-textarea v-model="formData.remark" placeholder="请输入描述" />
</a-form-item>
<!-- 扩展属性 -->
<a-form-item field="extendParams" label="扩展属性">
<!-- <a-input-->
<!-- v-model="formData.extendParams"-->
<!-- placeholder='请输入扩展属性'-->
<!-- />-->
<div style="width: 100%">
<div style="width: 100%; margin-bottom: 5px">
<a-space
v-for="(param, index) in paramsData"
:key="index"
style="margin-bottom: 5px"
>
<a-input v-model="param.name" placeholder="名称" allow-clear />
<a-input
v-model="param.identifier"
placeholder="标识"
allow-clear
/>
<a-select
v-model="param.dataType"
:options="dataTypeOptions"
allow-search
placeholder="数据类型"
style="width: 140px"
/>
<a-select
v-model="param.type"
:options="typeOptions"
allow-search
placeholder="类型"
style="width: 140px"
/>
<a-button type="text" @click="handleDeleteParams(index)"
><icon-minus-circle
/></a-button>
</a-space>
</div>
<a-button type="outline" @click="handleAddParams" style="width: 100%">
<icon-plus />
</a-button>
</div>
</a-form-item>
</a-form>
<template #footer>
<a-button class="editor-button" @click="handleCancel">取消</a-button>
<a-button class="editor-button" type="primary" @click="handleSubmit">确定</a-button
>
</template>
</a-modal>
</template>
<script lang="ts" setup>
import useVisible from '@/hooks/visible';
import {
computed,
defineEmits,
PropType,
ref,
shallowRef,
onBeforeUnmount,
} from 'vue';
import { CreateRecord } from '@/api/user';
import { FormInstance } from '@arco-design/web-vue/es/form';
import { Message } from '@arco-design/web-vue';
import '@wangeditor/editor/dist/css/style.css';
import {
createDevice,
queryDeviceByName,
queryDeviceDetail,
updateDevice,
} from '@/api/device';
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
import { queryProductDetail } from '@/api/product';
const props = defineProps({
prem: {
type: Object as PropType<CreateRecord>,
},
isCreate: Boolean,
});
const paramsData = ref([
{
name: '',
identifier: '',
dataType: '',
type: '',
},
]);
const dataTypeOptions = computed<SelectOptionData[]>(() => [
{
label: '整型',
value: 'INT',
},
{
label: '单精度浮点型',
value: 'FLOAT',
},
{
label: '双精度浮点型',
value: 'DOUBLE',
},
{
label: '布尔型',
value: 'BOOLEAN',
},
{
label: '字符串',
value: 'STRING',
},
{
label: '日期型',
value: 'DATE',
},
{
label: '透传',
value: 'RAW',
},
]);
const typeOptions = computed<SelectOptionData[]>(() => [
{
label: '输入',
value: 'INPUT',
},
{
label: '输出',
value: 'OUTPUT',
},
{
label: '读写属性',
value: 'RW',
},
]);
const emit = defineEmits(['refresh']);
const modalTitle = computed(() => {
return props.isCreate ? '创建设备' : '编辑设备';
});
const { visible, setVisible } = useVisible(false);
const checkKeys = ref<number[]>([]);
const CreateRef = ref<FormInstance>();
const formData = ref<any>({
...props.prem,
});
const editorRef = shallowRef();
const options = ref();
const loading = ref(false);
// 搜索
const handleSearch = (value: any) => {
if (value) {
loading.value = true;
options.value = [];
window.setTimeout(async () => {
const res = await queryDeviceByName({
name: value,
page: 1,
size: 10,
});
options.value = res.data.records.map((item: any) => {
return {
id: item.id,
name: item.name,
};
});
loading.value = false;
}, 1000);
} else {
options.value = [];
}
};
// 点击添加参数
const handleAddParams = () => {
// paramsVisible.value = true;
paramsData.value.push({
name: '',
identifier: '',
dataType: '',
type: '',
});
};
// 删除参数
const handleDeleteParams = (record: number) => {
if (record !== -1) {
paramsData.value.splice(record, 1);
}
};
// 组件被点击
const handleClick = () => {
setVisible(true);
if (!props.isCreate) {
const ID = formData.value.productId;
queryProductDetail(ID).then((res) => {
formData.value.productName = res.data.name;
});
queryDeviceDetail(formData.value.id).then((res) => {
paramsData.value = res.data.extendParams;
});
}
};
// 提交
const handleSubmit = async () => {
const valid = await CreateRef.value?.validate();
// formData.value.productId = formData.value.productId.id;
if (!valid) {
// 新增
formData.value.extendParams = paramsData.value;
const productId = await queryDeviceByName(formData.value.productName);
formData.value.productId = productId.data.records[0].id;
if (props.isCreate) {
// formData.value.username = formData.value.email;
const res = await createDevice(formData.value);
if (res.status === 200) {
Message.success({
content: '新建成功',
duration: 5 * 1000,
});
emit('refresh');
setVisible(false);
}
CreateRef.value?.resetFields();
} else {
// 编辑
const res = await updateDevice(formData.value);
if (res.status === 200) {
Message.success({
content: '编辑成功',
duration: 5 * 1000,
});
emit('refresh');
setVisible(false);
}
}
}
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
// 关闭
const handleCancel = async () => {
checkKeys.value = [];
setVisible(false);
};
</script>
<style scoped>
.editor-button {
position: static;
}
</style>