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