瀏覽代碼

Merge remote-tracking branch 'origin/master'

ysm 11 月之前
父節點
當前提交
7517bd642c
共有 63 個文件被更改,包括 11693 次插入38235 次删除
  1. 19 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue
  2. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/taskFunction.ts
  3. 8 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue
  4. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/deteleTables.vue
  5. 22 12
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue
  6. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue
  7. 29 14
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue
  8. 26 13
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  9. 5 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/type.d.ts
  10. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/api.ts
  11. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/deteleTables.vue
  12. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/information.vue
  13. 2 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue
  14. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/detail/index.vue
  15. 12 11
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue
  16. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/api.ts
  17. 9 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/attachment.vue
  18. 4 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/deteleTables.vue
  19. 22 12
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/information.vue
  20. 9 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/operationRecord.vue
  21. 13 14
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedBusiness.vue
  22. 11 11
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedContacts.vue
  23. 17 16
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedOrders.vue
  24. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/detail/index.vue
  25. 46 20
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  26. 7 7
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts
  27. 18 12
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/deteleTables.vue
  28. 33 23
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/information.vue
  29. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/products.vue
  30. 7 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/rebate.vue
  31. 3 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/detail/index.vue
  32. 23 14
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue
  33. 17 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue
  34. 23 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue
  35. 23 10
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue
  36. 24 15
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue
  37. 5 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue
  38. 17 15
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  39. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/register.vue
  40. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/system/role/index.vue
  41. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/api.ts
  42. 39 17
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/index.vue
  43. 3 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/api.ts
  44. 99 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/index.vue
  45. 5 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/AddPersonnelModal.vue
  46. 100 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/BatchOperation.vue
  47. 26 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/type.ts
  48. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/type.d.ts
  49. 23 7
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  50. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/type.d.ts
  51. 10821 37852
      fhKeeper/formulahousekeeper/management-crm/crm.log
  52. 4 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java
  53. 2 2
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/SalesOrderService.java
  54. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ProductServiceImpl.java
  55. 8 8
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/SalesOrderServiceImpl.java
  56. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessOpportunityMapper.xml
  57. 2 2
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WxCorpInfoController.java
  58. 1 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/WxCorpInfoService.java
  59. 20 6
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  60. 8 8
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  61. 8 4
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java
  62. 43 12
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ReportMapper.xml
  63. 5 4
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/statistic/index.vue

+ 19 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/index.vue

@@ -33,7 +33,7 @@
           </template>
           <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)">
+              filterable :disabled="disabledList && disabledList.includes(item.field)" @change="(e: any) => {taskFormChange(e, item.field)}">
               <el-option v-for="v in taskTypeValueData" :key="v.id" :value="v[item.valueIndex]"
                 :label="v[item.labelIndex]" />
             </el-select>
@@ -41,7 +41,7 @@
         </el-form-item>
         <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')">
+            :disabled="(disabledList && disabledList.includes('contactsId'))">
             <el-option v-for="item in contactValueData" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>
@@ -135,6 +135,7 @@ import { Delete, Plus } from "@element-plus/icons-vue"
 import { FormInstance, dayjs } from 'element-plus';
 import { getFromValue } from '@/utils/tools';
 import { Props, Emits } from './type';
+import { URL_GETALL } from '@/pages/contacts/api';
 const props = defineProps<Props>()
 const emits = defineEmits<Emits>();
 watch(() => props.saveLoading, (val) => {
@@ -214,6 +215,22 @@ const form = ref<any>({});
 const formRef = ref<FormInstance>();
 const generateFormRef = ref<InstanceType<typeof GenerateForm>>();
 const generateFormData = ref<any>({ ...defaultGenerateFormData });
+function taskFormChange(e: any, field: 'customId' | 'businessOpportunityId' | 'orderId' | 'clueId') {
+  const fieldMap = {
+    'customId': 'customerId',
+    'businessOpportunityId': 'businessId',
+    'orderId': 'salesId',
+    'clueId': ''
+  };
+  let fieldStr = fieldMap[field] || '';
+  updateContactPerson(e, fieldStr)
+}
+function updateContactPerson(val: any, field: string) {
+  let formVal = field ? { [field]: val } : {}
+  get(URL_GETALL, { ...formVal }).then(({ data }) => {
+    contactValueData.value = data;//联系人
+  })
+}
 function closeVisible() {
   formRef.value?.resetFields();
   generateFormData.value = { ...defaultGenerateFormData };

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/components/TaskModal/taskFunction.ts

@@ -24,7 +24,7 @@ export async function createTask(submitData: any, isClose: boolean) : Promise<Ta
         post(ADD_TASK, getFromValue(params)).then(() => {
             resolve({ saveLoading: '3', isClose })
         }).catch((err) => {
-            reject({ saveLoading: '4', isClose, message: err.message })
+            reject({ saveLoading: '4', isClose, message: err.msg })
         })
     })
 }

+ 8 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue

@@ -16,7 +16,7 @@
                 <el-table-column prop="name" label="附件名称" width="180" />
                 <el-table-column prop="size" label="附件大小" width="120" />
                 <el-table-column prop="userName" label="上传人" width="120" />
-                <el-table-column prop="createTime" label="上传时间" width="180" />
+                <el-table-column prop="newCreateTime" label="上传时间" width="180" />
                 <el-table-column label="操作" width="180" fixed="right">
                     <template #default="scope">
                         <el-button link type="primary" size="large" @click="fileDownload(scope.row)">下载</el-button>
@@ -50,6 +50,7 @@ import { post, uploadFile } from '@/utils/request';
 import { confirmAction, downloadFile } from '@/utils/tools';
 import { ref, reactive, onMounted, onUnmounted, defineEmits, defineExpose, inject, watchEffect } from 'vue'
 import { DETELEFILEFILE, REFIENAMEFILE, UPLOADFILEFILE } from '../api';
+import { formatDate } from '@/utils/times';
 
 const emits = defineEmits(['refreshData']);
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -119,7 +120,12 @@ async function httpUploadFile(param: UploadRequestOptions) {
 
 watchEffect(() => {
     information.value = props.information
-    attachmenttable.value = (props.information.uploadFilePList || [])
+    attachmenttable.value = (props.information.uploadFilePList || []).map((item: any) => {
+        return {
+            ...item,
+            newCreateTime: formatDate(new Date(item.createTime))
+        }
+    })
 });
 
 // 生命周期钩子

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/deteleTables.vue

@@ -100,7 +100,7 @@ function businessOperationItem(value: string | number, label: string, type: oper
             getTableList()
             changeBatch(false)
         }).catch((err) => {
-            globalPopup?.showError(err.message)
+            globalPopup?.showError(err.msg)
         })
     })
 }

+ 22 - 12
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue

@@ -7,41 +7,50 @@
                 <el-button type="primary" @click="claimBusiness()" v-if="!information.customerId">认领</el-button>
                 <el-button type="primary" @click="showVisible('transferBusinessVisible')"
                     v-if="information.customerId">转移</el-button>
-                <el-button type="primary" @click="showVisible('editBusinessVisible')">编辑</el-button>
+                <el-button type="primary" v-permission="['businessAddAnEdit']" @click="showVisible('editBusinessVisible')">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-20 text-right text-gray-500">商机名称:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.name }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ information.name }}</div>
             </div>
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-22 text-right text-gray-500">客户名称:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.customerName }}
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ information.customerName }}
                 </div>
             </div>
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-22 text-right text-gray-500">联系人:</div>
                 <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.contactsName }}
                 </div>
             </div>
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-22 text-right text-gray-500">商机金额:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.amountOfMoney || 0
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ information.amountOfMoney || 0
                 }} 元</div>
             </div>
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-22 text-right text-gray-500">负责人:</div>
                 <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.inchargerName }}</div>
             </div>
-            <div class="formItem flex pt-5 pb-1">
+            <div class="formItem flex pt-3 pb-1">
                 <div class="w-22 text-right text-gray-500">预计成交日期:</div>
                 <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{
                     information.expectedTransactionDate }}</div>
             </div>
-            <div class="formItem flex pt-5 pb-1" style="width: 100%;">
+            <div class="formItem flex pt-3 pb-1">
+                <div class="w-22 text-right text-gray-500">创建人:</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.creatorName }}</div>
+            </div>
+            <div class="formItem flex pt-3 pb-1">
+                <div class="w-22 text-right text-gray-500">创建时间:</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{
+                    information.createTime }}</div>
+            </div>
+            <div class="formItem flex pt-3 pb-1" style="width: 100%;">
                 <div class="w-22 text-right text-gray-500">备注:</div>
-                <div class="flex-1 ml-1 text ">
+                <div class="flex-1 ml-1 text " v-ellipsis-tooltip>
                     {{ information.remark }}
                 </div>
             </div>
