zhangjie 1 жил өмнө
parent
commit
0f077c411c

+ 27 - 0
src/components/global/my-drawer/index.vue

@@ -0,0 +1,27 @@
+<template>
+  <t-drawer v-bind="attrs">
+    <template #body v-if="isFirstOpen">
+      <slot></slot>
+    </template>
+    <template #footer v-if="slots.foot">
+      <slot name="foot"></slot>
+    </template>
+  </t-drawer>
+</template>
+<script setup name="MyDrawer">
+import { useAttrs, useSlots, ref, watch } from 'vue';
+const attrs = useAttrs();
+const slots = useSlots();
+let isFirstOpen = ref(false);
+watch(
+  () => attrs.visible,
+  () => {
+    if (!isFirstOpen.value) {
+      isFirstOpen.value = true;
+      if (attrs.callBacks) {
+        attrs.callBacks.forEach((item) => item());
+      }
+    }
+  }
+);
+</script>

+ 2 - 0
src/components/global/search-form/index.vue

@@ -248,6 +248,8 @@ const colToWidth = (colSpan) => {
 .table-search {
   padding: 16px 16px 1px;
   background-color: #fff;
+  border-bottom: 1px solid #e5e5e5;
+
   :deep(.t-date-range-picker) {
     width: 100%;
   }

+ 1 - 1
src/layout/index.vue

@@ -200,7 +200,7 @@ const clickHandler = (data) => {
       width: 18px;
       height: 18px;
     }
-    :deep(.t-menu__item) {
+    :deep(.t-menu__item:not(.t-is-active)) {
       color: #262626;
     }
     :deep(.t-menu__item.t-is-disabled) {

+ 1 - 1
src/router/modules/serviceUnit.js

@@ -81,7 +81,7 @@ export default {
             ),
           meta: {
             title: '新增服务范围',
-            bind: '"serviceScope"',
+            bind: 'serviceScope',
             // bind: 'RangeManage', //注意,这种不是菜单,但是也属于路由,比如name为"RangeManage"的时候,该路由也要有权限。需要在addRoute的时候考虑进去
           },
         },

+ 1 - 0
src/views/resource-guard/person-guard/person-files/add-person-file-dialog.vue

@@ -4,6 +4,7 @@
     :header="title"
     :width="1000"
     :closeOnOverlayClick="false"
+    attach="body"
     @close="emit('update:visible', false)"
     @opened="dialogOpened"
   >

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

@@ -4,6 +4,7 @@
     :header="`${isEdit ? '修改' : '新增'}派单`"
     :width="840"
     :closeOnOverlayClick="false"
+    attach="body"
     @close="emit('update:visible', false)"
   >
     <t-form ref="formRef" :data="formData" :rules="rules" labelWidth="120px">

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

@@ -8,11 +8,11 @@
     @close="emit('update:visible', false)"
     @opened="onOpened"
   >
-    <slot> </slot>
-    <t-form ref="formRef" :data="formData" :rules="rules" :labelWidth="140">
+    <slot></slot>
+    <t-form ref="formRef" :data="formData" :rules="rules" :labelWidth="100">
       <t-row :gutter="[0, 20]">
         <t-col :span="12">
-          <t-form-item :label="dialogTitle" name="serviceUnitId">
+          <t-form-item label="服务单元" name="serviceUnitId">
             <select-service-unit v-model="formData.serviceUnitId">
             </select-service-unit>
           </t-form-item>
@@ -47,7 +47,7 @@ const rules = {
   serviceUnitId: [
     {
       required: true,
-      message: '服务单元必选',
+      message: '未选择服务单元',
       type: 'error',
       trigger: 'change',
     },

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

@@ -64,7 +64,7 @@
 </template>
 
 <script setup name="AddRange">
-import { reactive, ref } from 'vue';
+import { reactive, ref, computed } from 'vue';
 import { omit } from 'lodash';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { serviceScopeUnbindCrmQueryApi } from '@/api/service-unit';
@@ -72,6 +72,7 @@ import useFetchTable from '@/hooks/useFetchTable';
 import { CUSTOMER_TYPE } from '@/config/constants';
 import { customerTypeFilter, timestampFilter } from '@/utils/filter';
 import MultDelineationDialog from '../../dispatch/dispatch-manage/mult-delineation-dialog.vue';
+import { dictToOptionList } from '@/utils/tool';
 
 let showMultDelineationDialog = ref(false);
 

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

@@ -0,0 +1,251 @@
+<template>
+  <my-drawer
+    :visible="visible"
+    size="80%"
+    :header="false"
+    :footer="false"
+    attach="body"
+    class="add-range-dialog"
+  >
+    <div class="add-range">
+      <div class="page-action">
+        <t-button
+          theme="primary"
+          :disabled="!selectedRowKeys.length"
+          @click="handlerBatchBind"
+        >
+          <template #icon><SaveIcon /></template>
+          批量划定
+        </t-button>
+        <t-button variant="text" @click="handleClose">
+          <template #icon><CloseIcon /></template>
+        </t-button>
+      </div>
+      <SearchForm :fields="fields" :params="params">
+        <template #user="{ item, params }">
+          <select-type-user
+            v-model="params[item.prop]"
+            type="ACCOUNT_MANAGER"
+          ></select-type-user>
+        </template>
+      </SearchForm>
+
+      <div class="flex-1 page-wrap">
+        <div class="btn-group"> </div>
+        <t-table
+          size="small"
+          row-key="id"
+          :columns="columns"
+          :data="tableData"
+          bordered
+          :pagination="{
+            defaultCurrent: 1,
+            defaultPageSize: 10,
+            onChange,
+            showJumper: true,
+            showPageSize: false,
+            current: pagination.pageNumber,
+          }"
+          v-loading="tableLoading"
+          :selected-row-keys="selectedRowKeys"
+          @select-change="selectChange"
+        >
+          <template #type="{ col, row }">
+            {{ customerTypeFilter(row[col.colKey]) }}
+          </template>
+          <template #begin-time="{ col, row }">
+            {{ timestampFilter(row[col.colKey]) }}
+          </template>
+          <template #exam-start-time="{ col, row }">
+            {{ timestampFilter(row[col.colKey]) }}
+          </template>
+          <template #exam-end-time="{ col, row }">
+            {{ timestampFilter(row[col.colKey]) }}
+          </template>
+          <template #create-time="{ col, row }">
+            {{ timestampFilter(row[col.colKey]) }}
+          </template>
+        </t-table>
+      </div>
+    </div>
+  </my-drawer>
+
+  <!-- MultDelineationDialog -->
+  <mult-delineation-dialog
+    v-model:visible="showMultDelineationDialog"
+    :crm-ids="selectedRowKeys"
+    dialog-title="保存划定"
+    @success="search"
+  >
+    <p style="color: #595959; margin-bottom: 28px"
+      >请选择您要需要将这些派单划定的服务单元!</p
+    >
+  </mult-delineation-dialog>
+</template>
+
+<script setup name="AddRangeDialog">
+import { reactive, ref, computed } from 'vue';
+import { omit } from 'lodash';
+import { MessagePlugin } from 'tdesign-vue-next';
+import { SaveIcon, CloseIcon } from 'tdesign-icons-vue-next';
+import { serviceScopeUnbindCrmQueryApi } from '@/api/service-unit';
+import useFetchTable from '@/hooks/useFetchTable';
+import { CUSTOMER_TYPE } from '@/config/constants';
+import { customerTypeFilter, timestampFilter } from '@/utils/filter';
+import MultDelineationDialog from '../../dispatch/dispatch-manage/mult-delineation-dialog.vue';
+import { dictToOptionList } from '@/utils/tool';
+
+const emit = defineEmits(['update:visible', 'success']);
+const props = defineProps({
+  visible: Boolean,
+});
+let showMultDelineationDialog = ref(false);
+
+const fields = ref([
+  {
+    prop: 'crmUserId',
+    label: '客户经理',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 5,
+    cell: 'user',
+  },
+  {
+    prop: 'productType',
+    label: '客户类型',
+    type: 'select',
+    labelWidth: 80,
+    colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'customName',
+    label: '客户名称',
+    labelWidth: 80,
+    colSpan: 5,
+    options: dictToOptionList(CUSTOMER_TYPE),
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    prop: 'crmNo',
+    label: '项目单号',
+    labelWidth: 80,
+    colSpan: 5,
+    attrs: {
+      clearable: true,
+    },
+  },
+  {
+    type: 'buttons',
+    colSpan: 2,
+    children: [
+      {
+        type: 'button',
+        text: '查询',
+        onClick: () => {
+          search();
+        },
+      },
+    ],
+  },
+  {
+    prop: 'crmTime',
+    label: '派单时间',
+    type: 'daterange',
+    labelWidth: 80,
+    colSpan: 10,
+    attrs: {
+      clearable: true,
+    },
+  },
+]);
+const params = reactive({
+  crmUserId: '',
+  productType: '',
+  customName: '',
+  crmNo: '',
+  crmTime: [],
+});
+const computedParams = computed(() => {
+  let data = omit(params, ['crmTime']);
+  data.startTime = params.crmTime[0];
+  data.endTime = params.crmTime[1];
+  return data;
+});
+
+const selectedRowKeys = ref([]);
+const selectChange = (value) => {
+  selectedRowKeys.value = value;
+};
+const columns = [
+  {
+    colKey: 'row-select',
+    type: 'multiple',
+    width: 50,
+    fixed: 'left',
+  },
+  { colKey: 'crmNo', title: '项目单号', minWidth: 80 },
+  { colKey: 'beginTime', title: '派单时间', width: 180, cell: 'begin-time' },
+  { colKey: 'crmUserName', title: '客户经理', minWidth: 80 },
+  { colKey: 'productType', title: '客户类型', width: 90, cell: 'type' },
+  { colKey: 'customName', title: '客户名称', minWidth: 100 },
+  { colKey: 'productName', title: '项目名称', minWidth: 80 },
+  { colKey: 'productName', title: '实施产品', minWidth: 80 },
+  {
+    colKey: 'examStartTime',
+    title: '考试开始时间',
+    width: 180,
+    cell: 'exam-start-time',
+  },
+  {
+    colKey: 'examEndTime',
+    title: '考试结束时间',
+    width: 180,
+    cell: 'exam-end-time',
+  },
+  { colKey: 'creatorName', title: '提交人', minWidth: 80 },
+  { colKey: 'createTime', title: '提交时间', width: 180, cell: 'create-time' },
+];
+const {
+  loading: tableLoading,
+  pagination,
+  tableData,
+  search,
+  onChange,
+} = useFetchTable(serviceScopeUnbindCrmQueryApi, {
+  fetchDataHandle: () => {
+    selectedRowKeys.value = [];
+  },
+  params: computedParams,
+});
+
+const handlerBatchBind = () => {
+  if (!selectedRowKeys.value.length) {
+    MessagePlugin.error('您还没有选择任何派单!');
+    return;
+  }
+  showMultDelineationDialog.value = true;
+};
+
+const handleClose = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style lang="less">
+.add-range-dialog {
+  .t-drawer__body {
+    background-color: #f2f3f5;
+    padding: 0;
+  }
+  .page-action {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+}
+</style>

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

@@ -52,6 +52,12 @@
         </template>
       </t-table>
     </div>
+
+    <!-- AddRangeDialog -->
+    <add-range-dialog
+      v-model:visible="showAddRangeDialog"
+      @success="fetchData"
+    ></add-range-dialog>
   </div>
 </template>
 
@@ -69,8 +75,10 @@ import useFetchTable from '@/hooks/useFetchTable';
 import { CUSTOMER_TYPE } from '@/config/constants';
 import { dictToOptionList } from '@/utils/tool';
 import { customerTypeFilter } from '@/utils/filter';
+import AddRangeDialog from './add-range-dialog.vue';
 
 const router = useRouter();
+const showAddRangeDialog = ref(false);
 
 const fields = ref([
   {
@@ -171,14 +179,16 @@ const getTotalData = async () => {
 };
 
 const handleAddRange = () => {
-  router.push({ name: 'AddRange' });
+  // router.push({ name: 'AddRange' });
+  showAddRangeDialog.value = true;
 };
 const handleDelete = (row) => {
   const confirmDia = DialogPlugin({
-    header: '移除提示',
+    header: '系统通知',
     body: `您确定要将当前派单从派单服务单元中移除吗?`,
     confirmBtn: '确定',
     cancelBtn: '取消',
+    theme: 'warning',
     onConfirm: async () => {
       confirmDia.hide();
       const res = await serviceScopeUnbindApi(row.crmId).catch(() => {});

+ 15 - 7
src/views/service-unit/service-unit-manage/regional-planning/add-region-dialog.vue

@@ -2,28 +2,28 @@
   <my-dialog
     :visible="visible"
     :header="title"
-    :width="600"
+    :width="670"
     attach="body"
     :closeOnOverlayClick="false"
     top="10vh"
     @close="emit('update:visible', false)"
   >
-    <t-form ref="formRef" :data="formData" :rules="rules" label-width="140px">
-      <t-form-item label="服务单元名称:" name="serviceUnitId">
+    <t-form ref="formRef" :data="formData" :rules="rules" label-width="80px">
+      <t-form-item label="服务单元" name="serviceUnitId">
         <select-service-unit v-model="formData.serviceUnitId">
         </select-service-unit>
       </t-form-item>
-      <t-form-item label="大区经理" name="leadId">
+      <t-form-item label="大区经理" name="leadId">
         <select-type-user v-model="formData.leadId" type="REGION_MANAGER">
         </select-type-user>
       </t-form-item>
-      <t-form-item label-width="0px" name="targetValue">
-        <div style="height: 400px; width: 100%">
+      <t-form-item label="区域" name="targetValue" requiredMark>
+        <div style="height: 400px">
           <t-transfer
             v-model="targetValue"
             v-model:checked="checkedRef"
             :data="areaData"
-            style="justify-content: center"
+            search
             @checked-change="handleCheckedChange"
           >
             <template #tree="slotProps">
@@ -147,3 +147,11 @@ const save = async () => {
   emit('success');
 };
 </script>
+
+<style lang="less" scoped>
+.t-transfer {
+  :deep(.t-transfer__list) {
+    width: 240px;
+  }
+}
+</style>

+ 12 - 8
src/views/service-unit/service-unit-manage/regional-planning/index.vue

@@ -1,5 +1,11 @@
 <template>
   <div class="unit-manage flex flex-col h-full">
+    <div class="page-action">
+      <t-button theme="primary" @click="handleAdd">
+        <template #icon><svg-icon name="add-circle" color="#fff" /></template
+        >新增大区
+      </t-button>
+    </div>
     <SearchForm :fields="fields" :params="params">
       <template #service="{ item, params }">
         <select-service-unit v-model="params[item.prop]"></select-service-unit>
@@ -15,9 +21,6 @@
       </template>
     </SearchForm>
     <div class="flex-1 page-wrap">
-      <div class="btn-group">
-        <t-button theme="success" @click="handleAdd">新增</t-button>
-      </div>
       <t-table
         size="small"
         row-key="id"
@@ -40,7 +43,7 @@
             <t-link theme="primary" hover="color" @click="handleEdit(row)">
               修改大区
             </t-link>
-            <t-link theme="danger" hover="color" @click="handleDelete(row)">
+            <t-link theme="primary" hover="color" @click="handleDelete(row)">
               删除
             </t-link>
           </div>
@@ -115,10 +118,10 @@ const params = reactive({
 });
 
 const columns = [
-  { colKey: 'serviceUnitName', title: '服务单元', minWidth: 150 },
-  { colKey: 'leadName', title: '大区经理', minWidth: 80 },
-  { colKey: 'regionInfo', title: '区域划分', minWidth: 150 },
-  { colKey: 'orderCount', title: '派单共计', minWidth: 80 },
+  { colKey: 'serviceUnitName', title: '服务单元', width: 160 },
+  { colKey: 'leadName', title: '大区经理', width: 120 },
+  { colKey: 'regionInfo', title: '区域划分', minWidth: 200 },
+  { colKey: 'orderCount', title: '派单共计', width: 100 },
   {
     title: '管理',
     colKey: 'operate',
@@ -150,6 +153,7 @@ const handleDelete = (row) => {
     body: `您确定要删除当前规划的大区吗?`,
     confirmBtn: '确定',
     cancelBtn: '取消',
+    theme: 'warning',
     onConfirm: async () => {
       confirmDia.hide();
       const res = await serviceRegionRemoveApi(row.serviceRegionId).catch(

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

@@ -4,6 +4,7 @@
     :header="`${isEdit ? '修改' : '新增'}服务单元`"
     :width="460"
     :closeOnOverlayClick="false"
+    attach="body"
     @close="emit('update:visible', false)"
   >
     <t-form ref="formRef" :data="formData" :rules="rules" labelWidth="120px">
@@ -77,7 +78,7 @@ import useClearDialog from '@/hooks/useClearDialog';
 import { serviceUnitEditApi } from '@/api/service-unit';
 import { CUSTOMER_TYPE } from '@/config/constants';
 
-const emit = defineEmits(['update:visible']);
+const emit = defineEmits(['update:visible', 'success']);
 const formRef = ref(null);
 
 const props = defineProps({