hlp 1 anno fa
parent
commit
4e17bf1b1d

+ 56 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/api.ts

@@ -1,14 +1,14 @@
 export const defalutModalForm = {
   taskName: "", //任务名称
   priority: "", //优先级
-  taskType: 2, //  任务类型
-  customerId: null, //  客户id 0
-  businessId: null, //商机id 1
+  taskType: 0, //  任务类型
+  customId: null, //  客户id 0
+  businessOpportunityId: null, //商机id 1
   orderId: null, //  订单id 2
   clueId: null, //线索id 3
   contactsId: null, //联系人id
   executorId: null, //执行人id
-  repeat: 0, //是否重复
+  isRepeat: 0, //是否重复
   repeatType: 0, //重复类型
   endType: 1, //结束类型
   repeatEndNever: 1,
@@ -37,23 +37,33 @@ export const TASK_TYPE = [
 ];
 export const TASK_TYPE_FIELD: {
   type: string;
-  field: "customerId" | "businessId" | "orderId" | "clueId";
+  field: "customId" | "businessOpportunityId" | "orderId" | "clueId";
+  valueIndex: string;
+  labelIndex: string;
 }[] = [
   {
     type: "0",
-    field: "customerId",
+    field: "customId",
+    valueIndex: "id",
+    labelIndex: "customName",
   },
   {
     type: "1",
-    field: "businessId",
+    field: "businessOpportunityId",
+    valueIndex: "id",
+    labelIndex: "name",
   },
   {
     type: "2",
     field: "orderId",
+    valueIndex: "value",
+    labelIndex: "label",
   },
   {
     type: "3",
     field: "clueId",
+    valueIndex: "id",
+    labelIndex: "clueName",
   },
 ];
 
@@ -68,4 +78,42 @@ export const defaultGenerateFormData = {
   list: [],
   config: {},
 };
-export const CUSTOMER_FORM_URL = "/sys-form/getListByCode/tasks";
+export const propertyToTaskTypeMap = {
+  customId: 0,
+  businessOpportunityId: 1,
+  orderId: 2,
+  clueId: 3,
+};
+export const propertyToEndTypeMap = {};
+/**
+ * 获取任务类型的函数
+ *
+ * @param obj 任意对象,期望该对象包含特定的属性以确定任务类型
+ * @returns 返回匹配到的任务类型值,如果没有匹配则返回null
+ */
+export function getTaskType(obj: any) {
+  if (!obj) {
+    return
+  }
+  if (obj.taskType) {
+    return obj.taskType;
+  }
+  let taskType = null;
+  for (const [property, taskTypeValue] of Object.entries(
+    propertyToTaskTypeMap
+  )) {
+    if (obj.hasOwnProperty(property)) {
+      taskType = taskTypeValue;
+      break;
+    }
+  }
+  return taskType;
+}
+
+export const CUSTOMER_FORM_URL = "/sys-form/getListByCode/tasks"; //自定义form表单
+export const ALL_CUSTOM = "/custom/getAll"; //客户
+export const ALL_CLUE = "/clue/getAll"; //线索
+export const ALL_BUSINESS = "/business-opportunity/getAll"; //商机
+export const ALL_CONTACTS = "/contacts/allContacts"; //联系人
+
+export const ALL_USERS = "/user/getSimpleActiveUserList"; //获取所有人

+ 77 - 40
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue

@@ -34,26 +34,27 @@
           <template v-for="item in TASK_TYPE_FIELD">
             <el-select v-model="form[item.field]" v-if="form.taskType == item.type" placeholder="请选择" clearable
               filterable :disabled="disabledList && disabledList.includes(item.field)">
-              <el-option v-for="item in taskTypeValueData" :key="item.value" :value="item.value" :label="item.label" />
+              <el-option v-for="v in taskTypeValueData" :key="v.id" :value="v[item.valueIndex]"
+                :label="v[item.labelIndex]" />
             </el-select>
           </template>
         </el-form-item>
-        <el-form-item label="联系人:" v-if="TASK_TYPE.find(v => v.value === (form.taskType || '1'))?.show">
+        <el-form-item label="联系人:" v-if="TASK_TYPE.find(v => v.value == (form.taskType || '1'))?.show">
           <el-select v-model="form.contactsId" placeholder="请选择" clearable filterable
             :disabled="disabledList && disabledList.includes('contactsId')">
-            <el-option v-for="item in contactValueData" :key="item.value" :value="item.value" :label="item.label" />
+            <el-option v-for="item in contactValueData" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>
         <el-form-item label="执行人:">
           <el-select v-model="form.executorId" placeholder="请选择" clearable multiple filterable
             :disabled="disabledList && disabledList.includes('executorId')">
-            <el-option v-for="item in executorValueData" :key="item.value" :value="item.value" :label="item.label" />
+            <el-option v-for="item in executorValueData" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>
         <el-form-item label="重复提醒:">
-          <el-switch v-model="form.repeat" :active-value="1" :inactive-value="0" @change="changeRepeat" />
+          <el-switch v-model="form.isRepeat" :active-value="1" :inactive-value="0" @change="changeRepeat" />
         </el-form-item>
-        <template v-if="form.repeat === 1">
+        <template v-if="form.isRepeat === 1">
           <el-form-item label="重复类型:">
             <el-select v-model="form.repeatType" placeholder="请选择" @change="changeRepeatType">
               <el-option v-for="item in REPEAT_TYPE" :key="item.value" :value="item.value" :label="item.label" />
@@ -65,14 +66,15 @@
             </el-form-item>
             <el-form-item label="结束:">
               <el-radio-group v-model="form.endType" @change="changeEndType">
-                <el-radio label="1" class="w-full">永不</el-radio>
-                <el-radio label="2" class="w-full mb-3"><el-input-number v-model="form.repeatEndCount" :min="1"
-                    controls-position="right" />
+                <el-radio :label="1" class="w-full">永不</el-radio>
+                <el-radio :label="2" class="w-full mb-3"><el-input-number v-model="form.repeatEndCount" :min="1"
+                    controls-position="right" :disabled="form.endType != 2" />
                   次以后
                 </el-radio>
-                <el-radio label="3" class="w-full">
+                <el-radio :label="3" class="w-full">
                   <el-date-picker v-model="form.repeatEndDate" type="date" placeholder="选择日期" style="width:65%"
-                    :disabled-date="(value: Date) => (new Date() > new Date(value))" />
+                    :disabled-date="(value: Date) => (new Date() > new Date(value))" value-format="YYYY-MM-DD"
+                    :disabled="form.endType != 3" />
                   以后
                 </el-radio>
               </el-radio-group>
@@ -111,11 +113,11 @@
         </el-form-item>
       </el-form>
       <GenerateForm ref="generateFormRef" :data="generateFormData" :value="form" />
-      <div v-if="editForm">
+      <div v-if="showLog">
         <el-form-item label="操作记录" label-width="7em">
           <div class="w-full">
             <div v-for="item in form.taskLogs" class=" border-b-2 w-full pl-3">
-              {{ `${item.modTime} ${item.userName} ${item.content}` }}
+              {{ `${dayjs(item.modTime).format('YYYY-MM-DD HH:mm:ss')} ${item.userName} ${item.content}` }}
             </div>
           </div>
         </el-form-item>
@@ -126,11 +128,11 @@
 
 <script lang="ts" setup>
 import { ref, watch } from 'vue';
-import { PRIORITY, TASK_TYPE, TASK_TYPE_FIELD, defalutModalForm, REPEAT_TYPE, CUSTOMER_FORM_URL, defaultGenerateFormData } from "./api";
+import { PRIORITY, TASK_TYPE, TASK_TYPE_FIELD, defalutModalForm, REPEAT_TYPE, CUSTOMER_FORM_URL, defaultGenerateFormData, ALL_CUSTOM, ALL_CLUE, ALL_BUSINESS, ALL_CONTACTS, ALL_USERS, getTaskType } from "./api";
 import { GenerateForm } from "@zmjs/form-design"
 import { get } from '@/utils/request';
 import { Delete, Plus } from "@element-plus/icons-vue"
-import { FormInstance } from 'element-plus';
+import { FormInstance, dayjs } from 'element-plus';
 import { getFromValue } from '@/utils/tools';
 import { Props, Emits } from './type';
 const props = defineProps<Props>()
@@ -139,10 +141,11 @@ watch(() => props.saveLoading, (val) => {
   if (val == "3") {
     formRef.value?.resetFields();
     form.value = { ...defalutModalForm };
+    generateFormRef.value?.reset();
   }
 })
 watch(() => props.visible, (val) => {
-  formRef.value?.resetFields();
+
   if (val) {
     get(CUSTOMER_FORM_URL).then(res => {
       if (Array.isArray(res.data) && res.data.length > 0) {
@@ -151,23 +154,47 @@ watch(() => props.visible, (val) => {
     })
   }
 })
+const customeData = ref<any>([])
+const clueData = ref<any>([])
+const businessData = ref<any>([])
 watch(() => props.editForm, (val) => {
-  if (!val) {
-    //TODO 如果是新增
-    form.value = { ...defalutModalForm };
-    taskTypeValueData.value = [{ label: '客户1', value: 1 }, { label: '客户2', value: 2 }];
-    contactValueData.value = [{ label: '联系人1', value: 1 }, { label: '联系人2', value: 2 }];
-    executorValueData.value = [{ label: '执行人1', value: 1 }, { label: '执行人2', value: 2 }];
-    return
-  }
-  //TODO 如果是编辑
-  form.value = { ...val };
-  customeDate.value = (form.value.repeatDesignDay || "").split(',').filter(Boolean);
-  console.log("customeDate.value ", customeDate.value, form.value.repeatDesignDay);
-  changeTaskType(form.value.taskType)
-  contactValueData.value = [{ label: '联系人1', value: 1 }, { label: '联系人2', value: 2 }];
-  executorValueData.value = [{ label: '执行人1', value: 1 }, { label: '执行人2', value: 2 }];
 
+  let taskType = 0;
+  if (val) {
+    taskType = getTaskType(val);
+  }
+  get(ALL_CUSTOM, {}).then(({ data }) => {
+    customeData.value = data;//客户
+    if (taskType == 0) {
+      taskTypeValueData.value = data;
+    }
+  })
+  get(ALL_BUSINESS, {}).then(({ data }) => {
+    businessData.value = data;//商机
+    if (taskType == 1) {
+      taskTypeValueData.value = data;
+    }
+  })
+  get(ALL_CLUE, {}).then(({ data }) => {
+    clueData.value = data;//线索
+    if (taskType == 3) {
+      taskTypeValueData.value = data;
+    }
+  })
+  get(ALL_CONTACTS, {}).then(({ data }) => {
+    contactValueData.value = data;//联系人
+  })
+  get(ALL_USERS, {}).then(({ data }) => {
+    executorValueData.value = data;
+  })
+  if (val) {
+    form.value = {
+      ...val,
+      taskType,
+    }
+  } else {
+    form.value = { ...defalutModalForm }
+  }
 })
 const rules = ref({
   taskName: [
@@ -180,9 +207,11 @@ const rules = ref({
 const form = ref<any>({});
 const formRef = ref<FormInstance>();
 const generateFormRef = ref<InstanceType<typeof GenerateForm>>();
-const generateFormData = ref<any>(defaultGenerateFormData);
+const generateFormData = ref<any>({ ...defaultGenerateFormData });
 function closeVisible() {
-  generateFormData.value = defaultGenerateFormData;
+  formRef.value?.resetFields();
+  generateFormData.value = { ...defaultGenerateFormData };
+  generateFormRef.value?.reset()
   emits('close')
 }
 function submitForm(formEl: FormInstance | undefined, isClose: boolean) {
@@ -193,6 +222,15 @@ function submitForm(formEl: FormInstance | undefined, isClose: boolean) {
     }
     const repeatDesignDay = customeDate.value.join(",")
     generateFormRef.value?.getData().then((res: any) => {
+      console.log(`{
+        ...form.value,
+        repeatDesignDay,
+        ...res
+      }`, {
+        ...form.value,
+        repeatDesignDay,
+        ...res
+      });
       let submitData = getFromValue({
         ...form.value,
         repeatDesignDay,
@@ -210,8 +248,8 @@ function changeTaskType(value: TASK_VALUE_TYPE) {
   form.value = {
     ...form.value,
     taskType: value,
-    customerId: null, //  客户id 0
-    businessId: null, //商机id 1
+    customId: null, //  客户id 0
+    businessOpportunityId: null, //商机id 1
     orderId: null, //  订单id 2
     clueId: null, //线索id 3
     contactsId: null, //联系人id
@@ -220,13 +258,13 @@ function changeTaskType(value: TASK_VALUE_TYPE) {
     case 0:
       taskTypeValueData.value = [];
       setTimeout(() => {
-        taskTypeValueData.value = [{ label: '客户1', value: 1 }, { label: '客户2', value: 2 }];
+        taskTypeValueData.value = customeData.value;
       }, 500)
       break;
     case 1:
       taskTypeValueData.value = [];
       setTimeout(() => {
-        taskTypeValueData.value = [{ label: "商机1", value: 1 }, { label: "商机2", value: 2 }]
+        taskTypeValueData.value = businessData.value;
       }, 500)
       break;
     case 2:
@@ -238,7 +276,7 @@ function changeTaskType(value: TASK_VALUE_TYPE) {
     case 3:
       taskTypeValueData.value = [];
       setTimeout(() => {
-        taskTypeValueData.value = [{ label: "线索1", value: 1 }, { label: "线索2", value: 2 }]
+        taskTypeValueData.value = clueData.value;
       }, 500)
       break;
     default:
@@ -254,7 +292,7 @@ const executorValueData = ref<any>([])
 function changeRepeat(value: string | number | boolean) {
   form.value = {
     ...form.value,
-    repeat: value,
+    isRepeat: value,
     repeatType: 0, //重复类型
     endType: 1, //结束类型
     repeatEndNever: 1,
@@ -288,7 +326,6 @@ function changeEndType(value: string | number | boolean) {
     repeatEndCount: null, //重复指定次数次数后结束
     repeatEndDate: null, //重复到指定日期后结束
     repeatDesignDay: null, //自定义日期
-    repeatDesignSameday: null, //自定义周期
   }
 }
 

+ 10 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/type.d.ts

@@ -16,12 +16,15 @@ export interface Props {
    * @default '新建任务'
    */
   title?: string;
+  /**
+   * 需要禁用的表单的字段
+   */
   disabledList?: (
     | "taskName"
     | "priority"
     | "taskType"
-    | "customerId"
-    | "businessId"
+    | "customId"
+    | "businessOpportunityId"
     | "orderId"
     | "clueId"
     | "contactsId"
@@ -29,6 +32,11 @@ export interface Props {
     | "startDate"
     | "endDate"
   )[];
+  /**
+   *  是否显示操作记录
+   * @default false
+   */
+  showLog?: boolean;
 }
 
 export interface Emits {

+ 13 - 10
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/ExportModal.vue

@@ -19,12 +19,12 @@
             <el-option v-for="item in PRIORITY " :key="item.value" :value="item.value" :label="item.label" />
           </el-select>
         </el-form-item>
-          <el-form-item label="执行人:">
+        <el-form-item label="执行人:">
           <el-select v-model="form.executorId" placeholder="请选择" clearable multiple filterable>
-            <el-option v-for="item in executorValueData" :key="item.value" :value="item.value" :label="item.label" />
+            <el-option v-for="item in executorValueData" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>
-         <el-form-item label="开始时间:" class="w50">
+        <el-form-item label="开始时间:" class="w50">
           <el-date-picker v-model="form.startDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" />
         </el-form-item>
         <el-form-item label="截止时间:" class="w50">
@@ -37,27 +37,30 @@
 
 <script lang="ts" setup>
 import { ref, watch } from 'vue';
-import { Props, Emits } from "./type"
-import { defalutExportForm,PRIORITY } from './api';
+import { defalutExportForm, PRIORITY,ALL_USERS } from './api';
+import { post } from '@/utils/request';
+import { Emits, Props } from './type';
 const props = defineProps<Props>();
 const emits = defineEmits<Emits>();
 watch(() => props.visible, (val) => {
   if (val) {
     form.value = { ...defalutExportForm }
-    executorValueData.value = [{ label: '执行人1', value: '1' }, { label: '执行人2', value: '2' }];
+    post(ALL_USERS, {}).then(({ data }) => {
+      executorValueData.value = data;
+    })
   }
- })
+})
 function closeVisible() {
   emits("close")
- }
+}
 function submit() {
   const { executorId, ...rest } = form.value;
   const data = {
     ...rest,
     executorId: executorId.join(','),
   }
-  emits("submit",data)
- }
+  emits("submit", data)
+}
 
 const formRef = ref();
 const form = ref<any>({})

+ 11 - 5
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/api.ts

@@ -21,10 +21,10 @@ export const defaultSearchForm = {
   orderName: "", //销售订单
   phone: "", //电话
   clueName: "", //线索名称
-  priority: "",//优先级
-  status: "",//任务状态
-  startDate: "",//开始时间
-  endDate: "",//截止时间
+  priority: "", //优先级
+  status: "", //任务状态
+  startDate: "", //开始时间
+  endDate: "", //截止时间
   pageIndex: 1,
   pageSize: 10,
 };
@@ -49,4 +49,10 @@ export const defalutExportForm = {
   endDate: "", //截止日期
 };
 
-export const PAGE_LIST = `/task/pageTask`;
+export const PAGE_LIST = `${MOD}/pageTask`; //列表
+export const ADD_TASK = `${MOD}/addTask`; //新建任务
+export const DELETE_TASKS = `${MOD}/deleteTasks`; //删除任务
+export const UPDATE_TASK_STATUS = `${MOD}/updateTaskStatus`; //更新任务状态
+export const UPDATE_TASK = `${MOD}/updateTask`;//修改任务
+
+export const ALL_USERS = "/user/getSimpleActiveUserList"; //获取所有人

+ 160 - 60
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/index.vue

@@ -12,25 +12,23 @@
                 <el-option v-for="item in PRIORITY" :key="item.value" :value="item.value" :label="item.label" />
               </el-select>
             </el-form-item>
-            <el-form-item label="客户名称:" label-width="7em" prop="customerName">
-              <el-input v-model="searchForm.customerName" placeholder="请输入" />
+            <el-form-item label="客户名称:" label-width="7em" prop="customName">
+              <el-input v-model="searchForm.customName" placeholder="请输入" />
             </el-form-item>
-            <el-form-item label="联系人:" label-width="7em" prop="tel">
-              <el-input v-model="searchForm.tel" placeholder="请输入" />
+            <el-form-item label="联系人:" label-width="7em" prop="contactsName">
+              <el-input v-model="searchForm.contactsName" placeholder="请输入" />
             </el-form-item>
-            <el-form-item label="执行人:" label-width="7em" prop="tel">
-              <el-select v-model="searchForm.status" placeholder="请选择">
-                <el-option v-for="item in STATUS" :key="item.value" :value="item.value" :label="item.label" />
-              </el-select>
+            <el-form-item label="执行人:" label-width="7em" prop="executorName">
+              <el-input v-model="searchForm.executorName" placeholder="请输入" />
             </el-form-item>
-            <el-form-item label="商机名称:" label-width="7em" prop="tel">
-              <el-input v-model="searchForm.tel" placeholder="请输入" />
+            <el-form-item label="商机名称:" label-width="7em" prop="businessName">
+              <el-input v-model="searchForm.businessName" placeholder="请输入" />
             </el-form-item>
-            <el-form-item label="销售订单:" label-width="7em" prop="tel">
-              <el-input v-model="searchForm.tel" placeholder="请输入" />
+            <el-form-item label="销售订单:" label-width="7em" prop="orderName">
+              <el-input v-model="searchForm.orderName" placeholder="请输入" />
             </el-form-item>
-            <el-form-item label="线索名称:" label-width="7em" prop="tel">
-              <el-input v-model="searchForm.tel" placeholder="请输入" />
+            <el-form-item label="线索名称:" label-width="7em" prop="clueName">
+              <el-input v-model="searchForm.clueName" placeholder="请输入" />
             </el-form-item>
             <el-form-item label="任务状态:" label-width="7em" prop="status">
               <el-select v-model="searchForm.status" placeholder="请选择">
@@ -51,7 +49,7 @@
         </div>
       </div>
     </div>
-    <div class="flex-1 p-5 overflow-auto" v-loading="loading">
+    <div class="flex-1 p-5 overflow-auto">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="ml-auto p-3">
           <el-button type="primary" @click="createTasks()">创建任务</el-Button>
@@ -59,8 +57,8 @@
           <el-button type="primary" @click="openImportModal()">导入</el-Button>
           <el-button type="primary" :loading="btnLoading" @click="exportTasks()">导出</el-Button>
         </div>
-        <div class="flex-1">
-          <el-table :data="tableData" style="width: 100%;height: 100%;" ref="tableRef">
+        <div class="flex-1 overflow-y-auto">
+          <el-table :data="tableData" style="width: 100%;height: 100%;" ref="tableRef" v-loading="loading">
             <el-table-column type="selection" width="55" />
             <el-table-column prop="taskName" label="任务名称" header-align="center" align="center" show-overflow-tooltip
               width="200" />
@@ -71,39 +69,70 @@
               </template>
             </el-table-column>
             <el-table-column prop="status" label="状态" width="100" header-align="center" align="center">
-
               <template #default="scope">
                 <el-text :type="STATUS[scope.row.status]?.type">
                   {{ STATUS[scope.row.status]?.label }}
                 </el-text>
               </template>
             </el-table-column>
-            <el-table-column prop="customerName" label="执行人" width="120" header-align="center" align="center" />
-            <el-table-column prop="startDate" label="开始时间" width="120" :sortable="true" header-align="center"
-              align="center" />
-            <el-table-column prop="endDate" label="截止时间" width="120" :sortable="true" header-align="center"
-              align="center" />
-            <el-table-column prop="contactsName" label="联系人" header-align="center" align="center" width="120" />
+            <el-table-column prop="customName" label="执行人" width="120" header-align="center" align="center" />
+            <el-table-column prop="startDate" label="开始时间" width="200" :sortable="true" header-align="center"
+              align="center" value-format="YYYY-MM-DD" />
+            <el-table-column prop="endDate" label="截止时间" width="200" :sortable="true" header-align="center"
+              align="center" value-format="YYYY-MM-DD" />
+            <el-table-column prop="contactsName" label="联系人" header-align="center" align="center" width="120">
+              <template #default="scope">
+                <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'contacts', 'contactsId')">
+                  {{ scope.row.contactsName }}
+                </el-link>
+              </template>
+            </el-table-column>
             <el-table-column prop="contactsTel" label="联系人号码" header-align="center" align="center" width="140" />
-            <el-table-column prop="customerName" label="客户名称" header-align="center" align="center" width="120" />
-            <el-table-column prop="businessName" label="商机名称" header-align="center" align="center" width="200" />
-            <el-table-column prop="businessName" label="销售订单" header-align="center" align="center" width="200" />
-            <el-table-column prop="businessName" label="线索名称" header-align="center" align="center" width="200" />
+            <el-table-column prop="customName" label="客户名称" header-align="center" align="center" width="120">
+              <template #default="scope">
+                <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'customer', 'customId')">
+                  {{ scope.row.customName }}
+                </el-link>
+              </template>
+            </el-table-column>
+            <el-table-column prop="businessName" label="商机名称" header-align="center" align="center" width="200">
+              <template #default="scope">
+                <el-link :underline="false" type="primary"
+                  @click="goDetail(scope.row, 'business', 'businessOpportunityId')">
+                  {{ scope.row.businessName }}
+                </el-link>
+              </template>
+            </el-table-column>
+            <el-table-column prop="orderName" label="销售订单" header-align="center" align="center" width="200">
+              <template #default="scope">
+                <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'order', 'orderId')">
+                  {{ scope.row.orderName }}
+                </el-link>
+              </template>
+            </el-table-column>
+            <el-table-column prop="clueName" label="线索名称" header-align="center" align="center" width="200">
+              <template #default="scope">
+                <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'thread', 'clueId')">
+                  {{ scope.row.clueName }}
+                </el-link>
+              </template>
+            </el-table-column>
+
             <el-table-column fixed="right" label="操作" header-align="center" align="center" width="150">
 
               <template #default="scope">
                 <el-button link type="primary" size="small" @click.prevent="editRow(scope.row)">
                   编辑
                 </el-button>
-                <el-button link type="primary" size="small" v-if="scope.row.status == '3'"
-                  @click.prevent="restart(scope.$index)">
+                <el-button link type="primary" size="small" v-if="scope.row.status == '2'"
+                  @click.prevent="restart(scope.row)">
                   重启
                 </el-button>
-                <el-button link type="primary" size="small" v-else @click.prevent="finishRow(scope.$index, scope)">
+                <el-button link type="primary" size="small" v-else @click.prevent="finishRow(scope.row)">
                   完成
                 </el-button>
 
-                <el-button link type="danger" size="small" @click.prevent="deleteRow(scope.$index)">
+                <el-button link type="danger" size="small" @click.prevent="deleteRow(scope.row)">
                   删除
                 </el-button>
               </template>
@@ -112,13 +141,12 @@
         </div>
         <div class="ml-auto">
           <el-pagination layout="total, prev, pager, next, sizes" :total="totalCount"
-            :current-page="searchForm.pageIndex" hide-on-single-page @size-change="sizeChage"
-            @current-change="currentChange" />
+            :current-page="searchForm.pageIndex" @size-change="sizeChage" @current-change="currentChange" />
         </div>
       </div>
     </div>
-    <TaskModal :visible="taskModalVisible" :title="taskForm ? '编辑任务' : '新建任务'" :save-loading="taskLoading"
-      :edit-form="taskForm" @close="closeTaskModal" @submit="submitForm" />
+    <TaskModal :visible="taskModalVisible" :title="isEdit ? '编辑任务' : '新建任务'" :save-loading="taskLoading"
+      :edit-form="taskForm" :show-log="isEdit" @close="closeTaskModal" @submit="submitForm" />
     <ImportModal :visible="importVisible" :save-loading="importLoading" @close="closeImportModal"
       @submit="importExcel" />
     <ExportModal :visible="exportVisible" :save-loading="exportLoading" @close="closeExportModal"
@@ -128,42 +156,59 @@
 
 <script lang="ts" setup>
 import { inject, onBeforeMount, onMounted, ref } from 'vue';
+import { useRouter } from 'vue-router';
 import { useStore } from '@/store';
-import { MOD, PRIORITY, STATUS, defaultSearchForm, PAGE_LIST } from './api';
-import { dayjs, ElTable } from 'element-plus';
+import { MOD, PRIORITY, STATUS, defaultSearchForm, PAGE_LIST, ADD_TASK, DELETE_TASKS, UPDATE_TASK, UPDATE_TASK_STATUS } from './api';
+import { ElTable, dayjs } from 'element-plus';
 import TaskModal from '@/components/TaskModal/index.vue';
 import ImportModal from './ImportModal.vue';
 import ExportModal from './ExportModal.vue';
-import { post, uploadFile } from '@/utils/request';
-import { getFromValue } from '@/utils/tools';
+import { get, post, uploadFile } from '@/utils/request';
+import { getFromValue, confirmAction } from '@/utils/tools';
+import { pushMap } from './type';
+const router = useRouter()
 const { getFunctionList } = useStore()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const pagePermission = ref<any[]>();
 const taskModalVisible = ref(false);
 const taskForm = ref<any>();
+const isEdit = ref(false);
+
 const taskLoading = ref<saveLoadingType>("1");
 function closeTaskModal() {
   taskModalVisible.value = false;
   taskForm.value = null;
 }
 function submitForm(data: any, isClose: boolean) {
-  const { executorId } = data;
-  console.log("原有的数据", data, isClose);
+  const { executorId, startDate, endDate, repeatEndDate } = data;
   let params = {
-    ...data
+    ...data,
+    startDate: startDate && dayjs(startDate).format('YYYY-MM-DD 00:00:00'),
+    endDate: endDate && dayjs(endDate).format('YYYY-MM-DD 23:59:59'),
+    repeatEndDate: repeatEndDate && dayjs(repeatEndDate).format('YYYY-MM-DD 23:59:59')
   }
   if (executorId) {
     params = {
       ...params,
-      executorId: executorId.join(',')
+      executorId: executorId.join(','),
+      taskLogs: []
     }
   }
-  console.log("提交的数据水水水水", params, isClose);
+  // console.log("提交的数据", getFromValue(params));
+  // return;
   taskLoading.value = "2";
-  setTimeout(() => {
+  let url = isEdit.value ? UPDATE_TASK : ADD_TASK
+  let msg = isEdit.value ? "修改成功" : "新建成功"
+  post(url, getFromValue(params)).then(() => {
     taskLoading.value = "3";
     taskModalVisible.value = isClose;
-  }, 2000)
+
+    globalPopup?.showSuccess(msg)
+    search();
+  }).catch(err => {
+    taskLoading.value = "4"
+    globalPopup?.showError(err.message)
+  })
 
 }
 const searchForm = ref<any>();
@@ -174,13 +219,19 @@ const totalCount = ref<number>(0);
 const tableData = ref<any[]>([])
 function search() {
   loading.value = true;
-  post(PAGE_LIST, getFromValue(searchForm.value)).then(({ data }) => {
+  const { startDate, endDate } = searchForm.value;
+  let params = {
+    ...searchForm.value,
+    startDate: startDate && dayjs(startDate).format('YYYY-MM-DD 00:00:00'),
+    endDate: endDate && dayjs(endDate).format('YYYY-MM-DD 23:59:59')
+  }
+  post(PAGE_LIST, getFromValue(params)).then(({ data }) => {
     loading.value = false;
     const { total, record } = data;
     totalCount.value = total;
     tableData.value = record;
   }).catch(err => {
-    console.log("err", err);
+    globalPopup?.showError(err);
     loading.value = false;
   })
 }
@@ -188,7 +239,6 @@ function reset() {
   searchForm.value = { ...defaultSearchForm };
 }
 function sizeChage(currentSize: number): void {
-  console.log("object", currentSize);
   searchForm.value = {
     ...searchForm.value,
     pageSize: currentSize,
@@ -198,7 +248,6 @@ function sizeChage(currentSize: number): void {
 }
 
 function currentChange(currentPage: number): void {
-  console.log("object", currentPage);
   searchForm.value = {
     ...searchForm.value,
     pageIndex: currentPage
@@ -209,10 +258,20 @@ function currentChange(currentPage: number): void {
 function createTasks() {
   taskModalVisible.value = true;
   taskForm.value = null;
+  isEdit.value = false;
 }
 function deleteTasks() {
-  console.log("deleteTasks", searchForm.value);
-  console.log(dayjs().format('YYYY-MM-DD'));
+  confirmAction("确定删除所选内容吗?").then(() => {
+    const taskIds = tableRef.value?.getSelectionRows()?.map((item: any) => item.id).join(",")
+    post(DELETE_TASKS, {
+      taskIds
+    }).then(() => {
+      search();
+      globalPopup?.showSuccess("删除成功")
+    }).catch(err => {
+      globalPopup?.showError(err)
+    })
+  });
 }
 
 
@@ -267,17 +326,58 @@ function exportExcel(data: any) {
   }, 2000)
 }
 function editRow(row: any) {
+  isEdit.value = true;
   taskModalVisible.value = true;
-  taskForm.value = row;
+  let value = {
+    ...row
+  }
+  if (value.executorId) {
+    value.executorId = value.executorId.split(",")
+  }
+  taskForm.value = value;
 }
-function finishRow(index: any, scope: any) {
-  console.log("finishRow", index, scope);
+function finishRow(item: any) {
+  post(UPDATE_TASK_STATUS, {
+    id: item.id,
+    status: 2
+  }).then(() => {
+    search()
+    globalPopup?.showSuccess("操作成功")
+  }).catch(err => {
+    globalPopup?.showError(err)
+  })
+}
+function restart(item: any) {
+  post(UPDATE_TASK_STATUS, {
+    id: item.id,
+    status: 0
+  }).then(() => {
+    search()
+    globalPopup?.showSuccess("操作成功")
+  }).catch(err => {
+    globalPopup?.showError(err)
+  })
 }
-function restart(index: any) {
-  console.log("restart", index);
+function deleteRow(item: any) {
+  confirmAction("确定删除吗?").then(() => {
+    post(DELETE_TASKS, {
+      taskIds: item.id
+    }).then(() => {
+      search();
+      globalPopup?.showSuccess("删除成功")
+    }).catch(err => {
+      console.log("err", err);
+      globalPopup?.showError(err)
+    })
+  })
 }
-function deleteRow(index: any) {
-  console.log("deleteRow", index);
+function goDetail(item: any, path: keyof pushMap, typeId: pushMap[keyof pushMap]) {
+  router.push({
+    path: `/${path}/detail`,
+    query: {
+      id: item[typeId]
+    }
+  })
 }
 onBeforeMount(() => {
   pagePermission.value = getFunctionList(MOD);

+ 7 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/type.d.ts

@@ -21,3 +21,10 @@ export interface Emits {
    */
   (event: "submit", submitData: Object): void;
 }
+export type pushMap = {
+  contacts: "contactsId"; //联系人
+  customer: "customId"; //客户
+  business: "businessOpportunityId"; //商机
+  order: "orderId"; //订单
+  thread: "clueId"; //线索
+};

+ 45 - 40
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

@@ -1,6 +1,6 @@
-import { defalutModalForm } from '@/components/TaskModal/api'
-import { ElMessageBox } from 'element-plus';
-import { get } from './request';
+import { defalutModalForm } from "@/components/TaskModal/api";
+import { ElMessageBox } from "element-plus";
+import { get } from "./request";
 /**
  * 判断值是否为空
  * @param value 值
@@ -49,7 +49,7 @@ export function resetFromValue<T>(formData: T, resetForm: any = {}) {
     result[key] = "";
   }
   // return result;
-  return { ...result, ...resetForm }
+  return { ...result, ...resetForm };
 }
 
 /**
@@ -113,34 +113,34 @@ export function getAllListByCode(arr: ListByCodeType) {
 /**
  * 获取当月第一天
  * @param date 日期 new Date()
- * @returns 
+ * @returns
  */
-export function getFirstDayOfMonth(date: Date) {  
-  const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);  
-  return formatDate(firstDay);  
-}  
+export function getFirstDayOfMonth(date: Date) {
+  const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
+  return formatDate(firstDay);
+}
 
 /**
  * 获取当月最后一天
  * @param date 日期 new Date()
- * @returns 
+ * @returns
  */
-export function getLastDayOfMonth(date: Date) {  
-  const nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0);  
-  return formatDate(nextMonth);  
-}  
+export function getLastDayOfMonth(date: Date) {
+  const nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0);
+  return formatDate(nextMonth);
+}
 
 /**
  * 将 Date 对象格式化为 "YYYY-MM-DD" 的形式
  * @param date 日期 new Date()
- * @returns 
+ * @returns
  */
-export function formatDate(date: Date) {  
-  const year = date.getFullYear();  
-  const month = (1 + date.getMonth()).toString().padStart(2, '0');  
-  const day = date.getDate().toString().padStart(2, '0');  
-  return `${year}-${month}-${day}`;  
-}  
+export function formatDate(date: Date) {
+  const year = date.getFullYear();
+  const month = (1 + date.getMonth()).toString().padStart(2, "0");
+  const day = date.getDate().toString().padStart(2, "0");
+  return `${year}-${month}-${day}`;
+}
 
 /**
  * 获取创建任务的 form
@@ -150,8 +150,8 @@ export function formatDate(date: Date) {
 export function createTaskFromType(taskType: TASK_VALUE_TYPE) {
   return {
     ...defalutModalForm,
-    taskType
-  }
+    taskType,
+  };
 }
 
 /**
@@ -160,14 +160,14 @@ export function createTaskFromType(taskType: TASK_VALUE_TYPE) {
  * @param fileName 文件名称
  */
 export async function downloadFile(fileData: any, fileName: string) {
-  const url=fileData;
-  const link = document.createElement('a');
+  const url = fileData;
+  const link = document.createElement("a");
   link.href = url;
-  link.setAttribute('download', fileName);
+  link.setAttribute("download", fileName);
   document.body.appendChild(link);
   link.click();
   document.body.removeChild(link);
-};
+}
 
 /**
  * 消息弹窗框
@@ -177,19 +177,24 @@ export async function downloadFile(fileData: any, fileName: string) {
  * @param options 消息弹窗框其他配置
  * @returns promise
  */
-export function confirmAction(message: string, title = '', type: componentType = 'warning', options = {}) {  
-  return new Promise<void>((resolve, reject) => {  
-    ElMessageBox.confirm(message, title, {  
-      ...{  
-        confirmButtonText: '确定',  
-        cancelButtonText: '取消',  
-        type: type,  
-      },  
-      ...options,  
-    })  
-      .then(() => resolve())  
-      .catch(() => reject());  
-  });  
+export function confirmAction(
+  message: string,
+  title = "",
+  type: componentType = "warning",
+  options = {}
+) {
+  return new Promise<void>((resolve, reject) => {
+    ElMessageBox.confirm(message, title, {
+      ...{
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: type,
+      },
+      ...options,
+    })
+      .then(() => resolve())
+      .catch(() => reject());
+  });
 }
 
 /**