Jelajahi Sumber

feat: 子设备crud

lvkun 3 tahun lalu
induk
melakukan
a6b5d8425f

+ 21 - 7
src/components/FormPro/components/indext.tsx

@@ -1,5 +1,5 @@
 
-import { defineComponent, PropType } from 'vue'
+import { defineComponent, PropType, ref } from 'vue'
 
 export const InputTsx = defineComponent({
   name: 'input-tsx',
@@ -26,19 +26,33 @@ export const SelectTsx = defineComponent({
       required: true,
       default: () => ({})
     },
-    list: {
-      type: Array as PropType<{name: string, key: string, value: any}[]>,
-      required: true,
-      default: () => []
+    request: {
+      type: Function,
+      default: () => {}
     }
   },
   emits: ['update:modelValue'],
   setup (props, context) {
+    const list = ref<{
+      name: string,
+      value: any,
+      key: string
+    }[]>([])
+
+    props.request().then((r: {
+      name: string,
+      value: any,
+      key: string
+    }[]) => {
+      list.value = r
+    })
+
     const onInput = (value: string) => context.emit('update:modelValue', value)
+
     return () => (
-      <a-select value={props.modelValue} onChange={(e: any) => onInput(e.target.value)}>
+      <a-select value={props.modelValue} onChange={(value: string) => onInput(value)}>
        {
-        props.list.map(item => <a-select-option key={item.key} value={item.value}>{item.name}</a-select-option>)
+        list.value.map(item => <a-select-option key={item.key} value={item.value}>{item.name}</a-select-option>)
        }
       </a-select>
     )

+ 15 - 18
src/components/FormPro/index.vue

@@ -13,7 +13,7 @@
       v-bind="validateInfos[item.key]"
     >
       <input-tsx v-if="item.type === 'input'"  v-model="modelRef[item.key]" />
-      <select-tsx  v-else-if="item.type === 'select'"  :list="item.request!()" :value="modelRef[item.key]" :on-change="(e) => onChange(e, item.key)"  />
+      <select-tsx  v-else-if="item.type === 'select'"  :request="item.request" v-model="modelRef[item.key]" :on-change="(e) => onChange(e, item.key)"  />
     </a-form-item>
     <!-- <a-form-item>
       <slot name="reset" > <a-button @click="resetForm">重置</a-button></slot>
@@ -39,11 +39,11 @@ export interface FormItemProps {
   key: string,
   value?: any,
   label: string,
-  request?: () => {
+  request?: () => Promise<{
     name: string,
     value: any,
     key: string
-  }[]
+  }[]>
 }
 
 /**
@@ -91,8 +91,6 @@ const emit = defineEmits(['submit', 'reset', 'search'])
 const props = defineProps<FormProProps>()
 
 const initFormPro = () => {
-  console.log('form pro props:', props)
-
   if (props.formProps) {
     props.formProps.forEach((item: FormItemProps) => {
       const key = item.key
@@ -114,6 +112,7 @@ const initFormPro = () => {
       }
     })
   }
+  console.log('rulesRef:', rulesRef)
 
   console.log('formProps:', formProps)
 }
@@ -129,19 +128,19 @@ const onChange = (record: any, key: string) => {
   modelRef[key] = record
 }
 
-const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef, {
-  onValidate: (...args) => console.log(...args)
-})
+const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef)
 
 const onSubmit = () => {
-  validate()
-    .then(() => {
-      console.log(toRaw(modelRef))
-      emit('submit', modelRef)
-    })
-    .catch(err => {
-      console.log('error', err)
-    })
+  return new Promise((resolve, reject) => {
+    validate()
+      .then(() => {
+        resolve(modelRef)
+      })
+      .catch(err => {
+        console.log('error', err)
+        reject(err)
+      })
+  })
 }
 
 defineExpose({
@@ -149,8 +148,6 @@ defineExpose({
 })
 
 onMounted(() => {
-  console.log('FormPro onMounted-----')
-
   initFormPro()
 })
 

+ 5 - 8
src/components/ModalPro/index.vue

@@ -31,7 +31,6 @@ import { ref, watch, watchEffect, computed, CSSProperties, reactive, onMounted }
 
 export interface ModalProPorps extends ModalProps {
   label: string,
-  okRequest?: () =>void,
   openConfirmLoading?: boolean,
   cancel?: () => void
 }
@@ -43,7 +42,7 @@ export interface ModalOkProps {
 
 const emit = defineEmits<{
   (e: 'close'): void
-  (e: 'ok'): void
+  (e: 'ok', { confirmStart, confirmed }: ModalOkProps): void
 }>()
 
 const props = defineProps<ModalProPorps>()
@@ -57,12 +56,10 @@ const state = reactive<Partial<StateProps>>({})
 const close = () => emit('close')
 
 const handleOk = async () => {
-  if (props.okRequest) {
-    state.confirmLoading = true
-    await props.okRequest()
-    state.confirmLoading = false
-  }
-  emit('ok')
+  emit('ok', {
+    confirmStart: () => state.confirmLoading = true,
+    confirmed: () => state.confirmLoading = false
+  })
 }
 
 //  拖拽相关的代码

+ 3 - 22
src/components/TablePro/index.vue

@@ -1,6 +1,6 @@
 <template>
     <a-row>
-      <a-col span="24" >
+      <!-- <a-col span="24" >
         <a-row justify="end">
             <a-col>
               <a-space>
@@ -24,7 +24,7 @@
               </a-space>
             </a-col>
         </a-row>
-      </a-col>
+      </a-col> -->
       <a-col span="24" style="overflow: hidden;overflow-x: scroll;">
         <a-table
           style="width: 100%;margin-top: 10px;"
@@ -55,16 +55,6 @@
         </a-table>
       </a-col>
     </a-row>
-
-    <!-- 弹窗 -->
-    <modal-pro
-      :label="props.modalTitle"
-      :visible="state.modelVisible"
-      @cancel="closeModel"
-      @ok="ok"
-    >
-      <form-pro ref="formProRef" />
-    </modal-pro>
 </template>
 
 <script lang="ts" setup >
@@ -97,7 +87,6 @@ export interface TablePropPorps extends TableProps {
   del: (id: string) => void
   params: any,
   columns: ColumnsType & {children: ColumnsChildren},
-  modalTitle: string
 }
 
 const props = defineProps<TablePropPorps>()
@@ -109,6 +98,7 @@ const state = reactive({
   data: [],
   pagination: {
     current: 1,
+    page: 1,
     total: 0,
     pageSize: 10
   },
@@ -116,15 +106,6 @@ const state = reactive({
   opraState: 'add'
 })
 
-const ok = ({
-  confirmStart,
-  confirmed
-}) => {
-  confirmStart()
-  formProRef.value.onSubmit()
-  confirmed()
-}
-
 const handleTableChange = (pag: { pageSize: number; current: number }) => {
   state.pagination = {
     ...state.pagination,

+ 6 - 0
src/controller/iot/device.ts

@@ -36,6 +36,12 @@ export class DeviceContriller {
     [DeviceMsgEnum.FAILED, { name: '失败', key: DeviceMsgEnum.FAILED }]
   ])
 
+  static searchKeyList = [
+    { name: '设备ID', key: 'deviceId' },
+    { name: '设备标识码', key: 'deviceCode' },
+    { name: '设备名称', key: 'deviceLabel' }
+  ]
+
   static async page (params: IOT.API.DEVICE.QueryPamars) {
     const { data: _data, sum } = await getDeviceList(params)
     const data = _data.map(item => {

+ 104 - 25
src/pages/Iot/device/components/subDevice.vue

@@ -4,11 +4,60 @@
         呈现通过网关方式接入到IoT的设备(传感器)。子设备的状态表示子设备接入网关的状态,由网关上报到IoT平台进行状态的刷新;如果网关不能正常上报子设备的状态信息到IoT平台,则展示的子设备状态不会刷新。
       </div>
       <a-row justify="space-between" style="margin: 20px 0;" >
-        <a-col></a-col>
+        <a-col>
+          <a-space>
+            <a-select style="width: 170px;"  v-model:value="state.queryParams.deviceStatus" >
+              <a-select-option
+                v-for="item in deviceStatusList"
+                :key="item.key"
+                :value="item.key"
+              >{{item.name}}</a-select-option>
+            </a-select>
+
+            <a-select style="width: 120px;"  v-model:value="state.queryParams.searchKey" >
+              <a-select-option
+                v-for="item in DeviceContriller.searchKeyList"
+                :key="item.key"
+                :value="item.key"
+              >{{item.name}}</a-select-option>
+            </a-select>
+
+            <a-input-search
+              v-model:value="state.queryParams.searchValue"
+              enter-button
+              @search="getSubDevicePage"
+            />
+          </a-space>
+        </a-col>
         <a-col>
           <a-button type="primary" @click="state.visible = true">添加子设备</a-button>
         </a-col>
       </a-row>
+
+      <a-table
+        :columns="columns"
+        :dataSource="state.dataSource"
+        :pagination="state.queryParams"
+      >
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'deviceStatus'">
+          <a-tag :color="DeviceContriller.deviceStatusMap.get(record.deviceStatus)?.color" >{{ DeviceContriller.deviceStatusMap.get(record.deviceStatus)?.name }}</a-tag>
+        </template>
+          <template v-if="column.key === 'action'">
+            <a-space>
+                <a>详情</a>
+                <a-popconfirm
+                  title="确实要删除吗?"
+                  ok-text="确定"
+                  cancel-text="取消"
+                  @confirm="delSubDevice(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+            </a-space>
+          </template>
+        </template>
+      </a-table>
   </a-card>
 
   <modal-pro
@@ -21,12 +70,12 @@
       <form-proo
         ref="formPro"
         validate
-        :columnsProps="colums"
+        :columnsProps="columns"
       />
   </modal-pro>
 </template>
 <script lang='ts' setup >
-import { DeviceContriller } from '@/controller'
+import { DeviceContriller, ModelCmdController, ModelController } from '@/controller'
 import { onMounted, reactive, ref } from 'vue'
 import { useRoute } from 'vue-router'
 import { Form } from 'ant-design-vue'
@@ -40,46 +89,80 @@ const formPro = ref('')
 
 const deviceId = route.query.id as string
 
-const colums: ColumnsProps[] = [
+const columns: ColumnsProps[] = [
+  {
+    title: '所属产品',
+    dataIndex: 'modelLabel',
+    formProps: {
+      rules: true,
+      type: 'select',
+      value: '',
+      label: '所属产品',
+      key: 'modelId',
+      request: async () => {
+        const { data } = await ModelController.list()
+        return data.map(item => {
+          return {
+            name: item.modelLabel,
+            value: item.id,
+            key: item.id
+          }
+        })
+      }
+    }
+  },
   {
     title: '状态',
-    dataIndex: 'deviceStatus'
+    dataIndex: 'deviceStatus',
+    key: 'deviceStatus'
   },
   {
     title: '设备名称',
-    dataIndex: 'deviceLabel'
+    dataIndex: 'deviceLabel',
+    formProps: {
+      rules: false,
+      type: 'input',
+      value: '',
+      label: '设备名称',
+      key: 'deviceLabel'
+    }
   },
   {
     title: '设备标识码',
-    dataIndex: 'deviceLabel',
+    dataIndex: 'deviceCode',
     formProps: {
       rules: true,
       type: 'input',
       value: null,
       label: '设备标识码',
-      key: 'deviceLabel'
+      key: 'deviceCode'
     }
   },
   {
-    title: '设备名称',
-    dataIndex: 'deviceLabel'
+    title: '设备ID',
+    dataIndex: 'deviceId'
   },
   {
-    title: '设备名称',
-    dataIndex: 'deviceLabel'
+    title: '操作',
+    dataIndex: 'action',
+    key: 'action'
   }
 ]
 
+const deviceStatusList = [...DeviceContriller.deviceStatus, { name: '所有状态', key: '' }]
+
 const state = reactive({
   loading: false,
   visible: false,
   dataSource: [],
   queryParams: {
+    // id: deviceId,
     page: 1,
     pageSize: 10,
     total: 0,
     deviceStatus: '',
-    searchValue: ''
+    searchValue: '',
+    searchKey: 'deviceId'
   }
 })
 
@@ -90,20 +173,16 @@ const subDeviceState = reactive({
   deviceCode: ''
 })
 
-const { resetFields, validate, validateInfos } = useForm(subDeviceState, reactive({
-  gatewayId: [{ required: true, message: '请选择网关' }],
-  deviceCode: [{ required: true, message: '请填写设备标识码' }],
-  modelId: [{ required: true, message: '请选择所属产品' }]
-}))
-
-const ok = () => {
-  formPro.value.onSubmit()
-  // validate().then(async () => {
-  //   await DeviceContriller.postSub(subDeviceState)
-  //   getSubDevicePage()
-  // })
+const ok = async () => {
+  const submitState = await formPro.value.onSubmit()
+  console.log('submitState:', submitState)
+  DeviceContriller.postSub({ ...submitState, gatewayId: deviceId })
+  state.visible = false
 }
 
+const delSubDevice = async (id: string) => {
+  // const {} = await DeviceContriller
+}
 const getSubDevicePage = async () => {
   state.loading = true
   const { data, sum } = await DeviceContriller.pageSub(deviceId, state.queryParams)