瀏覽代碼

人员调配

刘洋 1 年之前
父節點
當前提交
d8c6b3098e

+ 21 - 0
src/api/service-unit.js

@@ -174,3 +174,24 @@ export const serviceScopeBindNewApi = (data) =>
     url: '/api/service/service/scope/bind',
     data,
   });
+
+export const getCrmBindInfoApi = (params) =>
+  request({
+    url: '/api/admin/tb/crm/crm_bind_info',
+    params,
+  });
+
+export const getAllocationInfoApi = (params) =>
+  request({
+    url: '/api/admin/user/archives/allocation/info',
+    params,
+    loading: true,
+  });
+
+//人员调配保存
+export const saveAllocationInfoApi = (data) =>
+  request({
+    url: '/api/admin/user/archives/allocation/edit',
+    data,
+    loading: true,
+  });

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

@@ -11,12 +11,20 @@
       <t-row :gutter="[0, 20]">
         <t-col :span="6">
           <t-form-item label="项目单号" name="crmNo">
-            <t-input v-model="formData.crmNo" clearable></t-input>
+            <t-input
+              v-model="formData.crmNo"
+              clearable
+              :disabled="isEdit"
+            ></t-input>
           </t-form-item>
         </t-col>
         <t-col :span="6">
-          <t-form-item label="项目名称" name="name">
-            <t-input v-model="formData.name" clearable></t-input>
+          <t-form-item label="项目名称" name="crmName">
+            <t-input
+              v-model="formData.crmName"
+              clearable
+              :disabled="isEdit"
+            ></t-input>
           </t-form-item>
         </t-col>
         <t-col :span="6">
@@ -27,6 +35,7 @@
               enable-time-picker
               format="YYYY/MM/DD HH:mm"
               :time-picker-props="{ format: 'HH:mm' }"
+              :disabled="isEdit"
             />
           </t-form-item>
         </t-col>
@@ -35,12 +44,17 @@
             <select-type-user
               v-model="formData.crmUserId"
               type="ACCOUNT_MANAGER"
+              :disabled="isEdit"
             ></select-type-user>
           </t-form-item>
         </t-col>
         <t-col :span="6">
           <t-form-item label="客户类型" name="customType">
-            <t-select v-model="formData.customType" @change="customTypeChange">
+            <t-select
+              v-model="formData.customType"
+              @change="customTypeChange"
+              :disabled="isEdit"
+            >
               <t-option
                 v-for="(val, key) in CUSTOMER_TYPE"
                 :key="key"
@@ -90,15 +104,16 @@
             ></select-product>
           </t-form-item>
         </t-col>
-        <t-col :span="6">
+        <t-col :span="6" v-if="isEdit && otherParams.serviceId">
           <t-form-item label="服务单元">
             <select-service-unit
               v-if="visible"
-              v-model="formData.serviceId"
+              v-model="otherParams.serviceId"
               :filterParams="{
                 statusList: ['PUBLISH'],
                 type: formData.customType,
               }"
+              disabled
             ></select-service-unit>
           </t-form-item>
         </t-col>
@@ -113,34 +128,44 @@
   </my-dialog>
 </template>
 <script setup name="AddDispatchDialog">
-import { ref } from 'vue';
+import { ref, watch, reactive } 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';
+import { omit } from 'lodash-es';
 
 const props = defineProps({
   visible: Boolean,
   curRow: Object,
 });
 const emit = defineEmits(['update:visible']);
+
+const otherParams = reactive({
+  serviceId: props.curRow?.serviceId || '',
+});
+watch(
+  () => props.curRow,
+  () => {
+    otherParams.serviceId = props.curRow?.serviceId || '';
+    formData.customType = props.curRow?.customType || '';
+  }
+);
 const formRef = ref(null);
 
 const { formData, isEdit } = useClearDialog(
   {
     id: null,
     crmNo: '',
-    name: '',
+    crmName: '',
     beginTime: null,
-    serviceId: null,
     crmUserId: null,
-    customType: null,
     customId: null,
     examStartTime: null,
     examEndTime: null,
     productId: null,
-    leadId: null,
+    customType: '',
   },
   props,
   formRef,
@@ -166,7 +191,7 @@ const rules = {
       trigger: 'change',
     },
   ],
