zhangjie 1 жил өмнө
parent
commit
11a9a156a1
35 өөрчлөгдсөн 695 нэмэгдсэн , 328 устгасан
  1. 2 0
      components.d.ts
  2. 40 1
      src/api/service-unit.js
  3. 6 1
      src/api/system.js
  4. 6 0
      src/api/user.js
  5. 60 0
      src/components/common/select-customer/index.vue
  6. 13 1
      src/components/common/select-service-level/index.vue
  7. 9 0
      src/components/common/select-supplier/index.vue
  8. 3 8
      src/components/common/select-user/index.vue
  9. 13 0
      src/config/constants.js
  10. 1 1
      src/views/project-quality/project-quality-manage/issues-feedback/index.vue
  11. 1 1
      src/views/project-quality/project-quality-manage/issues-query/index.vue
  12. 1 1
      src/views/resource-guard/device-guard/registration-query/index.vue
  13. 1 1
      src/views/resource-guard/person-guard/person-allocate/index.vue
  14. 1 1
      src/views/resource-guard/person-guard/person-files/index.vue
  15. 164 40
      src/views/service-unit/dispatch/dispatch-manage/add-dispatch-dialog.vue
  16. 0 44
      src/views/service-unit/dispatch/dispatch-manage/delineation-dialog.vue
  17. 281 108
      src/views/service-unit/dispatch/dispatch-manage/index.vue
  18. 49 14
      src/views/service-unit/dispatch/dispatch-manage/mult-delineation-dialog.vue
  19. 8 8
      src/views/service-unit/service-unit-manage/add-range/index.vue
  20. 0 71
      src/views/service-unit/service-unit-manage/add-range/select-service-unit-dialog.vue
  21. 1 1
      src/views/service-unit/service-unit-manage/range-manage/index.vue
  22. 2 1
      src/views/service-unit/service-unit-manage/regional-planning/add-region-dialog.vue
  23. 6 10
      src/views/service-unit/service-unit-manage/regional-planning/index.vue
  24. 4 1
      src/views/service-unit/service-unit-manage/unit-manage/add-unit-dialog.vue
  25. 6 2
      src/views/service-unit/service-unit-manage/unit-manage/index.vue
  26. 1 1
      src/views/system/config-manage/checkin-manage/index.vue
  27. 6 1
      src/views/system/config-manage/customer-manage/edit-customer-dialog.vue
  28. 3 3
      src/views/system/config-manage/customer-manage/index.vue
  29. 1 1
      src/views/system/notice-log/log-manage/index.vue
  30. 1 1
      src/views/system/notice-log/notice-manage/index.vue
  31. 1 1
      src/views/system/notice-log/notice-manage/notice-message-dialog.vue
  32. 1 1
      src/views/work-hours/work-hours-manage/abnormal-check/done-check.vue
  33. 1 1
      src/views/work-hours/work-hours-manage/abnormal-check/wait-check.vue
  34. 1 1
      src/views/work-hours/work-hours-manage/work-attendance/index.vue
  35. 1 1
      src/views/work-hours/work-hours-manage/work-statistics/index.vue

+ 2 - 0
components.d.ts

