lvkun 3 жил өмнө
parent
commit
eac512e726

+ 61 - 0
src/api/iot/model.ts

@@ -41,9 +41,70 @@ export const addModel = (data: IOT.API.MODEL.Model) => {
   })
 }
 
+/**
+ * 此函数使用 API 请求按 ID 检索模型。
+ * @param {string} id - `id` 参数是一个字符串,表示模型的唯一标识符。此函数使用此标识符向服务器发出 GET 请求并检索相应的模型对象。
+ * @returns `getModelById` 函数返回一个解析为 `IOT.API.MODEL.ModelDot` 类型对象的
+ * Promise。该对象表示一个模型并包含有关它的信息。该函数正在向“/model/”端点发出 GET 请求,以检索具有指定“id”的模型。
+ */
 export const getModelById = (id: string) => {
   return request<IOT.API.MODEL.ModelDot>({
     url: `/model/${id}`,
     method: 'GET'
   })
 }
+
+/**
+ * 此函数发送 GET 请求以从 API 端点检索模型属性。
+ * @param {any} params - `params` 参数是一个对象,其中包含要与 GET 请求一起发送到 `/modelAttribute/page`
+ * 端点的查询参数。这些参数可能包括页码、页面大小、排序选项和过滤器等内容。 API 期望的具体参数将取决于其
+ * @returns `getModelAttribute` 函数返回一个解析为 `IOT.API.MODELATTR.ModelAttr` 类型对象的
+ * Promise。该对象表示模型属性的页面,通过使用指定参数向 `/modelAttribute/page` 端点发出 GET 请求获得。
+ */
+export const getModelAttribute = (params: any) => {
+  return request<IOT.API.MODELATTR.ModelAttr[]>({
+    url: '/modelAttribute/page',
+    method: 'GET',
+    params
+  })
+}
+
+/**
+ * 此函数使用 POST 请求将新模型属性添加到特定模型。
+ * @param data - `data` 参数是一个包含模型属性及其关联的 `modelId` 的对象。 `IOT.API.MODELATTR.ModelAttr`
+ * 类型表明该对象具有特定的结构,并且可能包含诸如 `name`、`dataType`、`description` 等属性。
+ * @returns `addModelAttribute` 函数返回一个解析为字符串的 Promise。
+ */
+export const addModelAttribute = (data: IOT.API.MODELATTR.ModelAttr & {modelId: string}) => {
+  return request<string>({
+    url: '/modelAttribute',
+    method: 'POST',
+    data
+  })
+}
+
+/**
+ * 此函数使用 PUT 请求更新 API 中的模型属性。
+ * @param data - `data` 参数是一个包含模型属性更新值的对象。它应该具有以下属性:
+ * @returns `updateModelAttribute` 函数返回一个解析为字符串的 Promise。
+ */
+export const updateModelAttribute = (data: IOT.API.MODELATTR.ModelAttr & {modelId: string} & {id: string}) => {
+  return request<string>({
+    url: '/modelAttribute',
+    method: 'PUT',
+    data
+  })
+}
+
+/**
+ * 此函数发送 DELETE 请求以删除具有特定 ID 的模型属性。
+ * @param {string} id - `id` 参数是一个字符串,表示需要删除的模型属性的唯一标识符。
+ * @returns `delModelAttribute` 函数返回一个解析为字符串的 Promise。该字符串表示向 `/modelAttribute/` 端点发送 DELETE
+ * 请求后服务器的响应。
+ */
+export const delModelAttribute = (id: string) => {
+  return request<string>({
+    url: `/modelAttribute/${id}`,
+    method: 'DELETE'
+  })
+}

+ 24 - 0
src/controller/iot/modelAttr.ts

@@ -0,0 +1,24 @@
+
+import { addModelAttribute, getModelAttribute, updateModelAttribute, delModelAttribute } from '@/api/iot/model'
+import { message } from 'ant-design-vue'
+
+export class ModelAttrController {
+  static async page (params: any) {
+    return await getModelAttribute(params)
+  }
+
+  static async post (data: IOT.API.MODELATTR.ModelAttr & {modelId: string}) {
+    await addModelAttribute(data)
+    message.success('新增成功')
+  }
+
+  static async update (data: IOT.API.MODELATTR.ModelAttr & {modelId: string, id: string}) {
+    await updateModelAttribute(data)
+    message.success('修改成功')
+  }
+
+  static async del (id: string) {
+    await delModelAttribute(id)
+    message.success('删除成功')
+  }
+}