-  name: [
+  crmName: [
     {
       required: true,
       message: '项目名称必填',
@@ -234,7 +259,9 @@ const save = async () => {
   const valid = await formRef.value.validate();
   if (valid !== true) return;
 
-  const res = await dispatchEditApi(formData).catch(() => {});
+  const res = await dispatchEditApi(omit(formData, 'customType')).catch(
+    () => {}
+  );
   if (!res) return;
 
   MessagePlugin.success('保存成功');

+ 126 - 45
src/views/service-unit/dispatch/dispatch-manage/allocation-dialog.vue

@@ -12,31 +12,35 @@
       <t-row :gutter="[20, 0]">
         <t-col :span="6">
           <t-form-item label="服务单元"
-            >{{ dispatchInfo.service }}
+            >{{ requestInfo.serviceUnitName }}
           </t-form-item>
         </t-col>
         <t-col :span="6">
-          <t-form-item label="项目单号">{{ dispatchInfo.crmNo }} </t-form-item>
+          <t-form-item label="项目单号">{{ requestInfo.crmNo }} </t-form-item>
         </t-col>
         <t-col :span="6">
           <t-form-item label="客户类型"
-            >{{ customerTypeFilter(dispatchInfo.customType) }}
+            >{{ customerTypeFilter(requestInfo.customType) }}
           </t-form-item>
         </t-col>
         <t-col :span="6">
-          <t-form-item label="客户名称">{{ dispatchInfo.custom }} </t-form-item>
+          <t-form-item label="客户名称"
+            >{{ requestInfo.customName }}
+          </t-form-item>
         </t-col>
         <t-col :span="6">
-          <t-form-item label="服务档位"></t-form-item>
+          <t-form-item label="服务档位">{{ requestInfo.level }} </t-form-item>
         </t-col>
         <t-col :span="12">
           <t-form-item label="客户地址">
-            <!-- <t-space>
-              <span>{{ formData.province }}</span>
-              <span>{{ formData.city }}</span>
-              <span>{{ formData.area }}</span>
-              <span>{{ formData.address }}</span>
-            </t-space> -->
+            <t-space>
+              <span>
+                <span>{{ requestInfo.customProvince }}</span>
+                <span>{{ requestInfo.customCity }}</span>
+                <span>{{ requestInfo.customArea }}</span>
+              </span>
+              <span>{{ requestInfo.customAddress }}</span>
+            </t-space>
           </t-form-item>
         </t-col>
         <t-col :span="12">
@@ -49,16 +53,34 @@
                 :data="tableData"
                 bordered
               >
-                <template #users="{ row }">
-                  <select-free-engineer
-                    v-model="row.userIdList"
-                    :type="row.roleType"
-                    :unit-id="dispatchInfo.serviceId"
-                    :crm-no="dispatchInfo.crmNo"
+                <template #key="{ row }">
+                  <t-select
+                    v-if="row.key === 'REGION_COORDINATOR'"
+                    v-model="formData.allocationParams[0].userIdList"
+                    :options="options1"
+                    placeholder="请选择"
+                    multiple
+                    :keys="{ label: 'name', value: 'userId' }"
+                  />
+                  <t-select
+                    v-if="row.key === 'PROJECT_MANAGER'"
+                    v-model="formData.allocationParams[1].userIdList"
+                    :options="options2"
+                    placeholder="请选择"
                     multiple
-                    :min-collapsed-num="10"
-                    :max="row.roleType === 'REGION_COORDINATOR' ? 1 : 0"
-                  ></select-free-engineer>
+                    :keys="{ label: 'name', value: 'userId' }"
+                  />
+                  <t-select
+                    v-if="row.key === 'ENGINEER'"
+                    v-model="formData.allocationParams[2].userIdList"
+                    :options="options3"
+                    placeholder="请选择"
+                    multiple
+                    :keys="{ label: 'name', value: 'userId' }"
+                  />
+                </template>
+                <template #history="{ row }">
+                  {{ row.history.join('、') }}
                 </template>
               </t-table>
             </div>
@@ -78,58 +100,117 @@
 import { computed, onMounted, ref, watch } from 'vue';
 import { MessagePlugin } from 'tdesign-vue-next';
 import { MinusCircleFilledIcon } from 'tdesign-icons-vue-next';
-import useAuthenRole from '@/hooks/useAuthenRole';
-import {
-  personAllocateDeployApi,
-  personAllocateRoleDetailApi,
-} from '@/api/resource-guard';
+import {} from '@/api/resource-guard';
 import { customerTypeFilter } from '@/utils/filter';
 import { cloneDeep } from 'lodash-es';
-
+import {
+  getAllocationInfoApi,
+  saveAllocationInfoApi,
+} from '@/api/service-unit';
+import useClearDialog from '@/hooks/useClearDialog';
 const emit = defineEmits(['update:visible', 'success']);
 const props = defineProps({
   visible: Boolean,
   curRow: Object,
   dispatchInfo: { type: Object, default: () => {} },
 });
-
+const requestInfo = ref({});
 const formRef = ref(null);
+const init = () => {
+  return [
+    {
+      sopRoleType: 'REGION_COORDINATOR',
+      userIdList: [],
+    },
+    {
+      sopRoleType: 'PROJECT_MANAGER',
+      userIdList: [],
+    },
+    {
+      sopRoleType: 'ENGINEER',
+      userIdList: [],
+    },
+  ];
+};
+const { formData, isEdit } = useClearDialog(
+  {
+    crmDetailId: '',
+    allocationParams: init(),
+  },
+  props,
+  formRef,
+  () => {
+    formData.crmDetailId = props.curRow?.id;
+    formData.allocationParams = init();
+    getOptions();
+  }
+);
 
-const { roleList, getRoleList } = useAuthenRole();
+const options1 = ref([]);
+const options2 = ref([]);
+const options3 = ref([]);
+const getOptions = () => {
+  getAllocationInfoApi({
+    crmDetailId: props.curRow?.id,
+  }).then((res) => {
+    requestInfo.value = res;
+    tableData.value[0].history = res.regionCoordinatorInfo.historicalList;
+    tableData.value[1].history = res.projectManagerInfo.historicalList;
+    tableData.value[2].history = res.engineerInfo.historicalList;
+    options1.value = [
+      ...(res.regionCoordinatorInfo.allocatedList || []),
+      ...(res.regionCoordinatorInfo.canChooseList || []),
+    ];
+    options2.value = [
+      ...(res.projectManagerInfo.allocatedList || []),
+      ...(res.projectManagerInfo.canChooseList || []),
+    ];
+    options3.value = [
+      ...(res.engineerInfo.allocatedList || []),
+      ...(res.engineerInfo.canChooseList || []),
+    ];
+    formData.allocationParams[0].userIdList = (
+      res.regionCoordinatorInfo.allocatedList || []
+    ).map((item) => item.userId);
+    formData.allocationParams[1].userIdList = (
+      res.projectManagerInfo.allocatedList || []
+    ).map((item) => item.userId);
+    formData.allocationParams[2].userIdList = (
+      res.engineerInfo.allocatedList || []
+    ).map((item) => item.userId);
+  });
+};
 
 const tableData = ref([
   {
     roleName: '区域协调人',
-    users: [],
-    history: '',
-    roleType: 'REGION_COORDINATOR',
+    history: [],
+    key: 'REGION_COORDINATOR',
   },
   {
     roleName: '项目经理',
-    users: [],
-    history: '',
-    roleType: 'REGION_MANAGER',
+    history: [],
+    key: 'PROJECT_MANAGER',
   },
   {
     roleName: '工程师',
-    users: [],
-    history: '',
-    roleType: 'EFFECT_ENGINEER,ASSISTANT_ENGINEER',
+    history: [],
+    key: 'ENGINEER',
   },
 ]);
 const roleColumns = [
   { colKey: 'roleName', title: '角色', width: 120 },
-  { colKey: 'users', title: '人员', cell: 'users' },
-  { colKey: 'history', title: '', width: 60 },
+  { colKey: 'key', title: '人员', cell: 'key' },
+  { colKey: 'history', title: '历史人员记录', cell: 'history', width: 200 },
 ];
 
 const save = async () => {
-  MessagePlugin.success('保存成功');
-  emit('update:visible', false);
-  emit('success');
+  saveAllocationInfoApi(formData).then(() => {
+    MessagePlugin.success('保存成功');
+    emit('update:visible', false);
+    emit('success');
+  });
 };
 
-onMounted(() => {
-  getRoleList();
-});
+onMounted(() => {});
 </script>

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

@@ -14,7 +14,7 @@
         <template #icon><svg-icon name="delete" color="#262626" /></template>
         作废
       </t-button>
-      <t-button
+      <!-- <t-button
         v-if="perm.BUTTON_BatchDelimit"
         variant="outline"
         :disabled="!selectedRowKeys.length"
@@ -23,7 +23,7 @@
         <template #icon
           ><svg-icon name="batch-delineation" color="#262626" /></template
         >批量划定</t-button
-      >
+      > -->
     </div>
     <SearchForm :fields="fields" :params="params" :search="refresh">
       <template #service="{ item, params }">
@@ -137,10 +137,10 @@
         perm.LINK_Delimit || perm.LINK_ReDelimit || perm.BUTTON_BatchDelimit
       "
       v-model:visible="showMultDelineationDialog"
-      :crm-ids="curCrmIds"
       :custom-type="curCrmCustomType"
       :dialog-title="curRow?.serviceId ? '重新划定服务单元' : undefined"
       @success="refresh"
+      :curRow="curRow"
     >
       <div v-if="curRow">
         <h4>派单信息</h4>
@@ -229,6 +229,7 @@ import { timestampFilter, customerTypeFilter } from '@/utils/filter';
 const showMultDelineationDialog = ref(false);
 const curRow = ref(null);
 const curCrmIds = ref([]);
+const crmId = ref('');
 const curCrmCustomType = ref('');
 const showAddDispatchDialog = ref(false);
 let waitCount = ref(0);
@@ -438,6 +439,7 @@ const handleDelineation = (row) => {
         confirmDia.hide();
         curRow.value = row;
         curCrmIds.value = [row.id];
+        crmId.value = row.id;
         curCrmCustomType.value = row.customType;
         showMultDelineationDialog.value = true;
       },
@@ -445,6 +447,7 @@ const handleDelineation = (row) => {
   } else {
     curRow.value = row;
     curCrmIds.value = [row.id];
+    crmId.value = row.id;
     curCrmCustomType.value = row.customType;
     showMultDelineationDialog.value = true;
   }

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

@@ -6,7 +6,6 @@
     attach="body"
     :closeOnOverlayClick="false"
     @close="emit('update:visible', false)"
-    @opened="onOpened"
   >
     <slot></slot>
     <t-form ref="formRef" :data="formData" :rules="rules" :labelWidth="100">
@@ -26,6 +25,8 @@
         <t-col :span="12">
           <t-form-item label="大区经理" name="leadType">
             <t-radio-group
+              :disabled="!canEdit"
+              allowUncheck
               v-model="formData.leadType"
               name="leadType"
               :options="[
@@ -38,6 +39,7 @@
         <t-col :span="12" v-if="formData.leadType == 'BY_PERSON'">
           <t-form-item label="大区经理" name="leadId">
             <select-type-user
+              :disabled="!canEdit"
               v-model="formData.leadId"
               type="REGION_MANAGER"
             ></select-type-user>
@@ -54,28 +56,43 @@
   </my-dialog>
 </template>
 <script setup name="MultDelineationDialog">
-import { ref, reactive } from 'vue';
+import { ref, reactive, watch } from 'vue';
 import { MessagePlugin } from 'tdesign-vue-next';
-import { serviceScopeBindNewApi } from '@/api/service-unit';
+import { serviceScopeBindNewApi, getCrmBindInfoApi } from '@/api/service-unit';
 import { omit } from 'lodash-es';
+import useClearDialog from '@/hooks/useClearDialog';
 
 const emit = defineEmits(['update:visible', 'success']);
 const formRef = ref(null);
 
 const props = defineProps({
   visible: Boolean,
-  crmIds: Array,
   customType: String,
   dialogWidth: { type: Number, default: 640 },
   dialogTitle: { type: String, default: '划定服务单元' },
+  curRow: {
+    type: Object,
+    default: () => ({}),
+  },
 });
 
-const formData = reactive({
-  serviceUnitId: null,
-  crmIdList: [],
-  leadType: 'BY_AREA',
-  leadId: '',
-});
+const { formData, isEdit } = useClearDialog(
+  {
+    serviceUnitId: null,
+    crmId: null,
+    leadType: '',
+    leadId: '',
+  },
+  props,
+  formRef,
+  () => {
+    formData.serviceUnitId = null;
+    formData.crmId = props.curRow.id;
+    if (props.curRow?.serviceId) {
+      formData.serviceUnitId = props.curRow.serviceId;
+    }
+  }
+);
 const rules = {
   serviceUnitId: [
     {
@@ -94,13 +111,30 @@ const rules = {
     },
   ],
 };
-
-const onOpened = () => {
-  formData.serviceUnitId = null;
-  formData.crmIdList = props.crmIds;
-  formRef.value.clearValidate();
+const canEdit = ref(true);
+const serviceIdChange = (val) => {
+  getCrmBindInfoApi({
+    customId: props.curRow?.customId,
+    serviceUnitId: val,
+  }).then((res) => {
+    formData.leadType = res.leadType || '';
+    if (res.leadType) {
+      canEdit.value = res.canEdit;
+    }
+    if (res.leadType === 'BY_PERSON') {
+      formData.leadId = res.leadId || '';
+    }
+  });
 };
 
+watch(
+  () => formData.serviceUnitId,
+  (val) => {
+    if (val) {
+      serviceIdChange(val);
+    }
+  }
+);
 const save = async () => {
   const valid = await formRef.value.validate();
   if (valid !== true) return;