diff --git a/src/api/device.ts b/src/api/device.ts index 6d3e98d..8eecd47 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -5,7 +5,7 @@ export interface DeviceRecord { size: number; current: number; name?: string; - clientId?: string; + clientId?: number; productId?: number; status?: string; isOnline?: boolean; @@ -83,6 +83,15 @@ export function queryDeviceRecord(data: DeviceRecord) { }); } +// 执行服务列表 +export function queryDeviceServeList(data: DeviceRecord) { + return axios({ + url: `/api/rest/device/serve`, + method: 'get', + params: data, + }); +} + // 批量创建 export function createDeviceBatch(data: DeviceCreateRecord) { return axios.post(`/api/rest/device/batch`, data); @@ -97,4 +106,13 @@ export function triggerEvent(data: DeviceEventRecord) { }); } +// 下发命令 +export function sendCommand(data: any) { + return axios({ + url: `/api/rest/device/send`, + method: 'post', + data, + }); +} + diff --git a/src/api/tsl.ts b/src/api/tsl.ts index 892b0f2..8abecc7 100644 --- a/src/api/tsl.ts +++ b/src/api/tsl.ts @@ -73,3 +73,8 @@ export function deleteProperty(data: any) { export function deleteEvent(data: any) { return axios.delete(`/api/rest/tsl/event/${data}`); } + +// 服务详情 +export function queryServeDetail(id: number) { + return axios.get(`/api/rest/tsl/serve/${id}`); +} diff --git a/src/components/dynamic-form/index.vue b/src/components/dynamic-form/index.vue index 0a2c686..1424064 100644 --- a/src/components/dynamic-form/index.vue +++ b/src/components/dynamic-form/index.vue @@ -1,630 +1,30 @@ <template> - <a-form ref="CreateRef" :model="formData" :style="{ width: '650px' }"> - <!-- 用户 --> - <a-form-item - v-if="userId" - field="userId" - :label="userId.label" - :validate-trigger="['change', 'input']" - :rules="[{ message: '请输入用戶' }]" - > - <a-input - v-if="userId.component === 'input'" - v-model="formData.userIds" - :type="userId.type" - placeholder="请选择用戶" - :value="formData.userIds" - @click="queryDeptTree" - /> - </a-form-item> - <!-- 用户2 --> - <a-form-item - v-if="username" - field="username" - :label="username.label" - :validate-trigger="['change', 'input']" - :rules="[ - { required: true, message: '用户名不能为空' }, - { - match: /^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$/, - message: '请输入正确格式的用户名', - }, - ]" - > - <a-input - v-if="username.component === 'input'" - v-model="formData.username" - placeholder="请输入用户名" - /> - - <div v-else>{{ formData.username }}</div> - </a-form-item> - <!-- 邮箱 --> - <a-form-item - v-if="email" - field="email" - :label="email.label" - :rules="[ - { - required: true, - type: 'email', - message: '请输入正确格式的邮箱', - }, - ]" - :validate-trigger="['change', 'input']" - > - <a-input - v-if="email.component === 'input'" - :type="email.type" - v-model="formData.email" - placeholder="请输入邮箱" - /> - </a-form-item> - <!-- 名称 --> - <a-form-item - v-if="name" - field="name" - :label="name.label" - :validate-trigger="['change', 'input']" - :rules="[{ required: true }]" - > - <a-input - v-if="name.component === 'input'" - v-model="formData.name" - :placeholder="`请输入${name.label}`" - /> - </a-form-item> - <!-- 标题 --> - <a-form-item - v-if="title" - field="title" - :label="title.label" - :validate-trigger="['change', 'input']" - :rules="[{ required: true }]" - > - <a-input - v-if="title.component === 'input'" - :type="title.type" - placeholder="请输入标题" - /> - </a-form-item> - <!-- 备注 --> - <a-form-item - v-if="remark" - field="remark" - :label="remark.label" - :validate-trigger="['change', 'input']" - > - <!-- v-if="isCreate"--> - <a-input - v-if="remark.component === 'input'" - :type="remark.type" - placeholder="请输入备注" - /> - <a-textarea - v-if="remark.component === 'textarea'" - v-model="formData.remark" - :show-word-limit="true" - placeholder="请输入备注" - style="height: 100px" - /> - </a-form-item> - <!-- 手机号 --> - <a-form-item - v-if="phone" - field="phone" - :label="phone.label" - :rules="[ - { required: true }, - { match: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }, - ]" - :validate-trigger="['change', 'input']" - > - <a-input - v-if="phone.component === 'input'" - v-model="formData.phone" - :type="phone.type" - placeholder="请输入手机号" - /> - </a-form-item> - <!-- 密码 --> - <a-form-item - v-if="password" - field="password" - :label="password.label" - :validate-trigger="['change', 'input']" - :rules="[{ required: true, message: '密码不能为空' }]" - > - <a-input - v-if="password.component === 'input'" - v-model="formData.password" - :type="password.type" - placeholder="请输入密码" - /> - </a-form-item> - <!-- 昵称 --> - <a-form-item v-if="nickName" field="nickName" :label="nickName.label"> - <a-input - v-if="nickName.component === 'input'" - v-model="formData.nickName" - :type="nickName.type" - :placeholder="$t('user.info.nickName.placeholder')" - /> - </a-form-item> - <!-- 地址 --> - <a-form-item v-if="address" field="address" :label="nickName.label"> - <a-input - v-if="address.component === 'input'" - v-model="formData.address" - :type="address.type" - :placeholder="$t('user.info.address.placeholder')" - /> - </a-form-item> - <!-- 部门 --> - <a-form-item - v-if="deptId" - field="deptId" - :label="deptId.label" - :rules="[{ required: true, message: '部门不能为空' }]" - :validate-trigger="['change']" - > - <a-tree-select - v-if="deptId.component === 'treeSelect'" - v-model="formData.deptId" - :field-names="{ - key: 'id', - title: 'name', - children: 'children', - }" - :data="deptOptions" - allow-clear - placeholder="请选择部门" - /> - </a-form-item> - <!-- 角色 --> - <a-form-item - v-if="roleId" - field="roleId" - :label="roleId.label" - :rules="[{ required: true, message: '角色不能为空' }]" - :validate-trigger="['change']" - > - <a-select - v-if="roleId.component === 'select'" - v-model="formData.roleId" - :options="roleOptions" - :field-names="{ - value: 'id', - label: 'name', - }" - placeholder="请选择角色" - /> - </a-form-item> - <div style="display: flex; margin-left: 75px"> - <!-- 短信 --> - <a-form-item - v-if="sms" - field="sms" - :label="sms.label" - :validate-trigger="['change', 'input']" - > - <a-switch - v-if="sms.component === 'switch'" - v-model="formData.sms" - :checked-value="true" - :unchecked-value="false" + <a-form :model="formData"> + <template v-for="(field, index) in fields" :key="index"> + <a-form-item :label="field.name"> + <a-input + v-model="formData[field.identifier]" + :placeholder="field.name" /> </a-form-item> - <!-- 邮件 --> - <a-form-item - v-if="email" - field="email" - :label="email.label" - :validate-trigger="['change', 'input']" - > - <a-switch - v-if="email.component === 'switch'" - v-model="formData.email" - :checked-value="true" - :unchecked-value="false" - /> - </a-form-item> - <!-- 置顶 --> - <a-form-item - v-if="top" - field="top" - :label="top.label" - :validate-trigger="['change', 'input']" - > - <a-switch - v-if="top.component === 'switch'" - v-model="formData.top" - :checked-value="true" - :unchecked-value="false" - /> - </a-form-item> - </div> - <!-- 附件 --> - <a-form-item v-if="attachmentIds" label="附件"> - <!-- v-if="isCreate"--> - <a-upload :custom-request="customRequest" @before-remove="beforeRemove" /> - </a-form-item> - <!-- 内容 --> - <a-form-item - v-if="richEditor" - field="content" - label="内容" - :rules="[{ required: true }]" - > - <div style="border: 1px solid #ccc; min-width: 700px"> - <Toolbar - style="border-bottom: 1px solid #ccc" - :editor="editorRef" - :default-config="toolbarConfig" - :mode="mode" - :class="{ 'fullscreen-toolbar': isFullScreen }" - /> - <Editor - v-model="formData.content" - style="overflow-y: hidden; height: 200px" - :default-config="editorConfig" - :mode="mode" - :class="{ 'fullscreen-editor': isFullScreen }" - @on-created="handleCreated" - /> - </div> - <!-- <a-textarea v-model="formData.content" placeholder="请输入公告内容" style="height: 100px" />--> - </a-form-item> - <!-- 产品id --> - <a-form-item - v-if="formSystem.productId" - field="productId" - :label="formSystem.productId.label" - :rules="[{ required: true, message: '产品id不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.productId.component === 'input'" - v-model="formData.productId" - placeholder="请输入产品id" - /> - </a-form-item> - <!-- 设备名称 --> - <a-form-item - v-if="formSystem.name" - field="name" - :label="formSystem.name.label" - :rules="[{ required: true, message: '设备名称不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.name.component === 'input'" - v-model="formData.name" - placeholder="请输入设备名称" - /> - </a-form-item> - <!-- 硬件版本 --> - <a-form-item - v-if="formSystem.hardwareVersion" - field="hardwareVersion" - :label="formSystem.hardwareVersion.label" - :rules="[{ required: true, message: '硬件版本不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.hardwareVersion.component === 'input'" - v-model="formData.hardwareVersion" - placeholder="请输入硬件版本" - /> - </a-form-item> - <!-- 固件版本 --> - <a-form-item - v-if="formSystem.firmwareVersion" - field="firmwareVersion" - :label="formSystem.firmwareVersion.label" - :rules="[{ required: true, message: '固件版本不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.firmwareVersion.component === 'input'" - v-model="formData.firmwareVersion" - placeholder="请输入固件版本" - /> - </a-form-item> - <!-- 扩展属性 --> - <a-form-item - v-if="formSystem.extendParams" - field="extendParams" - :label="formSystem.extendParams.label" - :rules="[{ required: true, message: '扩展属性不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.extendParams.component === 'input'" - v-model="formData.extendParams" - placeholder="请输入扩展属性" - /> - </a-form-item> - <!-- 设备物模型属性 --> - <a-form-item - v-if="formSystem.properties" - field="properties" - :label="formSystem.properties.label" - :rules="[{ required: true, message: '设备物模型属性不能为空' }]" - :validate-trigger="['change']" - > - <a-input - v-if="formSystem.properties.component === 'input'" - v-model="formData.properties" - placeholder="请输入设备物模型属性" - /> - </a-form-item> + </template> </a-form> </template> -<script lang="ts" setup> - import useVisible from '@/hooks/visible'; - import { - computed, - defineEmits, - PropType, - ref, - shallowRef, - onBeforeUnmount, - reactive, - } from 'vue'; - import { CreateRecord } from '@/api/user'; - import { FormInstance } from '@arco-design/web-vue/es/form'; - import { Message } from '@arco-design/web-vue'; - import { useMessageStore } from '@/store'; - import { Editor, Toolbar } from '@wangeditor/editor-for-vue'; - import { IEditorConfig } from '@wangeditor/editor'; - import '@wangeditor/editor/dist/css/style.css'; +<script setup> +import { ref } from 'vue'; - const props = defineProps({ - prem: { - type: Object as PropType<CreateRecord>, - }, - formData: { - type: Object as PropType<CreateRecord>, - }, - isCreate: Boolean, - }); - // 部门树模态框状态 - const deptVisible = ref(false); - const emit = defineEmits(['refresh']); - const { visible, setVisible } = useVisible(false); - const checkKeys = ref<number[]>([]); +const props = defineProps({ + fields: { + type: Array, + required: true, + }, +}); - const CreateRef = ref<FormInstance>(); - const formData = ref<any>({ - ...props.formData, - }); - const messageStore = useMessageStore(); - const editorRef = shallowRef(); - const isFullScreen = ref(false); - const mode = 'default'; - const selectedIds = ref<string[]>([]); - const toolbarConfig = { - excludeKeys: ['uploadVideo', 'insertImage', 'insertVideo'], - }; - // const handleCreated = (editor: any) => { - // editorRef.value = editor; // 记录 editor 实例,重要! - // // 监听全屏事件 - // editor.on('fullScreen', () => { - // }) - // } - const columns = computed<any[]>(() => [ - { - title: '操作', - dataIndex: 'key', - slotName: 'key', - }, - { - title: '用户', - dataIndex: 'title', - }, - ]); - const formSystem = ref(props.prem); - const { - userId, - title, - remark, - sms, - email, - richEditor, - attachmentIds, - name, - username, - phone, - password, - nickName, - address, - deptId, - roleId, - } = formSystem.value; - // 部门树数据 - const deptTreeData = reactive([ - { - key: '1', - title: '总部门', - children: [ - { - key: '2', - title: '部门1', - members: [ - { key: '101', title: '成员1' }, - { key: '102', title: '成员2' }, - ], - }, - { - key: '3', - title: '部门2', - members: [ - { key: '201', title: '成员3' }, - { key: '202', title: '成员4' }, - ], - }, - { - key: '4', - title: '部门3', - members: [ - { key: '203', title: '成员5' }, - { key: '204', title: '成员6' }, - ], - }, - ], - }, - ]); - const selectedDepartmentMembers: any = ref([]); - const renderData = ref<any[]>([]); - // 部门树查询 - const queryDeptTree = async () => { - deptVisible.value = true; - }; +const formData = ref({}); - // 广度优先遍历树,获取选中的成员 - const getSelectedMembers = (treeData: any[], selectedKeys: string[]) => { - const queue = [...treeData]; - const selectedMembers: any[] = []; - while (queue.length > 0) { - const node = queue.shift()!; - if (selectedKeys.includes(node.key)) { - if (node.members) { - selectedMembers.push(...node.members); - } - } - if (node.children) { - queue.push(...node.children); - } - } - return selectedMembers; - }; - - // 部门树被点击 - const handleClickTree = (key: string[]) => { - // 假设 '1' 是总部门的键 - if (key[0] === '1' || key.length === 0) { - // 广度优先遍历树,获取所有成员 - const allMembers: any[] = []; - const queue = [...deptTreeData]; - while (queue.length > 0) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const node = queue.shift()!; - if (node.members) { - allMembers.push(...node.members); - } - if (node.children) { - queue.push(...node.children); - } - } - selectedDepartmentMembers.value = allMembers; - renderData.value = selectedDepartmentMembers.value; - return; - } - const Members = getSelectedMembers(deptTreeData, key); - selectedDepartmentMembers.value = Members; - }; - - // 部门树被选中 - const handleCheckTree = (key: string[]) => { - if (key[0] === '1') { - // 假设 '1' 是总部门的键 - const allKeys: string[] = []; - const traverseTree = (node: any) => { - if (node.members) { - node.members.forEach((member: any) => { - allKeys.push(member.key); - }); - } - if (node.children) { - node.children.forEach((child: any) => { - traverseTree(child); - }); - } - }; - deptTreeData.forEach((node: any) => { - traverseTree(node); - }); - selectedIds.value = allKeys; - } else { - const selectedKeys = getSelectedMembers(deptTreeData, key); - selectedIds.value = selectedKeys.map((item) => item.key); - } - }; - - // 组件被点击 - const handleClick = () => { - setVisible(true); - }; - - // 编辑器配置 - const editorConfig: Partial<IEditorConfig> = { - placeholder: '请输入内容...', - MENU_CONF: { - // 隐藏菜单 - hide: [ - 'code', - 'table', - 'emoticon', - 'uploadImage', - 'video', - 'todo', - 'specialChar', - ], - // 配置上传图片 - uploadImage: { - base64LimitSize: 1024 * 1024, - // server: '/api/rest/bulletin/1/add', - }, - }, - }; - - // 组件销毁时,也及时销毁编辑器 - onBeforeUnmount(() => { - const editor = editorRef.value; - if (editor == null) return; - editor.destroy(); - }); - - // 关闭 - const handleCancel = async () => { - checkKeys.value = []; - setVisible(false); - }; - - // 部门树模态框提交 - const deptTreeSubmit = () => { - deptVisible.value = false; - formData.value.userIds = selectedIds.value; - }; - - // 部门树模态框 - const deptTreeCancel = () => { - deptVisible.value = false; - }; </script> <style scoped> - .fullscreen-toolbar { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 50px; /* 根据需要调整高度 */ - z-index: 999; - background-color: white; - } - .fullscreen-editor { - position: fixed; - top: 50px; /* 根据 toolbar 的高度调整 */ - left: 0; - width: 100%; - height: calc(100% - 50px); /* 减去 toolbar 的高度 */ - z-index: 999; - background-color: white; - } - .editor-button { - position: static; - } -</style> +/* ... existing code ... */ +</style> \ No newline at end of file diff --git a/src/views/iot/device/components/device-detail.vue b/src/views/iot/device/components/device-detail.vue index 7fe63e5..4583dcb 100644 --- a/src/views/iot/device/components/device-detail.vue +++ b/src/views/iot/device/components/device-detail.vue @@ -16,12 +16,22 @@ 设备详情</h3 > </template> - <a-descriptions-item label="设备名称">{{ renderData.name }}</a-descriptions-item> - <a-descriptions-item label="硬件版本">{{ renderData.hardwareVersion }}</a-descriptions-item> - <a-descriptions-item label="固件版本">{{ renderData.firmwareVersion }}</a-descriptions-item> - <a-descriptions-item label="所属产品">{{ renderData.productId }}</a-descriptions-item> + <a-descriptions-item label="设备名称">{{ + renderData.name + }}</a-descriptions-item> + <a-descriptions-item label="硬件版本">{{ + renderData.hardwareVersion + }}</a-descriptions-item> + <a-descriptions-item label="固件版本">{{ + renderData.firmwareVersion + }}</a-descriptions-item> + <a-descriptions-item label="所属产品">{{ + renderData.productName + }}</a-descriptions-item> <!-- <a-descriptions-item label="备注">{{renderData.remark }}</a-descriptions-item>--> - <a-descriptions-item label="创建时间">{{dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') }}</a-descriptions-item> + <a-descriptions-item label="创建时间">{{ + dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') + }}</a-descriptions-item> </a-descriptions> </a-card> <a-card class="general-card" style="margin-top: 10px"> @@ -35,39 +45,66 @@ </a-tab-pane> <a-tab-pane key="2" tab="基本信息" title="基本信息"> <a-card class="general-card" title=" "> - <a-descriptions size="large"> + <a-descriptions size="large"> <template #title> <h3 style="margin-top: -15px">所属产品详情</h3> </template> <a-descriptions-item label="产品名称">{{ - renderData.productName - }}</a-descriptions-item> + renderData.productName + }}</a-descriptions-item> <a-descriptions-item label="产品类型">{{ - renderData.productType - }}</a-descriptions-item> + renderData.productType + }}</a-descriptions-item> <a-descriptions-item label="产品型号">{{ - renderData.model - }}</a-descriptions-item> + renderData.model + }}</a-descriptions-item> <a-descriptions-item label="通讯协议">{{ - renderData.link - }}</a-descriptions-item> + renderData.link + }}</a-descriptions-item> <a-descriptions-item label="备注">{{ - renderData.remark - }}</a-descriptions-item> + renderData.remark + }}</a-descriptions-item> <a-descriptions-item label="创建时间">{{ - dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') - }}</a-descriptions-item> + dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') + }}</a-descriptions-item> </a-descriptions> </a-card> </a-tab-pane> <a-tab-pane key="3" tab="执行服务" title="执行服务"> - 执行服务内容 + <a-table :columns="deviceServeColumns" :data="deviceServerData" > + <template #operations="{ record }"> + <a-button + type="text" + status="success" + @click="openServeForm(record)" + > + 执行 + </a-button> + </template> + </a-table> </a-tab-pane> <a-tab-pane key="4" tab="上报记录" title="上报记录"> <a-table :columns="deviceReportColumns" :data="deviceReportData" /> </a-tab-pane> </a-tabs> </a-card> + + <a-modal + width="900px" + height="500px" + :visible="visible" + @cancel="handleCancel" + > + <template #title>执行服务</template> + <dynamicForm + :fields="fields" + @update:form-data="handleFormDataUpdate" + /> + <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> </div> </template> @@ -75,9 +112,14 @@ import dayjs from 'dayjs'; import { useRoute } from 'vue-router'; import { onMounted, ref } from 'vue'; - import { queryDeviceDetail, queryDeviceRecord } from '@/api/device'; + import { Message } from '@arco-design/web-vue'; + import { queryDeviceDetail, queryDeviceRecord, sendCommand } from '@/api/device'; + import { queryServeDetail, queryServeList } from '@/api/tsl'; + import useVisible from '@/hooks/visible'; + import dynamicForm from './dynamic-form.vue' const route = useRoute(); + const { visible, setVisible } = useVisible(); const id = Number(route.params.id); const columns = [ { @@ -113,21 +155,82 @@ slotName: 'content', }, ]; + const deviceServeColumns = [ + { + title: ' 服务名称', + dataIndex: 'name', + slotName: 'name', + }, + { + title: '备注', + dataIndex: 'remark', + slotName: 'remark', + }, + { + title: '操作', + dataIndex: 'operations', + slotName: 'operations', + }, + ]; const activeKey = ref('1'); - const renderData = ref([]); + const renderData = ref({ + clientId: 1, + productId: 1 + }); const deviceReportData = ref([]); + const deviceServerData = ref([]); + const fields = ref([]); const fetchData = async (Id: number) => { const res = await queryDeviceDetail(Id); renderData.value = res.data; const res1 = await queryDeviceRecord({ + clientId: renderData.value.clientId, size: 10, - current: 1 + current: 1, }); - deviceReportData.value = res1.data; + deviceReportData.value = res1.data.records; + const res2 = await queryServeList({ + productId: renderData.value.productId, + size: 10, + current: 1, + }) + deviceServerData.value = res2.data.records; }; const handleMenuClick = (e: any) => { activeKey.value = e; }; + const dynamicFormData = ref(); + // 关闭 + const handleCancel = async () => { + setVisible(false); + }; + + const openServeForm = async (record: object) => { + setVisible(true); + const res = await queryServeDetail(record.id); + fields.value = res.data.inputs; + }; + + const handleFormDataUpdate = (newFormData) => { + dynamicFormData.value = newFormData; // 更新 formData + }; + // 确定 + const handleSubmit = async () => { + const res = await sendCommand(dynamicFormData.value); + if (res.status === 200) { + Message.success({ + content: '执行成功', + duration: 5 * 1000, + }); + setVisible(false); + } else { + Message.error({ + content: '执行失败', + duration: 5 * 1000, + }); + } + }; + onMounted(() => { fetchData(id); }); diff --git a/src/views/iot/device/components/dynamic-form.vue b/src/views/iot/device/components/dynamic-form.vue new file mode 100644 index 0000000..fda01a6 --- /dev/null +++ b/src/views/iot/device/components/dynamic-form.vue @@ -0,0 +1,38 @@ +<template> + <a-form + :model="formData" + :style="{ width: '800px' }" + > + <template v-for="(field, index) in fields" :key="index"> + <a-form-item :label="field.name"> + <a-input + v-model="formData[field.identifier]" + :placeholder="field.name" + /> + </a-form-item> + </template> + </a-form> +</template> + +<script setup> + import { ref, watch } from 'vue'; + + const props = defineProps({ + fields: { + type: Array, + required: true, + }, + }); + + const formData = ref({}); + const emit = defineEmits(['update:formData']); + // 监听 formData 变化并触发事件 + watch(formData, (newValue) => { + emit('update:formData', newValue); + }, { deep: true }); + +</script> + +<style scoped> + /* ... existing code ... */ +</style> \ No newline at end of file diff --git a/src/views/iot/device/index.vue b/src/views/iot/device/index.vue index 69dc9ba..5a35e4e 100644 --- a/src/views/iot/device/index.vue +++ b/src/views/iot/device/index.vue @@ -226,7 +226,7 @@ </template> <script lang="ts" setup> - import { computed, onMounted, ref, watch } from 'vue'; + import { computed, onMounted, provide, ref, watch } from 'vue'; import useLoading from '@/hooks/loading'; import usePagination from '@/hooks/pagination'; import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface'; @@ -248,7 +248,12 @@ const { loading, setLoading } = useLoading(true); const { pagination, setPagination } = usePagination(); - const renderData = ref<[]>([]); + const renderData = ref([ + { + id: 1, + clientId:0 + }, + ]); const formModel = ref(generateFormModel()); const router = useRouter(); const { diff --git a/src/views/iot/product/components/product-tsl.vue b/src/views/iot/product/components/product-tsl.vue index 6da11ee..7bdbfb5 100644 --- a/src/views/iot/product/components/product-tsl.vue +++ b/src/views/iot/product/components/product-tsl.vue @@ -324,11 +324,11 @@ <!-- 事件名称 --> <a-form-item field="name" - label="服务名称" - :rules="[{ required: true, message: '服务名称不能为空' }]" + label="事件名称" + :rules="[{ required: true, message: '事件名称不能为空' }]" :validate-trigger="['change']" > - <a-input v-model="eventAddData.name" placeholder="请输入服务名称" /> + <a-input v-model="eventAddData.name" placeholder="请输入事件名称" /> </a-form-item> <!-- 标识 --> <a-form-item