+ 183 - 0
src/pages/Iot/model/components/modelDefine.vue

@@ -0,0 +1,183 @@
+<template>
+  <a-row justify="end">
+    <a-col  >
+      <a-space>
+        <a-button type="primary" @click="openModel('attrVisible', 'add')" >新增属性</a-button>
+      </a-space>
+    </a-col>
+  </a-row>
+  <a-table
+    style="margin-top: 10px;"
+    :columns="columns"
+    :dataSource="state.dataSource"
+    :loading="state.loading"
+    :pagination="state.queryParams"
+  >
+    <template #bodyCell="{column, record}">
+      <template v-if="column.key === 'action'">
+      </template>
+            <a-space>
+                <a href="#">修改</a>
+                <a-popconfirm
+                  title="确实要删除吗?"
+                  ok-text="确定"
+                  cancel-text="取消"
+                  @confirm="confirmDel('attr', record.id)"
+                >
+                  <a href="#">删除</a>
+                </a-popconfirm>
+            </a-space>
+    </template>
+  </a-table>
+
+  <a-modal
+    :title="modalTitle"
+    :visible="state.attrVisible"
+    @cancel="state.attrVisible = false"
+    @ok="ok('attr')"
+    ok-text="确定"
+    cancel-text="取消"
+  >
+    <a-form :label-col="{span: 4}" :wrapper-col="{span: 14}" >
+      <a-form-item label="属性名称" v-bind="validateInfos.attributeLabel" >
+        <a-input v-model:value="attrRef.attributeLabel"  />
+      </a-form-item>
+      <a-form-item label="数据类型" v-bind="validateInfos.dataType" >
+        <a-select v-model:value="attrRef.dataType" >
+          <a-select-option :value="item" v-for="item in dataTypes" :key="item" >{{item}}</a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="访问权限" v-bind="validateInfos.scope" >
+        <a-checkbox-group v-model:value="attrRef.scope" name="checkboxgroup" :options="[{label: '读', value: 'R'}, {label: '写', value: 'W'}]" />
+      </a-form-item>
+      <a-form-item label="单位" >
+        <a-input v-model:value="attrRef.dataUnit"  />
+      </a-form-item>
+      <a-form-item label="计算表达式" >
+        <a-input v-model:value="attrRef.expr"  />
+      </a-form-item>
+    </a-form>
+  </a-modal>
+</template>
+
+<script lang="ts" setup >
+import { ModelAttrController } from '@/controller/iot/modelAttr'
+import { computed } from '@vue/reactivity'
+import { ColumnProps } from 'ant-design-vue/lib/table'
+import { onMounted, reactive } from 'vue'
+import { Form } from 'ant-design-vue'
+import { useRoute } from 'vue-router'
+
+const columns: ColumnProps = [
+  {
+    title: '属性',
+    key: 'attributeKey'
+  },
+  {
+    title: '属性名称',
+    key: 'attributeLabel'
+  },
+  {
+    title: '数据类型',
+    key: 'dataType'
+  },
+  {
+    title: '数据单位',
+    key: 'dataUnit'
+  },
+  {
+    title: '权限',
+    key: 'scope'
+  },
+  {
+    title: '表达式',
+    key: 'expr'
+  },
+  {
+    title: '操作',
+    key: 'action'
+  }
+]
+
+const route = useRoute()
+
+const modelId = route.query.id! as string
+
+const useForm = Form.useForm
+
+const dataTypes = ['string(字符串)', 'long(整数)', 'boolean(布尔值)', 'double(浮点数)', 'json(JSON)']
+
+const state = reactive<{
+  dataSource: IOT.API.MODELATTR.ModelAttr[],
+  [key: string]: any
+}>({
+  dataSource: [],
+  loading: false,
+  opraState: 'add',
+  queryParams: {
+    page: 1,
+    pageSize: 10,
+    modelId: '',
+    total: 0
+  },
+  attrVisible: false,
+  commandVisible: false
+})
+
+const attrRef = reactive({
+  attributeLabel: '',
+  dataType: '',
+  dataUnit: '',
+  scope: [],
+  key: 'tem',
+  expr: '',
+  attributeKey: 'tem',
+  modelId: ''
+})
+
+const { resetFields, validate: validateAttr, validateInfos } = useForm(attrRef, reactive({
+  attributeLabel: [{ required: true, message: '请填写属性名称' }],
+  dataType: [{ required: true, message: '请选择数据类型' }],
+  dataUnit: [{ required: true, message: '请填写数据单位' }]
+}))
+
+const confirmDel = async (modalName: 'attr' | 'command', id: string) => {
+  modalName === 'attr' ? await ModelAttrController.del(id) : await ModelAttrController.del(id)
+  getModelAttr()
+}
+
+const ok = (modalName: 'attr' | 'command') => {
+  if (modalName === 'attr') {
+    validateAttr().then(() => {
+      ModelAttrController.post({ ...attrRef, scope: attrRef.scope.join(''), modelId })
+    })
+  }
+}
+
+const openModel = (key: string, opraState: 'add' | 'update') => {
+  state[key] = true
+  state.opraState = opraState
+}
+
+const getModelAttr = async () => {
+  state.loading = true
+  const { data, sum } = await ModelAttrController.page(state.queryParams)
+  state.loading = false
+  state.dataSource = data
+  state.queryParams.total = sum
+}
+
+onMounted(() => {
+  state.queryParams.modelId = route.query.id
+  getModelAttr()
+})
+
+const modalTitle = computed(() => {
+  const t1 = state.opraState === 'add' ? '新增' : '编辑'
+  const t2 = state.attrVisible ? '属性' : '命令'
+  return t1 + t2
+})
+</script>
+
+<style>
+</style>

