浏览代码

设备发货管理

刘洋 1 年之前
父节点
当前提交
c42c456fa1

+ 4 - 1
src/components/common/select-supplier/index.vue

@@ -29,6 +29,7 @@ const props = defineProps({
   modelValue: { type: [Number, String, Array], default: '' },
   type: { type: String, default: '' },
   typeRequired: { type: Boolean, default: false },
+  apiFunc: { type: Function, default: () => {} },
 });
 const isMultiple = computed(() => {
   const multiple = attrs.multiple;
@@ -41,7 +42,9 @@ const search = async () => {
   optionList.value = [];
   let data = { enable: true };
   if (props.type) data.type = props.type;
-  const res = await supplierListApi(data).catch(() => {});
+  const res = props.apiFunc
+    ? await apiFunc().catch(() => {})
+    : await supplierListApi(data).catch(() => {});
   if (!res) return;
 
   optionList.value = res;

+ 7 - 2
src/components/common/upload-button/index.vue

@@ -10,6 +10,7 @@
     @fail="handleError"
     @success="handleSuccess"
     @validate="handleValidate"
+    :allowUploadDuplicateFile="true"
   >
     <slot>
       <t-button theme="primary" v-bind="buttonProps"></t-button>
@@ -50,7 +51,7 @@ const props = defineProps({
   headers: {
     type: Object,
     default() {
-      return {'Content-Type': 'multipart/form-data'};
+      return { 'Content-Type': 'multipart/form-data' };
     },
   },
   buttonProps: {
@@ -67,6 +68,10 @@ const props = defineProps({
     type: String,
     default: 'file',
   },
+  successText: {
+    type: String,
+    default: '导入成功',
+  },
 });
 
 const emit = defineEmits(['on-fail', 'on-success', 'on-validate-error']);
@@ -93,7 +98,6 @@ const handleBeforeUpload = (file) => {
     MessagePlugin.error(content);
     return false;
   }
-
   return true;
 };
 
@@ -114,6 +118,7 @@ const upload = async (file) => {
   }).catch(() => {});
 
   if (res) {
+    MessagePlugin.success(props.successText);
     return { status: 'success', response: res };
   } else {
     return { status: 'fail', error: '上传失败' };

+ 7 - 0
src/config/constants.js

@@ -235,3 +235,10 @@ export const DATA_PRIVILEGE_TYPE = {
   SELF_ORG_BELOW: '本部门及下级部门数据权限',
   ALL: '全部数据权限',
 };
+
+export const DEVICE_SEND_STATUS = {
+  UN_DELIVER: '待发货',
+  DELIVER: '已发货',
+  RECEIVE: '已签收',
+  CANCEL: '作废',
+};

+ 7 - 7
src/router/asyncRoutes.js

@@ -108,7 +108,6 @@ export const devPushMenuList = [
     name: '数据驾驶舱',
     parentId: '-1',
     url: 'test',
-    sort: 9,
     type: 'MENU',
   },
   {
@@ -116,7 +115,6 @@ export const devPushMenuList = [
     name: '派单分析',
     parentId: '2000',
     url: 'test1',
-    sort: 1,
     type: 'MENU',
   },
   {
@@ -124,7 +122,6 @@ export const devPushMenuList = [
     name: '服务单元分析',
     parentId: '2000',
     url: 'test2',
-    sort: 2,
     type: 'MENU',
   },
   {
@@ -132,7 +129,6 @@ export const devPushMenuList = [
     name: 'SOP预警监控',
     parentId: '2000',
     url: 'test3',
-    sort: 3,
     type: 'MENU',
   },
   {
@@ -140,7 +136,6 @@ export const devPushMenuList = [
     name: '项目进度监控',
     parentId: '2000',
     url: 'test4',
-    sort: 4,
     type: 'MENU',
   },
   {
@@ -148,7 +143,6 @@ export const devPushMenuList = [
     name: '设备保障监控',
     parentId: '2000',
     url: 'test5',
-    sort: 5,
     type: 'MENU',
   },
   {
@@ -156,7 +150,13 @@ export const devPushMenuList = [
     name: '质量监控分析',
     parentId: '2000',
     url: 'test6',
-    sort: 6,
+    type: 'MENU',
+  },
+  {
+    id: '3001',
+    name: '设备发货管理',
+    parentId: '36',
+    url: 'test7',
     type: 'MENU',
   },
 ];

+ 2 - 1
src/router/modules/intelligence.js

@@ -5,7 +5,8 @@ export default {
     title: '智能客服',
     sort: 10,
     isModule: true,
-    alias: 'aiCustomerManage',
+    // alias: 'aiCustomerManage',
+    alias: 'aiCustomerManage333333333333',
     icon: 'zhinengkefu',
   },
   children: [

+ 11 - 13
src/router/modules/resourceGuard.js

@@ -58,31 +58,29 @@ export default {
       },
       children: [
         {
-          name: 'RegistrationQuery',
-          path: '/resource-guard/device-guard/registration-query',
+          name: 'DeviceSend',
+          path: '/resource-guard/device-guard/device-send',
           component: () =>
-            import(
-              '@/views/resource-guard/device-guard/registration-query/index.vue'
-            ),
+            import('@/views/resource-guard/device-guard/device-send/index.vue'),
           meta: {
-            title: '出入库登记查询',
+            title: '设备发货管理',
             sort: 1,
-            alias: 'deviceInOut',
+            alias: 'test7',
             icon: 'device-outin',
           },
         },
         {
-          name: 'DeviceMonitor',
-          path: '/resource-guard/device-guard/device-monitor',
+          name: 'RegistrationQuery',
+          path: '/resource-guard/device-guard/registration-query',
           component: () =>
             import(
-              '@/views/resource-guard/device-guard/device-monitor/index.vue'
+              '@/views/resource-guard/device-guard/registration-query/index.vue'
             ),
           meta: {
-            title: '设备资源监控',
+            title: '出入库登记查询',
             sort: 2,
-            alias: 'deviceControl',
-            icon: 'device-control',
+            alias: 'deviceInOut',
+            icon: 'device-outin',
           },
         },
       ],

+ 332 - 0
src/style/reset.css

@@ -0,0 +1,332 @@
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+*,
+::before,
+::after {
+  box-sizing: border-box;
+  /* 1 */
+  border-width: 0;
+  /* 2 */
+  border-style: solid;
+  /* 2 */
+  border-color: currentColor;
+  /* 2 */
+}
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+*/
+html {
+  line-height: 1;
+  -webkit-text-size-adjust: 100%;
+  /* 2 */
+  -moz-tab-size: 4;
+  /* 3 */
+  tab-size: 4;
+  /* 3 */
+  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+  /* 4 */
+}
+html,
+body,
+#app {
+  height: 100%;
+}
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+body {
+  margin: 0 !important;
+  /* 1 */
+  line-height: 1 !important;
+}
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+hr {
+  height: 0;
+  /* 1 */
+  color: inherit;
+  /* 2 */
+  border-top-width: 1px;
+  /* 3 */
+}
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+abbr:where([title]) {
+  text-decoration: underline dotted;
+}
+/*
+Remove the default font size and weight for headings.
+*/
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+a {
+  color: inherit;
+  text-decoration: inherit;
+}
+/*
+Add the correct font weight in Edge and Safari.
+*/
+b,
+strong {
+  font-weight: bolder;
+}
+/*
+1. Use the user's configured `mono` font family by default.
+2. Correct the odd `em` font sizing in all browsers.
+*/
+code,
+kbd,
+samp,
+pre {
+  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
+  /* 1 */
+  font-size: 1em;
+  /* 2 */
+}
+/*
+Add the correct font size in all browsers.
+*/
+small {
+  font-size: 80%;
+}
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sub {
+  bottom: -0.25em;
+}
+sup {
+  top: -0.5em;
+}
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+table {
+  text-indent: 0;
+  /* 1 */
+  border-color: inherit;
+  /* 2 */
+  border-collapse: collapse;
+  /* 3 */
+}
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit;
+  /* 1 */
+  font-size: 100%;
+  /* 1 */
+  line-height: inherit;
+  /* 1 */
+  color: inherit;
+  /* 1 */
+  margin: 0;
+  /* 2 */
+  padding: 0;
+  /* 3 */
+}
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+button,
+select {
+  text-transform: none;
+}
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+  -webkit-appearance: button;
+  /* 1 */
+  /* background-color: transparent; 2 */
+  background-image: none;
+  /* 2 */
+}
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+:-moz-focusring {
+  outline: auto;
+}
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+:-moz-ui-invalid {
+  box-shadow: none;
+}
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+progress {
+  vertical-align: baseline;
+}
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+  height: auto;
+}
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+[type='search'] {
+  -webkit-appearance: textfield;
+  /* 1 */
+  outline-offset: -2px;
+  /* 2 */
+}
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+::-webkit-file-upload-button {
+  -webkit-appearance: button;
+  /* 1 */
+  font: inherit;
+  /* 2 */
+}
+/*
+Add the correct display in Chrome and Safari.
+*/
+summary {
+  display: list-item;
+}
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+  margin: 0;
+}
+fieldset {
+  margin: 0;
+  padding: 0;
+}
+legend {
+  padding: 0;
+}
+ol,
+ul,
+menu {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+/*
+Prevent resizing textareas horizontally by default.
+*/
+textarea {
+  resize: vertical;
+}
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+input::placeholder,
+textarea::placeholder {
+  opacity: 1;
+  /* 1 */
+}
+/*
+Set the default cursor for buttons.
+*/
+button,
+[role='button'] {
+  cursor: pointer;
+}
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+:disabled {
+  cursor: default;
+}
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+   This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+img,
+video {
+  max-width: 100%;
+  max-height: 100%;
+  height: auto;
+}
+/*
+Ensure the default browser behavior of the `hidden` attribute.
+*/
+[hidden] {
+  display: none;
+}
+/*---滚动条默认显示样式--*/
+::-webkit-scrollbar-thumb {
+  background-color: #bbb;
+  border-radius: 3px;
+}
+/*---鼠标点击滚动条显示样式--*/
+::-webkit-scrollbar-thumb:hover {
+  background-color: #aaa;
+  border-radius: 3px;
+}
+/*---滚动条大小--*/
+::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+/*---滚动框背景样式--*/
+::-webkit-scrollbar-track-piece {
+  background-color: rgba(0, 0, 0, 0);
+  border-radius: 0;
+}

+ 2 - 2
src/style/reset.less

@@ -40,9 +40,9 @@ body,
 */
 
 body {
-  margin: 0; /* 1 */
+  margin: 0 !important; /* 1 */
   //line-height: inherit; /* 2 */
-  line-height: 1;
+  line-height: 1 !important;
 }
 
 /*

+ 0 - 7
src/views/resource-guard/device-guard/device-monitor/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div>设备资源监控</div>
-</template>
-
-<script setup name="DeviceMonitor"></script>
-
-<style></style>

+ 136 - 0
src/views/resource-guard/device-guard/device-send/edit-device-info-dialog.vue

@@ -0,0 +1,136 @@
+<template>
+  <my-dialog
+    :visible="visible"
+    header="修改设备发货信息"
+    :width="700"
+    :closeOnOverlayClick="false"
+    attach="body"
+    @close="emit('update:visible', false)"
+  >
+    <div class="readonly-info">
+      <t-row :gutter="[0, 20]">
+        <t-col :span="6"></t-col>
+      </t-row>
+    </div>
+    <t-form ref="formRef" :data="formData" :rules="rules" labelWidth="120px">
+      <t-row :gutter="[0, 20]">
+        <t-col :span="6">
+          <t-form-item label="邮寄地址" name="a">
+            <t-input v-model="formData.a"></t-input>
+          </t-form-item>
+        </t-col>
+        <t-col :span="6">
+          <t-form-item label="收件人" name="b">
+            <t-input v-model="formData.b"></t-input>
+          </t-form-item>
+        </t-col>
+        <t-col :span="6">
+          <t-form-item label="收件人联系电话" name="c">
+            <t-input v-model="formData.c"></t-input>
+          </t-form-item>
+        </t-col>
+        <t-col :span="6">
+          <t-form-item label="快递单号" name="d">
+            <t-input v-model="formData.d"></t-input>
+          </t-form-item>
+        </t-col>
+      </t-row>
+    </t-form>
+    <template #foot>
+      <t-button theme="default" @click="emit('update:visible', false)"
+        >取消</t-button
+      >
+      <t-button theme="primary" @click="save">保存</t-button>
+    </template>
+  </my-dialog>
+</template>
+<script setup name="EditDeviceInfoDialog">
+import { ref, computed } from 'vue';
+import { MessagePlugin } from 'tdesign-vue-next';
+import useClearDialog from '@/hooks/useClearDialog';
+
+const emit = defineEmits(['update:visible']);
+const props = defineProps({
+  visible: Boolean,
+  curRow: Object,
+});
+
+const formRef = ref(null);
+
+const { formData, isEdit } = useClearDialog(
+  {
+    a: '',
+    b: '',
+    c: '',
+    d: '',
+  },
+  props,
+  formRef,
+  () => {
+    for (let key in formData) {
+      formData[key] = props.curRow[key];
+    }
+  }
+);
+
+const rules = {
+  a: [
+    {
+      required: true,
+      message: '请输入邮寄地址',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  b: [
+    {
+      required: true,
+      message: '请输入收件人',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  c: [
+    {
+      required: true,
+      message: '请输入收件人联系电话',
+      type: 'error',
+      trigger: 'change',
+    },
+    {
+      telnumber: true,
+      message: '请输入正确的手机号码',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  d: [
+    {
+      required: true,
+      message: '请输入快递单号',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+};
+
+const save = async () => {
+  const valid = await formRef.value.validate();
+  if (valid !== true) return;
+
+  //   const res = await personFilesEditApi(formData).catch(() => {});
+  //   if (!res) return;
+
+  MessagePlugin.success('保存成功');
+  emit('update:visible', false);
+  emit('success');
+};
+</script>
+<style lang="less" scoped>
+.readonly-info {
+  border: 1px solid #e5e5e5;
+  border-radius: 3px;
+  padding: 16px;
+  margin-bottom: 24px;
+}
+</style>

+ 323 - 0
src/views/resource-guard/device-guard/device-send/index.vue

@@ -0,0 +1,323 @@
+<template>
+  <div class="flex flex-col h-full">
+    <div class="page-action">
+      <t-space size="small">
+        <upload-button
+          upload-url="/api/admin/user/archives/import"
+          :format="['xls', 'xlsx']"
+        >
+          <t-button variant="outline">
+            <template #icon><svg-icon name="import" color="#262626" /></template
+            >批量导入
+          </t-button>
+        </upload-button>
+        <t-button variant="outline" @click="multExport">
+          <template #icon><svg-icon name="export" color="#262626" /></template
+          >批量导出
+        </t-button>
+        <t-button
+          variant="outline"
+          :disabled="!selectedRowKeys.length"
+          @click="handleDestroy"
+        >
+          <template #icon><svg-icon name="delete" color="#262626" /></template
+          >批量发货
+        </t-button>
+        <t-button
+          variant="outline"
+          :disabled="!selectedRowKeys.length"
+          @click="handleDestroy"
+        >
+          <template #icon><svg-icon name="delete" color="#262626" /></template
+          >批量签收
+        </t-button>
+        <t-button
+          variant="outline"
+          :disabled="!selectedRowKeys.length"
+          @click="handleDestroy"
+        >
+          <template #icon><svg-icon name="delete" color="#262626" /></template
+          >批量作废
+        </t-button>
+      </t-space>
+    </div>
+
+    <SearchForm :fields="fields" :params="params" :search="search">
+      <template #service="{ item, params }">
+        <select-service-unit
+          v-model="params[item.prop]"
+          :clearable="true"
+        ></select-service-unit>
+      </template>
+      <template #user="{ item, params }">
+        <select-filter-user
+          v-model="params[item.prop]"
+          clearable
+        ></select-filter-user>
+      </template>
+      <template #supplier="{ item, params }">
+        <select-supplier
+          v-model="params[item.prop]"
+          type="DEVICE"
+        ></select-supplier>
+      </template>
+    </SearchForm>
+    <div class="flex-1 page-wrap">
+      <t-table
+        size="small"
+        row-key="userArchivesId"
+        :columns="columns"
+        :data="tableData"
+        bordered
+        :pagination="{
+          defaultCurrent: 1,
+          defaultPageSize: 10,
+          onChange,
+          showJumper: true,
+          showPageSize: false,
+          total: pagination.total,
+          current: pagination.pageNumber,
+        }"
+        :selected-row-keys="selectedRowKeys"
+        @select-change="selectChange"
+      >
+        <template #operate="{ row }">
+          <div class="table-operations" @click.stop>
+            <t-link
+              v-if="perm.LINK_Update"
+              theme="primary"
+              hover="color"
+              @click="handleEdit(row)"
+            >
+              修改
+            </t-link>
+          </div>
+        </template>
+      </t-table>
+    </div>
+    <EditDeviceInfoDialog
+      v-model:visible="showEditDeviceDialog"
+      :curRow="curRow"
+    ></EditDeviceInfoDialog>
+  </div>
+</template>
+
+<script setup name="DeviceSend">
+import { ref, reactive, computed, onMounted } from 'vue';
+import { omit } from 'lodash';
+
+import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
+import { ErrorCircleFilledIcon } from 'tdesign-icons-vue-next';
+import useFetchTable from '@/hooks/useFetchTable';
+import {
+  personFilesListApi,
+  personFilesStatisticsApi,
+  personFilesDestroyApi,
+  personFilesExportApi,
+} from '@/api/resource-guard';
+import { DEVICE_SEND_STATUS } from '@/config/constants';
+import usePermission from '@/hooks/usePermission';
+import EditDeviceInfoDialog from './edit-device-info-dialog.vue';
+import { dictToOptionList } from '@/utils/tool';
+const { perm } = usePermission();
+
+const curRow = ref(null);
+const showEditDeviceDialog = ref(false);
+setTimeout(() => {
+  showEditDeviceDialog.value = true;
+});
+
+const fields = ref([
+  {
+    prop: 'a',
+    label: '服务单元',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 6,
+    cell: 'service',
+  },
+  {
+    prop: 'b',
+    label: '用途类型',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 6,
+    options: [],
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'c',
+    label: '项目单号',
+    labelWidth: 80,
+    colSpan: 6,
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'd',
+    label: '发货状态',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 6,
+    options: dictToOptionList(DEVICE_SEND_STATUS),
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'e',
+    label: '发货人',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 6,
+    cell: 'user',
+  },
+  {
+    prop: 'f',
+    label: '发货时间',
+    labelWidth: 80,
+    type: 'daterange',
+    colSpan: 12,
+    attrs: {
+      clearable: true,
+      valueType: 'time-stamp',
+    },
+  },
+  {
+    prop: 'h',
+    label: '设备编号',
+    labelWidth: 80,
+    colSpan: 6,
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'supplierId',
+    label: '供应商',
+    labelWidth: 80,
+    type: 'select',
+    colSpan: 6,
+    cell: 'supplier',
+  },
+  {
+    prop: 'g',
+    label: '验收时间',
+    labelWidth: 80,
+    type: 'daterange',
+    colSpan: 12,
+    attrs: {
+      clearable: true,
+      valueType: 'time-stamp',
+    },
+  },
+
+  {
+    type: 'buttons',
+    colSpan: 2,
+    labelWidth: 0,
+    children: [
+      {
+        type: 'button',
+        text: '搜索',
+        onClick: () => {
+          search();
+        },
+      },
+    ],
+  },
+]);
+
+const params = reactive({
+  a: '',
+  b: '',
+  c: '',
+  d: '',
+  e: '',
+  f: [],
+  g: [],
+  h: '',
+  supplierId: '',
+});
+const computedParams = computed(() => {
+  let data = omit(params, ['f', 'g']);
+  // data.archivesTimeStart = params.archivesTime[0];
+  // data.archivesTimeEnd = params.archivesTime[1];
+  return data;
+});
+
+const columns = [
+  {
+    colKey: 'row-select',
+    type: 'multiple',
+    width: 50,
+    fixed: 'left',
+  },
+  {
+    title: '管理',
+    colKey: 'operate',
+    fixed: 'right',
+    width: 80,
+  },
+];
+const { pagination, tableData, fetchData, search, onChange } = useFetchTable(
+  personFilesListApi,
+  {
+    fetchDataHandle: () => {
+      selectedRowKeys.value = [];
+    },
+    params: computedParams,
+  }
+);
+
+const selectedRowKeys = ref([]);
+const selectChange = (value) => {
+  selectedRowKeys.value = value;
+};
+
+const handleEdit = (row) => {
+  curRow.value = row;
+  showAddPersonFileDialog.value = true;
+};
+const handleDestroy = () => {
+  if (!selectedRowKeys.value.length) {
+    MessagePlugin.error('请选择要作废的记录');
+    return;
+  }
+
+  const confirmDia = DialogPlugin({
+    header: '操作提示',
+    body: `确定要作废当前选择的所有记录吗`,
+    confirmBtn: '确定',
+    cancelBtn: '取消',
+    onConfirm: async () => {
+      confirmDia.hide();
+      const res = await personFilesDestroyApi(selectedRowKeys.value).catch(
+        () => {}
+      );
+      if (!res) return;
+      MessagePlugin.success('操作成功');
+      fetchData();
+    },
+  });
+};
+const multExport = () => {
+  const confirmDia = DialogPlugin({
+    header: '操作提示',
+    body: `确定要导出所有记录吗?`,
+    confirmBtn: '确定',
+    cancelBtn: '取消',
+    onConfirm: async () => {
+      confirmDia.hide();
+      const res = await personFilesExportApi(computedParams.value).catch(
+        () => {}
+      );
+      if (!res) return;
+      MessagePlugin.success('导出任务提交成功,请前往任务管理中下载');
+    },
+  });
+};
+</script>

+ 13 - 0
src/views/system/config-manage/device-manage/index.vue

@@ -234,6 +234,15 @@ const fields = ref([
       clearable: true,
     },
   },
+  {
+    prop: 'serialNo',
+    label: '设备序列号',
+    labelWidth: 80,
+    colSpan: 6,
+    attrs: {
+      clearable: true,
+    },
+  },
   {
     type: 'buttons',
     colSpan: 2,
@@ -241,6 +250,9 @@ const fields = ref([
       {
         type: 'button',
         text: '搜索',
+        attrs: {
+          style: { marginLeft: '0 !important' },
+        },
         onClick: () => {
           search();
         },
@@ -286,6 +298,7 @@ const params = reactive({
   brand: '',
   model: '',
   deviceCode: '',
+  serialNo: '',
   status: '',
   bound: '',
   enable: '',

+ 70 - 0
src/views/user/auth-manage/user-manage/bind-supplier-dialog.vue

@@ -0,0 +1,70 @@
+<template>
+  <my-dialog
+    :visible="visible"
+    :header="'绑定供应商'"
+    :width="600"
+    :closeOnOverlayClick="false"
+    @close="emit('update:visible', false)"
+  >
+    <t-form ref="formRef" :data="formData" :rules="rules" labelAlign="top">
+      <t-row :gutter="[20, 20]">
+        <t-col :span="12">
+          <t-form-item label="供应商" name="a">
+            <t-input v-model="formData.a"></t-input>
+          </t-form-item>
+        </t-col>
+      </t-row>
+    </t-form>
+    <template #foot>
+      <t-button theme="default" @click="emit('update:visible', false)"
+        >取消</t-button
+      >
+      <t-button theme="primary" @click="save">保存</t-button>
+    </template>
+  </my-dialog>
+</template>
+<script setup name="AddUserDialog">
+import useClearDialog from '@/hooks/useClearDialog';
+import { ref, computed } from 'vue';
+
+const props = defineProps({
+  visible: Boolean,
+  curRow: Object,
+});
+const emit = defineEmits(['close', 'success']);
+const formRef = ref(null);
+const getDetail = async () => {
+  //编辑状态下获取回显数据的接口请求业务,如果curRow里的字段够用,就直接把curRow里的字段赋值给formData
+};
+const { formData, isEdit } = useClearDialog(
+  {
+    a: '',
+  },
+  props,
+  formRef,
+  getDetail
+);
+
+const rules = {
+  a: [
+    {
+      required: true,
+      message: '请选择供应商',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+};
+const bindHandler = () => {
+  //   addUser({ ...formData, id: props.curRow?.id || undefined }).then(() => {
+  //     emit('success');
+  //   });
+};
+const save = () => {
+  formRef.value.validate().then(async (result) => {
+    if (result === true) {
+      bindHandler();
+    }
+  });
+};
+</script>

+ 30 - 7
src/views/user/auth-manage/user-manage/index.vue

@@ -49,6 +49,13 @@
             >
               修改
             </t-link>
+            <t-link
+              theme="primary"
+              hover="color"
+              @click="handleBindSupplier(row)"
+            >
+              绑定供应商
+            </t-link>
             <t-link
               v-if="perm.LINK_Enable"
               theme="primary"
@@ -75,6 +82,13 @@
       @success="updatePwdSuccess"
     >
     </UpdateUserPwdDialog>
+
+    <BindSupplierDialog
+      v-model:visible="showBindSupplierDialog"
+      :curRow="curRow"
+      @success="bindSupplierSuccess"
+    >
+    </BindSupplierDialog>
   </div>
 </template>
 
@@ -87,6 +101,7 @@ import UpdateUserPwdDialog from './update-user-pwd-dialog.vue';
 import { toggleUserStatus } from '@/api/user';
 import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
 import usePermission from '@/hooks/usePermission';
+import BindSupplierDialog from './bind-supplier-dialog.vue';
 const { perm } = usePermission();
 
 const showAddUserDialog = ref(false);
@@ -95,17 +110,17 @@ const curRow = ref(null);
 
 const columns = [
   { colKey: 'loginName', title: '登录名', width: 140 },
-  { colKey: 'realName', title: '姓名', minWidth: 140 },
-  { colKey: 'genderStr', title: '性别', width: 80 },
-  { colKey: 'mobileNumber', title: '手机', width: 160 },
+  { colKey: 'realName', title: '姓名', minWidth: 90 },
+  { colKey: 'genderStr', title: '性别', width: 70 },
+  { colKey: 'mobileNumber', title: '手机', width: 130 },
   { colKey: 'orgName', title: '所属节点', width: 160 },
-  { colKey: 'roles', title: '角色' },
-  { colKey: 'enable', title: '状态', width: 100 },
+  { colKey: 'roles', title: '角色', minWidth: 130 },
+  { colKey: 'enable', title: '状态', width: 90 },
   {
     title: '管理',
     colKey: 'operate',
     fixed: 'right',
-    width: 200,
+    width: 280,
   },
 ];
 
@@ -126,7 +141,11 @@ const handleEdit = (row) => {
   curRow.value = row;
   showAddUserDialog.value = true;
 };
-
+const showBindSupplierDialog = ref(false);
+const handleBindSupplier = (row) => {
+  curRow.value = row;
+  showBindSupplierDialog.value = true;
+};
 const handleEnable = (row) => {
   const name = !row.enable ? '启用' : '禁用';
 
@@ -176,4 +195,8 @@ const updatePwdSuccess = () => {
   // showUpdateUserPwdDialog.value = false;
   MessagePlugin.success('操作成功');
 };
+
+const bindSupplierSuccess = () => {
+  MessagePlugin.success('绑定成功');
+};
 </script>