@@ -204,6 +213,7 @@ function claimBusiness() {
 function editBusiness() {
     generateForm.value?.getData().then((res: any) => {
         let formVal = {
+            id: information.value.id,
             ...res,
             expectedTransactionDate: res.expectedTransactionDate ? formatDateTime(new Date(res.expectedTransactionDate)) : '',
             businessItemProductList: JSON.stringify(productTableListValue.value)

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue

@@ -3,7 +3,7 @@
         <div class="flex justify-between">
             <div class="title">相关产品</div>
             <div>
-                <el-button type="primary" @click="editProductShow()">编辑产品</el-button>
+                <el-button type="primary" v-permission="['businessAddAnEdit']" @click="editProductShow()">编辑产品</el-button>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">

+ 29 - 14
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue

@@ -7,7 +7,7 @@
         </el-link>
       </div>
       <div class="mr-8">
-        <el-select v-model="optionVal" placeholder="请选择" style="width: 150px" filterable @change="selectChange()">
+        <el-select v-model="optionVal" placeholder="请选择" style="width: 250px" filterable @change="selectChange()">
           <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </div>
@@ -19,29 +19,35 @@
           <div class="text-nowrap">{{ item.plan }}</div>
         </div>
       </div>
-      <div class="relative rounded-md flex items-center itemPing backGray endStep item pl-6 pr-6 mr-4 resetStyle" v-if="currentStage >= 0">
+      <div class="relative rounded-md flex items-center itemPing backGray endStep item pl-6 pr-6 mr-4 resetStyle"
+        v-if="currentStage >= 0">
         <el-select v-model="stageStatusVal" placeholder="结束" style="width: 100px" class="selectClas"
           @change="advanceChange()">
           <el-option v-for="(item, index) in stageListOption" :key="index" :label="item.label" :value="item.value" />
         </el-select>
       </div>
-      <div class="relative rounded-md flex items-center justify-around backOrange endStep item pl-6 pr-6 mr-4 resetStyle" v-if="businessInfo.stageValue == '输单'" style="padding-top: 6px;padding-bottom: 6px;">
+      <div
+        class="relative rounded-md flex items-center justify-around backOrange endStep item pl-6 pr-6 mr-4 resetStyle"
+        v-if="businessInfo.stageValue == '输单'" style="padding-top: 6px;padding-bottom: 6px;">
         <div>{{ businessInfo.stageValue }}</div>
         <div class="ml-5">0%</div>
       </div>
-      <div class="relative rounded-md flex items-center justify-around backWan endStep item pl-6 pr-6 mr-4 resetStyle" v-if="businessInfo.stageValue == '赢单'" style="padding-top: 6px;padding-bottom: 6px;">
+      <div class="relative rounded-md flex items-center justify-around backWan endStep item pl-6 pr-6 mr-4 resetStyle"
+        v-if="businessInfo.stageValue == '赢单'" style="padding-top: 6px;padding-bottom: 6px;">
         <div>{{ businessInfo.stageValue }}</div>
         <div class="ml-4"> 100%</div>
       </div>
-      <div class="relative rounded-md flex items-center justify-around backGray endStep item pl-6 pr-6 mr-4 resetStyle" v-if="businessInfo.stageValue == '无效'" style="padding-top: 6px;padding-bottom: 6px;">
+      <div class="relative rounded-md flex items-center justify-around backGray endStep item pl-6 pr-6 mr-4 resetStyle"
+        v-if="businessInfo.stageValue == '无效'" style="padding-top: 6px;padding-bottom: 6px;">
         <div>{{ businessInfo.stageValue }}</div>
         <div class="ml-5">0%</div>
       </div>
-      <div class="bg-[#075985] rounded-md text itemPing pl-2 pr-2 flex items-center aloneText" @click="advancementStage()"
+      <div class="bg-[#075985] rounded-md text itemPing pl-2 pr-2 flex items-center aloneText"
         v-if="currentStage != -1">
-        <el-link :underline="false" v-if="(currentStage + 1) != stageList.length">推进至下个阶段【{{ stageList[currentStage +
-          1]?.name }}】</el-link>
-        <el-link :underline="false" v-else>赢单</el-link>
+        <el-link :underline="false" v-if="(currentStage + 1) != stageList.length"
+          @click="advancementStage(false)">推进至下个阶段【{{ stageList[currentStage +
+            1]?.name }}】</el-link>
+        <el-link :underline="false" v-else class="ml-4 mr-4" @click="advancementStage(true)">赢单</el-link>
       </div>
     </div>
     <!-- 内容 -->
@@ -91,7 +97,7 @@
     </el-dialog>
   </div>
 </template>
-  
+
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
 import type { FormInstance, FormRules } from 'element-plus'
@@ -118,7 +124,7 @@ const route = useRoute()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const detailCompinentsData = ref([])
 const optionVal = ref<any>('')
-const stageStatusVal = ref('')
+const stageStatusVal = ref<any>('')
 const stageStatusValOriginally = ref('')
 const advanceVal = ref('')
 const options = ref<optionType[]>([])
@@ -142,9 +148,16 @@ function refreshData() {
   getDetail()
 }
 
-function advancementStage() {
+function advancementStage(flag: boolean) {
   console.log('点击了推进阶段')
-  advanceSave(false)
+  if (!flag) {
+    allLoading.advanceSaveLoading = true
+    advancementStageNext(true)
+    return
+  }
+  let val = stageListOption.value.find((item: any) => item.label == '赢单')
+  stageStatusVal.value = Number(val?.value || '')
+  advanceChange()
 }
 
 function advanceChange() {
@@ -289,7 +302,7 @@ onMounted(() => {
   }, 500)
 })
 </script>
-  
+
 <style lang="scss" scoped>
 .businessDetail {
   .selected {
@@ -319,10 +332,12 @@ onMounted(() => {
     background-color: #F4F5F7;
     color: #000;
   }
+
   .backOrange {
     background-color: #FF5531;
     color: #fff;
   }
+
   .backWan {
     background-color: #075985;
     color: #fff;

+ 26 - 13
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -8,7 +8,7 @@
               <el-input v-model="businessOpportunityForm.name" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="商机阶段">
-              <el-select v-model="businessOpportunityForm.stageId" placeholder="请选择">
+              <el-select v-model="businessOpportunityForm.stageId" placeholder="请选择" clearable>
                 <el-option v-for="item in fixedData.BusinessStage" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -19,12 +19,13 @@
               <el-input v-model="businessOpportunityForm.contactPerson" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="产品">
-              <el-select v-model="businessOpportunityForm.product" placeholder="请选择">
-                <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
+              <el-select v-model="businessOpportunityForm.product" placeholder="请选择" clearable>
+                <el-option v-for="item in fixedData.ProductArr" :key="item.value" :label="item.label"
+                  :value="item.value" />
               </el-select>
             </el-form-item>
             <el-form-item label="负责人">
-              <el-select v-model="businessOpportunityForm.inchargerId" placeholder="请选择">
+              <el-select v-model="businessOpportunityForm.inchargerId" placeholder="请选择" clearable>
                 <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -61,13 +62,13 @@
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <el-table ref="businessTableRef" :data="businessTable" border v-loading="allLoading.businessTableLading"
-            @selection-change="changeBatch" style="width: 100%;height: 100%;">
+            :show-overflow-tooltip="tableShowOverflowTooltip" @selection-change="changeBatch"
+            style="width: 100%;height: 100%;">
             <el-table-column type="selection" width="55" />
             <el-table-column v-for="(item, index) in tableColumn" :prop="item.prop" :label="item.label" :key="index"
               :width="item.width">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="dealWithTableColumn(scope.row, item.eventName)"
-                  v-if="item.eventName">{{ scope.row[item.prop] }}</el-button>
+                <div class="table-text-textnowrap" v-if="item.eventName" @click="dealWithTableColumn(scope.row, item.eventName)">{{ scope.row[item.prop] }}</div>
                 <template v-else>{{ scope.row[item.prop] }}</template>
               </template>
             </el-table-column>
@@ -98,7 +99,7 @@
           <h4 :id="titleId">{{ allText.newBusinessisibleText }}</h4>
           <div>
             <el-button type="primary" :loading="allLoading.newBusinessSaveLading"
-              :disabled="allLoading.businessSaveLading" @click="editBusiness(true)">保存并新建</el-button>
+              :disabled="allLoading.businessSaveLading" @click="editBusiness(true)" v-if="!businessTemplateValue.id">保存并新建</el-button>
             <el-button type="primary" @click="editBusiness(false)" :loading="allLoading.businessSaveLading"
               :disabled="allLoading.newBusinessSaveLading">保存</el-button>
             <el-button @click="closeVisible('newBusinessisible')">取消</el-button>
@@ -183,10 +184,12 @@ import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, cre
 import { createTask } from '@/components/TaskModal/taskFunction'
 import { formatDateTime } from '@/utils/times'
 import { GenerateForm } from '@zmjs/form-design';
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
 import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
 import TaskModal from '@/components/TaskModal/index.vue'
 import DeteleBusiness from './component/deteleTables.vue'
 import StageSetting from './component/stageSetting.vue'
+import { GETTABLELISTPRODUCT } from "../order/api";
 
 const route = useRoute()
 const router = useRouter()
@@ -195,7 +198,7 @@ const businessTableRef = ref<InstanceType<typeof ElTable>>() // 商机table dom
 const businessTotalTable = ref(0)
 const businessTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
 const relatedProductsRef = ref<typeof RelatedProducts>()
-const businessTemplateValue = ref({})
+const businessTemplateValue = ref<any>({})
 const businessTemplateKey = ref(1)
 const businessTemplate = ref({
   config: {},
@@ -244,7 +247,8 @@ const businessOpportunityForm = reactive<businessOpportunityFormType>({
 })
 const fixedData = reactive({
   BusinessStage: [] as fixedDataInterface[],
-  Personnel: [] as personnelInterface[]
+  Personnel: [] as personnelInterface[],
+  ProductArr: [] as productInterface[]
 })
 const productTableList = ref([])
 const productTableListValue = ref([])
@@ -253,8 +257,8 @@ const productTableListValue = ref([])
 function editBusiness(visibles: boolean) {
   businessTemplateRef.value?.getData().then((res: any) => {
     let productTableListData = relatedProductsRef?.value?.returnData()
-    console.log(!productTableListData, judgmentaAmounteEqual({...businessTemplateValue.value, ...res}, productTableListData))
-    if(!productTableListData || judgmentaAmounteEqual({...businessTemplateValue.value, ...res}, productTableListData)) {
+    console.log(!productTableListData, judgmentaAmounteEqual({ ...businessTemplateValue.value, ...res }, productTableListData))
+    if (!productTableListData || judgmentaAmounteEqual({ ...businessTemplateValue.value, ...res }, productTableListData)) {
       return
     }
 
@@ -352,7 +356,7 @@ function businessDeteleItem(value: string | number, label: string, batch: boolea
       changeBatch(false)
       getBusinessTableList()
     }).catch((err) => {
-      globalPopup?.showError(err.message)
+      globalPopup?.showError(err.msg)
     })
   })
 }
@@ -481,6 +485,15 @@ async function getSystemField() {
     }
   })
 
+  post(GETTABLELISTPRODUCT, { pageIndex: -1, pageSize: -1 }).then(({ data }) => {
+    fixedData.ProductArr = (data.record || []).map((item: any) => {
+      const { id, productName } = item
+      return {
+        value: id, label: productName
+      }
+    })
+  })
+
   const res = await get(GETGENERATEFOEM)
   businessTemplate.value = JSON.parse(res.data[0].config)
 }

+ 5 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/type.d.ts

@@ -33,4 +33,9 @@ interface businessTableColumnInterface {
   width: string;
   eventName?: string;
   event?: () => void;
+}
+
+interface productInterface {
+  value: string | number;
+  label: string;
 }

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/api.ts

@@ -29,7 +29,7 @@ export const actionButtons: any[] = [
 ]
 
 export const tableColumns: TableColumn[] = [
-    { prop: 'name', label: '联系人', event: 'toDetali', width: '150' },
+    { prop: 'name', label: '联系人姓名', event: 'toDetali', width: '150' },
     { prop: 'customName', label: '客户名称', width: '150' },
     { prop: 'phone', label: '电话号码', width: '200' },
     { prop: 'email', label: '邮箱', width: '200' },

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/deteleTables.vue

@@ -89,7 +89,7 @@ function batchOperation(type: operationType) {
 }
 
 function businessOperationItem(value: string | number, label: string, type: operationType, batch: boolean = false) {
-    confirmAction(`确定${batch ? '批量' : ''}${type}【${label}】商机吗?`).then(() => {
+    confirmAction(`确定${batch ? '批量' : ''}${type}【${label}】联系人吗?`).then(() => {
         let url = type == '恢复' ? URL_RESTORE : URL_DETELEITEM
         post(url, { ids: value }).then(res => {
             if (res.code != 'ok') {
@@ -100,7 +100,7 @@ function businessOperationItem(value: string | number, label: string, type: oper
             getTableList()
             changeBatch(false)
         }).catch((err) => {
-            globalPopup?.showError(err.message)
+            globalPopup?.showError(err.msg)
         })
     })
 }

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/information.vue

@@ -5,13 +5,13 @@
             <div>
                 <el-button type="primary" v-if="!info.ownerId">认领</el-button>
                 <el-button type="primary" v-else @click="operationCli(false)">转移</el-button>
-                <el-button type="primary" @click="editInfo(info)">编辑</el-button>
+                <el-button type="primary" v-permission="['contactsEdit']" @click="editInfo(info)">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
             <div v-for="item in formItems" :key="item.label" class="formItem flex pt-2 pb-1" :style="{ width: item.width }">
                 <div :class="item.labelClass">{{ item.label }}:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ item.value }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ item.value }}</div>
             </div>
         </div>
 

+ 2 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/component/relatedBusiness.vue

@@ -2,7 +2,7 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关商机</div>
-            <div>
+            <div v-permission="['businessAddAnEdit']">
                 <el-button type="primary" @click="addBusiness()">新建商机</el-button>
             </div>
         </div>
@@ -15,14 +15,13 @@
                         }}</el-button>
                     </template>
                 </el-table-column>
-                <el-table-column prop="customerName" label="客户名称" width="130" />
+                <el-table-column prop="customerName" label="客户名称" width="140" />
                 <el-table-column prop="inchargerName" label="负责人" width="130" />
                 <el-table-column prop="amountOfMoney" label="商机金额" width="130" />
                 <el-table-column prop="expectedTransactionDate" label="预计成交时间" width="170" />
                 <el-table-column prop="stageValue" label="商机阶段" width="130" />
                 <el-table-column prop="creatorName" label="创建人" width="130" />
                 <el-table-column prop="createTime" label="创建时间" width="130" />
-                <el-table-column prop="modifyTime" label="修改时间" width="130" />
             </el-table>
         </div>
 

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/detail/index.vue

@@ -81,7 +81,7 @@ function getAllContacts() {
     post(URL_GETALL, {}).then(({ data }) => {
         options.value = (data || []).map((item: any) => ({ value: item.id, label: item.name }))
     }).catch((err) => {
-        globalPopup?.showError(err.message)
+        globalPopup?.showError(err.msg)
     })
 }
 

+ 12 - 11
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue

@@ -26,11 +26,11 @@
         <div class="flex justify-end pb-3">
           <!-- 操作按钮 -->
           <!-- <el-button v-for="(button, index) in actionButtons" :key="index" type="primary">{{ button.text }}</el-button> -->
-          <el-button type="primary" @click="editContacts(false)">新建联系人</el-button>
+          <el-button type="primary" v-permission="['contactsAdd']" @click="editContacts(false)">新建联系人</el-button>
           <el-button type="primary" @click="batchDeteleItem" :disabled="batchTableData.length <= 0">批量删除</el-button>
           <el-button type="primary" @click="showVisible('deteleContactsVisible')">回收站</el-button>
-          <el-button type="primary" @click="showVisible('importVisible')">导入</el-button>
-          <el-button type="primary" @click="exportCustomerTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
+          <el-button type="primary" v-permission="['contactsImport']" @click="showVisible('importVisible')">导入</el-button>
+          <el-button type="primary" v-permission="['contactsExport']" @click="exportCustomerTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <!-- 表格 -->
@@ -49,11 +49,11 @@
                 </template>
               </template>
             </el-table-column>
-            <el-table-column :label="'操作'" :width="'200px'" fixed="right">
+            <el-table-column :label="'操作'" :width="'200px'" fixed="right" v-permission="['contactsEdit', 'tasksAdd']">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="editContacts(scope.row)">编辑</el-button>
-                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
-                <el-button link type="danger" size="large"
+                <el-button link type="primary" size="large" v-permission="['contactsEdit']" @click="editContacts(scope.row)">编辑</el-button>
+                <el-button link type="primary" size="large" v-permission="['tasksAdd']" @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="danger" size="large" v-permission="['contactsEdit']"
                   @click="contactsDeteleItem(scope.row.id, scope.row.customName)">删除</el-button>
               </template>
             </el-table-column>
@@ -73,7 +73,7 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.editContactsText }}</h4>
           <div>
-            <el-button type="primary" :loading="allLoading.editContactsSaveLoading"
+            <el-button type="primary" :loading="allLoading.editContactsSaveLoading" v-if="!contactsTemplateValue.id"
               @click="editContactsSave(true)">保存并新建</el-button>
             <el-button type="primary" :loading="allLoading.editContactsSaveLoading"
               @click="editContactsSave(false)">保存</el-button>
@@ -169,7 +169,7 @@ const contactsTemplate = ref({
   list: [],
   config: {}
 })
-const contactsTemplateValue = ref({})
+const contactsTemplateValue = ref<any>({})
 const contactsTemplateRefKey = ref(1)
 const contactsTemplateRef = ref<typeof GenerateForm>()
 const contactsTableRef = ref<InstanceType<typeof ElTable>>()
@@ -250,8 +250,9 @@ function batchDeteleItem() {
 }
 
 function contactsDeteleItem(value: string | number, label: string, batch: boolean = false) {
-  confirmAction(`确定${batch ? '批量' : ''}删除【${label}】客户吗?`).then(() => {
-    let url = batch ? URL_BATCHDETELE : URL_DETELERECYCLE
+  confirmAction(`确定${batch ? '批量' : ''}删除【${label}】联系人吗?`).then(() => {
+    // let url = batch ? URL_BATCHDETELE : URL_DETELERECYCLE
+    let url = URL_DETELERECYCLE
     post(url, { ids: value }).then(res => {
       if (res.code != 'ok') {
         globalPopup?.showError(res.msg)

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/api.ts

@@ -1,5 +1,5 @@
 export const MOD = '/customer'
-export const IMPORTMOD = 'Custom'
+export const IMPORTMOD = 'Customer'
 export const PREFIX = '/custom'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'

+ 9 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/attachment.vue

@@ -2,7 +2,7 @@
     <div class="attachment pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">附件</div>
-            <div>
+            <div v-permission="['customerEdit']">
                 <el-upload ref="uploadRef" :http-request="httpUploadFile" :limit="1" :show-file-list="false"
                     element-loading-text="正在上传">
                     <template #trigger>
@@ -16,7 +16,7 @@
                 <el-table-column prop="name" label="附件名称" width="180" />
                 <el-table-column prop="size" label="附件大小" width="120" />
                 <el-table-column prop="userName" label="上传人" width="120" />
-                <el-table-column prop="createTime" label="上传时间" width="180" />
+                <el-table-column prop="createTime" label="上传时间" width="180" sortable />
                 <el-table-column label="操作" width="180" fixed="right">
                     <template #default="scope">
                         <el-button link type="primary" size="large" @click="fileDownload(scope.row)">下载</el-button>
@@ -50,6 +50,7 @@ import { UploadRequestOptions } from 'element-plus';
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
 import { URL_DETELEFILE, URL_REFFILENAME, URL_UPLOADFILE } from '../api';
 import { confirmAction, downloadFile } from '@/utils/tools';
+import { formatDate } from '@/utils/times';
 
 const emits = defineEmits(['refreshData']);
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -118,7 +119,12 @@ function showVisible(item: any) {
 
 watchEffect(() => {
     information.value = props.data
-    attachmenttable.value = (props.data.files || [])
+    attachmenttable.value = (props.data.files || []).map((item: any) => {
+        return {
+            ...item,
+            createTime: formatDate(new Date(item.createTime))
+        }
+    })
 });
 
 // 生命周期钩子

+ 4 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/deteleTables.vue

@@ -30,9 +30,9 @@
                     <el-table-column label="操作" fixed="right" width="120">
                         <template #default="scope">
                             <el-button link type="primary" size="large"
-                                @click="operationItem(scope.row.id, scope.row.name, '恢复')">恢复</el-button>
+                                @click="operationItem(scope.row.id, scope.row.customName, '恢复')">恢复</el-button>
                             <el-button link type="danger" size="large"
-                                @click="operationItem(scope.row.id, scope.row.name, '删除')">删除</el-button>
+                                @click="operationItem(scope.row.id, scope.row.customName, '删除')">删除</el-button>
                         </template>
                     </el-table-column>
                 </el-table>
@@ -87,7 +87,7 @@ watch(() => props.visibles, (newVal) => {
 
 function batchOperation(type: operationType) {
     const value = batchTableData.value.map((item: any) => item.id).join(',')
-    const label = batchTableData.value.map((item: any) => item.name).join(',')
+    const label = batchTableData.value.map((item: any) => item.customName).join(',')
     operationItem(value, label, type, true)
 }
 
@@ -103,7 +103,7 @@ function operationItem(value: string | number, label: string, type: operationTyp
             getTableList()
             changeBatch(false)
         }).catch((err) => {
-            globalPopup?.showError(err.message)
+            globalPopup?.showError(err.msg)
         })
     })
 }

+ 22 - 12
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/information.vue

@@ -5,27 +5,31 @@
             <div>
                 <el-button type="primary" @click="claimCustomer()" v-if="!information.inchargerName">认领</el-button>
                 <el-button type="primary" @click="transferCli()">转移</el-button>
-                <el-button type="primary" @click="editCustomer()">编辑</el-button>
+                <el-button type="primary" v-permission="['customerEdit']" @click="editCustomer()">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-20 text-right text-gray-500">客户名称:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.customName }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{
+                    information.customName }}</div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">客户来源:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.customSourceValue }}
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{
+                    information.customSourceValue }}
                 </div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">电话号码:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.companyPhone }}
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{
+                    information.companyPhone }}
                 </div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">邮箱:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.email }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{
+                    information.email }}</div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">客户行业:</div>
@@ -34,7 +38,8 @@
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">客户级别:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.customerLevelValue
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{
+                    information.customerLevelValue
                 }}</div>
             </div>
             <div class="formItem flex pt-2 pb-1">
@@ -48,7 +53,8 @@
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">创建人:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.creatorName }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ information.creatorName }}
+                </div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">创建时间:</div>
@@ -57,7 +63,7 @@
             </div>
             <div class="formItem flex pt-2 pb-1" style="width: 100%;">
                 <div class="w-22 text-right text-gray-500">备注:</div>
-                <div class="flex-1 ml-1 text ">
+                <div class="flex-1 ml-1 text " v-ellipsis-tooltip>
                     {{ information.customDesc }}
                 </div>
             </div>
@@ -91,7 +97,8 @@
                 <div class="flex justify-between items-center border-b pb-3 dialog-header">
                     <h4 :id="titleId">{{ '编辑客户' }}</h4>
                     <div>
-                        <el-button type="primary" @click="saveCustomer()" :loading="allLoading.saveLading">保存</el-button>
+                        <el-button type="primary" @click="saveCustomer()"
+                            :loading="allLoading.saveLading">保存</el-button>
                         <el-button @click="closeVisible('editCustomerVisible')">取消</el-button>
                     </div>
                 </div>
@@ -144,7 +151,9 @@ const allVisible = reactive({
 function saveCustomer() {
     generateForm.value?.getData().then((res: any) => {
         allLoading.saveLading = true
-        post(URL_EDITSAVE, { ...generateFormValue.value, ...res }).then((_res) => {
+        let formVal = { ...generateFormValue.value, ...res }
+        delete formVal.createTime
+        post(URL_EDITSAVE, { ...formVal }).then((_res) => {
             globalPopup?.showSuccess('操作成功')
             closeVisible('editCustomerVisible')
             emits('refreshData')
@@ -188,11 +197,12 @@ function claimCustomer() {
 }
 
 function editCustomer() {
-    const { id, companyPhone, customName, inchargerId, createTime, customSourceId, customerIndustryId, customerLevelId, email, telPhone } = information.value
+    const { id, companyPhone, customName, inchargerId, createTime, customSourceId, customerIndustryId, customerLevelId, email, telPhone, customDesc } = information.value
     const formVal = {
         id, customName, inchargerId, customerIndustryId, customerLevelId, email, customSourceId,
         createTime: formatDate(new Date(createTime)),
-        telPhone, companyPhone
+        telPhone, companyPhone,
+        customDesc
     }
     generateFormValue.value = formVal
     allLoading.generateFormDataLoading = true

+ 9 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/operationRecord.vue

@@ -5,14 +5,15 @@
         </div>
         <div class="flex-1 overflow-auto pt-5">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
-                <el-table-column prop="creaTime" label="操作时间" width="140" />
-                <el-table-column prop="username" label="操作人" width="120" />
+                <el-table-column prop="creatTime" label="操作时间" width="140" />
+                <el-table-column prop="userName" label="操作人" width="120" />
                 <el-table-column prop="name" label="操作内容" />
             </el-table>
         </div>
     </div>
 </template>
 <script lang="ts" setup>
+import { formatDate } from '@/utils/times';
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
 
 const operationRecordtable = ref([])
@@ -25,7 +26,12 @@ const props = defineProps<{
 watchEffect(() => {
     const { data } = props
     information.value = data
-    operationRecordtable.value = data.actionLogs || []
+    operationRecordtable.value = (data.actionLogs || []).map((item: any) => {
+        return {
+            ...item,
+            creatTime: formatDate(new Date(item.creatTime))
+        }
+    })
 })
 
 // 生命周期钩子

+ 13 - 14
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedBusiness.vue

@@ -2,27 +2,26 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关商机</div>
-            <div>
+            <div v-permission="['businessAddAnEdit']">
                 <el-button type="primary" @click="editNewBusiness()">新建商机</el-button>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
-                <el-table-column prop="taskName" label="商机名称">
+                <el-table-column prop="taskName" label="name">
                     <template #default="scope">
                         <el-button link type="primary" size="large">{{
-                            scope.row.taskName
-                        }}</el-button>
+                            scope.row.name
+                            }}</el-button>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="客户名称" width="130" />
-                <el-table-column prop="status" label="负责人" width="130" />
-                <el-table-column prop="executor" label="商机金额" width="130" />
-                <el-table-column prop="startTime" label="预计成交时间" width="130" />
-                <el-table-column prop="endTime" label="商机阶段" width="130" />
-                <el-table-column prop="endTime" label="创建人" width="130" />
-                <el-table-column prop="endTime" label="创建时间" width="130" />
-                <el-table-column prop="endTime" label="修改时间" width="130" />
+                <el-table-column prop="customerName" label="客户名称" width="130" />
+                <el-table-column prop="inchargerName" label="负责人" width="130" />
+                <el-table-column prop="amountOfMoney" label="商机金额" width="130" />
+                <el-table-column prop="expectedTransactionDate" label="预计成交时间" width="200" />
+                <el-table-column prop="stageValue" label="商机阶段" width="140" />
+                <el-table-column prop="creatorName" label="创建人" width="130" />
+                <el-table-column prop="createTime" label="创建时间" width="130" />
             </el-table>
         </div>
 
@@ -87,7 +86,7 @@ const allLoading = reactive({
 function editBusiness(visibles: boolean) {
     businessTemplateRef.value?.getData().then((res: any) => {
         let productTableListData = relatedProductsRef?.value?.returnData()
-        if(!productTableListData || judgmentaAmounteEqual({ ...businessTemplateValue.value, ...res }, productTableListData)) {
+        if (!productTableListData || judgmentaAmounteEqual({ ...businessTemplateValue.value, ...res }, productTableListData)) {
             return
         }
         productTableListData.forEach((item: any) => {
@@ -168,7 +167,7 @@ function getProductTableList() {
 watchEffect(() => {
     const { data } = props
     information.value = data
-    relatedTaskstable.value = []
+    relatedTaskstable.value = (data.businessOpportunitys || [])
 })
 
 // 生命周期钩子

+ 11 - 11
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedContacts.vue

@@ -2,7 +2,7 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关联系人</div>
-            <div>
+            <div v-permission="['contactsAdd']">
                 <el-button type="primary" @click="editContacts(information)">新建联系人</el-button>
             </div>
         </div>
@@ -13,20 +13,20 @@
                         {{ scope.$index + 1 }}
                     </template>
                 </el-table-column>
-                <el-table-column prop="taskName" label="联系人姓名">
+                <el-table-column prop="name" label="联系人姓名">
                     <template #default="scope">
                         <el-button link type="primary" size="large">{{
-                            scope.row.taskName
+                            scope.row.name
                         }}</el-button>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="电话号码" width="130" />
-                <el-table-column prop="status" label="邮箱" width="130" />
-                <el-table-column prop="executor" label="职务" width="130" />
-                <el-table-column prop="startTime" label="性别" width="130" />
-                <el-table-column prop="endTime" label="负责人" width="130" />
-                <el-table-column prop="endTime" label="创建人" width="130" />
-                <el-table-column prop="endTime" label="创建时间" width="130" />
+                <el-table-column prop="phone" label="电话号码" width="130" />
+                <el-table-column prop="email" label="邮箱" width="130" />
+                <el-table-column prop="position" label="职务" width="130" />
+                <el-table-column prop="sexValue" label="性别" width="130" />
+                <el-table-column prop="ownerName" label="负责人" width="130" />
+                <el-table-column prop="creatorName" label="创建人" width="130" />
+                <el-table-column prop="createTime" label="创建时间" width="130" />
             </el-table>
         </div>
 
@@ -116,7 +116,7 @@ const allVisible = reactive({
 watchEffect(() => {
     const { data } = props
     information.value = data
-    relatedCustomertable.value = []
+    relatedCustomertable.value = (data.contacts || [])
 })
 
 async function getSystemField() {

+ 17 - 16
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/component/relatedOrders.vue

@@ -2,29 +2,29 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关销售订单</div>
-            <div>
+            <div v-permission="['orderAdd']">
                 <el-button type="primary" @click="editOrder()">新建销售订单</el-button>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="relatedOrders" border style="width: 100%;height: 300px;">
-                <el-table-column prop="priority" label="订单编号" width="130" />
-                <el-table-column prop="taskName" label="订单名称">
+                <el-table-column prop="orderCode" label="订单编号" width="130" />
+                <el-table-column prop="orderName" label="订单名称" min-width="200">
                     <template #default="scope">
                         <el-button link type="primary" size="large">{{
-                            scope.row.taskName
-                        }}</el-button>
+                            scope.row.orderName
+                            }}</el-button>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="客户名称" width="130" />
-                <el-table-column prop="status" label="订单金额" width="130" />
-                <el-table-column prop="executor" label="已回款" width="130" />
-                <el-table-column prop="startTime" label="未回款" width="130" />
-                <el-table-column prop="endTime" label="订单类型" width="130" />
-                <el-table-column prop="endTime" label="下单时间" width="130" />
-                <el-table-column prop="endTime" label="负责人" width="130" />
-                <el-table-column prop="endTime" label="创建人" width="130" />
-                <el-table-column prop="endTime" label="创建时间" width="130" />
+                <el-table-column prop="customName" label="客户名称" width="130" />
+                <el-table-column prop="price" label="订单金额(¥)" width="130" />
+                <el-table-column prop="receivedPayment" label="已回款(¥)" width="130" />
+                <el-table-column prop="unReceivedPayment" label="未回款(¥)" width="130" />
+                <el-table-column prop="typeName" label="订单类型" width="130" />
+                <el-table-column prop="placeTime" label="下单时间" width="200" />
+                <el-table-column prop="inchargerName" label="负责人" width="130" />
+                <el-table-column prop="creatorName" label="创建人" width="130" />
+                <el-table-column prop="createTime" label="创建时间" width="200" />
             </el-table>
         </div>
 
@@ -103,6 +103,7 @@ function saveOrder(flag: boolean) {
             ...res,
             orderEndDate: res.orderEndDate ? formatDate(res.orderEndDate) : '',
             orderStartDate: res.orderStartDate ? formatDate(res.orderStartDate) : '',
+            placeTime: res.placeTime ? formatDate(res.placeTime) : '',
             orderProductDetailString: produt
         }).then((_res) => {
             allVisible.editOrderVisible = flag
@@ -122,7 +123,7 @@ function saveOrder(flag: boolean) {
 function editOrder() {
     showVisible('editOrderVisible')
     allLoading.orderTemplateLoadinng = true
-    
+
     orderTemplateValue.value = { customId: information.value.id }
     productTableListValue.value = []
     setTimeout(() => {
@@ -176,7 +177,7 @@ function getProductTableList() {
 watchEffect(() => {
     const { data } = props
     information.value = data
-    relatedOrders.value = []
+    relatedOrders.value = (data.salesOrders || [])
 })
 
 // 生命周期钩子

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/detail/index.vue

@@ -7,7 +7,7 @@
         </el-link>
       </div>
       <div class="mr-8">
-        <el-select v-model="values" placeholder="请选择" style="width: 150px" @change="getDetail()">
+        <el-select v-model="values" placeholder="请选择" style="width: 250px" @change="getDetail()">
           <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
       </div>

+ 46 - 20
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue

@@ -12,7 +12,7 @@
                 <el-option v-for="item in fixedData.ClueSources" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
-            <el-form-item label="电话号码">
+            <el-form-item label="公司号码">
               <el-input v-model="customerCriteriaForm.telPhone" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="邮箱">
@@ -20,7 +20,8 @@
             </el-form-item>
             <el-form-item label="客户行业">
               <el-select v-model="customerCriteriaForm.customerIndustryId" placeholder="请选择" clearable>
-                <el-option v-for="item in fixedData.CustomIndustry" :key="item.id" :label="item.name" :value="item.id" />
+                <el-option v-for="item in fixedData.CustomIndustry" :key="item.id" :label="item.name"
+                  :value="item.id" />
               </el-select>
             </el-form-item>
             <el-form-item label="客户级别">
@@ -52,46 +53,48 @@
     <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="flex justify-end pb-3">
-          <el-button type="primary" @click="editCustomer(false)">新建客户</el-button>
+          <el-button type="primary" v-permission="['customerAdd']" @click="editCustomer(false)">新建客户</el-button>
           <el-button type="primary" @click="showVisible('batchTransferVisible')"
             :disabled="batchTableData.length <= 0">批量转移</el-button>
           <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
           <el-button type="primary" @click="showVisible('deteleCustomerVisible')">回收站</el-button>
-          <el-button type="primary" @click="showVisible('importVisible')">导入</el-button>
-          <el-button type="primary" @click="exportCustomerTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
+          <el-button type="primary" v-permission="['customerImport']" @click="showVisible('importVisible')">导入</el-button>
+          <el-button type="primary" v-permission="['customerExport']" @click="exportCustomerTableList()"
+            :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
-          <el-table ref="customerTableRef" :data="customerTable" border v-loading="allLoading.customerTableLading"
-            style="width: 100%;height: 100%;" @selection-change="changeBatch">
+          <el-table ref="customerTableRef" :show-overflow-tooltip="tableShowOverflowTooltip" :data="customerTable" border v-loading="allLoading.customerTableLading"
+            style="width: 100%;height: 100%;" @selection-change="changeBatch" @sort-change="sortChange">
             <el-table-column type="selection" width="55" />
             <el-table-column prop="customName" label="客户名称" width="180">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click.prevent="toCustomerTableDetail(scope.row)">{{
+                <!-- <el-button link type="primary" size="large" @click.prevent="toCustomerTableDetail(scope.row)">{{
                   scope.row.customName
-                }}</el-button>
+                }}</el-button> -->
+                <div class="table-text-textnowrap" @click.prevent="toCustomerTableDetail(scope.row)">{{ scope.row.customName }}</div>
               </template>
             </el-table-column>
             <el-table-column prop="customSourceValue" label="客户来源" width="180"></el-table-column>
             <el-table-column prop="companyPhone" label="公司电话" width="180"></el-table-column>
             <el-table-column prop="email" label="邮箱" width="200"></el-table-column>
             <el-table-column prop="customerIndustryValue" label="客户行业" width="180"></el-table-column>
-            <el-table-column prop="customerLevelValue" label="客户级别" width="180"></el-table-column>
+            <el-table-column prop="customerLevelValue" label="客户级别" width="180" sortable="custom"></el-table-column>
             <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
             <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
             <el-table-column prop="newCreateTime" label="创建时间" width="180"></el-table-column>
-            <el-table-column label="操作" fixed="right" width="200">
+            <el-table-column label="操作" fixed="right" width="200" v-permission="['customerEdit', 'tasksAdd', 'customerEdit']">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="editCustomer(scope.row)">编辑</el-button>
-                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
-                <el-button link type="danger" size="large"
+                <el-button link type="primary" size="large" v-permission="['customerEdit']" @click="editCustomer(scope.row)">编辑</el-button>
+                <el-button link type="primary" size="large" v-permission="['tasksAdd']" @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="danger" size="large" v-permission="['customerEdit']"
                   @click="customerDeteleItem(scope.row.id, scope.row.customName)">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
         </div>
         <div class="flex justify-end pt-3">
-          <el-pagination layout="total, prev, pager, next, sizes" :total="customerTotalTable" :hide-on-single-page="true"
-            @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+          <el-pagination layout="total, prev, pager, next, sizes" :total="customerTotalTable"
+            :hide-on-single-page="true" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
         </div>
       </div>
     </div>
@@ -102,7 +105,7 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.editCustomerText }}</h4>
           <div>
-            <el-button type="primary" :loading="allLoading.editCustomerSaveLoading"
+            <el-button type="primary" :loading="allLoading.editCustomerSaveLoading" v-if="!customerTemplateValue.id"
               @click="editCustomerSave(true)">保存并新建</el-button>
             <el-button type="primary" :loading="allLoading.editCustomerSaveLoading"
               @click="editCustomerSave(false)">保存</el-button>
@@ -181,6 +184,7 @@ import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
 import { createTask } from "@/components/TaskModal/taskFunction";
 import { ElTable, UploadRequestOptions } from "element-plus";
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
 
 import TaskModal from '@/components/TaskModal/index.vue'
 import DeteleBusiness from './component/deteleTables.vue'
@@ -209,6 +213,7 @@ interface customerCriteriaFormType { // 线索筛选条件类型
   customerIndustryId: string | number,
   customerLevelId: string | number,
   inchargerId: string | number,
+  isDesc?: string | number,
   startTime: string | number,
   endTime: string | number,
   pageIndex: string | number,
@@ -226,6 +231,7 @@ const customerCriteriaForm = reactive<customerCriteriaFormType>({ // 筛选条
   customerIndustryId: '',
   customerLevelId: '',
   inchargerId: '',
+  isDesc: '',
   startTime: getFirstDayOfMonth(new Date()),
   endTime: formatDate(new Date()),
   pageIndex: 1,
@@ -266,7 +272,7 @@ const customerTemplate = ref({
   config: {}
 })
 const customerTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
-const customerTemplateValue = ref({})
+const customerTemplateValue = ref<any>({})
 const customerTemplateRefKey = ref(1)
 const taskModalForm = ref({})
 const taskLoading = ref<saveLoadingType>('1')
@@ -276,6 +282,21 @@ const transferPersonnel = ref('')
 
 
 // 定义方法
+function sortChange(data: any) {
+  customerCriteriaForm.pageIndex = 1
+  switch (data.order) {
+    case 'ascending':
+      customerCriteriaForm.isDesc = 1
+      break
+    case 'descending':
+      customerCriteriaForm.isDesc = 0
+      break
+    default:
+      customerCriteriaForm.isDesc = ''
+  }
+  getCustomerTable()
+}
+
 async function importBusiness(param: UploadRequestOptions) {
   allLoading.importLoading = true
   const formData = new FormData();
@@ -331,7 +352,7 @@ function customerDeteleItem(value: string | number, label: string, batch: boolea
       changeBatch(false)
       getCustomerTable()
     }).catch((err) => {
-      globalPopup?.showError(err.message)
+      globalPopup?.showError(err.msg)
     })
   })
 }
@@ -360,7 +381,12 @@ function newTask(item: any) {
 function editCustomerSave(flag: boolean) {
   customerTemplateRef.value?.getData().then((res: any) => {
     allLoading.editCustomerSaveLoading = true
-    post(URL_EDITSAVE, { ...res }).then((_res) => {
+    let formVal = {
+      ...customerTemplateValue.value,
+      ...res
+    }
+    delete formVal.createTime
+    post(URL_EDITSAVE, { ...formVal }).then((_res) => {
       allVisible.editCustomerVisible = flag
       globalPopup?.showSuccess('保存成功')
       if (flag) {

+ 7 - 7
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/api.ts

@@ -27,16 +27,16 @@ export const tableColumns: TableColumn[] = [
     { prop: 'orderName', label: '订单名称', width: '150' },
     { prop: 'customName', label: '客户名称', width: '200' },
     { prop: 'businessOpportunityName', label: '商机名称', width: '200' },
-    { prop: 'price', label: '订单金额', width: '100' },
-    { prop: 'receivedPayment', label: '已回款', width: '100' },
-    { prop: 'unReceivedPayment', label: '未回款', width: '100' },
-    { prop: 'status', label: '回放状态', width: '100' },
+    { prop: 'price', label: '订单金额(¥)', width: '120' },
+    { prop: 'receivedPayment', label: '已回款(¥)', width: '100' },
+    { prop: 'unReceivedPayment', label: '未回款(¥)', width: '100' },
+    { prop: 'statusValue', label: '回款状态', width: '100' },
     { prop: 'typeName', label: '订单类型', width: '200' },
     { prop: 'placeTime', label: '下单时间', width: '200' },
     { prop: 'orderStartDate', label: '订单开始时间', width: '200' },
-    { prop: 'orderEndDate', label: '订单结束时间', width: '200' },
-    { prop: 'customSigner', label: '客户签的人', width: '200' },
-    { prop: 'companySigner', label: '公司签的人', width: '200' },
+    { prop: 'orderEndDate', label: '订单结束时间', width: '140' },
+    { prop: 'customSignerName', label: '客户签的人', width: '140' },
+    { prop: 'companySignerName', label: '公司签的人', width: '200' },
     { prop: 'inchargerName', label: '负责人', width: '200' },
     { prop: 'creatorName', label: '创建人', width: '200' },
     { prop: 'createTime', label: '创建时间', width: '200' },

+ 18 - 12
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/deteleTables.vue

@@ -5,10 +5,10 @@
             <div class="flex justify-between items-center border-b pb-3 dialog-header">
                 <h4 :id="titleId">销售订单回收站</h4>
                 <div>
-                    <el-button type="primary" v-loading="allLoading.batchRecoveryLoading" :disabled="batchTableData.length == 0"
-                        @click="batchOperation('恢复')">批量恢复</el-button>
-                    <el-button type="primary" v-loading="allLoading.batchDeteleLoading" :disabled="batchTableData.length == 0"
-                        @click="batchOperation('删除')">批量删除</el-button>
+                    <el-button type="primary" v-loading="allLoading.batchRecoveryLoading"
+                        :disabled="batchTableData.length == 0" @click="batchOperation('恢复')">批量恢复</el-button>
+                    <el-button type="primary" v-loading="allLoading.batchDeteleLoading"
+                        :disabled="batchTableData.length == 0" @click="batchOperation('删除')">批量删除</el-button>
                     <el-button @click="cancel()">取消</el-button>
                 </div>
             </div>
@@ -18,8 +18,8 @@
                 <el-table ref="busiessTableRef" :data="deteleBusinessTable" border v-loading="allLoading.tableLoading"
                     @selection-change="changeBatch" style="width: 100%;height: 100%;">
                     <el-table-column type="selection" width="55" />
-                    <el-table-column v-for="(item, index) in tableColumns" :prop="item.prop" :label="item.label" :key="index"
-                        :width="item.width">
+                    <el-table-column v-for="(item, index) in tableColumns" :prop="item.prop" :label="item.label"
+                        :key="index" :width="item.width">
                         <template #default="scope">
                             <span>{{ scope.row[item.prop] }}</span>
                         </template>
@@ -27,9 +27,9 @@
                     <el-table-column label="操作" fixed="right" width="120">
                         <template #default="scope">
                             <el-button link type="primary" size="large"
-                                @click="businessOperationItem(scope.row.id, scope.row.name, '恢复')">恢复</el-button>
+                                @click="businessOperationItem(scope.row.id, scope.row.orderName, '恢复')">恢复</el-button>
                             <el-button link type="danger" size="large"
-                                @click="businessOperationItem(scope.row.id, scope.row.name, '删除')">删除</el-button>
+                                @click="businessOperationItem(scope.row.id, scope.row.orderName, '删除')">删除</el-button>
                         </template>
                     </el-table-column>
                 </el-table>
@@ -45,7 +45,7 @@
 <script lang="ts" setup>
 import { post } from '@/utils/request';
 import { ref, reactive, onMounted, watchEffect, watch, inject } from 'vue'
-import { GETTABLELIST, tableColumns, URL_BATCHDELETE, URL_RECOVER } from '../api';
+import { GETTABLELIST, paymentStatus, tableColumns, URL_BATCHDELETE, URL_RECOVER } from '../api';
 import { ElTable } from 'element-plus';
 import { confirmAction } from '@/utils/tools';
 import { formatDate } from '@/utils/times';
@@ -84,7 +84,7 @@ watch(() => props.visibles, (newVal) => {
 
 function batchOperation(type: operationType) {
     const value = batchTableData.value.map((item: any) => item.id).join(',')
-    const label = batchTableData.value.map((item: any) => item.name).join(',')
+    const label = batchTableData.value.map((item: any) => item.orderName).join(',')
     businessOperationItem(value, label, type, true)
 }
 
@@ -101,7 +101,7 @@ function businessOperationItem(value: string | number, label: string, type: oper
             getTableList()
             changeBatch(false)
         }).catch((err) => {
-            globalPopup?.showError(err.message)
+            globalPopup?.showError(err.msg)
         })
     })
 }
@@ -120,7 +120,13 @@ function getTableList() {
     post(GETTABLELIST, { ...tableForm, isDelete: 1 }).then((res) => {
         if (res.code == 'ok') {
             const { record, total } = res.data
-            deteleBusinessTable.value = record
+            deteleBusinessTable.value = (record || []).map((item: any) => {
+                let val = paymentStatus.find((items: any) => items.value == item.status)
+                return {
+                    ...item,
+                    statusValue: val ? val.label : ''
+                }
+            })
             businessTotalTable.value = total
         }
     }).finally(() => {

+ 33 - 23
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/information.vue

@@ -4,13 +4,14 @@
             <div class="title">基本信息</div>
             <div>
                 <el-button type="primary" @click="transferCli()">转移</el-button>
-                <el-button type="primary" @click="editInfo(info)">编辑</el-button>
+                <el-button type="primary" v-permission="['orderEdit']" @click="editInfo(info)">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
-            <div v-for="item in formItems" :key="item.label" class="formItem flex" :style="{ width: item.width }">
+            <div v-for="item in formItems" :key="item.label" class="formItem flex" :style="`width: ${item.width}`">
                 <div :class="item.labelClass">{{ item.label }}:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ item.value }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{
+                    item.value }}</div>
             </div>
         </div>
 
@@ -62,7 +63,7 @@ import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffec
 import { GenerateForm } from '@zmjs/form-design';
 import { getFromValue, getTemplateKey } from '@/utils/tools';
 import { get, post } from '@/utils/request';
-import { GETGENERATEFOEM, GETPERSONNEL, URL_OEDERUPDATE, URL_PRODUTWITHORDER, URL_TRANSFER } from '../api';
+import { GETGENERATEFOEM, GETPERSONNEL, URL_OEDERUPDATE, URL_PRODUTWITHORDER, URL_TRANSFER, paymentStatus } from '../api';
 import { formatDate } from '@/utils/times';
 
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -102,6 +103,7 @@ function editOrderSave() {
             ...res,
             orderEndDate: res.orderEndDate ? formatDate(res.orderEndDate) : '',
             orderStartDate: res.orderStartDate ? formatDate(res.orderStartDate) : '',
+            placeTime: res.placeTime ? formatDate(res.placeTime) : '',
             orderProductDetailString: JSON.stringify(productTableListValue.value || [])
         }).then((_res) => {
             closeVisible('editOrderVisible')
@@ -178,32 +180,38 @@ function closeVisible(type: keyof typeof allVisible) {
 }
 
 const formItems = reactive([
-    { label: '订单编号', key: 'orderCode', value: '', labelClass: 'w-20 text-right text-gray-500', width: '48%' },
-    { label: '订单名称', key: 'orderName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '客户名称', key: 'customName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '商机名称', key: 'businessOpportunityName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '订单金额', key: 'price', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '回款状态', key: 'receivedStatus', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '已回款金额', key: 'receivedPayment', value: '', labelClass: 'w-24 text-right text-gray-500', width: '48%' },
-    { label: '未回款', key: 'unReceivedPayment', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '订单类型', key: 'type', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '下单时间', key: 'placeTime', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '订单开始时间', key: 'orderStartDate', value: '', labelClass: 'w-30 text-right text-gray-500', width: '48%' },
-    { label: '订单结束时间', key: 'orderEndDate', value: '', labelClass: 'w-30 text-right text-gray-500', width: '48%' },
-    { label: '负责人', key: 'inchargerName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '创建人', key: 'createName', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '创建时间', key: 'createTime', value: '', labelClass: 'w-22 text-right text-gray-500', width: '48%' },
-    { label: '客户签约人', key: 'customSigner', value: '', labelClass: 'w-24 text-right text-gray-500', width: '48%' },
-    { label: '公司签约人', key: 'companySigner', value: '', labelClass: 'w-24 text-right text-gray-500', width: '48%' },
-    { label: '备注', key: 'remark', value: '', labelClass: 'w-22 text-right text-gray-500', width: '100%' },
+    { label: '订单编号', key: 'orderCode', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '订单名称', key: 'orderName', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '客户名称', key: 'customName', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '商机名称', key: 'businessOpportunityName', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '订单金额', key: 'price', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '回款状态', key: 'statusValue', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '已回款金额', key: 'receivedPayment', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '未回款', key: 'unReceivedPayment', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '订单类型', key: 'type', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '下单时间', key: 'placeTime', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '订单开始时间', key: 'orderStartDate', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '订单结束时间', key: 'orderEndDate', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '负责人', key: 'inchargerName', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '创建人', key: 'creatorName', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '创建时间', key: 'createTime', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '客户签约人', key: 'customSigner', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '公司签约人', key: 'companySigner', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '48%' },
+    { label: '备注', key: 'remark', value: '', labelClass: 'w-[115px] text-right text-gray-500', width: '100%' },
 ])
 
 watchEffect(() => {
     const { data } = props
     info.value = data
     formItems.forEach(item => {
-        item.value = info.value[item.key] || '';
+        if (item.key === 'statusValue') {
+            const status = info.value['status'];
+            item.value = status !== '' && status !== null ? (paymentStatus.find(p => p.value === status)?.label || '') : '';
+        } else {
+            item.value = info.value[item.key] || '';
+        }
     });
+
 })
 
 async function getSystemField() {
@@ -234,6 +242,8 @@ onMounted(async () => {
 
     .form {
         .formItem {
+            width: 48%;
+
             .text {
                 display: -webkit-box;
                 /* Safari */

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/products.vue

@@ -2,7 +2,7 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关产品</div>
-            <div class="flex">
+            <div class="flex" v-permission="['productEdit']">
                 <el-button type="primary" @click="productClick()">编辑产品</el-button>
             </div>
         </div>
@@ -97,6 +97,7 @@ function saveOrder() {
         ...items,
         orderEndDate: items.orderEndDate ? items.orderEndDate : '',
         orderStartDate: items.orderStartDate ? items.orderStartDate : '',
+        placeTime: items.placeTime ? formatDate(items.placeTime) : '',
         orderProductDetailString: produt
     }).then(() => {
         globalPopup?.showSuccess('操作成功')

+ 7 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/component/rebate.vue

@@ -2,7 +2,7 @@
     <div class="operationRecord pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">回款</div>
-            <div class="flex">
+            <div class="flex" v-permission="['orderEdit']">
                 <el-button type="primary" @click="editRebate(false)">新增回款</el-button>
             </div>
         </div>
@@ -98,8 +98,12 @@ function editRebate(item: any) {
 }
 
 function saveRebate() {
-    if (!mony.value || mony.value == '.') {
-        globalPopup?.showWarning('请输入金额')
+    if (!mony.value || mony.value == '.' || Number(mony.value as string) < 0) {
+        globalPopup?.showWarning(Number(mony.value as string) < 0 ? '请不要输入负数' : '请输入金额')
+        return
+    }
+    if(Number(mony.value as string) > info.value.unReceivedPayment) {
+        globalPopup?.showWarning('回款金额超过了未回款金额')
         return
     }
     allLoading.rebateLoading = true

+ 3 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/detail/index.vue

@@ -94,7 +94,7 @@ function getAllContacts() {
         options.value = (data.record || []).map((item: any) => ({ value: item.id, label: item.orderName }))
         values.value = rowId.value
     }).catch((err) => {
-        globalPopup?.showError(err.message)
+        globalPopup?.showError(err.msg)
     })
 }
 
@@ -157,12 +157,13 @@ async function getAll(event: allTypeStr) {
         } else if (event == 'getFileList') {
             await getFileList()
         } else if (event == 'getRelatedTasks') {
-            await getFileList()
+            await getRelatedTasks()
         } else if (event == 'getOperationRecord') {
             await getOperationRecord()
         } else if (event == 'getRelatedProducts') {
             await getRelatedProducts()
         } else if (event == 'getPaymentCollectionList') {
+            await getDetail()
             await getPaymentCollectionList()
         }
 

+ 23 - 14
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue

@@ -36,31 +36,32 @@
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="flex justify-end pb-3">
           <!-- 操作按钮 -->
-          <el-button type="primary" @click="editOrder(false)">新建订单</el-button>
+          <el-button type="primary" v-permission="['orderAdd']" @click="editOrder(false)">新建订单</el-button>
           <el-button type="primary" :disabled="batchTableData.length <= 0">批量转移</el-button>
           <el-button type="primary" @click="batchDeteleItem()" :disabled="batchTableData.length <= 0">批量删除</el-button>
           <el-button type="primary" @click="showVisible('deteleOrderVisible')">回收站</el-button>
-          <el-button type="primary" @click="showVisible('importVisible')">导入</el-button>
-          <el-button type="primary" @click="exportOrderTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
+          <el-button type="primary" v-permission="['orderImport']" @click="showVisible('importVisible')">导入</el-button>
+          <el-button type="primary" v-permission="['orderExport']" @click="exportOrderTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <!-- 表格 -->
-          <el-table ref="otherTableRef" :data="formTable" border v-loading="allLoading.formTableLading"
+          <el-table ref="otherTableRef" :data="formTable" :show-overflow-tooltip="tableShowOverflowTooltip" border v-loading="allLoading.formTableLading"
             style="width: 100%;height: 100%;" @selection-change="changeBatch">
             <el-table-column type="selection" width="55" />
             <el-table-column v-for="(column, index) in tableColumns" :key="index" :prop="column.prop"
               :label="column.label" :width="column.width">
               <template #default="scope">
                 <template v-if="column.event === 'toDetali'">
-                  <el-button link type="primary" size="large" @click="toDetali(scope.row)">{{ scope.row[column.prop]
-                  }}</el-button>
+                  <!-- <el-button link type="primary" size="large" @click="toDetali(scope.row)">{{ scope.row[column.prop]
+                  }}</el-button> -->
+                  <div class="table-text-textnowrap" @click.prevent="toDetali(scope.row)">{{ scope.row[column.prop] }}</div>
                 </template>
               </template>
             </el-table-column>
-            <el-table-column :label="'操作'" :width="'200px'" fixed="right">
+            <el-table-column :label="'操作'" :width="'200px'" fixed="right" v-permission="['orderEdit']">
               <template #default="scope">
                 <el-button link type="primary" size="large" @click="editOrder(scope.row)">编辑</el-button>
-                <el-button link type="primary" size="large" @click="newTask(scope.row)">新建任务</el-button>
+                <el-button link type="primary" size="large" v-permission="['tasksEdit']" @click="newTask(scope.row)">新建任务</el-button>
                 <el-button link type="danger" size="large"
                   @click="orderDeteleItem(scope.row.id, scope.row.orderName)">删除</el-button>
               </template>
@@ -81,7 +82,7 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.orderEditText }}</h4>
           <div>
-            <el-button type="primary" :loading="allLoading.editSaveLading" @click="saveOrder(true)">保存并新建</el-button>
+            <el-button type="primary" :loading="allLoading.editSaveLading" v-if="!orderTemplateValue.id" @click="saveOrder(true)">保存并新建</el-button>
             <el-button type="primary" :loading="allLoading.editSaveLading" @click="saveOrder(false)">保存</el-button>
             <el-button @click="closeVisible('editOrderVisible')">取消</el-button>
           </div>
@@ -132,12 +133,13 @@
 import { ref, reactive, onMounted, inject, defineExpose } from "vue";
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, getTemplateKey, createTaskFromType, confirmAction, downloadFile, downloadTemplate } from '@/utils/tools'
 import { post, get, uploadFile } from "@/utils/request";
-import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT, GETTABLELISTPRODUCT, URL_OEDERUPDATE, URL_PRODUTWITHORDER, URL_DETELEITEM, EXPORTTIME, IMPORTMOD, IMPORITEM } from "./api";
+import { tableColumns, GETSYSFILED, GETPERSONNEL, GETGENERATEFOEM, MOD, GETTABLELIST, GETALLPRODUCT, GETTABLELISTPRODUCT, URL_OEDERUPDATE, URL_PRODUTWITHORDER, URL_DETELEITEM, EXPORTTIME, IMPORTMOD, IMPORITEM, paymentStatus } from "./api";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
 import { formatDateTime } from "@/utils/times";
 import { ElTable, UploadRequestOptions } from "element-plus";
 import { createTask } from "@/components/TaskModal/taskFunction";
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
 import { URL_FETALL } from "../customer/api";
 
 import RelatedProducts from '@/components/relatedProducts/relatedProducts.vue'
@@ -200,7 +202,7 @@ const filterItems = ref<FilterItem[]>([
   { label: '负责人', key: 'inchargerId', type: 'select', options: selectData.Personnel },
   { label: '下单时间', key: '', type: 'date' },
 ]) // 渲染筛选条件
-const orderTemplateValue = ref({})
+const orderTemplateValue = ref<any>({})
 const orderTemplateKey = ref(1)
 const orderTemplateRef = ref<typeof GenerateForm>()
 const relatedProductsRef = ref<typeof RelatedProducts>()
@@ -244,7 +246,7 @@ function batchDeteleItem() {
 }
 
 function orderDeteleItem(value: string | number, label: string, batch: boolean = false) {
-  confirmAction(`确定${batch ? '批量' : ''}删除【${label}】客户吗?`).then(() => {
+  confirmAction(`确定${batch ? '批量' : ''}删除【${label}】销售订单吗?`).then(() => {
     post(URL_DETELEITEM, { ids: value }).then(res => {
       if (res.code != 'ok') {
         globalPopup?.showError(res.msg)
@@ -254,7 +256,7 @@ function orderDeteleItem(value: string | number, label: string, batch: boolean =
       changeBatch(false)
       getTableList()
     }).catch((err) => {
-      globalPopup?.showError(err.message)
+      globalPopup?.showError(err.msg)
     })
   })
 }
@@ -295,6 +297,7 @@ function saveOrder(flag: boolean) {
       ...res,
       orderEndDate: res.orderEndDate ? formatDate(res.orderEndDate) : '',
       orderStartDate: res.orderStartDate ? formatDate(res.orderStartDate) : '',
+      placeTime: res.placeTime ? formatDate(res.placeTime) : '',
       orderProductDetailString: produt
     }).then((_res) => {
       allVisible.editOrderVisible = flag
@@ -351,7 +354,13 @@ function getTableList() {
   allLoading.formTableLading = true
   post(GETTABLELIST, { ...formValue, ...formPaging }).then(res => {
     const { total, record } = res.data
-    formTable.value = record
+    formTable.value = (record || []).map((item: any) => {
+      let val = paymentStatus.find((items: any) => items.value == item.status)
+      return {
+        ...item,
+        statusValue: val ? val.label : ''
+      }
+    })
     formTablePaging.total = total
   }).finally(() => {
     allLoading.formTableLading = false

+ 17 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue

@@ -20,6 +20,7 @@
                 <el-table-column label="操作" width="180" fixed="right">
                     <template #default="scope">
                         <el-button link type="primary" size="large" @click="fileDownload(scope.row)">下载</el-button>
+                        <el-button link type="primary" size="large" @click="fileDownload2(scope.row)">下载2</el-button>
                         <el-button link type="primary" size="large" @click="showVisible(scope.row)">重命名</el-button>
                         <el-button link type="danger" size="large" @click="deteleFile(scope.row)">删除</el-button>
                     </template>
@@ -71,10 +72,22 @@ const props = defineProps<{
     data: any,
     information: any
 }>()
+const uploadRef = ref()
 
 // 下载文件
 function fileDownload(item: any) {
-    downloadFile(item.url, `${item.attachmentName}${item.attachmentSuffix}`)
+    downloadFile(item.url, `${removeSuffix(item.attachmentName, item.attachmentSuffix)}${item.attachmentSuffix}`)
+}
+
+function fileDownload2(item: any) {
+    downloadFile(item.serverName, `${removeSuffix(item.attachmentName, item.attachmentSuffix)}${item.attachmentSuffix}`)
+}
+
+function removeSuffix(str: string, suffix: string) {
+    if (str.endsWith(suffix)) {
+        return str.slice(0, -suffix.length);
+    }
+    return str;
 }
 
 // 保存重命名
@@ -122,7 +135,9 @@ async function httpUploadFile(param: UploadRequestOptions) {
     formData.append('file', param.file)
     formData.append('moduleId', id)
     formData.append('moduleCode', MODUCODE)
-    const res = await uploadFile(UPLOADATTACHMENT, formData)
+    const res = await uploadFile(UPLOADATTACHMENT, formData).finally(() => {
+        uploadRef.value.clearFiles()
+    })
     allLoading.uploadLoading = false
     if (res.code == 'ok') {
         globalPopup?.showSuccess('上传成功')

+ 23 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue

@@ -3,18 +3,19 @@
         <div class="flex justify-between">
             <div class="title">基本信息</div>
             <div>
-                <el-button type="primary" @click="showVisible('proudDialogVisible')">转移</el-button>
-                <el-button type="primary" @click="editProduct(info)">编辑</el-button>
+                <el-button type="primary" @click="claimProduct()" v-loading="allLoading.claimLoading" v-if="!info.inchargerName">认领</el-button>
+                <el-button type="primary" @click="showVisible('proudDialogVisible')" v-if="info.inchargerName">转移</el-button>
+                <el-button type="primary" v-permission="['productEdit']" @click="editProduct(info)">编辑</el-button>
             </div>
         </div>
         <div class="form flex flex-wrap justify-between">
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-20 text-right text-gray-500">产品编号:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ info.productCode }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ info.productCode }}</div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">产品名称:</div>
-                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1">{{ info.productName }}</div>
+                <div class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap ml-1" v-ellipsis-tooltip>{{ info.productName }}</div>
             </div>
             <div class="formItem flex pt-2 pb-1">
                 <div class="w-22 text-right text-gray-500">产品类别:</div>
@@ -50,7 +51,7 @@
             </div>
             <div class="formItem flex pt-2 pb-1" style="width: 100%;">
                 <div class="w-22 text-right text-gray-500">备注:</div>
-                <div class="flex-1 ml-1 text ">
+                <div class="flex-1 ml-1 text " v-ellipsis-tooltip>
                     {{ info.descs }}
                 </div>
             </div>
@@ -129,7 +130,8 @@ const dialogVisible = reactive({
 const allLoading = reactive({
     productLoading: false,
     generateFormLading: false,
-    saveBtnLoading: false
+    saveBtnLoading: false,
+    claimLoading: false
 })
 const allText = reactive({
     productText: '转移产品'
@@ -185,6 +187,21 @@ function transferProduct() {
     })
 }
 
+function claimProduct() {
+    const ids = info.value?.id
+    const inchargerId = userInfo.id
+    allLoading.claimLoading = true
+    post(GETINCHARGER, { id: ids, userId: inchargerId }).then((res) => {
+        if (res.code == 'ok') {
+            globalPopup?.showSuccess('操作成功')
+            dialogVisible.proudDialogVisible = false
+            emits('getInformationData')
+        }
+    }).finally(() => {
+        allLoading.claimLoading = false
+    })
+}
+
 // 显示弹窗
 function showVisible(filed: keyof typeof dialogVisible) {
     if (filed == 'proudDialogVisible') {

+ 23 - 10
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue

@@ -4,25 +4,25 @@
             <div class="title">相关商机</div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
-            <el-table :data="relatedTaskstable" border style="width: 100%;height: 100%;">
-                <el-table-column prop="taskName" label="任务名称">
+            <el-table :data="relatedTaskstable" :show-overflow-tooltip="tableShowOverflowTooltip" border
+                style="width: 100%;height: 100%;">
+                <el-table-column v-for="(item, index) in tableColumn" :prop="item.prop" :label="item.label" :key="index"
+                    :width="item.width">
                     <template #default="scope">
-                        <el-button link type="primary" size="large">{{
-                            scope.row.taskName
-                        }}</el-button>
+                        <div class="table-text-textnowrap" v-if="item.eventName"
+                            @click="dealWithTableColumn(scope.row, item.eventName)">{{ scope.row[item.prop] }}</div>
+                        <template v-else>{{ scope.row[item.prop] }}</template>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="优先级" width="130" />
-                <el-table-column prop="status" label="状态" width="130" />
-                <el-table-column prop="executor" label="执行人" width="130" />
-                <el-table-column prop="startTime" label="开始时间" width="130" />
-                <el-table-column prop="endTime" label="截至时间" width="130" />
             </el-table>
         </div>
     </div>
 </template>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { tableColumn, MOD } from '@/pages/business/api'
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
+import router from '@/router';
 
 const relatedTaskstable = ref([])
 const information: any = ref({})
@@ -38,6 +38,19 @@ function receiveAssignment(item: any) {
     information.value = item.information
 }
 
+function dealWithTableColumn(row: any, eventName: string) {
+  if (eventName == 'toClueTableDetail') {
+    toBusinessTableDetail(row)
+  }
+}
+
+function toBusinessTableDetail(row: any) {
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
+  })
+}
+
 watchEffect(() => {
     receiveAssignment(props)
 });

+ 24 - 15
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
-            <div class="title">相关产品</div>
+            <div class="title">相关销售订单</div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
@@ -10,28 +10,24 @@
                         {{ scope.$index + 1 }}
                     </template>
                 </el-table-column>
-                <el-table-column prop="taskName" label="产品名称">
+                <el-table-column v-for="(column, index) in tableColumns" :key="index" :prop="column.prop"
+                    :label="column.label" :width="column.width">
                     <template #default="scope">
-                        <el-button link type="primary" size="large">{{
-                            scope.row.taskName
-                        }}</el-button>
+                        <template v-if="column.event === 'toDetali'">
+                            <el-button link type="primary" size="large" @click="toDetali(scope.row)">{{
+                                scope.row[column.prop]
+                                }}</el-button>
+                        </template>
                     </template>
                 </el-table-column>
-                <el-table-column prop="priority" label="产品类别" width="130" />
-                <el-table-column prop="status" label="产品类型" width="130" />
-                <el-table-column prop="executor" label="单位" width="130" />
-                <el-table-column prop="startTime" label="标准价格" width="130" />
-                <el-table-column prop="endTime" label="库存" width="130" />
-                <el-table-column prop="endTime" label="售价" width="130" />
-                <el-table-column prop="endTime" label="数量" width="130" />
-                <el-table-column prop="endTime" label="折扣(%)" width="130" />
-                <el-table-column prop="endTime" label="合计" width="130" />
             </el-table>
         </div>
     </div>
 </template>
 <script lang="ts" setup>
 import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import { tableColumns, MOD, paymentStatus } from '@/pages/order/api'
+import router from '@/router';
 
 const relatedTaskstable = ref([])
 
@@ -41,7 +37,20 @@ const props = defineProps<{
 
 // 接收参数赋值
 function receiveAssignment(item: any) {
-    relatedTaskstable.value = item.data
+    relatedTaskstable.value = (item.data || []).map((item: any) => {
+      let val = paymentStatus.find((items: any) => items.value == item.status)
+      return {
+        ...item,
+        statusValue: val ? val.label : ''
+      }
+    })
+}
+
+function toDetali(row: any) {
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
+  })
 }
 
 watchEffect(() => {

+ 5 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue

@@ -7,7 +7,7 @@
         </el-link>
       </div>
       <div class="mr-8">
-        <el-select v-model="value" placeholder="请选择" style="width: 150px" @change="getDetail(false)">
+        <el-select v-model="addressParameters" placeholder="请选择" style="width: 250px" @change="getDetail(false)">
           <el-option v-for="item in options" :key="item.id" :label="item.productName" :value="item.id" />
         </el-select>
       </div>
@@ -34,7 +34,7 @@
 
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
-          <Products :data="products" />
+          <RelatedSalesOrder :data="products" />
         </div>
       </div>
     </div>
@@ -52,9 +52,10 @@ import Information from '../component/information.vue'
 import Attachment from '../component/attachment.vue'
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import OperationRecord from '../component/operationRecord.vue';
-import Products from '../component/products.vue';
+import RelatedSalesOrder from '../component/relatedSalesOrder.vue';
 import { GETBUSINESS, GETDETAIL, GETCENTERLIST, GETORDER, MODUCODE, GETATTACHMENT, GETTABLELIST } from "../api";
 import { post } from "@/utils/request";
+import { number } from "echarts";
 
 const route = useRoute()
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -121,7 +122,7 @@ function getProductList() {
 
 onMounted(() => {
   const { id } = route.query
-  addressParameters.value = id
+  addressParameters.value = (id || '') ? Number(id) : ''
   getProductList()
   getDetail(true)
 })

+ 17 - 15
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -11,17 +11,17 @@
               <el-input v-model="filterProductForm.productName" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="产品类别">
-              <el-select v-model="filterProductForm.type" placeholder="请选择" clearable>
+              <el-select v-model="filterProductForm.type" placeholder="请选择" clearable filterable>
                 <el-option v-for="item in fixedData.ProductType" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
             <el-form-item label="状态">
-              <el-select v-model="filterProductForm.status" placeholder="请选择">
-                <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
+              <el-select v-model="filterProductForm.status" placeholder="请选择" filterable clearable>
+                <el-option v-for="item in SELECTSTATUS" :key="item.value" :label="item.label" :value="item.value" />
               </el-select>
             </el-form-item>
             <el-form-item label="负责人">
-              <el-select v-model="filterProductForm.userId" placeholder="请选择">
+              <el-select v-model="filterProductForm.userId" placeholder="请选择" filterable clearable>
                 <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -44,22 +44,23 @@
     <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="flex justify-end pb-3">
-          <el-button type="primary" @click="editProduct(false)">新建产品</el-button>
+          <el-button type="primary" v-permission="['productAdd']" @click="editProduct(false)">新建产品</el-button>
           <el-button type="primary" @click="batchDelete()">批量删除</el-button>
           <el-button type="primary" @click="showDeteleProduct(true)">回收站</el-button>
-          <el-button type="primary" @click="dialogVisible.importVisible = true">导入</el-button>
-          <el-button type="primary" @click="exportProductTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
+          <el-button type="primary" v-permission="['productImport']" @click="dialogVisible.importVisible = true">导入</el-button>
+          <el-button type="primary" v-permission="['productExport']" @click="exportProductTableList()" :loading="allLoading.exoprtLoading">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
-          <el-table ref="productTableRef" :data="productTableList" border v-loading="allLoading.productTableLading"
+          <el-table ref="productTableRef" :show-overflow-tooltip="tableShowOverflowTooltip" :data="productTableList" border v-loading="allLoading.productTableLading"
             style="width: 100%;height: 100%;">
             <el-table-column type="selection" width="55" />
             <el-table-column prop="productCode" label="产品编号" width="180"></el-table-column>
             <el-table-column prop="productName" label="产品名称" width="180">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click="toProductDetail(scope.row)">{{
+                <!-- <el-button link type="primary" size="large" @click="toProductDetail(scope.row)">{{
                   scope.row.productName
-                }}</el-button>
+                }}</el-button> -->
+                <div class="table-text-textnowrap" @click.prevent="toProductDetail(scope.row)">{{ scope.row.productName }}</div>
               </template>
             </el-table-column>
             <el-table-column prop="typeName" label="产品类别" width="180"></el-table-column>
@@ -74,7 +75,7 @@
             <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
             <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
             <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
-            <el-table-column label="操作" fixed="right" width="200">
+            <el-table-column label="操作" fixed="right" width="200" v-permission="['productEdit']">
               <template #default="scope">
                 <el-button link type="primary" size="large" @click.stop="editProduct(scope.row)">编辑</el-button>
                 <el-button link type="danger" size="large" @click.stop="deteleRow([scope.row])">删除</el-button>
@@ -96,7 +97,7 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.editClueText }}</h4>
           <div>
-            <el-button type="primary" @click="saveProductRow(true)" :loading="allLoading.saveLoading">保存并新建</el-button>
+            <el-button type="primary" @click="saveProductRow(true)" v-if="!genereditForm.id":loading="allLoading.saveLoading">保存并新建</el-button>
             <el-button type="primary" @click="saveProductRow(false)" :loading="allLoading.saveLoading">保存</el-button>
             <el-button @click="dialogVisible.editProductVisible = false">取消</el-button>
           </div>
@@ -136,9 +137,10 @@
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
-import { GETSYSFILED, MOD, MODUCODE, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE, UPLOADFILE, EXPORTTIME } from './api'
+import { GETSYSFILED, MOD, MODUCODE, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE, UPLOADFILE, EXPORTTIME, SELECTSTATUS } from './api'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, downloadFile, formatDate, createTaskFromType, confirmAction, downloadTemplate } from '@/utils/tools'
 import { FormInstance, FormRules, ElMessageBox, ElTable, UploadRequestOptions } from 'element-plus'
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
 import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
@@ -188,7 +190,7 @@ const productTemplate = ref({
   list: [],
   config: {}
 }) // 产品模板
-const genereditForm = ref({}) // 编辑表单
+const genereditForm = ref<any>({}) // 编辑表单
 const generateFormKey = ref(1)
 
 // 方法定义
@@ -311,7 +313,7 @@ function handleCurrentChange(val: number) {
 }
 
 function resetFilter() {
-  let newResetForm = resetFromValue(filterProductForm, { startTime: getFirstDayOfMonth(new Date()), endTime: formatDate(new Date()), pageIndex: 1, pageFrom: 10 })
+  let newResetForm = resetFromValue(filterProductForm, { startTime: getFirstDayOfMonth(new Date()), endTime: formatDate(new Date()), pageIndex: 1, pageSize: 10 })
   Object.assign(filterProductForm, newResetForm)
   getProductTableList()
 }

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/register.vue

@@ -163,7 +163,7 @@ const register = (formEl: FormInstance | undefined) => {
         registerLoading.value = false;
       }
     }).catch(err => {
-      globalPopup?.showError(err.message || err.msg || "注册失败")
+      globalPopup?.showError(err.msg || err.msg || "注册失败")
       registerLoading.value = false;
     })
 

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/system/role/index.vue

@@ -65,7 +65,7 @@
       :before-close="handleClose">
       <div class="permissionsData">
         <div v-for="(item, index) in permissionsData" :key="index" class="list">
-          <div class="itemName">
+          <div class="itemName" v-if="item.name.indexOf('详情') == -1">
             <el-checkbox size="large" v-model="item.checked" style="width: 16px; font-weight: bold;"
               @change="changeCheckBox(item, true)">{{ item.name }}</el-checkbox>
           </div>

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

@@ -30,9 +30,9 @@ export const defaultSearchForm = {
 };
 export const PRIORITY = [
   //优先级
-  { label: "", value: 2 },
+  { label: "", value: 2 },
   { label: "中", value: 1 },
-  { label: "", value: 0 },
+  { label: "", value: 0 },
 ];
 export const STATUS: StatusType[] = [
   //任务状态

+ 39 - 17
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/index.vue

@@ -15,7 +15,7 @@
             <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="contactsName">
+            <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="executorName">
@@ -52,13 +52,14 @@
     <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>
+          <el-button type="primary" v-permission="['tasksAdd']" @click="createTasks()">创建任务</el-Button>
           <el-button type="primary" :disabled="len == 0" :loading="btnLoading" @click="deleteTasks()">批量删除</el-Button>
-          <el-button type="primary" @click="openImportModal()">导入</el-Button>
-          <el-button type="primary" :loading="btnLoading" @click="exportTasks()">导出</el-Button>
+          <el-button type="primary" v-permission="['tasksImport']" @click="openImportModal()">导入</el-Button>
+          <!-- <el-button type="primary" :loading="btnLoading" @click="exportTasks()">导出</el-Button> -->
+          <el-button type="primary" v-permission="['tasksExport']" :loading="btnLoading" @click="newExportTasks()">导出</el-Button>
         </div>
         <div class="flex-1 overflow-y-auto">
-          <el-table :data="tableData" style="width: 100%;height: 100%;" ref="tableRef" v-loading="loading">
+          <el-table :data="tableData" :show-overflow-tooltip="tableShowOverflowTooltip" 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" />
@@ -75,19 +76,11 @@
                 </el-text>
               </template>
             </el-table-column>
-            <el-table-column prop="customName" label="执行人" width="120" header-align="center" align="center" />
+            <el-table-column prop="executorNames" 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="customName" label="客户名称" header-align="center" align="center" width="120">
               <template #default="scope">
                 <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'customer', 'customId')">
@@ -117,8 +110,16 @@
                 </el-link>
               </template>
             </el-table-column>
+            <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 fixed="right" label="操作" header-align="center" align="center" width="150">
+            <el-table-column fixed="right" label="操作" header-align="center" align="center" width="160" v-permission="['tasksEdit']">
 
               <template #default="scope">
                 <el-button link type="primary" @click.prevent="editRow(scope.row)">
@@ -165,6 +166,7 @@ import ImportModal from './ImportModal.vue';
 import ExportModal from './ExportModal.vue';
 import { post, uploadFile } from '@/utils/request';
 import { getFromValue, confirmAction, downloadFile } from '@/utils/tools';
+import { tableShowOverflowTooltip } from '@/utils/globalVariables'
 import { pushMap } from './type';
 const router = useRouter()
 const { getFunctionList } = useStore()
@@ -206,7 +208,7 @@ function submitForm(data: any, isClose: boolean) {
     search();
   }).catch(err => {
     taskLoading.value = "4"
-    globalPopup?.showError(err.message)
+    globalPopup?.showError(err.msg)
   })
 
 }
@@ -216,6 +218,23 @@ const tableRef = ref<InstanceType<typeof ElTable>>();
 const loading = ref<boolean>(false);
 const totalCount = ref<number>(0);
 const tableData = ref<any[]>([])
+
+function newExportTasks() {
+  btnLoading.value = true
+  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(EXPORT_DATA_BY_TASK_ID, {...getFromValue(params)}).then((res) => {
+    globalPopup?.showSuccess("导出成功")
+    downloadFile(res.data, "任务列表.xlsx");
+  }).finally(() => {
+    btnLoading.value = false
+  })
+}
+
 function search() {
   loading.value = true;
   const { startDate, endDate } = searchForm.value;
@@ -228,7 +247,10 @@ function search() {
     loading.value = false;
     const { total, record } = data;
     totalCount.value = total;
-    tableData.value = record;
+    tableData.value = record.map((item: any) => ({
+      ...item,
+      executorNames: item.taskExecutors?.join(',') ?? ''
+    }));
   }).catch(err => {
     globalPopup?.showError(err);
     loading.value = false;

+ 3 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/api.ts

@@ -7,3 +7,6 @@ export const GET_ADDDEPT = '/department/add'
 export const DETELE_DEPT = '/department/delete'
 export const ADD_USER = '/user/insertUser'
 export const GET_USERINFO = '/user/getUserInfo'
+export const BACTHUPDATEDEPT = `/user/batchUpdateDept`
+export const BACTHUPDATEROLE = `/user/batchUpdateRole`
+export const BACTHSERROLE = `/user/setActiveByIds`

+ 99 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="h-full flex flex-col teamstyle">
+  <div class="h-full flex flex-col teamstyle overflow-hidden">
     <!-- 头部 -->
     <div class="bg-white flex justify-between team-header">
       <div class="flex items-center">
@@ -10,7 +10,8 @@
         <span class="textSpan">共 0 人</span>
       </div>
       <div class="teamForm flex items-center">
-        <el-input v-model="teamForm.keyword" style="max-width: 650px" size="default" placeholder="请输入姓名搜索" class="mr-6">
+        <el-input v-model="teamForm.keyword" style="max-width: 650px" size="default" placeholder="请输入姓名搜索" class="mr-6"
+          clearable @clear="getTableData()" @keyup.enter.native="getTableData()">
           <template #prepend>
             <el-select v-model="teamForm.matchingType" style="width: 80px">
               <el-option label="姓名" :value="0" />
@@ -19,19 +20,21 @@
             </el-select>
           </template>
           <template #append>
-            <el-button :icon="Search" />
+            <el-button :icon="Search" @click="getTableData()" />
           </template>
         </el-input>
 
         <div class="formItem mr-6 flex items-center">
           <div class="text-nowrap">状态:</div>
-          <el-select v-model="teamForm.status" placeholder="请选择" size="default" style="width: 100px">
+          <el-select v-model="teamForm.status" placeholder="请选择" size="default" style="width: 100px"
+            @change="getTableData()">
             <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
         </div>
         <div class="formItem mr-6 flex items-center">
           <div class="text-nowrap">角色:</div>
-          <el-select v-model="teamForm.roleId" placeholder="请选择" size="default" style="width: 150px">
+          <el-select v-model="teamForm.roleId" placeholder="请选择" size="default" style="width: 150px" clearable
+            @change="getTableData()">
             <el-option v-for="item in roleList" :key="item.id" :label="item.rolename" :value="item.id" />
           </el-select>
         </div>
@@ -42,11 +45,9 @@
           </el-button>
           <template #dropdown>
             <el-dropdown-menu>
-              <el-dropdown-item @click="addPersone(false)">添加人员</el-dropdown-item>
-              <el-dropdown-item>导出人员</el-dropdown-item>
-              <el-dropdown-item>批量导入</el-dropdown-item>
-              <el-dropdown-item>导入薪资</el-dropdown-item>
-              <el-dropdown-item>自定义配置</el-dropdown-item>
+              <el-dropdown-item @click="addPersone(false)" v-permission="['teamAdd']">添加人员</el-dropdown-item>
+              <el-dropdown-item v-permission="['teamExport']">导出人员</el-dropdown-item>
+              <el-dropdown-item v-permission="['teamImport']">批量导入</el-dropdown-item>
             </el-dropdown-menu>
           </template>
         </el-dropdown>
@@ -54,7 +55,7 @@
     </div>
     <!-- 内容 -->
     <div class="flex-1 flex">
-      <div class="p-5 w-80 pr-0">
+      <div class="p-4 w-80 pr-0">
         <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
           <div class="flex-1 overflow-y-auto const-left">
             <el-tree style="max-width: 600px" :data="deptList" :props="treeProps" @node-click="treeNode">
@@ -75,45 +76,51 @@
           </div>
         </div>
       </div>
-      <div class="flex-1 p-5 overflow-auto">
-        <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
-          <div class="flex-1 p-3">
+      <div class="flex-1 p-4 overflow-auto">
+        <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col overflow-hidden pt-2 pl-2 pr-2">
+          <div class="flex-1">
             <el-table ref="multipleTableRef" :data="tableData" v-loading="loadingFrom.tableLoading"
-              style="width: 100%;height: 100%;">
+              @selection-change="changeBatch" style="width: 100%;height: 100%;">
               <el-table-column type="selection" width="55" />
               <el-table-column label="姓名" property="name" width="150"></el-table-column>
-              <el-table-column label="手机" property="phone" ></el-table-column>
+              <el-table-column label="手机" property="phone"></el-table-column>
               <el-table-column label="工号" property="jobNumber"></el-table-column>
               <el-table-column label="部门" property="departmentName"></el-table-column>
               <el-table-column label="角色" property="roleName"></el-table-column>
               <el-table-column label="创建时间" property="createTime"></el-table-column>
-              <el-table-column label="操作" width="150" fixed="right">
+              <el-table-column label="操作" width="200" fixed="right">
                 <template #default="scope">
                   <el-button :size="'small'">重置</el-button>
                   <el-button type="primary" :size="'small'" @click="addPersone(scope.row)">编辑</el-button>
+                  <el-button :size="'small'" v-if="scope.row.isActive == 1">停用</el-button>
+                  <el-button :size="'small'" v-if="scope.row.isActive == 0">启用</el-button>
                 </template>
               </el-table-column>
             </el-table>
           </div>
-          <div class="flex items-center justify-between p-3 bg-slate-100">
+          <div class="flex justify-between pb-2 pt-2 pl-3 pr-3">
             <div class="flex">
-              <el-button size="default">取消</el-button>
+              <el-button size="default" @click="changeBatch(false)"
+                :disabled="batchTableData.length == 0">取消</el-button>
               <el-dropdown class="ml-3">
                 <el-button type="primary">
                   更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
                 </el-button>
                 <template #dropdown>
                   <el-dropdown-menu>
-                    <el-dropdown-item>批量修改部门</el-dropdown-item>
-                    <el-dropdown-item>批量修改角色</el-dropdown-item>
-                    <el-dropdown-item>修正工时所属部门</el-dropdown-item>
-                    <el-dropdown-item>批量启用员工</el-dropdown-item>
+                    <el-dropdown-item @click="batchItem('批量修改部门', 'dept', deptList)"
+                      :disabled="batchTableData.length == 0">批量修改部门</el-dropdown-item>
+                    <el-dropdown-item @click="batchItem('批量修改角色', 'role', roleList)"
+                      :disabled="batchTableData.length == 0">批量修改角色</el-dropdown-item>
+                    <el-dropdown-item @click="batchEnableItem"
+                      :disabled="batchTableData.length == 0">批量启用员工</el-dropdown-item>
                   </el-dropdown-menu>
                 </template>
               </el-dropdown>
             </div>
             <div class="pr-4">
-              <el-pagination layout="total, prev, pager, next, sizes" :total="totalTable" :hide-on-single-page="true" />
+              <el-pagination layout="total, prev, pager, next, sizes" :total="totalTable" :page-size="teamForm.pageSize"
+                @size-change="handleSizeChange" @current-change="handleCurrentChange" />
             </div>
           </div>
         </div>
@@ -123,7 +130,7 @@
     <!-- 新增部门 -->
     <el-dialog v-model="dialogFrom.addDeptDialogVisible" :title="deptListItem.label || '创建部门'" width="500"
       :before-close="handleClose">
-      <div>
+      <div class="pt-2">
         <el-form ref="deptRuleFormRef" style="max-width: 500px" :model="deptForm" :rules="deptRules" label-width="auto"
           size="large" status-icon>
           <el-form-item label="部门名称" prop="name">
@@ -159,6 +166,10 @@
       roleList: roleList,
       personnelFromData: personnelFromData
     }" @closeModal="closeModal" @personnelModalConfirm="personnelModalConfirm" />
+
+    <!-- 批量操作 -->
+    <BatchOperation :batchData="visibleData" :batchNode="batchTableData" :visibleText="allText.batchText"
+      :popup="visibleType" :batchOperationVisible="dialogFrom.batchOperationVisible" @close="closeModal" />
   </div>
 </template>
 
@@ -168,12 +179,13 @@ import { dayjs } from 'element-plus'
 import { Search, CirclePlusFilled, Edit, CirclePlus, Delete } from '@element-plus/icons-vue'
 import { FormInstance, FormRules, ElMessageBox } from 'element-plus'
 import { useStore } from '@/store/index'
-import { GET_DATA_LIST, DETELE_DEPT, MOD, GET_USERINFO, GET_ROUTELIST, GET_DEPTLIST, GET_USERLIST, GET_ADDDEPT, ADD_USER } from './api'
+import { GET_DATA_LIST, DETELE_DEPT, MOD, GET_USERINFO, GET_ROUTELIST, GET_DEPTLIST, BACTHSERROLE, GET_USERLIST, GET_ADDDEPT, ADD_USER } from './api'
 import { post } from "@/utils/request";
 import { getFromValue, updateDepTreeData, resetFromValue } from '@/utils/tools'
 
 // 导入页面
 import AddPersonnelModal from './module/AddPersonnelModal.vue'
+import BatchOperation from './module/BatchOperation.vue'
 
 const { getFunctionList, getUserInfoVal } = useStore()
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -198,13 +210,21 @@ const loadingFrom = reactive({ // 所有加载状态
 })
 const dialogFrom: any = reactive({ // 所有弹窗状态
   addDeptDialogVisible: false,
-  addPersonnelDialogVisible: false
+  addPersonnelDialogVisible: false,
+  batchOperationVisible: false
 });
+const allText = reactive({
+  batchText: '批量操作'
+})
+const visibleType = ref<batchOperationType>('dept') // 弹窗类型
+const visibleData = ref<any>([]) // 批量弹窗数据源
 const totalTable = ref(0) // 表格总数
 const tableData: any = ref([]) // 表格数据
 const roleList: any = ref([]) // 角色列表
 const userList: any = ref([]) // 用户列表
 const deptList: any = ref([]) // 部门数据
+const batchTableData: any = ref([]) // 批量数据
+const multipleTableRef: any = ref()
 const deptListUntreated: any = ref([]) // 部门数据(未处理)
 const deptListItem: any = ref({}) // 选中的部门数据
 const personnelFromData = ref({}) // 人员表单数据
@@ -237,17 +257,39 @@ const deptRules = reactive<FormRules<typeof deptForm>>({ // 部门表单校验
 })
 
 // 定义方法
+function batchEnableItem() {
+  const userIds = batchTableData.value.map((item: any) => item.id)
+  post(BACTHSERROLE, { ids: JSON.stringify(userIds), isActive: 1 }).then(() => {
+    globalPopup?.showSuccess('操作成功')
+    changeBatch(false)
+    getTableData()
+  }).catch((err) => {
+    globalPopup?.showError(err.msg)
+  })
+}
+
+function changeBatch(flag: boolean = true) {
+  if (flag) {
+    batchTableData.value = multipleTableRef.value && multipleTableRef.value.getSelectionRows()
+  } else {
+    batchTableData.value = []
+    multipleTableRef.value && multipleTableRef.value.clearSelection()
+  }
+}
+
 function addPersone(item: any) {
   console.log(item)
-  if(!item) {
+  if (!item) {
+    personnelFromData.value = {}
     dialogFrom.addPersonnelDialogVisible = true
     return
-  } 
+  }
   post(GET_USERINFO, { userId: item.id }).then(res => {
     const { id, name, phone, jobNumber, roleId, departmentCascade, inductionDate } = res.data
-    let newData = { id, name, phone, jobNumber, roleId, departmentId: 
-      departmentCascade && departmentCascade.split(',').map(Number).reverse(), 
-      inductionDate 
+    let newData = {
+      id, name, phone, jobNumber, roleId, departmentId:
+        departmentCascade && departmentCascade.split(',').map(Number).reverse(),
+      inductionDate
     }
     personnelFromData.value = newData
     dialogFrom.addPersonnelDialogVisible = true
@@ -382,17 +424,39 @@ function dialogFromCli(type: string, data: any = {}, flag: boolean = false) {
   dialogFrom[type] = true
 }
 
+function handleSizeChange(val: number) {
+  teamForm.pageIndex = 1
+  teamForm.pageSize = val
+  getTableData()
+}
+
+function handleCurrentChange(val: number) {
+  teamForm.pageIndex = val
+  getTableData()
+}
+
 function resetDialog() {
   let newDeptForm = resetFromValue(deptForm)
   Object.assign(deptForm, newDeptForm)
 }
 
+function batchItem(text: string, type: batchOperationType, data: any) {
+  allText.batchText = text,
+    visibleType.value = type
+  visibleData.value = data
+  dialogFrom.batchOperationVisible = true
+}
+
 function handleClose(done: any) {
   done()
 }
 
-function closeModal(modelType: string) {
+function closeModal(modelType: string, flag: boolean = false) {
   dialogFrom[modelType] = false
+  if (flag) {
+    changeBatch(false)
+    getTableData()
+  }
 }
 
 onBeforeMount(() => {
@@ -411,6 +475,7 @@ onMounted(() => {
 .teamstyle {
   .team-header {
     padding: 0.75rem 1.25rem;
+    box-sizing: border-box
   }
 
   .textFont {
@@ -449,6 +514,7 @@ onMounted(() => {
     }
   }
 }
+
 .operation {
   cursor: pointer;
 }

+ 5 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/AddPersonnelModal.vue

@@ -1,6 +1,6 @@
 <template>
     <el-dialog v-model="data.addPersonnelDialogVisible" :title="'添加人员'" width="500" :before-close="handleClose">
-        <div>
+        <div class="pt-3">
             <el-form ref="personnelRuleFormRef" style="max-width: 500px" :model="personnelFrom" :rules="personnelRules"
                 label-width="auto" size="large" status-icon>
                 <el-form-item label="姓名" prop="name">
@@ -67,7 +67,7 @@ const data = ref<Props['data']>({
     personnelFromData: {}
 })
 const personnelRuleFormRef = ref<FormInstance>() // 表单实例
-const personnelFrom = reactive<personnelFromType>({ // 填写的内容
+const personnelFrom = ref<personnelFromType>({ // 填写的内容
     id: '',
     name: '',
     phone: '',
@@ -88,15 +88,16 @@ const personnelRules = reactive<FormRules<typeof personnelFrom>>({ // 部门表
 // 定义方法
 function addPersonel(formEl: FormInstance | undefined) {
     if (!formEl) return
-    let dataForm = getFromValue(personnelFrom)
+    let dataForm = getFromValue(personnelFrom.value)
     const { departmentId } = dataForm
     emit('personnelModalConfirm', { ...dataForm, departmentId: departmentId && departmentId[departmentId.length - 1]  }, 'addPersonnelDialogVisible')
 }
 
 // 监听 Props 的变化
 watch(() => props.data, (newValue) => {
+    console.log('开始执行', newValue)
     data.value = newValue
-    Object.assign(personnelFrom, newValue.personnelFromData)
+    personnelFrom.value = newValue.personnelFromData
 });
 
 const handleClose = () => {

+ 100 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/BatchOperation.vue

@@ -0,0 +1,100 @@
+<template>
+    <el-dialog v-model="props.batchOperationVisible" width="800px" :show-close="false" :close-on-click-modal="false"
+        top="10vh">
+        <template #header="{ titleId, titleClass }">
+            <div class="flex justify-between items-center border-b pb-3">
+                <h4 :id="titleId">{{ '批量操作' }}</h4>
+                <div>
+                    <el-button @click="cancel">取消</el-button>
+                    <el-button type="primary" @click="confirm" v-loading="confirmloading">确认</el-button>
+                </div>
+            </div>
+        </template>
+        <div class="pt-4 pb-2">
+            <template v-if="props.popup == 'dept'">
+                <div class="w-full flex items-center">
+                    <div class="w-[100px] text-right">设置部门:</div>
+                    <div class="flex-1 pl-3">
+                        <el-cascader v-model="bindingVal" :options="props.batchData" class="w-full"
+                            :props="cascaderProps" />
+                    </div>
+                </div>
+            </template>
+            <template v-if="props.popup == 'role'">
+                <div class="w-full flex items-center">
+                    <div class="w-[100px] text-right">设置角色:</div>
+                    <div class="flex-1 pl-3">
+                        <el-select v-model="bindingVal" placeholder="请选择" class="w-full" filterable>
+                            <el-option v-for="item in props.batchData" :key="item.id" :label="item.rolename"
+                                :value="item.id" />
+                        </el-select>
+                    </div>
+                </div>
+            </template>
+        </div>
+    </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+import type { CascaderProps } from 'element-plus'
+import { Props } from './type';
+import { BACTHUPDATEDEPT, BACTHUPDATEROLE } from '../api';
+import { post } from '@/utils/request';
+const props = defineProps<Props>()
+const emits = defineEmits(['close']);
+
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const confirmloading = ref<boolean>(false)
+const cascaderProps = ref<CascaderProps>({
+    value: 'id',
+    expandTrigger: 'hover',
+    checkStrictly: true
+})
+const bindingVal = ref<any>([])
+
+const submitParameters = ref<any>({
+    'dept': {
+        url: BACTHUPDATEDEPT, // 请求地址
+        whether_str: false, // 是否转成字符串
+        filed: 'deptId', // 参数字段
+        param: {}
+    },
+    'role': {
+        url: BACTHUPDATEROLE, // 请求地址
+        whether_str: false, // 是否转成字符串
+        filed: 'roleId', // 参数字段
+        param: {}
+    }
+})
+
+function confirm() {
+    let params = processingParameters()
+    confirmloading.value = true
+    post(params.url, { ...params.param }).then(_res => {
+        globalPopup?.showSuccess('操作成功')
+        cancel()
+    }).catch(err => {
+        globalPopup?.showError(err.msg)
+    }).finally(() => {
+        confirmloading.value = false
+    })
+}
+
+function processingParameters() {
+    let { url, whether_str, filed, param } = submitParameters.value[props.popup]
+    const userIds = props.batchNode.map((item: any) => item.id)
+    let val = bindingVal.value
+    if (Array.isArray(bindingVal.value)) {
+        val = bindingVal.value[bindingVal.value.length - 1]
+    }
+    let rsult = { [filed]: val, userIds: !whether_str ? JSON.stringify(userIds) : userIds.join(',') }
+    return { url, param: { ...param, ...rsult } }
+}
+
+function cancel() {
+    emits('close', 'batchOperationVisible', true)
+}
+</script>
+
+<style lang="scss"></style>

+ 26 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/module/type.ts

@@ -0,0 +1,26 @@
+export interface Props {
+    /**
+     *  弹窗是否显示
+     */
+    batchOperationVisible: boolean;
+    /**
+     * 弹窗标题
+     */
+    visibleText: String;
+    /**
+     * 弹窗类型
+     */
+    popup: batchOperationType;
+    /**
+     * 数据源
+     */
+    batchData: any;
+    /**
+     * 批量节点
+     */
+    batchNode: any[]
+    /**
+     * 其他配置
+     */
+    otherConfig?: any;
+  }

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/team/type.d.ts

@@ -0,0 +1 @@
+type batchOperationType = 'dept' | 'role'

+ 23 - 7
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -8,7 +8,7 @@
               <el-input v-model="filterCriteriaForm.clueName" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="线索来源">
-              <el-select v-model="filterCriteriaForm.clueSourceId" placeholder="请选择" clearable>
+              <el-select v-model="filterCriteriaForm.clueSourceId" placeholder="请选择" clearable filterable>
                 <el-option v-for="item in fixedData.ClueSources" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -19,17 +19,17 @@
               <el-input v-model="filterCriteriaForm.email" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="客户行业">
-              <el-select v-model="filterCriteriaForm.customerIndustryId" placeholder="请选择">
+              <el-select v-model="filterCriteriaForm.customerIndustryId" placeholder="请选择" filterable clearable>
                 <el-option v-for="item in fixedData.CustomIndustry" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
             <el-form-item label="客户级别">
-              <el-select v-model="filterCriteriaForm.customerLevelId" placeholder="请选择">
+              <el-select v-model="filterCriteriaForm.customerLevelId" placeholder="请选择" filterable clearable>
                 <el-option v-for="item in fixedData.CustomLevel" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
             <el-form-item label="负责人">
-              <el-select v-model="filterCriteriaForm.inchargerId" placeholder="请选择">
+              <el-select v-model="filterCriteriaForm.inchargerId" placeholder="请选择" filterable clearable>
                 <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -61,7 +61,7 @@
         </div>
         <div class="flex-1 w-full overflow-hidden">
           <el-table :show-overflow-tooltip="tableShowOverflowTooltip" ref="clueTableRef" :data="clueTable" border v-loading="allLoading.clueTableLading"
-            style="width: 100%;height: 100%;" @selection-change="changeBatch">
+            style="width: 100%;height: 100%;" @selection-change="changeBatch" @sort-change="sortChange">
             <el-table-column type="selection" width="55" />
             <el-table-column prop="clueName" label="线索名称" width="180">
               <template #default="scope">
@@ -72,7 +72,7 @@
             <el-table-column prop="phone" label="电话号码" width="180"></el-table-column>
             <el-table-column prop="email" label="邮箱" width="180"></el-table-column>
             <el-table-column prop="customerIndustryValue" label="客户行业" width="180"></el-table-column>
-            <el-table-column prop="customerLevelValue" label="客户级别" width="180"></el-table-column>
+            <el-table-column prop="customerLevelValue" label="客户级别" width="180" sortable="custom"></el-table-column>
             <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
             <el-table-column prop="createName" label="创建人" width="180"></el-table-column>
             <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
@@ -208,6 +208,7 @@ const filterCriteriaForm = reactive<filterCriteriaFormType>({ // 筛选条件for
   inchargerId: '',
   startTime: getFirstDayOfMonth(new Date()),
   endTime: formatDate(new Date()),
+  isDesc: '',
   pageIndex: 1,
   pageFrom: 10
 })
@@ -236,7 +237,7 @@ const fixedData = reactive({
   ClueSources: [] as fixedDataInterface[],
   CustomIndustry: [] as fixedDataInterface[],
   CustomLevel: [] as fixedDataInterface[],
-  Personnel: [] as personnelInterface[]
+  Personnel: [] as personnelInterface[],
 })
 const clueTable = ref([]) // 线索table数据
 const clueTotalTable = ref(0) // 线索 table 数据总数
@@ -258,6 +259,21 @@ const transferForm = reactive({
 
 
 // 定义方法
+function sortChange(data: any) {
+  filterCriteriaForm.pageIndex = 1
+  switch (data.order) {
+    case 'ascending':
+      filterCriteriaForm.isDesc = 1
+      break
+    case 'descending':
+      filterCriteriaForm.isDesc = 0
+      break
+    default:
+      filterCriteriaForm.isDesc = ''
+  }
+  getClueTable()
+}
+
 function exportTheadTableList() {
   allLoading.exoprtLoading = true
   let valueForm = getFromValue(filterCriteriaForm)

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/type.d.ts

@@ -9,5 +9,6 @@ interface filterCriteriaFormType { // 线索筛选条件类型
   startTime: string | number,
   endTime: string | number,
   pageIndex: number,
-  pageFrom: number
+  pageFrom: number,
+  isDesc?: number | string
 }

文件差異過大導致無法顯示
+ 10821 - 37852
fhKeeper/formulahousekeeper/management-crm/crm.log


+ 4 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java

@@ -58,8 +58,8 @@ public class SalesOrderController {
     @RequestMapping("/list")
     public HttpRespMsg list(String inchargerId,Integer orderType, String orderName,
                             String orderCode,Integer customId,String businessName,
-                            Integer receivedStatus,String startDate,String endDate, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete){
-        return salesOrderService.getList(inchargerId,orderType,orderName,orderCode,customId,businessName,receivedStatus,startDate,endDate,productCode,pageIndex,pageSize,isDelete);
+                            Integer receivedStatus,String startTime,String endTime, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete){
+        return salesOrderService.getList(inchargerId,orderType,orderName,orderCode,customId,businessName,receivedStatus,startTime,endTime,productCode,pageIndex,pageSize,isDelete);
     }
 
     /**
@@ -285,8 +285,8 @@ public class SalesOrderController {
     * @Date: 2024/5/14
     */
     @RequestMapping("/exportData")
-    public HttpRespMsg exportData(String userId, String orderName,String orderCode, String productCode) throws Exception {
-        return salesOrderService.exportData(userId,orderName,orderCode,productCode);
+    public HttpRespMsg exportData(String userId, String orderName,String orderCode, String productCode,String startTime,String endTime) throws Exception {
+        return salesOrderService.exportData(userId,orderName,orderCode,productCode,startTime,endTime);
     }
 
 

+ 2 - 2
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/SalesOrderService.java

@@ -17,11 +17,11 @@ public interface SalesOrderService extends IService<SalesOrder> {
 
     HttpRespMsg getList(String inchargerId,Integer orderType, String orderName,
                         String orderCode,Integer customId,String businessName,
-                        Integer receivedStatus,String startDate,String endDate, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete);
+                        Integer receivedStatus,String startTime,String endTime, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete);
 
     HttpRespMsg importData(MultipartFile multipartFile);
 
-    HttpRespMsg exportData(String userId, String orderName, String orderCode, String productCode) throws Exception;
+    HttpRespMsg exportData(String userId, String orderName, String orderCode, String productCode,String startTime,String endTime) throws Exception;
 
     HttpRespMsg salesKit(Integer queryType,Integer dateType, String startDate, String endDate);
 

+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ProductServiceImpl.java

@@ -122,6 +122,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
                 deptIds=deptIds.stream().distinct().collect(Collectors.toList());
                 List<Integer> finalDeptIds2 = deptIds;
                 List<String> userIds = userList.stream().filter(u -> finalDeptIds2.contains(u.getDepartmentId())).map(User::getId).collect(Collectors.toList());
+                userIds.add("-1");
                 queryWrapper.in(Product::getCreatorId,userIds);
             }
         }

+ 8 - 8
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/SalesOrderServiceImpl.java

@@ -94,7 +94,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
     @Override
     public HttpRespMsg getList(String inchargerId,Integer orderType, String orderName,
                                String orderCode,Integer customId,String businessName,
-                               Integer receivedStatus,String startDate,String endDate, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete) {
+                               Integer receivedStatus,String startTime,String endTime, String productCode, Integer pageIndex, Integer pageSize,Integer isDelete) {
         HttpRespMsg msg=new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("token"));
         List<Department> departments = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()));
@@ -164,8 +164,8 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                 orderLambdaQueryWrapper.and(wrapper->wrapper.isNull(SalesOrder::getReceivedPayment).or().eq(SalesOrder::getReceivedPayment,0));
             }
         }
-        if(!StringUtils.isEmpty(startDate)&&!StringUtils.isEmpty(endDate)){
-            orderLambdaQueryWrapper.lt(SalesOrder::getOrderStartDate,endDate).gt(SalesOrder::getOrderEndDate,startDate);
+        if(!StringUtils.isEmpty(startTime)&&!StringUtils.isEmpty(endTime)){
+            orderLambdaQueryWrapper.lt(SalesOrder::getOrderStartDate,endTime).gt(SalesOrder::getOrderEndDate,startTime);
         }
         if(!StringUtils.isEmpty(orderName)){
             orderLambdaQueryWrapper.like(SalesOrder::getOrderName,orderName);
@@ -560,7 +560,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
     }
 
     @Override
-    public HttpRespMsg exportData(String userId, String orderName, String orderCode, String productCode) throws Exception {
+    public HttpRespMsg exportData(String userId, String orderName, String orderCode, String productCode,String startTime,String endTime) throws Exception {
         User user = userMapper.selectById(request.getHeader("token"));
         SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCompanyId, user.getCompanyId()).eq(SysForm::getCode, "Order").eq(SysForm::getIsCurrent, 1));
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
@@ -586,7 +586,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
             }
         }
         dataList.add(titleList);
-        HttpRespMsg respMsg = getList( userId,null, orderName,orderCode,null,null,null,null,null,productCode, null,null,0);
+        HttpRespMsg respMsg = getList( userId,null, orderName,orderCode,null,null,null,startTime,endTime,productCode, null,null,0);
         Map<String, Object> msgData = (Map<String, Object>) respMsg.getData();
         List<SalesOrder> salesOrderList = (List<SalesOrder>) msgData.get("record");
         for (SalesOrder salesOrder : salesOrderList) {
@@ -794,7 +794,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
         double businessOpportunityPrice = businessOpportunityList.stream().filter(b->!StringUtils.isEmpty(b.getAmountOfMoney())).mapToDouble(b ->Double.valueOf(b.getAmountOfMoney())).sum();
         Integer salesOrderCount = salesOrderMapper.selectCount(salesOrderLambdaQueryWrapper);
         List<SalesOrder> salesOrders = salesOrderMapper.selectList(salesOrderLambdaQueryWrapper);
-        double salesOrdersPrice = salesOrders.stream().mapToDouble(s -> s.getPrice().doubleValue()).sum();
+        double salesOrdersPrice = salesOrders.stream().filter(i->i.getPrice()!=null).mapToDouble(s -> s.getPrice().doubleValue()).sum();
         Integer clueCount = clueMapper.selectCount(clueLambdaQueryWrapper);
 
         int customCount1 = customService.count(customLambdaQueryWrapper1);
@@ -804,7 +804,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
         double businessOpportunityPrice1 = businessOpportunityList1.stream().filter(b->!StringUtils.isEmpty(b.getAmountOfMoney())).mapToDouble(b -> Double.valueOf(b.getAmountOfMoney())).sum();
         Integer salesOrderCount1 = salesOrderMapper.selectCount(salesOrderLambdaQueryWrapper1);
         List<SalesOrder> salesOrders1 = salesOrderMapper.selectList(salesOrderLambdaQueryWrapper1);
-        double salesOrdersPrice1 = salesOrders1.stream().mapToDouble(s -> s.getPrice().doubleValue()).sum();
+        double salesOrdersPrice1 = salesOrders1.stream().filter(s->s.getPrice()!=null).mapToDouble(s ->s.getPrice().doubleValue()).sum();
         Integer clueCount1 = clueMapper.selectCount(clueLambdaQueryWrapper1);
         Map<String,Object> customMap=new HashMap<>();
         customMap.put("customCount",customCount);
@@ -819,7 +819,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
         businessOpportunityMap.put("businessOpportunityPromote",getPromote(businessOpportunityCount,businessOpportunityCount1));
         resultMap.put("businessOpportunity",businessOpportunityMap);
         Map<String,Object> businessOpportunityPriceMap=new HashMap<>();
-        businessOpportunityPriceMap.put("businessOpportunityPrice",businessOpportunityPrice);
+        businessOpportunityPriceMap.put("businessOpportunityPrice",String.format("%.2f",businessOpportunityPrice));
         businessOpportunityPriceMap.put("businessOpportunityPromote",getPromote((int)businessOpportunityPrice,(int)businessOpportunityPrice1));
         resultMap.put("businessOpportunityPrice",businessOpportunityPriceMap);
         Map<String,Object> salesOrderMap=new HashMap<>();

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessOpportunityMapper.xml

@@ -245,7 +245,7 @@
     <select id="getDataSummary" resultType="java.util.Map">
         SELECT COUNT(*) newNum,SUM(bo.amount_of_money) AS allAmountOfMoney,SUM(s.name='赢单') winning,SUM(s.name='输单') losting  FROM business_opportunity bo
         LEFT JOIN stage s ON bo.stage_id=s.id
-        WHERE company_id=#{companyId} and is_delete=0
+        WHERE bo.company_id=#{companyId} and is_delete=0
         <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
             and DATE_FORMAT(bo.create_time,'%Y-%m-%d') BETWEEN #{startDate} AND #{endDate}
         </if>

+ 2 - 2
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/controller/WxCorpInfoController.java

@@ -94,8 +94,8 @@ public class WxCorpInfoController {
         filter2.put("key","sp_status");
         filter2.put("value",2);
         jsonArrayFilter.add(filter2);
-        JSONArray approvalInfo = wxCorpInfoService.getApprovalInfo(7, startDate, endDate, "", jsonArrayFilter);
-        msg.setData(approvalInfo.toArray());
+        List<String> approvalInfo = wxCorpInfoService.getApprovalInfo(7, startDate, endDate, "", jsonArrayFilter);
+        msg.setData(approvalInfo);
         return msg;
     }
 }

+ 1 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/WxCorpInfoService.java

@@ -81,7 +81,7 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
      */
     public String getCorpAgentAccessToken(WxCorpInfo corpInfo) throws Exception;
 
-    JSONArray getApprovalInfo(Integer companyId, String startDate, String endDate,String newCursor, JSONArray jsonArrayFilter) throws Exception;
+    List<String> getApprovalInfo(Integer companyId, String startDate, String endDate,String newCursor, JSONArray jsonArrayFilter) throws Exception;
 
     String getApprovalInfoDetail(Integer companyId, String spNo) throws Exception;
 }

+ 20 - 6
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -131,6 +131,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     private ProductMapper productMapper;
     @Resource
     private ProdProcedureMapper prodProcedureMapper;
+    @Resource
+    private LeaveSheetService leaveSheetService;
 
     @Value(value = "${upload.path}")
     private String path;
@@ -4114,6 +4116,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         personWorkHoursWagesList.addAll(totalList);
         //日期范围内所有分配数据
         List<ProdProcedureTeam> allProcedureTeamList = prodProcedureTeamMapper.selectList(new LambdaQueryWrapper<ProdProcedureTeam>().between(ProdProcedureTeam::getDistributeDate, startDate, endDate));
+        //日期范围内所有请假数据
+        List<LeaveSheet> leaveSheetList = leaveSheetService.list(new LambdaQueryWrapper<LeaveSheet>().le(LeaveSheet::getStartDate, endDate).ge(LeaveSheet::getEndDate, startDate));
         //日期范围内所有派工数据
         List<Integer> ids = allProcedureTeamList.stream().map(ProdProcedureTeam::getPlanProcedureId).distinct().collect(Collectors.toList());
         List<PlanProcedureTotal> planProcedureTotalList = planProcedureTotalMapper.selectList(new LambdaQueryWrapper<PlanProcedureTotal>().in(PlanProcedureTotal::getId, ids));
@@ -4168,6 +4172,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                 } else {
                     Map map = new HashMap();
+                    //不存在报工数据显示请假详情数据
+                    boolean match = leaveSheetList.stream().anyMatch(l ->
+                            (l.getStartDate().isBefore(LocalDate.parse(date, dtf1)) || l.getStartDate().isEqual(LocalDate.parse(date, dtf1)))
+                                    &&
+                                    (l.getEndDate().isAfter(LocalDate.parse(date, dtf1)) || l.getEndDate().isEqual(LocalDate.parse(date, dtf1))) && l.getOwnerId().equals(u.getId()));
+                    if(match){
+                        map.put("leave","当天请假");
+                    }
                     map.put("crateDate", date);
                     map.put("cost", 0);
                     map.put("workTime", 0);
@@ -4285,12 +4297,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         List<Integer> deptIds = departmentList.stream().map(Department::getDepartmentId).distinct().collect(Collectors.toList());
         List<Integer> otherDeptIds = departmentOtherManagers.stream().map(DepartmentOtherManager::getDepartmentId).distinct().collect(Collectors.toList());
         deptIds.addAll(otherDeptIds);
+        //日期范围内所有请假数据
+        List<LeaveSheet> leaveSheetList = leaveSheetService.list(new LambdaQueryWrapper<LeaveSheet>().le(LeaveSheet::getStartDate, endDate).ge(LeaveSheet::getEndDate, startDate).eq(LeaveSheet::getOwnerId,userId));
         List<Map<String,Object>> mapList=reportMapper.getPersonWorkHoursWagesDetail(date,userId,user.getCompanyId(),startDate,endDate,checkStatus,detailStatus);
         HttpRespMsg httpRespMsg=new HttpRespMsg();
         HashMap map=new HashMap();
         map.put("record",mapList);
-        map.put("totalWorkingTime",mapList.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
-        map.put("totalCost",mapList.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
+        map.put("totalWorkingTime",mapList.stream().filter(i->i.get("working_time")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
+        map.put("totalCost",mapList.stream().filter(i->i.get("cost")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
         if(checkStatus!=null && detailStatus==null){
             mapList=reportMapper.getPersonWorkHoursWagesDetail(date,user.getId(),user.getCompanyId(),startDate,endDate,checkStatus,detailStatus);
             DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyy-MM-dd");
@@ -4359,13 +4373,13 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                 }
                 item.put("subDataList",theData);
-                item.put("working_time",list.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
-                item.put("cost",list.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
+                item.put("working_time",list.stream().filter(i->i.get("working_time")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
+                item.put("cost",list.stream().filter(i->i.get("cost")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
                 resultList.add(item);
             }
             map.put("record",resultList);
-            map.put("totalWorkingTime",resultList.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
-            map.put("totalCost",resultList.stream().mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
+            map.put("totalWorkingTime",resultList.stream().filter(i->i.get("working_time")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("working_time")))).sum());
+            map.put("totalCost",resultList.stream().filter(i->i.get("cost")!=null).mapToDouble(mt->Double.valueOf(String.valueOf(mt.get("cost")))).sum());
         }
         httpRespMsg.setData(map);
         return httpRespMsg;

+ 8 - 8
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -2003,7 +2003,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
      *    Integer sp_status 1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
      * */
     @Override
-    public JSONArray getApprovalInfo(Integer companyId, String startDate, String endDate, String newCursor, JSONArray filterArray) throws Exception {
+    public List<String> getApprovalInfo(Integer companyId, String startDate, String endDate, String newCursor, JSONArray filterArray) throws Exception {
         DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         LocalDateTime startDateTime = LocalDate.parse(startDate, df).atTime(LocalTime.MIN);
         LocalDateTime endDateTime = LocalDate.parse(endDate, df).atTime(LocalTime.MAX);
@@ -2025,19 +2025,19 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
         ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
         if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
-            JSONArray jsonArray=new JSONArray();
+            List<String> list=new ArrayList<>();
             String resp = ResponseEntity.getBody();
             JSONObject jsonObject = JSONObject.parseObject(resp);
             if(jsonObject.getString("errmsg").equals("ok")){
-                JSONArray sp_no_list = jsonObject.getJSONArray("sp_no_list");
-                jsonArray.addAll(sp_no_list);
+                List<String> sp_no_list = (List<String>) jsonObject.get("sp_no_list");
+                list.addAll(sp_no_list);
                 if(jsonObject.containsKey("new_next_cursor")){
                     String new_next_cursor = jsonObject.getString("new_next_cursor");
-                    JSONArray approvalInfo = getApprovalInfo(companyId, startDate, endDate, new_next_cursor, filterArray);
-                    jsonArray.addAll(approvalInfo);
+                    List<String> approvalInfo = getApprovalInfo(companyId, startDate, endDate, new_next_cursor, filterArray);
+                    list.addAll(approvalInfo);
                 }
-                System.out.println(jsonArray);
-                return jsonArray;
+                System.out.println(list);
+                return list;
             }
             System.out.println(jsonObject.getString("errmsg"));
         }

+ 8 - 4
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/task/TimingTask.java

@@ -237,13 +237,16 @@ public class TimingTask {
         filter2.put("key","sp_status");
         filter2.put("value",2);
         for (WxCorpInfo wxCorpInfo : list) {
-            JSONArray approvalInfo = wxCorpInfoService.getApprovalInfo(wxCorpInfo.getCompanyId(), df.format(start), df.format(end), "", jsonArrayFilter);
+            List<String> approvalInfo = wxCorpInfoService.getApprovalInfo(wxCorpInfo.getCompanyId(), df.format(start), df.format(end), "", jsonArrayFilter);
             List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, wxCorpInfo.getCompanyId()));
             if(approvalInfo!=null){
                 List<LeaveSheet> leaveSheets = new ArrayList<>();
                 for (int i = 0; i < approvalInfo.size(); i++) {
-                    JSONObject item = approvalInfo.getJSONObject(i);
-                    JSONObject applyer = item.getJSONObject("applyer");
+                    String codeNum = approvalInfo.get(i);
+                    String approvalInfoDetailResp = wxCorpInfoService.getApprovalInfoDetail(wxCorpInfo.getCompanyId(), codeNum);
+                    JSONObject approvalInfoDetail = JSONObject.parseObject(approvalInfoDetailResp);
+                    JSONObject info = approvalInfoDetail.getJSONObject("info");
+                    JSONObject applyer = info.getJSONObject("applyer");
                     String userid = applyer.getString("userid");
                     Optional<User> first = userList.stream().filter(u -> u.getCorpwxUserid().equals(userid)).findFirst();
                     if(!first.isPresent()){
@@ -254,7 +257,8 @@ public class TimingTask {
                     leaveSheet.setStatus(0);
                     leaveSheet.setOwnerId(first.get().getId());
                     leaveSheet.setOwnerName(first.get().getName());
-                    JSONObject apply_data = item.getJSONObject("apply_data");
+                    JSONObject apply_data = info.getJSONObject("apply_data");
+                    System.out.println("获取到的单据信息===========>"+apply_data);
                     JSONArray contents = apply_data.getJSONArray("contents");
                     for (int i1 = 0; i1 < contents.size(); i1++) {
                         JSONObject map = contents.getJSONObject(i1);

+ 43 - 12
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ReportMapper.xml

@@ -154,20 +154,51 @@
         </if>
         group by b.id, a.create_date
     </select>
+<!--修改前 人员工时工价表详情数据-->
+<!--    <select id="getPersonWorkHoursWagesDetail" resultType="java.util.Map">-->
+<!--        select r.cost,r.working_time,r.finish_num, r.creator_id,ppt.total_progress as progress,DATE_FORMAT(r.create_date,'%Y%m%d') as createDate,pp.name as procedureName,(case  when pp.check_type=0 then '自检' when pp.check_type=1 then '互检' else '专检' end) as checkType,-->
+<!--        p.name as productName,DATE_FORMAT(plan.start_date,'%Y%m%d') as planStartDate,DATE_FORMAT(plan.end_date,'%Y%m%d') as planEndDate ,-->
+<!--        plan.task_change_notice_num as taskName,plan.plan_type as planType,u.name as checkerName,u2.name as creatorName,plan.product_scheduling_num,r.finish_num as finishNum-->
+<!--        from report r-->
+<!--        left join prod_procedure_team ppt2 on r.user_procedure_team_id=ppt2.id-->
+<!--        left join prod_procedure pp on r.prod_procedure_id=pp.id-->
+<!--        left join plan_procedure_total ppt on ppt.id=ppt2.plan_procedure_id-->
+<!--        left join product p on p.id=r.product_id-->
+<!--        left join plan on plan.id=r.plan_id-->
+<!--        left join user u on r.checker_id=u.id-->
+<!--        left join user u2 on r.creator_id=u2.id-->
+<!--        where r.company_id=#{companyId}  and r.finish_num &gt; 0-->
+<!--        <if test="date!=null and date!=''">-->
+<!--            and r.create_date=#{date}-->
+<!--        </if>-->
+<!--        <if test="userId!=null and userId!=''">-->
+<!--            <choose>-->
+<!--                <when test="checkStatus!=null and checkStatus==1 and detailStatus==null">-->
+<!--                    and plan.foreman_id=#{userId}-->
+<!--                </when>-->
+<!--                <otherwise>-->
+<!--                    and r.creator_id=#{userId}-->
+<!--                </otherwise>-->
+<!--            </choose>-->
+<!--        </if>-->
+<!--        <if test="startDate!=null and endDate!=null">-->
+<!--            and r.create_date between #{startDate} and #{endDate}-->
+<!--        </if>-->
+<!--    </select>-->
 
     <select id="getPersonWorkHoursWagesDetail" resultType="java.util.Map">
-        select r.cost,r.working_time,r.finish_num, r.creator_id,ppt.total_progress as progress,DATE_FORMAT(r.create_date,'%Y%m%d') as createDate,pp.name as procedureName,(case  when pp.check_type=0 then '自检' when pp.check_type=1 then '互检' else '专检' end) as checkType,
+        select r.cost,r.working_time,r.finish_num as finish_num, r.creator_id,ppt.total_progress as progress,DATE_FORMAT(r.create_date,'%Y%m%d') as createDate,pp.name as procedureName,(case  when pp.check_type=0 then '自检' when pp.check_type=1 then '互检' else '专检' end) as checkType,
         p.name as productName,DATE_FORMAT(plan.start_date,'%Y%m%d') as planStartDate,DATE_FORMAT(plan.end_date,'%Y%m%d') as planEndDate ,
         plan.task_change_notice_num as taskName,plan.plan_type as planType,u.name as checkerName,u2.name as creatorName,plan.product_scheduling_num,r.finish_num as finishNum
-        from report r
-        left join prod_procedure_team ppt2 on r.user_procedure_team_id=ppt2.id
-        left join prod_procedure pp on r.prod_procedure_id=pp.id
-        left join plan_procedure_total ppt on ppt.id=ppt2.plan_procedure_id
-        left join product p on p.id=r.product_id
-        left join plan on plan.id=r.plan_id
-        left join user u on r.checker_id=u.id
-        left join user u2 on r.creator_id=u2.id
-        where r.company_id=#{companyId}  and r.finish_num &gt; 0
+        FROM prod_procedure_team ppt2
+        LEFT JOIN plan_procedure_total ppt ON ppt.id=ppt2.plan_procedure_id
+        LEFT JOIN plan ON plan.id=ppt.plan_id
+        LEFT JOIN report r ON r.user_procedure_team_id=ppt2.id
+        LEFT JOIN prod_procedure pp ON ppt.prod_procedure_id=pp.id
+        LEFT JOIN product p ON p.id=plan.product_id
+        LEFT JOIN USER u ON r.checker_id=u.id
+        LEFT JOIN USER u2 ON r.creator_id=u2.id
+        WHERE ppt2.company_id=#{companyId}
         <if test="date!=null and date!=''">
             and r.create_date=#{date}
         </if>
@@ -177,12 +208,12 @@
                     and plan.foreman_id=#{userId}
                 </when>
                 <otherwise>
-                    and r.creator_id=#{userId}
+                    and ppt2.user_id=#{userId}
                 </otherwise>
             </choose>
         </if>
         <if test="startDate!=null and endDate!=null">
-            and r.create_date between #{startDate} and #{endDate}
+            and ppt2.distribute_date between #{startDate} and #{endDate}
         </if>
     </select>
 

+ 5 - 4
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/statistic/index.vue

@@ -91,8 +91,9 @@
                         <div v-for="(items, indexs) in scope.row.personWorkHoursWages" :key="indexs" @click="showReportDetail(scope.row,item,0)" :class="`${scope.row.departmentCascade== '小计' ? '' : 'colorText'}`">
                             <div v-if="items.crateDate == item">
                               <div  style="color: black;" v-if="items.planWorkTime">平均 {{items.planWorkTime}}分钟  {{items.planCost}}元</div>
-                               <div>已填 {{items.workTime}}分钟  {{items.cost}}元</div> 
-                               <div style="color: red;" v-if="items.surplusTime">剩余 {{items.surplusTime}}分钟  {{items.surplusCost}}元</div>
+                              <div v-if="items.leave">{{items.leave}}</div>
+                              <div v-else>已填 {{items.workTime}}分钟  {{items.cost}}元</div> 
+                              <div style="color: red;" v-if="items.surplusTime">剩余 {{items.surplusTime}}分钟  {{items.surplusCost}}元</div>
                             </div>
                         </div>
                     </template>
@@ -371,14 +372,14 @@
               <el-table-column prop="procedureName" label="工序名称" width="180"></el-table-column>
               <el-table-column prop="finishNum" label="完成件数" width="80">
                 <template slot-scope="scope">
-                  {{scope.row.finishNum?scope.row.finishNum:0}}
+                  {{scope.row.finishNum?scope.row.finishNum:''}}
                 </template>
               </el-table-column>
               <el-table-column prop="cost" label="工钱" width="80"></el-table-column>
               <el-table-column prop="checkType" label="质检方式" width="80"></el-table-column>
               <el-table-column prop="checkerName" label="质检人" width="180"></el-table-column>
               <el-table-column prop="working_time" label="工作时长" width="180">
-                <template slot-scope="scope">
+                <template slot-scope="scope" v-if="scope.row.working_time">
                   {{scope.row.working_time}}分钟
                 </template>
               </el-table-column>