+ 34 - 7
src/pages/Iot/model/detail.vue

@@ -1,8 +1,5 @@
 <template>
-  <a-card
-
-  >
-  <!--  -->
+  <a-card>
   <template #title>
     <a-row :gutter="[8, 8]">
       <a-col> <h1>{{state.model?.modelLabel}}</h1> </a-col>
@@ -21,21 +18,51 @@
         <a-descriptions-item label="产品描述">{{state.model?.modelDescription}}</a-descriptions-item>
   </a-descriptions>
   </a-card>
+
+  <a-card style="margin-top: 20px;" >
+    <a-tabs v-model:activeKey="state.activeKey">
+      <a-tab-pane  :key="item.key" :tab="item.label" v-for="item in tabsdata">
+        <ModelDefine />
+      </a-tab-pane>
+    </a-tabs>
+  </a-card>
 </template>
 
 <script lang="ts" setup >
 import { ModelController } from '@/controller'
-import { onMounted, reactive } from 'vue'
+import { onMounted, reactive, ref } from 'vue'
 import { useRoute } from 'vue-router'
+import ModelDefine from './components/modelDefine.vue'
 
 const queryParams = useRoute().query as {id: string}
 
 const state = reactive<{
-  model: IOT.API.MODEL.ModelDot | null
+  model: IOT.API.MODEL.ModelDot | null,
+  activeKey: number
 }>({
-  model: null
+  model: null,
+  activeKey: 0
 })
 
+const tabsdata = [
+  {
+    label: '模型定义',
+    key: 0
+  },
+  {
+    label: '插件开发',
+    key: 1
+  },
+  {
+    label: '在线调试',
+    key: 2
+  },
+  {
+    label: 'Topic管理',
+    key: 3
+  }
+]
+
 const getModelById = async (id: string) => {
   state.model = await ModelController.detail(id)
 }

+ 5 - 0
src/pages/Iot/model/index.vue

@@ -91,6 +91,11 @@ const columns = [
     dataIndex: 'modelLabel',
     key: 'modelLabel'
   },
+  {
+    title: '产品id',
+    dataIndex: 'id',
+    key: 'id'
+  },
   {
     title: '传输协议',
     dataIndex: 'transportType',

+ 1 - 0
src/service/request.ts

@@ -16,6 +16,7 @@ const catchErr = (response: AxiosResponse) => {
   const { data } = response
   if (data.code === 500) {
     message.error(data.msg)
+    throw new Error('')
   } else if (data.code === 400) {
     message.error('参数出现错误')
   }

+ 1 - 4
src/styles/theme.less

@@ -4,7 +4,4 @@
 @primary-color: red;
 @border-radius-base: 10px;
 
-
-
-
-@label-color: #8a8e99;
+@label-color: #8a8e99; 

+ 11 - 0
src/type/iot.d.ts

@@ -27,5 +27,16 @@ declare namespace IOT {
         tenantId: string
       }
     }
+
+    namespace MODELATTR {
+      interface ModelAttr {
+        attributeKey: string
+        attributeLabel: string
+        dataType: string
+        dataUnit: string
+        scope: string
+        expr: string
+      }
+    }
   }
 }