@@ -15,6 +15,7 @@ declare module 'vue' {
     SearchForm: typeof import('./src/components/global/search-form/index.vue')['default']
     SearchFormItem: typeof import('./src/components/global/search-form/components/search-form-item.vue')['default']
     SelectArea: typeof import('./src/components/common/select-area/index.vue')['default']
+    SelectCustomer: typeof import('./src/components/common/select-customer/index.vue')['default']
     SelectRole: typeof import('./src/components/common/select-role/index.vue')['default']
     SelectServiceLevel: typeof import('./src/components/common/select-service-level/index.vue')['default']
     SelectServiceUnit: typeof import('./src/components/common/select-service-unit/index.vue')['default']
@@ -32,6 +33,7 @@ declare module 'vue' {
     TDatePicker: typeof import('tdesign-vue-next')['DatePicker']
     TDateRangePicker: typeof import('tdesign-vue-next')['DateRangePicker']
     TDialog: typeof import('tdesign-vue-next')['Dialog']
+    TDivider: typeof import('tdesign-vue-next')['Divider']
     TDropdown: typeof import('tdesign-vue-next')['Dropdown']
     TForm: typeof import('tdesign-vue-next')['Form']
     TFormItem: typeof import('tdesign-vue-next')['FormItem']

+ 40 - 1
src/api/service-unit.js

@@ -1,4 +1,43 @@
-import { request } from '@/utils/request.js';
+import { request, paramsSerializer } from '@/utils/request.js';
+
+// dispatch-manage
+export const dispatchQueryApi = (data) =>
+  request({
+    url: '/api/admin/tb/crm/query',
+    params: data,
+  });
+export const dispatchEditApi = (data) =>
+  request({
+    url: '/api/admin/tb/crm/save',
+    data,
+  });
+export const dispatchDetailApi = (id) =>
+  request({
+    url: '/api/admin/tb/crm/get',
+    params: { id },
+    method: 'get',
+  });
+export const dispatchDeleteApi = (id) =>
+  request({
+    url: '/api/admin/tb/crm/delete',
+    params: { id },
+  });
+export const dispatchBatchDisableApi = (crmIds) =>
+  request({
+    url: '/api/admin/tb/crm/batchDisable',
+    params: { crmIds },
+    paramsSerializer,
+  });
+export const dispatchBatchZoneApi = (data) =>
+  request({
+    url: '/api/admin/tb/crm/batchZone',
+    params: data,
+  });
+export const dispatchCountWaitZoneApi = () =>
+  request({
+    url: '/api/admin/tb/crm/countWaitZone',
+    method: 'get',
+  });
 
 // unit-manage
 export const serviceUnitQueryApi = (data) =>

+ 6 - 1
src/api/system.js

@@ -1,11 +1,16 @@
 import { request, paramsSerializer } from '@/utils/request.js';
 
 // customer-manage
-export const customeryQueryApi = (data) =>
+export const customerQueryApi = (data) =>
   request({
     url: '/api/sys/custom/query',
     params: data,
   });
+export const customerListApi = (data) =>
+  request({
+    url: '/api/sys/custom/list',
+    params: data,
+  });
 export const customerDetailApi = (id) =>
   request({
     url: '/api/sys/custom/get',

+ 6 - 0
src/api/user.js

@@ -106,3 +106,9 @@ export const editUser = (data) =>
     method: 'post',
     data,
   });
+
+export const getRoleUserList = (roleType) =>
+  request({
+    url: '/api/admin/common/get_user_list_by_role_id',
+    params: { roleTypeEnum: roleType },
+  });

+ 60 - 0
src/components/common/select-customer/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <t-select v-model="selected" filterable v-bind="attrs" @change="onChange">
+    <t-option
+      v-for="item in optionList.value"
+      :key="item.id"
+      :value="item.id"
+      :label="item.name"
+    />
+  </t-select>
+</template>
+
+<script setup name="SelectCustomer">
+import { onMounted, reactive, ref, useAttrs, watch } from 'vue';
+import { customerListApi } from '@/api/system';
+
+let optionList = reactive([]);
+let selected = ref('');
+
+const attrs = useAttrs();
+
+const emit = defineEmits(['update:modelValue', 'change']);
+const props = defineProps({
+  modelValue: { type: [Number, String], default: '' },
+  type: { type: String, default: '' },
+  typeRequired: { type: Boolean, default: false },
+});
+
+const search = async () => {
+  if (props.typeRequired && !props.type) return;
+  optionList.value = [];
+  let data = { enable: true };
+  if (props.type) data.type = props.type;
+  const res = await customerListApi(data).catch(() => {});
+  if (!res) return;
+
+  optionList.value = res;
+};
+
+const onChange = () => {
+  emit('update:modelValue', selected.value);
+  emit('change', selected.value);
+};
+
+onMounted(() => {
+  search();
+});
+
+watch(
+  () => props.modelValue,
+  (val) => {
+    selected.value = val;
+  }
+);
+watch(
+  () => props.type,
+  (val, oldval) => {
+    if (val !== oldval) search();
+  }
+);
+</script>

+ 13 - 1
src/components/common/select-service-level/index.vue

@@ -21,11 +21,17 @@ const attrs = useAttrs();
 const emit = defineEmits(['update:modelValue', 'change']);
 const props = defineProps({
   modelValue: { type: [Number, String], default: '' },
+  type: { type: String, default: '' },
+  typeRequired: { type: Boolean, default: false },
 });
 
 const search = async () => {
+  if (props.typeRequired && !props.type) return;
+
   optionList.value = [];
-  const res = await serviceLevelListApi().catch(() => {});
+  let data = { enable: true };
+  if (props.type) data.type = props.type;
+  const res = await serviceLevelListApi(data).catch(() => {});
   if (!res) return;
 
   optionList.value = res;
@@ -46,4 +52,10 @@ watch(
     selected.value = val;
   }
 );
+watch(
+  () => props.type,
+  (val, oldval) => {
+    if (val !== oldval) search();
+  }
+);
 </script>

+ 9 - 0
src/components/common/select-supplier/index.vue

@@ -22,9 +22,12 @@ const emit = defineEmits(['update:modelValue', 'change']);
 const props = defineProps({
   modelValue: { type: [Number, String], default: '' },
   type: { type: String, default: '' },
+  typeRequired: { type: Boolean, default: false },
 });
 
 const search = async () => {
+  if (props.typeRequired && !props.type) return;
+
   optionList.value = [];
   let data = { enable: true };
   if (props.type) data.type = props.type;
@@ -49,4 +52,10 @@ watch(
     selected.value = val;
   }
 );
+watch(
+  () => props.type,
+  (val, oldval) => {
+    if (val !== oldval) search();
+  }
+);
 </script>

+ 3 - 8
src/components/common/select-user/index.vue

@@ -11,7 +11,7 @@
 
 <script setup name="SelectUser">
 import { onMounted, reactive, ref, useAttrs, watch } from 'vue';
-import { getUserList } from '@/api/user';
+import { getRoleUserList } from '@/api/user';
 
 let optionList = reactive([]);
 let selected = ref('');
@@ -26,15 +26,10 @@ const props = defineProps({
 
 const search = async () => {
   optionList.value = [];
-  const res = await getUserList({
-    enable: true,
-    // roleType: props.roleType,
-    pageNumber: 1,
-    pageSize: 20,
-  }).catch(() => {});
+  const res = await getRoleUserList(props.roleType).catch(() => {});
   if (!res) return;
 
-  optionList.value = res.records;
+  optionList.value = res;
 };
 
 const onChange = () => {

+ 13 - 0
src/config/constants.js

@@ -1,3 +1,16 @@
+export const ROLE_TYPE = {
+  ADMIN: '系统管理员',
+  PMO: '总负责人',
+  BUSSINESS: '业务线负责人',
+  REGION_MANAGER: '大区经理',
+  REGION_COORDINATOR: '区域协调人',
+  EFFECT_ENGINEER: '实施工程师',
+  ASSISTANT_ENGINEER: '助理工程师',
+  QA: 'QA',
+  CUSTOM: '技术客服',
+  DEFINED: '自定义',
+};
+
 // 系统管理 ------->
 // 客户类型
 export const CUSTOMER_TYPE = {

+ 1 - 1
src/views/project-quality/project-quality-manage/issues-feedback/index.vue

@@ -21,7 +21,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         :selected-row-keys="selectedRowKeys"
         select-on-row-click

+ 1 - 1
src/views/project-quality/project-quality-manage/issues-query/index.vue

@@ -13,7 +13,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
       >
       </t-table>

+ 1 - 1
src/views/resource-guard/device-guard/registration-query/index.vue

@@ -13,7 +13,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
       >
       </t-table>

+ 1 - 1
src/views/resource-guard/person-guard/person-allocate/index.vue

@@ -38,7 +38,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         :selected-row-keys="selectedRowKeys"
         select-on-row-click

+ 1 - 1
src/views/resource-guard/person-guard/person-files/index.vue

@@ -35,7 +35,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         :selected-row-keys="selectedRowKeys"
         select-on-row-click

+ 164 - 40
src/views/service-unit/dispatch/dispatch-manage/add-dispatch-dialog.vue

@@ -6,39 +6,60 @@
     :width="600"
     :closeOnOverlayClick="false"
   >
-    <t-form ref="formRef" :model="formData" labelWidth="120px">
-      <t-form-item label="项目单号:">
-        <t-input v-model="formData.a"></t-input>
+    <t-form ref="formRef" :data="formData" :rules="rules" labelWidth="120px">
+      <t-form-item label="项目单号:" name="crmNo">
+        <t-input v-model="formData.crmNo" clearable></t-input>
       </t-form-item>
-      <t-form-item label="项目名称:">
-        <t-input v-model="formData.b"></t-input>
+      <t-form-item label="项目名称:" name="name">
+        <t-input v-model="formData.name" clearable></t-input>
       </t-form-item>
-      <t-form-item label="派单时间:">
-        <t-date-picker v-model="formData.c" />
+      <t-form-item label="派单时间:" name="beginTime">
+        <t-date-picker v-model="formData.beginTime" value-type="time-stamp" />
       </t-form-item>
-      <t-form-item label="服务单元名称:">
-        <t-select v-model="formData.d"></t-select>
+      <t-form-item label="服务单元:">
+        <select-service-unit
+          v-model="formData.serviceId"
+          clearable
+        ></select-service-unit>
       </t-form-item>
-      <t-form-item label="派单人:">
-        <t-select v-model="formData.e"></t-select>
+      <t-form-item label="派单人:" name="crmUserId">
+        <select-user v-model="formData.crmUserId" clearable></select-user>
       </t-form-item>
-      <t-form-item label="客户类型:">
-        <t-select v-model="formData.f"></t-select>
+      <t-form-item label="客户类型" name="customType">
+        <t-select v-model="formData.customType">
+          <t-option
+            v-for="(val, key) in CUSTOMER_TYPE"
+            :key="key"
+            :label="val"
+            :value="key"
+          />
+        </t-select>
       </t-form-item>
-      <t-form-item label="客户名称:">
-        <t-select v-model="formData.g"></t-select>
+      <t-form-item label="客户名称:" name="customId">
+        <select-customer
+          v-model="formData.customId"
+          clearable
+          :type="formData.customType"
+          type-required
+        ></select-customer>
       </t-form-item>
       <t-form-item label="考试开始时间:">
-        <t-date-picker v-model="formData.h" />
+        <t-date-picker
+          v-model="formData.examStartTime"
+          :disable-date="{ after: formData.examEndTime || undefined }"
+          value-type="time-stamp"
+        />
       </t-form-item>
       <t-form-item label="考试结束时间:">
-        <t-date-picker v-model="formData.i" />
+        <t-date-picker
+          v-model="formData.examEndTime"
+          :disable-date="{ before: formData.examStartTime }"
+          value-type="time-stamp"
+        />
       </t-form-item>
-      <t-form-item label="实施产品:">
-        <t-select v-model="formData.j"></t-select>
-      </t-form-item>
-      <t-form-item label="大区经理:">
-        <t-select v-model="formData.k"></t-select>
+      <t-form-item label="实施产品:" name="productId">
+        <!-- todo: 使用选择产品列表组件-->
+        <t-select v-model="formData.productId" clearable></t-select>
       </t-form-item>
     </t-form>
     <template #foot>
@@ -50,34 +71,137 @@
   </my-dialog>
 </template>
 <script setup name="AddDispatchDialog">
-import useClearDialog from '@/hooks/useClearDialog';
 import { ref } from 'vue';
+import { MessagePlugin } from 'tdesign-vue-next';
+
+import useClearDialog from '@/hooks/useClearDialog';
+import { dispatchEditApi } from '@/api/service-unit';
+import { CUSTOMER_TYPE } from '@/config/constants';
+
 const props = defineProps({
   visible: Boolean,
   curRow: Object,
 });
 const emit = defineEmits(['update:visible']);
 const formRef = ref(null);
-const getDetail = async () => {
-  //编辑状态下获取回显数据的接口请求业务,如果curRow里的字段够用,就直接把curRow里的字段赋值给formData
-  alert('获取详情中...');
-};
+
 const { formData, isEdit } = useClearDialog(
   {
-    a: '',
-    b: '',
-    c: '',
-    d: '',
-    e: '',
-    f: '',
-    g: '',
-    h: '',
-    i: '',
-    j: '',
-    k: '',
+    id: null,
+    crmNo: '',
+    name: '',
+    beginTime: null,
+    serviceId: null,
+    crmUserId: '13',
+    customType: null,
+    customId: null,
+    examStartTime: null,
+    examEndTime: null,
+    productId: '1',
+    leadId: null,
   },
   props,
-  getDetail
+  formRef,
+  () => {
+    for (let key in formData) {
+      formData[key] = props.curRow[key];
+    }
+  }
 );
-const save = () => {};
+
+const rules = {
+  crmNo: [
+    {
+      required: true,
+      message: '项目单号必填',
+      type: 'error',
+      trigger: 'change',
+    },
+    {
+      max: 100,
+      message: '至多需要100个字',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  name: [
+    {
+      required: true,
+      message: '项目名称必填',
+      type: 'error',
+      trigger: 'change',
+    },
+    {
+      max: 100,
+      message: '至多需要100个字',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  beginTime: [
+    {
+      required: true,
+      message: '派单时间必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  crmUserId: [
+    {
+      required: true,
+      message: '派单人必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  customType: [
+    {
+      required: true,
+      message: '客户类型必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  customId: [
+    {
+      required: true,
+      message: '客户必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  productId: [
+    {
+      required: true,
+      message: '实施产品必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+  leadId: [
+    {
+      required: true,
+      message: '大区经理必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+};
+
+const save = async () => {
+  const valid = await formRef.value.validate();
+  if (valid !== true) return;
+
+  if (formData.examStartTime >= formData.examEndTime) {
+    MessagePlugin.success('考试开始时间不得迟于考试结束时间');
+    return;
+  }
+
+  const res = await dispatchEditApi(formData).catch(() => {});
+  if (!res) return;
+
+  MessagePlugin.success('保存成功');
+  emit('update:visible', false);
+  emit('success');
+};
 </script>

+ 0 - 44
src/views/service-unit/dispatch/dispatch-manage/delineation-dialog.vue

@@ -1,44 +0,0 @@
-// 划定 弹框
-<template>
-  <my-dialog
-    :visible="visible"
-    @close="emit('update:visible', false)"
-    header="划定"
-    :width="600"
-    :closeOnOverlayClick="false"
-  >
-    <div class="form-title">派单信息</div>
-    <t-form ref="formRef" :model="formData" labelWidth="120px">
-      <t-form-item label="服务单元名称:">
-        <t-select v-model="formData.a"></t-select>
-      </t-form-item>
-    </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="DelineationDialog">
-import { ref } from 'vue';
-import useClearDialog from '@/hooks/useClearDialog';
-const emit = defineEmits(['update:visible', 'success']);
-const formRef = ref(null);
-
-const props = defineProps({
-  visible: Boolean,
-  curRow: Object,
-});
-const { formData } = useClearDialog(
-  {
-    a: '',
-  },
-  props
-);
-const save = () => {
-  //ajax...
-  emit('success');
-};
-</script>

+ 281 - 108
src/views/service-unit/dispatch/dispatch-manage/index.vue

@@ -3,21 +3,17 @@
     <SearchForm :fields="fields" :params="params"></SearchForm>
     <div class="flex-1 page-wrap">
       <div class="btn-group">
+        <t-button theme="success" @click="handleAdd">新增</t-button>
         <t-button
           theme="success"
-          @click="
-            curRow = null;
-            showAddDispatchDialog = true;
-          "
-          >新增</t-button
-        >
-        <t-button theme="success" :disabled="!selectedRowKeys.length"
+          :disabled="!selectedRowKeys.length"
+          @click="handleBatchDisable"
           >作废</t-button
         >
         <t-button
           theme="success"
           :disabled="!selectedRowKeys.length"
-          @click="multDelineationHandle"
+          @click="handleMultDelineation"
           >批量划定</t-button
         >
       </div>
@@ -32,145 +28,188 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
+          current: pagination.pageNumber,
         }"
+        v-loading="tableLoading"
         :selected-row-keys="selectedRowKeys"
         select-on-row-click
         @select-change="selectChange"
       >
+        <template #type="{ col, row }">
+          {{ customerTypeFilter(row[col.colKey]) }}
+        </template>
+        <template #begin-time="{ col, row }">
+          {{ timestampFilter(row[col.colKey]) }}
+        </template>
+        <template #start-time="{ col, row }">
+          {{ timestampFilter(row[col.colKey]) }}
+        </template>
+        <template #end-time="{ col, row }">
+          {{ timestampFilter(row[col.colKey]) }}
+        </template>
+        <template #create-time="{ col, row }">
+          {{ timestampFilter(row[col.colKey]) }}
+        </template>
+        <template #operate="{ row }">
+          <div class="table-operations" @click.stop>
+            <t-link
+              theme="primary"
+              hover="color"
+              @click="handleDelineation(row)"
+            >
+              {{ row.serviceId ? '重新划定' : '划定' }}
+            </t-link>
+            <t-link theme="primary" hover="color" @click="handleEdit(row)">
+              修改
+            </t-link>
+          </div>
+        </template>
       </t-table>
     </div>
 
     <AddDispatchDialog
       v-model:visible="showAddDispatchDialog"
       :curRow="curRow"
+      @success="fetchData"
     ></AddDispatchDialog>
-    <DelineationDialog v-model:visible="showDelineationDialog" :curRow="curRow">
-    </DelineationDialog>
-    <MultDelineationDialog
+    <!-- DelineationDialog -->
+    <mult-delineation-dialog
       v-model:visible="showMultDelineationDialog"
-      :selectedRowKeys="selectedRowKeys"
+      :crm-ids="curCrmIds"
+      :dialog-width="curRow ? 1100 : 600"
+      @success="refresh"
     >
-    </MultDelineationDialog>
+      <div v-if="curRow">
+        <t-divider align="left" dashed>
+          <span>派单信息</span>
+        </t-divider>
+        <t-form label-width="140px">
+          <t-row :gutter="[0, 0]">
+            <t-col :span="4">
+              <t-form-item label="项目单号:">
+                {{ curRow.crmNo }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="项目名称:">
+                {{ curRow.name }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="派单时间:">
+                {{ timestampFilter(curRow.beginTime) }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="派单人:">
+                {{ curRow.crmUserName }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="客户类型:">
+                {{ customerTypeFilter(curRow.customType) }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="客户名称:">
+                {{ curRow.custom }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="考试开始时间:">
+                {{ timestampFilter(curRow.examStartTime) }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="考试结束时间:">
+                {{ timestampFilter(curRow.examEndTime) }}
+              </t-form-item>
+            </t-col>
+            <t-col :span="4">
+              <t-form-item label="实施产品:">
+                {{ curRow.product }}
+              </t-form-item>
+            </t-col>
+          </t-row>
+        </t-form>
+        <t-divider align="left" dashed>
+          <span>划定派单</span>
+        </t-divider>
+      </div>
+    </mult-delineation-dialog>
   </div>
 </template>
 
 <script setup lang="jsx" name="DispatchManage">
-import { reactive, ref } from 'vue';
-import { useRequest } from 'vue-request';
-import { getTableData } from '@/api/test';
+import { reactive, ref, computed, onMounted } from 'vue';
+import { omit } from 'lodash';
+import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
+
+import {
+  dispatchQueryApi,
+  dispatchBatchDisableApi,
+  dispatchCountWaitZoneApi,
+} from '@/api/service-unit';
 import useFetchTable from '@/hooks/useFetchTable';
 import AddDispatchDialog from './add-dispatch-dialog.vue';
-import DelineationDialog from './delineation-dialog.vue';
 import MultDelineationDialog from './mult-delineation-dialog.vue';
 
-const showDelineationDialog = ref(false);
+import { CUSTOMER_TYPE } from '@/config/constants';
+import { dictToOptionList } from '@/utils/tool';
+import { timestampFilter, customerTypeFilter } from '@/utils/filter';
+
 const showMultDelineationDialog = ref(false);
 const curRow = ref(null);
+const curCrmIds = ref([]);
 const showAddDispatchDialog = ref(false);
+let waitCount = ref(0);
+
 const selectedRowKeys = ref([]);
-const selectChange = (value, { selectedRowData }) => {
+const selectChange = (value) => {
   selectedRowKeys.value = value;
 };
-const multDelineationHandle = () => {
-  showMultDelineationDialog.value = true;
-};
-const handleDelineation = (row) => {
-  curRow.value = row;
-  showDelineationDialog.value = true;
-};
-const columns = [
-  {
-    colKey: 'row-select',
-    type: 'multiple',
-    width: 50,
-    fixed: 'left',
-  },
-  { colKey: 'a', title: '服务单元' },
-  { colKey: 'b', title: '项目单号' },
-  { colKey: 'c', title: '派单时间' },
-  { colKey: 'd', title: '派单人' },
-  { colKey: 'e', title: '客户类型' },
-  { colKey: 'f', title: '客户名称' },
-  { colKey: 'g', title: '项目名称' },
-  { colKey: 'h', title: '实施产品' },
-  { colKey: 'i', title: '考试开始时间' },
-  { colKey: 'j', title: '考试结束时间' },
-  { colKey: 'k', title: '大区经理' },
-  { colKey: 'l', title: '提交人' },
-  { colKey: 'm', title: '提交时间' },
-  {
-    title: '操作',
-    colKey: 'operate',
-    fixed: 'right',
-    width: 200,
-    cell: (h, { row }) => {
-      return (
-        <div class="table-operations">
-          <t-link
-            theme="primary"
-            hover="color"
-            onClick={(e) => {
-              e.stopPropagation();
-              handleDelineation(row);
-            }}
-          >
-            划定
-          </t-link>
-          <t-link
-            theme="primary"
-            hover="color"
-            onClick={(e) => {
-              e.stopPropagation();
-              curRow.value = row;
-              showAddDispatchDialog.value = true;
-            }}
-          >
-            修改
-          </t-link>
-          <t-link
-            theme="primary"
-            hover="color"
-            onClick={(e) => {
-              e.stopPropagation();
-              handleDelineation(row);
-            }}
-          >
-            重新划定
-          </t-link>
-        </div>
-      );
-    },
-  },
-];
 
 const fields = ref([
   {
-    prop: 'a',
+    prop: 'serviceId',
     label: '服务单元',
     type: 'select',
     labelWidth: 80,
     colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
   },
   {
-    prop: 'b',
+    prop: 'leadId',
     label: '大区经理',
     type: 'select',
     labelWidth: 80,
     colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
   },
   {
-    prop: 'c',
+    prop: 'crmUserId',
     label: '派单人',
     type: 'select',
     labelWidth: 80,
     colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
   },
   {
-    prop: 'd',
+    prop: 'type',
     label: '客户类型',
     type: 'select',
     labelWidth: 80,
     colSpan: 5,
+    options: dictToOptionList(CUSTOMER_TYPE),
+    attrs: {
+      clearable: true,
+    },
   },
   {
     type: 'buttons',
@@ -179,48 +218,182 @@ const fields = ref([
       {
         type: 'button',
         text: '查询',
+        onClick: () => {
+          refresh();
+        },
       },
     ],
   },
   {
-    prop: 'e',
+    prop: 'custom',
     label: '客户名称',
     labelWidth: 80,
     colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
   },
   {
-    prop: 'f',
+    prop: 'crmNo',
     label: '项目单号',
     labelWidth: 80,
     colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
   },
   {
-    prop: 'g',
+    prop: 'beginTime',
     label: '派单时间',
     type: 'daterange',
     labelWidth: 80,
     colSpan: 10,
+    attrs: {
+      clearable: true,
+    },
   },
 ]);
 const params = reactive({
-  a: '',
-  b: '',
-  c: '',
-  d: '',
-  e: '',
-  f: '',
-  g: [],
+  serviceId: '',
+  leadId: '',
+  crmUserId: '',
+  type: '',
+  custom: '',
+  crmNo: '',
+  beginTime: [],
 });
 
+const computedParams = computed(() => {
+  let data = omit(params, ['beginTime']);
+  data.startTime = params.beginTime[0];
+  data.endTime = params.beginTime[1];
+  return data;
+});
+
+const columns = [
+  {
+    colKey: 'row-select',
+    type: 'multiple',
+    width: 50,
+    fixed: 'left',
+  },
+  { colKey: 'service', title: '服务单元' },
+  { colKey: 'crmNo', title: '项目单号' },
+  { colKey: 'beginTime', title: '派单时间', cell: 'begin-time', width: 170 },
+  { colKey: 'crmUserName', title: '派单人' },
+  { colKey: 'customType', title: '客户类型', cell: 'type', width: 100 },
+  { colKey: 'custom', title: '客户名称' },
+  { colKey: 'name', title: '项目名称' },
+  { colKey: 'product', title: '实施产品' },
+  {
+    colKey: 'examStartTime',
+    title: '考试开始时间',
+    cell: 'start-time',
+    width: 170,
+  },
+  {
+    colKey: 'examEndTime',
+    title: '考试结束时间',
+    cell: 'end-time',
+    width: 170,
+  },
+  { colKey: 'leadName', title: '大区经理' },
+  { colKey: 'createName', title: '提交人' },
+  { colKey: 'createTime', title: '提交时间', cell: 'create-time', width: 170 },
+  {
+    title: '操作',
+    colKey: 'operate',
+    fixed: 'right',
+    width: 140,
+    cell: 'operate',
+  },
+];
+
 const {
   loading: tableLoading,
   pagination,
   tableData,
+  search,
   fetchData,
   onChange,
-} = useFetchTable(getTableData);
+} = useFetchTable(dispatchQueryApi, {
+  fetchDataHandle: () => {
+    selectedRowKeys.value = [];
+  },
+  params: computedParams,
+});
 
-const refresh = async () => {};
-</script>
+const refresh = () => {
+  search();
+  getWaitCount();
+};
+
+const getWaitCount = async () => {
+  const res = await dispatchCountWaitZoneApi();
+  waitCount.value = res || 0;
+};
+
+const handleMultDelineation = () => {
+  if (!selectedRowKeys.value.length) {
+    MessagePlugin.error('请选择要划定的记录');
+    return;
+  }
+  curRow.value = null;
+  curCrmIds.value = selectedRowKeys.value;
+  showMultDelineationDialog.value = true;
+};
+const handleDelineation = (row) => {
+  if (row.serviceId) {
+    const confirmDia = DialogPlugin({
+      header: '操作提示',
+      body: `重新划定到新的服务单元后,相关大区负责人信息、SOP信息将全部被清空,确定要操作吗?`,
+      confirmBtn: '确定',
+      cancelBtn: '取消',
+      onConfirm: () => {
+        confirmDia.hide();
+        curRow.value = row;
+        curCrmIds.value = [curRow.value.id];
+        showMultDelineationDialog.value = true;
+      },
+    });
+  } else {
+    curRow.value = row;
+    curCrmIds.value = [curRow.value.id];
+    showMultDelineationDialog.value = true;
+  }
+};
 
-<style></style>
+const handleAdd = () => {
+  curRow.value = null;
+  showAddDispatchDialog.value = true;
+};
+const handleEdit = (row) => {
+  curRow.value = row;
+  showAddDispatchDialog.value = true;
+};
+const handleBatchDisable = () => {
+  if (!selectedRowKeys.value.length) {
+    MessagePlugin.error('请选择要作废的记录');
+    return;
+  }
+  const confirmDia = DialogPlugin({
+    header: '作废提示',
+    body: `您确定要将所选的派单作废吗?`,
+    confirmBtn: '确定',
+    cancelBtn: '取消',
+    onConfirm: async () => {
+      confirmDia.hide();
+      const res = await dispatchBatchDisableApi(selectedRowKeys.value).catch(
+        () => {}
+      );
+      if (!res) return;
+      MessagePlugin.success('操作成功');
+      refresh();
+    },
+  });
+};
+
+onMounted(() => {
+  getWaitCount();
+});
+</script>

+ 49 - 14
src/views/service-unit/dispatch/dispatch-manage/mult-delineation-dialog.vue

@@ -1,16 +1,25 @@
-// 批量划定 弹框
 <template>
   <my-dialog
     :visible="visible"
-    @close="emit('update:visible', false)"
-    header="批量划定"
-    :width="500"
+    header="确认提示"
+    :width="dialogWidth"
+    attach="body"
     :closeOnOverlayClick="false"
+    @close="emit('update:visible', false)"
+    @opened="onOpened"
   >
-    <t-form ref="formRef" :model="formData" labelWidth="120px">
-      <t-form-item label="服务单元名称:">
-        <t-select v-model="formData.a"></t-select>
-      </t-form-item>
+    <slot>
+      <p>请选择您要需要将这些派单划定的服务单元!</p>
+    </slot>
+    <t-form ref="formRef" :data="formData" :rules="rules" :labelWidth="140">
+      <t-row :gutter="[0, 20]">
+        <t-col :span="12">
+          <t-form-item label="服务单元名称" name="serviceUnitId">
+            <select-service-unit v-model="formData.serviceUnitId">
+            </select-service-unit>
+          </t-form-item>
+        </t-col>
+      </t-row>
     </t-form>
     <template #foot>
       <t-button theme="default" @click="emit('update:visible', false)"
@@ -22,18 +31,44 @@
 </template>
 <script setup name="MultDelineationDialog">
 import { ref, reactive } from 'vue';
+import { MessagePlugin } from 'tdesign-vue-next';
+import { serviceScopeBindBatchApi } from '@/api/service-unit';
+
 const emit = defineEmits(['update:visible', 'success']);
 const formRef = ref(null);
 
 const props = defineProps({
   visible: Boolean,
-  selectedRowKeys: Array,
+  crmIds: Array,
+  dialogWidth: { type: Number, default: 600 },
 });
-const formData = reactive({
-  a: 1,
-});
-const save = () => {
-  //ajax...
+
+const formData = reactive({ serviceUnitId: null, crmIdList: [] });
+const rules = {
+  serviceUnitId: [
+    {
+      required: true,
+      message: '服务单元必选',
+      type: 'error',
+      trigger: 'change',
+    },
+  ],
+};
+
+const onOpened = () => {
+  formData.serviceUnitId = null;
+  formData.crmIdList = props.crmIds;
+  formRef.value.clearValidate();
+};
+
+const save = async () => {
+  const valid = await formRef.value.validate();
+  if (valid !== true) return;
+
+  const res = await serviceScopeBindBatchApi(formData).catch(() => {});
+  if (!res) return;
+  MessagePlugin.success('操作成功');
+  emit('update:visible', false);
   emit('success');
 };
 </script>

+ 8 - 8
src/views/service-unit/service-unit-manage/add-range/index.vue

@@ -21,7 +21,7 @@
           defaultCurrent: 1,
           defaultPageSize: 10,
           onChange,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
         :selected-row-keys="selectedRowKeys"
@@ -46,12 +46,12 @@
       </t-table>
     </div>
 
-    <!-- SelectServiceUnitDialog -->
-    <select-service-unit-dialog
-      v-model:visible="showSelectServiceUnitDialog"
+    <!-- MultDelineationDialog -->
+    <mult-delineation-dialog
+      v-model:visible="showMultDelineationDialog"
       :crm-ids="selectedRowKeys"
       @success="search"
-    ></select-service-unit-dialog>
+    ></mult-delineation-dialog>
   </div>
 </template>
 
@@ -63,9 +63,9 @@ import { serviceScopeUnbindCrmQueryApi } from '@/api/service-unit';
 import useFetchTable from '@/hooks/useFetchTable';
 import { CUSTOMER_TYPE } from '@/config/constants';
 import { customerTypeFilter, timestampFilter } from '@/utils/filter';
-import SelectServiceUnitDialog from './select-service-unit-dialog.vue';
+import MultDelineationDialog from '../../dispatch/dispatch-manage/mult-delineation-dialog.vue';
 
-let showSelectServiceUnitDialog = ref(false);
+let showMultDelineationDialog = ref(false);
 
 const fields = ref([
   {
@@ -196,6 +196,6 @@ const handlerBatchBind = () => {
     MessagePlugin.error('请选择要划定的记录');
     return;
   }
-  showSelectServiceUnitDialog.value = true;
+  showMultDelineationDialog.value = true;
 };
 </script>

+ 0 - 71
src/views/service-unit/service-unit-manage/add-range/select-service-unit-dialog.vue

@@ -1,71 +0,0 @@
-<template>
-  <my-dialog
-    :visible="visible"
-    header="确认提示"
-    :width="600"
-    attach="body"
-    :closeOnOverlayClick="false"
-    @close="emit('update:visible', false)"
-    @opened="onOpened"
-  >
-    <p>请选择您要需要将这些派单划定的服务单元!</p>
-    <t-form ref="formRef" :data="formData" :rules="rules" :labelWidth="140">
-      <t-row :gutter="[0, 20]">
-        <t-col :span="12">
-          <t-form-item label="服务单元名称" name="serviceUnitId">
-            <select-service-unit v-model="formData.serviceUnitId">
-            </select-service-unit>
-          </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="SelectServiceUnitDialog">
-import { ref, reactive } from 'vue';
-import { MessagePlugin } from 'tdesign-vue-next';
-import { serviceScopeBindBatchApi } from '@/api/service-unit';
-
-const emit = defineEmits(['update:visible', 'success']);
-const formRef = ref(null);
-
-const props = defineProps({
-  visible: Boolean,
-  crmIds: Array,
-});
-
-const formData = reactive({ serviceUnitId: null, crmIdList: [] });
-const rules = {
-  serviceUnitId: [
-    {
-      required: true,
-      message: '服务单元必选',
-      type: 'error',
-      trigger: 'change',
-    },
-  ],
-};
-
-const onOpened = () => {
-  formData.serviceUnitId = null;
-  formData.crmIdList = props.crmIds;
-  formRef.value.clearValidate();
-};
-
-const save = async () => {
-  const valid = await formRef.value.validate();
-  if (valid !== true) return;
-
-  const res = await serviceScopeBindBatchApi(formData).catch(() => {});
-  if (!res) return;
-  MessagePlugin.success('操作成功');
-  emit('update:visible', false);
-  emit('success');
-};
-</script>

+ 1 - 1
src/views/service-unit/service-unit-manage/range-manage/index.vue

@@ -33,7 +33,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
       >

+ 2 - 1
src/views/service-unit/service-unit-manage/regional-planning/add-region-dialog.vue

@@ -14,7 +14,8 @@
         </select-service-unit>
       </t-form-item>
       <t-form-item label="大区经理:" name="leadId">
-        <select-user v-model="formData.leadId"> </select-user>
+        <select-user v-model="formData.leadId" role-type="REGION_MANAGER">
+        </select-user>
       </t-form-item>
       <t-form-item label-width="0px" name="targetValue">
         <div style="height: 400px; width: 100%">

+ 6 - 10
src/views/service-unit/service-unit-manage/regional-planning/index.vue

@@ -8,7 +8,11 @@
         ></select-service-unit>
       </template>
       <template #lead="{ item, params }">
-        <select-user v-model="params[item.prop]" clearable></select-user>
+        <select-user
+          v-model="params[item.prop]"
+          role-type="REGION_MANAGER"
+          clearable
+        ></select-user>
       </template>
       <template #city="{ item, params }">
         <select-area
@@ -33,12 +37,9 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
-        :selected-row-keys="selectedRowKeys"
-        select-on-row-click
-        @select-change="selectChange"
       >
         <template #operate="{ row }">
           <div class="table-operations">
@@ -74,11 +75,6 @@ import AddRegionDialog from './add-region-dialog.vue';
 const curRow = ref(null);
 const showAddRegionDialog = ref(false);
 
-const selectedRowKeys = ref([]);
-const selectChange = (value) => {
-  selectedRowKeys.value = value;
-};
-
 const fields = ref([
   {
     prop: 'serviceUnitId',

+ 4 - 1
src/views/service-unit/service-unit-manage/unit-manage/add-unit-dialog.vue

@@ -55,7 +55,10 @@
         <span style="padding: 0 10px"> (区域协调人数量/项目数量)</span>
       </t-form-item>
       <t-form-item label="负责人:" name="serviceLeadId">
-        <select-user v-model="formData.serviceLeadId"></select-user>
+        <select-user
+          v-model="formData.serviceLeadId"
+          role-type="BUSSINESS"
+        ></select-user>
       </t-form-item>
     </t-form>
     <template #foot>

+ 6 - 2
src/views/service-unit/service-unit-manage/unit-manage/index.vue

@@ -2,7 +2,11 @@
   <div class="unit-manage flex flex-col h-full">
     <SearchForm :fields="fields" :params="params">
       <template #leader="{ item, params }">
-        <select-user v-model="params[item.prop]" clearable></select-user>
+        <select-user
+          v-model="params[item.prop]"
+          role-type="BUSSINESS"
+          clearable
+        ></select-user>
       </template>
     </SearchForm>
     <div class="flex-1 page-wrap">
@@ -20,7 +24,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
       >

+ 1 - 1
src/views/system/config-manage/checkin-manage/index.vue

@@ -23,7 +23,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
       >

+ 6 - 1
src/views/system/config-manage/customer-manage/edit-customer-dialog.vue

@@ -38,7 +38,12 @@
         </t-col>
         <t-col :span="6">
           <t-form-item label="服务档位">
-            <select-service-level v-model="formData.levelId" clearable>
+            <select-service-level
+              v-model="formData.levelId"
+              clearable
+              :type="formData.type"
+              type-required
+            >
             </select-service-level>
           </t-form-item>
         </t-col>

+ 3 - 3
src/views/system/config-manage/customer-manage/index.vue

@@ -31,7 +31,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
       >
@@ -64,7 +64,7 @@ import { ref, reactive } from 'vue';
 import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
 import useFetchTable from '@/hooks/useFetchTable';
 import EditCustomerDialog from './edit-customer-dialog.vue';
-import { customeryQueryApi, customerDeleteApi } from '@/api/system';
+import { customerQueryApi, customerDeleteApi } from '@/api/system';
 import { CUSTOMER_TYPE } from '@/config/constants';
 import { dictToOptionList } from '@/utils/tool';
 import { customerTypeFilter, timestampFilter } from '@/utils/filter';
@@ -183,7 +183,7 @@ const {
   fetchData,
   search,
   onChange,
-} = useFetchTable(customeryQueryApi, { params });
+} = useFetchTable(customerQueryApi, { params });
 
 const handleAdd = () => {
   curRow.value = null;

+ 1 - 1
src/views/system/notice-log/log-manage/index.vue

@@ -14,7 +14,7 @@
             defaultPageSize: 10,
             onChange,
             total: pagination.total,
-            current: pagination.page,
+            current: pagination.pageNumber,
           }"
           v-loading="tableLoading"
         >

+ 1 - 1
src/views/system/notice-log/notice-manage/index.vue

@@ -23,7 +23,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
         @select-change="selectChange"

+ 1 - 1
src/views/system/notice-log/notice-manage/notice-message-dialog.vue

@@ -42,7 +42,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         v-loading="tableLoading"
       >

+ 1 - 1
src/views/work-hours/work-hours-manage/abnormal-check/done-check.vue

@@ -12,7 +12,7 @@
         defaultPageSize: 10,
         onChange,
         total: pagination.total,
-        current: pagination.page,
+        current: pagination.pageNumber,
       }"
     >
     </t-table>

+ 1 - 1
src/views/work-hours/work-hours-manage/abnormal-check/wait-check.vue

@@ -26,7 +26,7 @@
         defaultPageSize: 10,
         onChange,
         total: pagination.total,
-        current: pagination.page,
+        current: pagination.pageNumber,
       }"
       :selected-row-keys="selectedRowKeys"
       select-on-row-click

+ 1 - 1
src/views/work-hours/work-hours-manage/work-attendance/index.vue

@@ -38,7 +38,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
         :selected-row-keys="selectedRowKeys"
         select-on-row-click

+ 1 - 1
src/views/work-hours/work-hours-manage/work-statistics/index.vue

@@ -20,7 +20,7 @@
           defaultPageSize: 10,
           onChange,
           total: pagination.total,
-          current: pagination.page,
+          current: pagination.pageNumber,
         }"
       >
       </t-table>