瀏覽代碼

feat(device): 设备管理

tangning 3 年之前
父節點
當前提交
b3a0dbe23f

+ 15 - 11
src/api/customer/index.ts

@@ -1,6 +1,6 @@
 import { defHttp } from '/@/utils/http/axios';
 import { PageParams, deleteParams, addParams, cameraListParams, companyExcelParams } from './model';
-import { Result } from '/#/axios';
+import { Result, FileStream, UploadFileParams } from '/#/axios';
 
 enum Api {
   companyList = '/newV4/service/manage/company/list',
@@ -63,7 +63,7 @@ export const cameraList = (params: cameraListParams) =>
     },
   });
 export const downTemplate = (params: companyExcelParams) =>
-  defHttp.get<Result>({
+  defHttp.downloadFile<FileStream>({
     url: Api.downTemplate,
     params: params,
     // data: params,
@@ -71,14 +71,18 @@ export const downTemplate = (params: companyExcelParams) =>
       // @ts-ignore
       ignoreCancelToken: true,
     },
+    responseType: 'blob'
   });
 
-export const companyUploadExcel = (params: companyExcelParams) => {
-  return defHttp.uploadFile<Result>(
-    {
-      url: Api.companyUploadExcel,
-      // onUploadProgress,
-    },
-    params,
-  );
-};
+export function companyUploadExcel(
+    params: UploadFileParams,
+    onUploadProgress: (progressEvent: ProgressEvent) => void,
+  ) {
+    return defHttp.uploadFile<Result>(
+      {
+        url: Api.companyUploadExcel,
+        onUploadProgress,
+      },
+      params,
+    );
+   }

+ 1 - 1
src/api/customer/model.ts

@@ -29,6 +29,6 @@ export interface cameraListParams {
   companyId?: number;
 }
 export interface companyExcelParams {
-  file: File | Blob;
+  file?: File | Blob;
   type?: Number;
 }

+ 66 - 0
src/api/device/index.ts

@@ -0,0 +1,66 @@
+import { defHttp } from '/@/utils/http/axios';
+import { PageParams} from './model';
+import { Result } from '/#/axios';
+
+enum Api {
+  getParam = '/newV4/service/manage/camera/getParam',
+  getUpdate = '/newV4/service/manage/camera/update',
+  getOut = '/newV4/service/manage/camera/out',
+  getDelete = '/newV4/service/manage/camera/delete',
+  getIn = '/newV4/service/manage/camera/in',
+}
+
+export const cameraParam = (params: PageParams) =>
+  defHttp.get<Result>({
+    url: Api.getParam,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const cameraDelete = (params: PageParams) =>
+  defHttp.post<Result>({
+    url: Api.getDelete,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+  export const cameraUpdate = (params: PageParams) =>
+  defHttp.post<Result>({
+    url: Api.getUpdate,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+  export const cameraOut = (params: PageParams) =>
+  defHttp.post<Result>({
+    url: Api.getOut,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const cameraIn = (params: PageParams) =>
+  defHttp.post<Result>({
+    url: Api.getIn,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+});

+ 5 - 0
src/api/device/model.ts

@@ -0,0 +1,5 @@
+import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
+/**
+ * @description: Request list interface parameters
+ */
+export type PageParams = BasicPageParams;

+ 7 - 0
src/locales/lang/zh-CN/routes/product.ts

@@ -14,10 +14,17 @@ export default {
   description_en:'英文更新说明',
   file:'文件',
   type:{
+    0:'旧双目相机',
     1:'四维看看',
     2:'四维看见',
     3:'四维深时',
   },
+  outType:{
+    0:'正常销售',
+    1:'员工自用',
+    2:'礼品赠送',
+    3:'其他',
+  },
   sdkType:{
     1:'Unity',
     2:'UE4',

+ 142 - 0
src/views/device/OutflowModal.vue

@@ -0,0 +1,142 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="批量出库"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+    :min-height="0"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm" :model="model">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+      <a @click="getTemplate" style="padding: 20px 0 0 80px">下载批量出库模板</a>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { downloadByData } from '/@/utils/file/download'
+  // import { sceneMove } from '/@/api/operate';
+  import { companyUploadExcel, downTemplate } from '/@/api/customer';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi, AddAndUpload } from '/@/api/product/index';
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const modelRef = ref({});
+      const fileFlow = reactive({
+        file: null,
+      });
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'file',
+          component: 'Upload',
+          label: t('routes.product.file'),
+          required: true,
+          rules: [{ required: true, message: t('common.uploadMessge') }],
+          // helpMessage: t('routes.corporation.uploadHelp'),
+          itemProps: {
+            validateTrigger: 'onBlur',
+          },
+          componentProps: {
+            api: uploadApi,
+            maxNumber: 1,
+            maxSize: 5,
+            fileFlow: true,
+            accept: ['xls', 'xlsx'],
+            afterFetch: function (data) {
+              // console.log('uploadApi', data);
+              // Reflect.set(data, 'url', data.file);
+              fileFlow.file = data.file;
+              console.log(fileFlow.file);
+              return data;
+            },
+          },
+
+          colProps: {
+            span: 22,
+          },
+        },
+      ];
+      const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        // console.log(data);
+        data && onDataReceive(data);
+      });
+
+      function onDataReceive(data) {
+        modelRef.value = data;
+        resetFields();
+        setFieldsValue({
+          type: data.sceneName,
+        });
+      }
+      const handleSubmit = async () => {
+        try {
+          const params = await validate();
+          const apiData = {
+            file: fileFlow.file,
+            data:{
+              type: 2,
+            }
+          };
+          const res = await companyUploadExcel(apiData);
+          console.log('res', res);
+          closeModal();
+          resetFields();
+          createMessage.success('导出成功');
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+      function handleVisibleChange(v) {
+        // console.log(v);
+        // v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      async function getTemplate() {
+        try {
+          const res:BlobPart = await downTemplate({ type: 1 });
+          downloadByData(res.data,'出库模板.xls')
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      }
+      return {
+        register,
+        schemas,
+        registerForm,
+        model: modelRef,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+        getTemplate,
+      };
+    },
+  });
+</script>

+ 9 - 7
src/views/device/DeviceLinkModal.vue

@@ -2,7 +2,7 @@
   <BasicModal
     v-bind="$attrs"
     @register="register"
-    title="客户关联"
+    title="批量入库"
     @visible-change="handleVisibleChange"
     @cancel="resetFields"
     @ok="handleSubmit"
@@ -14,7 +14,7 @@
           {{ model[field] }}
         </template>
       </BasicForm>
-      <a @click="getTemplate" style="padding: 20px 0 0 80px">下载客户关联模板</a>
+      <a @click="getTemplate" style="padding: 20px 0 0 80px">下载批量入库模板</a>
     </div>
   </BasicModal>
 </template>
@@ -26,7 +26,7 @@
   // import { sceneMove } from '/@/api/operate';
   import { companyUploadExcel, downTemplate } from '/@/api/customer';
   import { useI18n } from '/@/hooks/web/useI18n';
-  import { uploadApi, AddAndUpload } from '/@/api/product/index';
+  import { downloadByData } from '/@/utils/file/download'
   const { t } = useI18n();
   export default defineComponent({
     components: { BasicModal, BasicForm },
@@ -52,7 +52,6 @@
             validateTrigger: 'onBlur',
           },
           componentProps: {
-            api: uploadApi,
             maxNumber: 1,
             maxSize: 5,
             fileFlow: true,
@@ -98,7 +97,9 @@
           const params = await validate();
           const apiData = {
             file: fileFlow.file,
-            type: 2,
+            data:{
+              type: 0,
+            }
           };
           const res = await companyUploadExcel(apiData);
           console.log('res', res);
@@ -115,8 +116,9 @@
       }
       async function getTemplate() {
         try {
-          const res = await downTemplate({ type: 2 });
-          console.log('res', res);
+          const res:BlobPart = await downTemplate({ type: 0 });
+          console.log('downTemplate',res)
+          downloadByData(res.data,'入库模板.xls')
         } catch (error) {
           console.log('not passing', error);
         }

+ 219 - 0
src/views/device/detailsMoadl.vue

@@ -0,0 +1,219 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+    :height="800"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm" :model="model">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+import { defineComponent, ref, onMounted, reactive } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+import { useMessage } from '/@/hooks/web/useMessage';
+// import { sceneMove } from '/@/api/operate';
+import { downTemplate } from '/@/api/customer';
+import { cameraParam, cameraUpdate, cameraOut } from '/@/api/device';
+import { CameraList } from '/@/api/order';
+import { useI18n } from '/@/hooks/web/useI18n';
+const { t } = useI18n();
+interface Option {
+  value: string;
+}
+
+export default defineComponent({
+  components: { BasicModal, BasicForm },
+  props: {
+    userData: { type: Object },
+  },
+  emits: ['reload'],
+  setup(_, { emit }) {
+    const modelRef = ref({
+      isUpdate:false,
+    });
+    const title = ref('设备出库');
+    const optionsOrderSn = ref<Option[]>([]);
+    const optionsName = ref<Option[]>([]);
+    const fileFlow = reactive({
+      file: null,
+    });
+    const { createMessage } = useMessage();
+    const schemas: FormSchema[] = [
+      {
+        field: 'id',
+        component: 'Input',
+        label: 'id',
+        show: false,
+      },
+      {
+        field: 'outType',
+        component: 'Select',
+        label: '出库类型',
+        colProps: {
+          span: 18,
+        },
+        componentProps: {
+          options: [
+            {
+              label: t('routes.product.outType.0'),
+              value: 0,
+              key: '0',
+            },
+            {
+              label: t('routes.product.outType.1'),
+              value: 1,
+              key: '1',
+            },
+            {
+              label: t('routes.product.outType.2'),
+              value: 2,
+              key: '2',
+            },
+            {
+              label: t('routes.product.outType.3'),
+              value: 3,
+              key: '3',
+            },
+          ],
+        },
+      },
+      {
+        field: 'companyName',
+        component: 'AutoComplete',
+        label: '客户名称',
+        colProps: {
+          span: 18,
+        },
+        componentProps: {
+          filterOption: onFilterOption,
+          onSearch: async (searchText: string) => {
+            const paramList = await cameraParam({ type: 1, companyName: searchText });
+            console.log('searchText', searchText, paramList);
+            optionsName.value = !searchText
+              ? []
+              : [
+                  { value: searchText },
+                  { value: searchText + searchText },
+                  { value: searchText + searchText + searchText },
+                ];
+          },
+          onChange: (data) => {
+            console.log('data', data);
+          },
+        },
+      },
+      {
+        field: 'orderSn',
+        component: 'AutoComplete',
+        label: '订单号',
+        colProps: {
+          span: 18,
+        },
+        componentProps: {
+          options: optionsOrderSn.value,
+          filterOption: onFilterOption,
+          onSearch: async (searchText: string) => {
+            const { list } = await CameraList({ orderSn: searchText });
+            optionsOrderSn.value = !searchText ? [] : list.map((ele) => { return { value: ele.orderSn }; });
+            updateSchema({
+              field: 'orderSn',
+              componentProps:{
+                options: optionsOrderSn.value,
+              },
+            })
+          },
+          onChange: (data) => {
+            console.log('data', data);
+          },
+        },
+      },
+    ];
+    const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({
+      labelWidth: 120,
+      schemas,
+      showActionButtonGroup: false,
+      actionColOptions: {
+        span: 24,
+      },
+    });
+    onMounted(() => {});
+    let addListFunc = () => {};
+    const [register, { closeModal }] = useModalInner((data) => {
+      // console.log(data);
+      data && onDataReceive(data);
+    });
+
+    function onDataReceive(data) {
+      modelRef.value = data;
+      title.value = data.isUpdate?'编辑':'设备出库'
+      console.log('onDataReceive', data);
+      const { outType } = data;
+      let obj = t('routes.product.outType')
+      resetFields();
+      setFieldsValue({
+        type: obj[outType],
+        ...data,
+      });
+    }
+
+    const handleSubmit = async () => {
+      const apiUrl = modelRef.value.isUpdate?cameraUpdate:cameraOut
+      try {
+        const params = await validate();
+        console.log('params', params);
+        const res = await apiUrl(params);
+        console.log('res', res);
+        closeModal();
+        resetFields();
+        createMessage.success(t('common.optSuccess'));
+        emit('reload');
+      } catch (error) {
+        console.log('not passing', error);
+      }
+    };
+    function onFilterOption(inputText: string, option: Option) {
+      return option.value.toUpperCase().indexOf(inputText.toUpperCase()) >= 0;
+    }
+
+    function handleVisibleChange(v) {
+      // console.log(v);
+      // v && props.userData && nextTick(() => onDataReceive(props.userData));
+    }
+
+    async function getTemplate() {
+      try {
+        const res = await downTemplate({ type: 2 });
+        console.log('res', res);
+      } catch (error) {
+        console.log('not passing', error);
+      }
+    }
+    return {
+      register,
+      schemas,
+      registerForm,
+      model: modelRef,
+      title,
+      fileFlow,
+      handleVisibleChange,
+      onFilterOption,
+      handleSubmit,
+      addListFunc,
+      resetFields,
+      t,
+      getTemplate,
+    };
+  },
+});
+</script>

+ 166 - 60
src/views/device/index.vue

@@ -3,15 +3,30 @@
     <div class="desc-wrap-BasicTable">
       <BasicTable @register="registerTable">
         <template #toolbar>
-          <a-button type="primary" @click="deviceLink"> 设备关联</a-button>
-          <a-button type="primary" @click="back">返回</a-button>
+          <a-button type="primary" @click="put"> 入库</a-button>
+          <a-button type="primary" @click="batchPut"> 批量入库</a-button>
+          <a-button type="primary" @click="batchOutflow">批量出库</a-button>
         </template>
         <template #action="{ record }">
           <TableAction
             stopButtonPropagation
             :actions="[
               {
+                label: '删除',
+                color: 'error',
+                ifShow: !Boolean(record.outType),
+                onClick: handleDelete.bind(null, record),
+              },{
+                label: '出库',
+                ifShow: !Boolean(record.companyName),
+                onClick: handleCheckout.bind(null, record),
+              },{
+                label: '编辑',
+                ifShow: Boolean(record.companyName),
+                onClick: handleEdit.bind(null, record),
+              },{
                 label: '解绑',
+                ifShow: Boolean(record.userName),
                 color: 'error',
                 onClick: handleUnbind.bind(null, record),
               },
@@ -20,11 +35,14 @@
         </template>
       </BasicTable>
     </div>
-    <DeviceLinkModal @register="registerLinkModal" />
+    <batchOutflowModal @register="registerLinkModal" @reload="reload" />
+    <detailModal @register="register" @reload="reload" />
+    <batchPutModal @register="registerPut" @reload="reload" />
+    <PutModal @register="registerEnter" @reload="reload" />
   </PageWrapper>
 </template>
 <script lang="ts">
-  import { defineComponent, h, reactive, toRefs, onMounted } from 'vue';
+  import { defineComponent, h, onMounted } from 'vue';
   import {
     BasicTable,
     useTable,
@@ -34,22 +52,28 @@
     FormProps,
   } from '/@/components/Table';
   import { PageWrapper } from '/@/components/Page';
-  import { Time } from '/@/components/Time';
   import { Descriptions } from 'ant-design-vue';
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { cameraList } from '/@/api/customer';
-  import { message } from 'ant-design-vue';
-  import DeviceLinkModal from './DeviceLinkModal.vue';
+  import { cameraDelete } from '/@/api/device'
+  import batchOutflowModal from './OutflowModal.vue';
+  import detailModal from './detailsMoadl.vue';
+  import batchPutModal from './batchPutModal.vue';
+  import PutModal from './putModal.vue';
   import { useModal } from '/@/components/Modal';
   import { useRouter } from 'vue-router';
+  import { UnbindCameraApi } from '/@/api/account';
   export default defineComponent({
     components: {
       BasicTable,
       TableAction,
       PageWrapper,
       TableImg,
-      DeviceLinkModal,
+      batchOutflowModal,
+      detailModal,
+      batchPutModal,
+      PutModal,
       [Descriptions.name]: Descriptions,
       [Descriptions.Item.name]: Descriptions.Item,
     },
@@ -57,6 +81,9 @@
       const { t } = useI18n();
       const { createMessage, createConfirm } = useMessage();
       const [registerLinkModal, { openModal: openLinkModal }] = useModal();
+      const [register, { openModal }] = useModal();
+      const [registerPut, { openModal:openModalPut }] = useModal();
+      const [registerEnter, { openModal:openModalEnter }] = useModal();
       const router = useRouter();
       const companyId: Number = router.currentRoute.value.params.id - 0;
       onMounted(() => {
@@ -99,6 +126,9 @@
           title: '绑定账号',
           dataIndex: 'userName',
           width: 180,
+          customRender({ record }) {
+            return record.userName?record.userName:'未绑定'
+          },
         },
 
         {
@@ -108,80 +138,121 @@
           ifShow: true,
           fixed: 'right',
           flag: 'ACTION',
-          width: 60,
+          width: 120,
         },
       ];
       const searchForm: Partial<FormProps> = {
-        labelWidth: 100,
+        labelWidth: 80,
+        // showAdvancedButton: true,
+        autoAdvancedLine:1,
+        actionColOptions: {
+          span: 24,
+        },
+        // compact: true,
         schemas: [
           {
             field: 'snCode',
-            label: 'SN码',
             component: 'Input',
-            componentProps: {
-              maxLength: 100,
-            },
+            label: 'SN码',
             colProps: {
-              xl: 4,
-              xxl: 4,
+              xl: 6,
+              xxl: 6,
             },
-          },
-          {
+          },{
             field: 'type',
-            label: '设备类型',
             component: 'Select',
+            label: '设备类型',
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
             componentProps: {
-              maxLength: 100,
               options: [
                 {
-                  label: '旧双目相机',
-                  value: '0',
-                },
-                {
-                  label: '四维看看',
-                  value: '1',
-                },
-                {
-                  label: '四维看看lite',
-                  value: '2',
-                },
-                {
-                  label: '四维看见',
-                  value: '9',
-                },
-                {
-                  label: '四维深时',
-                  value: '10',
+                  label: t('routes.product.type.0'),
+                  value: 0,
+                  key: '0',
+                },{
+                  label: t('routes.product.type.1'),
+                  value: 1,
+                  key: '1',
+                },{
+                  label: t('routes.product.type.2'),
+                  value: 2,
+                  key: '2',
+                },{
+                  label: t('routes.product.type.3'),
+                  value: 3,
+                  key: '3',
                 },
               ],
             },
-            colProps: {
-              xl: 4,
-              xxl: 4,
-            },
           },
           {
-            field: 'activatedTime',
-            label: '激活时间',
+            field: 'sceneName',
+            label: '下单时间',
             component: 'RangePicker',
-            componentProps: {
-              maxLength: 100,
-            },
             colProps: {
               xl: 7,
               xxl: 7,
             },
           },
           {
-            field: 'userName',
-            label: '绑定账号',
+            field: 'outType',
+            component: 'Select',
+            label: '出库类型',
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
+            componentProps: {
+              options: [
+                {
+                  label: t('routes.product.outType.0'),
+                  value: 0,
+                  key: '0',
+                },{
+                  label: t('routes.product.outType.1'),
+                  value: 1,
+                  key: '1',
+                },{
+                  label: t('routes.product.outType.2'),
+                  value: 2,
+                  key: '2',
+                },{
+                  label: t('routes.product.outType.3'),
+                  value: 3,
+                  key: '3',
+                },
+              ],
+            },
+          },
+          {
+            field: 'companyName',
+            label: '客户名称',
             component: 'Input',
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
             componentProps: {
-              maxLength: 100,
+              // api: brandTypeListApi,
+              resultField: 'list',
+              labelField: 'name',
+              valueField: 'brandType',
+              params: {
+                page: 1,
+                limit: 1000,
+              },
             },
+          },
+          {
+            field: 'userName',
+            component: 'Input',
+            label: '绑定账号',
             colProps: {
-              xl: 4,
-              xxl: 4,
+              xl: 6,
+              xxl: 6,
             },
           },
         ],
@@ -191,11 +262,12 @@
         // title: '四维深时场景列表',
         // titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
         columns: columns,
-        rowSelection: { type: 'checkbox',onChange: onSelectChange },
+        // rowSelection: { type: 'checkbox',onChange: onSelectChange },
         searchInfo: { companyId },
         useSearchForm: true,
         formConfig: searchForm,
         showTableSetting: true,
+        showIndexColumn:false,
         rowKey: 'id',
         fetchSetting: {
           pageField: 'pageNum',
@@ -205,32 +277,66 @@
         },
         canResize: false,
       });
-      function onSelectChange(val): void {
-        console.log('onSelectChange',val)
-      }
       async function handleUnbind(record: Recordable) {
         createConfirm({
           iconType: 'warning',
           title: () => h('span', '温馨提示'),
           content: '解绑后用户将看不到该相机拍摄的场景。<br/>确定解绑吗?',
           onOk: async () => {
-            // await DownExport();
+            await await UnbindCameraApi({cameraId:record.id})
+            createMessage.success(t('common.optSuccess'));
+            reload()
           },
         });
       }
+      async function handleDelete(record: Recordable){
+        const res = await cameraDelete({id:record.id})
+        createMessage.success(t('common.optSuccess'));
+        reload()
+        console.log('res',res)
+      }
 
       function deviceLink() {
         openLinkModal(true);
       }
-      function back() {
-        router.push('/customer/index');
+      function handleCheckout(record: Recordable) {
+        openModal(true, {
+          ...record,
+          isUpdate: false,
+        });
+      }
+      function handleEdit(record: Recordable) {
+        openModal(true, {
+          ...record,
+          isUpdate: true,
+        });
+      }
+      function put() {
+        openModalEnter(true)
+      }
+      function batchPut() {
+        console.log('批量入库');
+        openModalPut(true, {})
+      }
+      function batchOutflow() {
+        console.log('批量出库');
+        openLinkModal(true, {})
       }
       return {
         registerTable,
         handleUnbind,
         deviceLink,
         registerLinkModal,
-        back,
+        register,
+        registerEnter,
+        put,
+        batchPut,
+        batchOutflow,
+        handleEdit,
+        handleCheckout,
+        reload,
+        handleDelete,
+        registerPut,
       };
     },
   });

+ 126 - 0
src/views/device/putModal.vue

@@ -0,0 +1,126 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="设备入库"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+    :min-height="0"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm" :model="model">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { cameraIn } from '/@/api/device'
+  import { companyUploadExcel, downTemplate } from '/@/api/customer';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['reload',],
+    setup(_, { emit }) {
+      const modelRef = ref({});
+      const fileFlow = reactive({
+        file: null,
+      });
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'wifiName',
+          component: 'Input',
+          label: 'wifi名称',
+          colProps: {
+            span: 18,
+          },
+          helpMessage:'wifi名称需包含前缀,如“4DKKPRO_”、“4DKKMI_”、“4DSS_”、“4DKK_”。',
+          rules: [
+            {
+              required: true,
+              // @ts-ignore
+              validator: async (rule, value) => {
+                // var reg = /\S+@\S+\.\S+/;
+                if (!value) {
+                  return Promise.reject('请输入wifi名称');
+                }
+                var list:string[] = ['4DKKPRO_','4DKKMI_','4DSS_','4DKK_'];
+                const some = list.some(item=>{
+                  return value.indexOf(item) != -1
+                })
+                console.log('validator',some)
+                if(!some){
+                  return Promise.reject('wifi名称需包含前缀,如“4DKKPRO_”、“4DKKMI_”、“4DSS_”、“4DKK_”。');
+                }
+                return Promise.resolve();
+              },
+              trigger: 'change',
+            },
+          ],
+        }
+      ];
+      const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        // console.log(data);
+        data && onDataReceive(data);
+      });
+
+      function onDataReceive(data) {
+        modelRef.value = data;
+        resetFields();
+        setFieldsValue({
+          type: data.sceneName,
+        });
+      }
+      function handleVisibleChange() {
+
+      }
+
+      const handleSubmit = async () => {
+        try {
+          const params = await validate();
+          await cameraIn(params);
+          closeModal();
+          resetFields();
+          createMessage.success(t('common.optSuccess'));
+          emit('reload');
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+      return {
+        register,
+        schemas,
+        registerForm,
+        model: modelRef,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+      };
+    },
+  });
+</script>

+ 1 - 0
types/axios.d.ts

@@ -30,6 +30,7 @@ export interface Result<T = any> {
   type: 'success' | 'error' | 'warning';
   message: string;
   result: T;
+  list?: T;
   data?: T;
 }
 //文件流