Parcourir la source

Merge branch 'dev' into 'purchaseDev'

Dev

See merge request new-business/drp-web!269
黄梓星 il y a 1 an
Parent
commit
203079a907
47 fichiers modifiés avec 10054 ajouts et 492 suppressions
  1. 29 0
      src/api/business/spd/goal_management/aDemo.js
  2. 44 0
      src/api/business/spd/goal_management/annualSaleGoal.js
  3. 44 0
      src/api/business/spd/goal_management/annualSaleGoalDetails.js
  4. 44 0
      src/api/business/spd/goal_management/annualSaleGoalMerge.js
  5. 26 0
      src/api/business/spd/goal_management/annualSaleMergeDetails.js
  6. 44 0
      src/api/business/spd/goal_management/monthGoalMerge.js
  7. 53 0
      src/api/business/spd/goal_management/monthGoalMergeDetails.js
  8. 44 0
      src/api/business/spd/goal_management/monthReturnGoal.js
  9. 44 0
      src/api/business/spd/goal_management/monthReturnGoalDetails.js
  10. 44 0
      src/api/business/spd/goal_management/monthReturnMerge.js
  11. 53 0
      src/api/business/spd/goal_management/monthReturnMergeDetails.js
  12. 44 0
      src/api/business/spd/goal_management/monthSaleGoal.js
  13. 44 0
      src/api/business/spd/goal_management/monthSaleGoalDetails.js
  14. 52 0
      src/api/business/spd/starget/target.js
  15. 60 0
      src/api/business/spd/starget/targetTemplate.js
  16. 64 0
      src/api/business/spd/task_management/visitingPlan/visitingPlan.js
  17. 15 0
      src/components/popover-select/components/CUSTOMER_PARAM_ZT.js
  18. 9 0
      src/components/popover-select/components/LINKMAN_PARAM.js
  19. 15 0
      src/components/popover-select/components/MK_SALESAREA_PARAM.js
  20. 9 0
      src/components/popover-select/components/MK_TARGET_CYCLE_PARAM.js
  21. 9 0
      src/components/popover-select/components/MK_TARGET_INDEX_PARAM.js
  22. 9 0
      src/components/popover-select/components/MK_TARGET_TEMPLATE_PARAM.js
  23. 5 5
      src/views/business/spd/bo/basic/process.vue
  24. 19 108
      src/views/business/spd/bo/behavior/behaviorList.vue
  25. 254 78
      src/views/business/spd/bo/behavior/index.vue
  26. 18 51
      src/views/business/spd/bo/contact/contactList.vue
  27. 363 247
      src/views/business/spd/bo/contact/index.vue
  28. 899 0
      src/views/business/spd/goal_management/AnnualSaleGoal.vue
  29. 1280 0
      src/views/business/spd/goal_management/AnnualSaleGoalMerge.vue
  30. 1067 0
      src/views/business/spd/goal_management/MonthGoalMerge.vue
  31. 713 0
      src/views/business/spd/goal_management/MonthReturnGoal.vue
  32. 766 0
      src/views/business/spd/goal_management/MonthReturnMerge.vue
  33. 826 0
      src/views/business/spd/goal_management/MonthSaleGoal.vue
  34. 254 0
      src/views/business/spd/target/targetMk/add.vue
  35. 284 0
      src/views/business/spd/target/targetMk/index.vue
  36. 177 0
      src/views/business/spd/target/targetMk/item.vue
  37. 131 0
      src/views/business/spd/target/targetTemplate/add/columns.js
  38. 350 0
      src/views/business/spd/target/targetTemplate/add/index.vue
  39. 38 0
      src/views/business/spd/target/targetTemplate/columns.js
  40. 94 0
      src/views/business/spd/target/targetTemplate/delete/index.vue
  41. 14 0
      src/views/business/spd/target/targetTemplate/dicts.js
  42. 158 0
      src/views/business/spd/target/targetTemplate/index.vue
  43. 110 0
      src/views/business/spd/target/targetTemplate/see/columns.js
  44. 170 0
      src/views/business/spd/target/targetTemplate/see/index.vue
  45. 604 0
      src/views/business/spd/task_management/visitingPlan/add.vue
  46. 658 0
      src/views/business/spd/task_management/visitingPlan/index.vue
  47. 3 3
      vue.config.js

+ 29 - 0
src/api/business/spd/goal_management/aDemo.js

@@ -0,0 +1,29 @@
+// 此文件为算法实验文件,用来验证算法的正确性与稳定性
+
+// 合并数组
+function mergeArray() {
+  // 原始数组
+  const arr = [
+    { saleOrg: 'org1', saleZone: 'zone1', custom: 'custom1', creator: 'creator1', totalGoal: 100 },
+    { saleOrg: 'org1', saleZone: 'zone1', custom: 'custom2', creator: 'creator1', totalGoal: 200 },
+    { saleOrg: 'org2', saleZone: 'zone2', custom: 'custom3', creator: 'creator3', totalGoal: 300 },
+    { saleOrg: 'org2', saleZone: 'zone2', custom: 'custom4', creator: 'creator3', totalGoal: 400 },
+    { saleOrg: 'org3', saleZone: 'zone3', custom: 'custom5', creator: 'creator5', totalGoal: 500 }
+  ];
+// 根据saleOrg、saleZone和creator属性进行合并并相加totalGoal的函数
+  const mergeAndSumTotalGoal = (array) => {
+    return Array.from(array.reduce((map, obj) => {
+      const key = `${obj.saleOrg}-${obj.saleZone}-${obj.creator}`;
+      if (map.has(key)) {
+        const existingObj = map.get(key);
+        existingObj.totalGoal += obj.totalGoal;
+      } else {
+        map.set(key, { ...obj });
+      }
+      return map;
+    }, new Map()).values());
+  };
+// 调用合并函数
+  const mergedArray = mergeAndSumTotalGoal(arr);
+  console.log(mergedArray);
+}

+ 44 - 0
src/api/business/spd/goal_management/annualSaleGoal.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询年度销售目标列表
+export function listAnnualSaleGoal(query) {
+  return request({
+    url: '/goal_management/annualSaleGoal/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询年度销售目标详细
+export function getAnnualSaleGoal(id) {
+  return request({
+    url: '/goal_management/annualSaleGoal/' + id,
+    method: 'get'
+  })
+}
+
+// 新增年度销售目标
+export function addAnnualSaleGoal(data) {
+  return request({
+    url: '/goal_management/annualSaleGoal',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改年度销售目标
+export function updateAnnualSaleGoal(data) {
+  return request({
+    url: '/goal_management/annualSaleGoal',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除年度销售目标
+export function delAnnualSaleGoal(id) {
+  return request({
+    url: '/goal_management/annualSaleGoal/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/annualSaleGoalDetails.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询年度销售目标明细列表
+export function listAnnualSaleGoalDetails(query) {
+  return request({
+    url: '/goal_management/annualSaleGoalDetails/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询年度销售目标明细详细
+export function getAnnualSaleGoalDetails(id) {
+  return request({
+    url: '/goal_management/annualSaleGoalDetails/parent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增年度销售目标明细
+export function addAnnualSaleGoalDetails(data) {
+  return request({
+    url: '/goal_management/annualSaleGoalDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改年度销售目标明细
+export function updateAnnualSaleGoalDetails(data) {
+  return request({
+    url: '/goal_management/annualSaleGoalDetails',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除年度销售目标明细
+export function delAnnualSaleGoalDetails(id) {
+  return request({
+    url: '/goal_management/annualSaleGoalDetails/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/annualSaleGoalMerge.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询年销售目标合并列表
+export function listAnnualSaleGoalMerge(query) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询年销售目标合并详细
+export function getAnnualSaleGoalMerge(id) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge/' + id,
+    method: 'get'
+  })
+}
+
+// 新增年销售目标合并
+export function addAnnualSaleGoalMerge(data) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改年销售目标合并
+export function updateAnnualSaleGoalMerge(data) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除年销售目标合并
+export function delAnnualSaleGoalMerge(id) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge/' + id,
+    method: 'delete'
+  })
+}

+ 26 - 0
src/api/business/spd/goal_management/annualSaleMergeDetails.js

@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+
+// 查询年销售目标合并明细详细
+export function getAnnualSaleMergeDetails(parentId) {
+  return request({
+    url: '/goal_management/annualSaleMergeDetails/parent/' + parentId,
+    method: 'get'
+  })
+}
+
+// 删除年销售目标合并明细
+export function delAnnualSaleMergeDetails(id) {
+  return request({
+    url: '/goal_management/annualSaleMergeDetails/' + id,
+    method: 'delete'
+  })
+}
+
+// 年销售目标合并明细
+export function mergeAnnualSaleMergeDetails(query) {
+  return request({
+    url: '/goal_management/annualSaleGoalMerge/merge',
+    method: 'get',
+    params: query
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthGoalMerge.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月销售目标合并列表
+export function listMonthGoalMerge(query) {
+  return request({
+    url: '/goal_management/monthGoalMerge/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月销售目标合并详细
+export function getMonthGoalMerge(id) {
+  return request({
+    url: '/goal_management/monthGoalMerge/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月销售目标合并
+export function addMonthGoalMerge(data) {
+  return request({
+    url: '/goal_management/monthGoalMerge',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月销售目标合并
+export function updateMonthGoalMerge(data) {
+  return request({
+    url: '/goal_management/monthGoalMerge',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月销售目标合并
+export function delMonthGoalMerge(id) {
+  return request({
+    url: '/goal_management/monthGoalMerge/' + id,
+    method: 'delete'
+  })
+}

+ 53 - 0
src/api/business/spd/goal_management/monthGoalMergeDetails.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询月销售目标合并明细列表
+export function listMonthGoalMergeDetails(query) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月销售目标合并明细详细
+export function getMonthGoalMergeDetails(id) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails/parent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月销售目标合并明细
+export function addMonthGoalMergeDetails(data) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月销售目标合并明细
+export function updateMonthGoalMergeDetails(data) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月销售目标合并明细
+export function delMonthGoalMergeDetails(id) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails/' + id,
+    method: 'delete'
+  })
+}
+
+// 合并月销售目标明细
+export function mergeMonthSaleMergeDetails(query) {
+  return request({
+    url: '/goal_management/monthGoalMergeDetails/merge',
+    method: 'get',
+    params: query
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthReturnGoal.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月回款目标填报列表
+export function listMonthReturnGoal(query) {
+  return request({
+    url: '/mk/monthReturnGoal/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月回款目标填报详细
+export function getMonthReturnGoal(id) {
+  return request({
+    url: '/mk/monthReturnGoal/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月回款目标填报
+export function addMonthReturnGoal(data) {
+  return request({
+    url: '/mk/monthReturnGoal',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月回款目标填报
+export function updateMonthReturnGoal(data) {
+  return request({
+    url: '/mk/monthReturnGoal',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月回款目标填报
+export function delMonthReturnGoal(id) {
+  return request({
+    url: '/mk/monthReturnGoal/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthReturnGoalDetails.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月回款目标填报明细列表
+export function listMonthReturnGoalDetails(query) {
+  return request({
+    url: '/mk/monthReturnGoalDetails/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月回款目标填报明细详细
+export function getMonthReturnGoalDetails(id) {
+  return request({
+    url: '/mk/monthReturnGoalDetails/parent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月回款目标填报明细
+export function addMonthReturnGoalDetails(data) {
+  return request({
+    url: '/mk/monthReturnGoalDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月回款目标填报明细
+export function updateMonthReturnGoalDetails(data) {
+  return request({
+    url: '/mk/monthReturnGoalDetails',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月回款目标填报并明细
+export function delMonthReturnGoalDetails(id) {
+  return request({
+    url: '/mk/monthReturnGoalDetails/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthReturnMerge.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月回款目标填报列表
+export function listMonthReturnMerge(query) {
+  return request({
+    url: '/mk/monthReturnMerge/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月回款目标填报详细
+export function getMonthReturnMerge(id) {
+  return request({
+    url: '/mk/monthReturnMerge/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月回款目标填报
+export function addMonthReturnMerge(data) {
+  return request({
+    url: '/mk/monthReturnMerge',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月回款目标填报
+export function updateMonthReturnMerge(data) {
+  return request({
+    url: '/mk/monthReturnMerge',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月回款目标填报
+export function delMonthReturnMerge(id) {
+  return request({
+    url: '/mk/monthReturnMerge/' + id,
+    method: 'delete'
+  })
+}

+ 53 - 0
src/api/business/spd/goal_management/monthReturnMergeDetails.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询月回款目标填报明细列表
+export function listMonthReturnMergeDetails(query) {
+  return request({
+    url: '/mk/monthReturnMergeDetails/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月回款目标填报明细详细
+export function getMonthReturnMergeDetails(id) {
+  return request({
+    url: '/mk/monthReturnMergeDetails/parent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月回款目标填报明细
+export function addMonthReturnMergeDetails(data) {
+  return request({
+    url: '/mk/monthReturnMergeDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月回款目标填报明细
+export function updateMonthReturnMergeDetails(data) {
+  return request({
+    url: '/mk/monthReturnMergeDetails',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月回款目标填报并明细
+export function delMonthReturnMergeDetails(id) {
+  return request({
+    url: '/mk/monthReturnMergeDetails/' + id,
+    method: 'delete'
+  })
+}
+
+// 合并月销售目标明细
+export function mergeMonthReturnMergeDetails(query) {
+  return request({
+    url: '/mk/monthReturnMergeDetails/merge',
+    method: 'get',
+    params: query
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthSaleGoal.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月销售目标填报列表
+export function listMonthSaleGoal(query) {
+  return request({
+    url: '/goal_management/monthSaleGoal/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月销售目标填报详细
+export function getMonthSaleGoal(id) {
+  return request({
+    url: '/goal_management/monthSaleGoal/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月销售目标填报
+export function addMonthSaleGoal(data) {
+  return request({
+    url: '/goal_management/monthSaleGoal',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月销售目标填报
+export function updateMonthSaleGoal(data) {
+  return request({
+    url: '/goal_management/monthSaleGoal',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月销售目标填报
+export function delMonthSaleGoal(id) {
+  return request({
+    url: '/goal_management/monthSaleGoal/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
src/api/business/spd/goal_management/monthSaleGoalDetails.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询月销售目标明细列表
+export function listMonthSaleGoalDetails(query) {
+  return request({
+    url: '/goal_management/monthSaleGoalDetails/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询月销售目标明细详细
+export function getMonthSaleGoalDetails(id) {
+  return request({
+    url: '/goal_management/monthSaleGoalDetails/parent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增月销售目标明细
+export function addMonthSaleGoalDetails(data) {
+  return request({
+    url: '/goal_management/monthSaleGoalDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改月销售目标明细
+export function updateMonthSaleGoalDetails(data) {
+  return request({
+    url: '/goal_management/monthSaleGoalDetails',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除月销售目标明细
+export function delMonthSaleGoalDetails(id) {
+  return request({
+    url: '/goal_management/monthSaleGoalDetails/' + id,
+    method: 'delete'
+  })
+}

+ 52 - 0
src/api/business/spd/starget/target.js

@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 查询营销目标列表
+export function listTarget(query) {
+  return request({
+    url: '/mk/target/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询营销目标详细
+export function getTarget(id) {
+  return request({
+    url: '/mk/target/' + id,
+    method: 'get'
+  })
+}
+
+// 查询营销目标明细
+export function getTargetItem(id) {
+  return request({
+    url: '/mk/target/item/' + id,
+    method: 'get'
+  })
+}
+
+// 新增营销目标
+export function addTarget(data) {
+  return request({
+    url: '/mk/target',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改营销目标
+export function updateTarget(data) {
+  return request({
+    url: '/mk/target',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除营销目标
+export function delTarget(id) {
+  return request({
+    url: '/mk/target/' + id,
+    method: 'delete'
+  })
+}

+ 60 - 0
src/api/business/spd/starget/targetTemplate.js

@@ -0,0 +1,60 @@
+import request from '@/utils/request'
+
+// 查询目标模板列表
+export function listTargetTemplate(query) {
+  return request({
+    url: '/mk/target/targetTemplate/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询目标模板详细
+export function getTargetTemplate(id) {
+  return request({
+    url: '/mk/target/targetTemplate/' + id,
+    method: 'get'
+  })
+}
+
+// 新增目标模板
+export function addTargetTemplate(data) {
+  return request({
+    url: '/mk/target/targetTemplate',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改目标模板
+export function updateTargetTemplate(data) {
+  return request({
+    url: '/mk/target/targetTemplate',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除目标模板
+export function delTargetTemplate(id) {
+  return request({
+    url: '/mk/target/targetTemplate/' + id,
+    method: 'delete'
+  })
+}
+
+// 获取动态表头数据
+export function getHeaderData(id) {
+  return request({
+    url: '/mk/target/targetTemplate/getHeaderData/' + id,
+    method: 'get'
+  })
+}
+
+//校验目标模板是否被引用
+export function checkQuote(id) {
+  return request({
+    url: '/mk/target/targetTemplate/checkQuote/' + id,
+    method: 'get'
+  })
+}

+ 64 - 0
src/api/business/spd/task_management/visitingPlan/visitingPlan.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+
+//拜访计划列表
+export function getPlanList(data) {
+    return request({
+        url: '/mk/bo/plan/list',
+        method: 'get',
+        params: data
+    })
+}
+//拜访计划新增
+export function addPlan(data) {
+    return request({
+        url: '/mk/bo/plan/',
+        method: 'post',
+        data: data
+    })
+}
+//拜访计划编辑
+export function editPlan(data) {
+    return request({
+        url: '/mk/bo/plan/',
+        method: 'put',
+        data: data
+    })
+}
+//拜访计划提交
+export function submitPlan(data) {
+    return request({
+      url: `/mk/bo/plan/submit`,
+      method: 'POST',
+      data: data
+    })
+}
+//拜访计划基本信息详情
+export function getPlanDetail(id) {
+    return request({
+      url: '/mk/bo/plan/' + id,
+      method: 'get',
+    })
+}
+//拜访计划基本子表详情
+export function getPlanSonDetail(planId) {
+    return request({
+      url: `/mk/bo/item/` + planId,
+      method: 'get',
+    })
+}
+//拜访计划删除
+export function delPlan(id) {
+    return request({
+        url: '/mk/bo/plan/' + id,
+        method: 'delete'
+    })
+}
+// 采购需求单导出
+export function exportPlan(data) {
+    return request({
+      url: `/mk/bo/plan/export`,
+      method: 'post',
+      data: data,
+      responseType: 'blob'
+    })
+  }

+ 15 - 0
src/components/popover-select/components/CUSTOMER_PARAM_ZT.js

@@ -0,0 +1,15 @@
+// 收货客户
+export default [
+  {
+    key: "code",
+    title: "客户编码",
+    type: "Input",
+    search: true,
+  },
+  {
+    key: "name",
+    title: "客户名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 9 - 0
src/components/popover-select/components/LINKMAN_PARAM.js

@@ -0,0 +1,9 @@
+// 收货客户
+export default [
+  {
+    key: "name",
+    title: "名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 15 - 0
src/components/popover-select/components/MK_SALESAREA_PARAM.js

@@ -0,0 +1,15 @@
+// 销售区域
+export default [
+  {
+    key: "code",
+    title: "区域编码",
+    type: "Input",
+    search: true,
+  },
+  {
+    key: "name",
+    title: "区域名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 9 - 0
src/components/popover-select/components/MK_TARGET_CYCLE_PARAM.js

@@ -0,0 +1,9 @@
+// 目标周期
+export default [
+  {
+    key: "name",
+    title: "周期名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 9 - 0
src/components/popover-select/components/MK_TARGET_INDEX_PARAM.js

@@ -0,0 +1,9 @@
+// 目标指标
+export default [
+  {
+    key: "name",
+    title: "指标名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 9 - 0
src/components/popover-select/components/MK_TARGET_TEMPLATE_PARAM.js

@@ -0,0 +1,9 @@
+// 目标摸吧
+export default [
+  {
+    key: "name",
+    title: "模板名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 5 - 5
src/views/business/spd/bo/basic/process.vue

@@ -25,7 +25,7 @@
       <!-- 商机审核 -->
       <el-tab-pane label="阶段动作" name="t00101" style="height: 200px; overflow-y: scroll" v-if="tabsName.t00101" >
         <el-descriptions >
-          <el-descriptions-item label="医院收总额">
+          <el-descriptions-item label="医院收总额">
             <div v-for="dict in dict.type.mk_bo_total_revenue" v-if="form.totalHosRevenue == dict.value">
               <div>{{dict.label}}</div>
             </div>
@@ -303,7 +303,7 @@
       <!-- 商机审核 -->
       <el-tab-pane label="阶段动作" name="t10101" style="height: 200px; overflow-y: scroll" v-if="tabsName.t10101">
         <el-descriptions >
-          <el-descriptions-item label="医院收总额">
+          <el-descriptions-item label="医院收总额">
             <div v-for="dict in dict.type.mk_bo_total_revenue" v-if="form.totalHosRevenue == dict.value">
               <div>{{dict.label}}</div>
             </div>
@@ -518,7 +518,7 @@
       <!-- 商机审核 -->
       <el-tab-pane label="阶段动作" name="t20201" style="height: 200px; overflow-y: scroll" v-if="tabsName.t20201">
         <el-descriptions >
-          <el-descriptions-item label="医院收总额">
+          <el-descriptions-item label="医院收总额">
             <div v-for="dict in dict.type.mk_bo_total_revenue" v-if="form.totalHosRevenue == dict.value">
               <div>{{dict.label}}</div>
             </div>
@@ -748,7 +748,7 @@
       <!-- 商机审核 -->
       <el-tab-pane label="阶段动作" name="t30201" style="height: 200px; overflow-y: scroll" v-if="tabsName.t30201">
         <el-descriptions >
-          <el-descriptions-item label="医院收总额">
+          <el-descriptions-item label="医院收总额">
             <div v-for="dict in dict.type.mk_bo_total_revenue" v-if="form.totalHosRevenue == dict.value">
               <div>{{dict.label}}</div>
             </div>
@@ -978,7 +978,7 @@
       <!-- 商机审核 -->
       <el-tab-pane label="阶段动作" name="t40201" style="height: 200px; overflow-y: scroll" v-if="tabsName.t40201">
         <el-descriptions >
-          <el-descriptions-item label="医院收总额">
+          <el-descriptions-item label="医院收总额">
             <div v-for="dict in dict.type.mk_bo_total_revenue" v-if="form.totalHosRevenue == dict.value">
               <div>{{dict.label}}</div>
             </div>

+ 19 - 108
src/views/business/spd/bo/behavior/behaviorList.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <el-row :gutter="10" class="mb8" v-if="this.source == 'BoDetails' ? this.bo.winningState == 0 ? true : false : true">
+    <el-row :gutter="10" class="mb8" v-if="this.bo.winningState == 0">
       <el-col :span="1.5">
         <el-button
           type="primary"
@@ -11,31 +11,8 @@
           v-if="this.boAuthority.boAuthority.behaviorAdd"
         >新增</el-button>
       </el-col>
-      <!-- <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="el-icon-edit"
-          size="mini"
-          :disabled="single"
-          @click="handleUpdate"
-        >修改</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-        >删除</el-button>
-      </el-col> -->
-      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
     </el-row>
-
-    <el-table v-loading="loading" :data="behaviorList" @selection-change="handleSelectionChange">
-      <el-table-column type="index" label="序号" width="55" align="center"/>
+    <el-table v-loading="loading" :data="behaviorList">
       <el-table-column label="负责人" align="center" prop="staffName" />
       <el-table-column label="行动日期" align="center" prop="time" />
       <el-form-item label="行动日期" prop="time">
@@ -59,46 +36,27 @@
       </el-table-column>
       <el-table-column label="协助内容" align="center" prop="assistContent" />
       <el-table-column label="洽谈内容" align="center" prop="content" />
-
-      <el-table-column label="任务编码" align="center" prop="taskCode" v-if="source == 'Behavior'"/>
-      <el-table-column label="行动类型" align="center" prop="type" v-if="source == 'Behavior'">
+      <el-table-column label="行动类型" align="center" prop="type">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.mk_bo_behavior_type" :value="scope.row.type"/>
         </template>
       </el-table-column>
-      <el-table-column label="客户" align="center" prop="customerName" v-if="source == 'Behavior'"/>
-      <el-table-column label="拜访目的" align="center" prop="purpose" v-if="source == 'Behavior'">
+      <el-table-column label="拜访目的" align="center" prop="purpose">
         <template slot-scope="scope">
             <dict-tag :options="dict.type.mk_bo_behavior_goal" :value="scope.row.purpose"/>
         </template>
       </el-table-column>
-      <el-table-column label="销售组织" align="center" prop="salesOrgName" v-if="source == 'Behavior'"/>
-      <el-table-column label="部门" align="center" prop="deptName" v-if="source == 'Behavior'"/>
-
+      <el-table-column label="销售组织" align="center" prop="salesOrgName"/>
+      <el-table-column label="部门" align="center" prop="deptName"/>
       <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width">
-      <!-- <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width" v-if="this.source == 'BoDetails' ? this.bo.winningState == 0 ? true : false : true"> -->
         <template slot-scope="scope">
           <el-button
             size="mini"
             type="text"
-            icon="el-icon-edit"
-            @click="handleUpdate(scope.row)"
-            :disabled="!boAuthority.boAuthority.behaviorEdit"
-          >修改</el-button>
-          <el-button
-            size="mini"
-            type="text"
             icon="el-icon-view"
             @click="handleBrowse(scope.row)"
             :disabled="!boAuthority.boAuthority.behaviorView"
           >查看</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            :disabled="!boAuthority.boAuthority.behaviorDel"
-          >删除</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -119,11 +77,6 @@
         </el-divider>
         <el-row>
           <el-col :span="8">
-            <el-form-item label="任务" prop="taskId" v-if="!(this.source == 'BoDetails')">
-              <el-input v-model="form.taskCode" placeholder="请输入任务" :disabled="this.source == 'TaskList'"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
             <el-form-item label="行动类型" prop="type">
               <el-select v-model="form.type" placeholder="请输入行动类型">
                 <el-option
@@ -149,7 +102,7 @@
         <el-row>
           <el-col :span="8">
             <el-form-item label="客户" prop="customerName">
-              <el-input v-model="form.customerName" placeholder="请输入客户" disabled="this.source == 'BoDetails' || this.source == 'TaskList'"/>
+              <el-input v-model="form.customerName" placeholder="请输入客户" disabled/>
             </el-form-item>
           </el-col>
           <el-col :span="8">
@@ -260,7 +213,7 @@
         <el-dialog :visible.sync="dialogVisible">
           <img width="100%" :src="dialogImageUrl" alt="">
         </el-dialog>
-        
+
         <div class="md-auditInfo">
           <el-divider content-position="left">
             <dev style="width: 50px; height: 40px; font-size: 18px">其它信息</dev>
@@ -319,7 +272,7 @@ import SaleaeaRef from '@/views/business/spd/bo/refer/saleaea/index.vue';
 
 export default {
   name: "BehaviorList",
-  props:["source","bo","boAuthority"],
+  props:["bo","boAuthority"],
   dicts: ['mk_bo_behavior_res','mk_bo_behavior_type','sys_yes_no','mk_bo_behavior_goal'],
   components: {ContactRef,SaleaeaRef},
   data() {
@@ -400,19 +353,10 @@ export default {
   },
   created() {
     console.log('this.boAuthority',this.boAuthority);
-    if(this.source == 'Behavior'){
-      this.queryParams = this.bo;
-    }
-    if(this.source == 'BoDetails'){
-      this.queryParams.bo = this.bo.id;
-      this.queryParams.boStage = this.bo.boStage;
-      let params = {"post":this.boAuthority.post};
-      this.queryParams.params = params;
-    }
-    if(this.source == 'TaskList'){
-      this.queryParams.taskCode = this.bo.code;
-      console.log("this.bo", this.bo);
-    }
+    this.queryParams.bo = this.bo.id;
+    this.queryParams.boStage = this.bo.boStage;
+    let params = {"post":this.boAuthority.post};
+    this.queryParams.params = params;
     this.getList();
   },
   methods: {
@@ -506,23 +450,12 @@ export default {
       this.reset();
       this.operatingState = "Insert";
       //新增行动设置默认值
-      if(this.source == 'BoDetails'){
-        this.queryParams.bo = this.bo.id;
-        this.form.bo = this.bo.id;
-        this.form.boName = this.bo.boName;
-        this.form.boStage = this.bo.boStage;
-        this.form.customer = this.bo.customer;
-        this.form.customerName = this.bo.customerName;
-      }
-      if(this.source == 'TaskList'){
-        this.form.bo = this.bo.bo;
-        this.form.boName = this.bo.boName;
-        this.form.boStage = this.bo.boStage;
-        this.form.customer = this.bo.customer;
-        this.form.customerName = this.bo.customerName;
-        this.form.task = this.bo.id;
-        this.form.taskCode = this.bo.code;
-      }
+      this.queryParams.bo = this.bo.id;
+      this.form.bo = this.bo.id;
+      this.form.boName = this.bo.boName;
+      this.form.boStage = this.bo.boStage;
+      this.form.customer = this.bo.customer;
+      this.form.customerName = this.bo.customerName;
       this.form.type = '0';
       this.form.staff = this.$store.state.user.id;
       this.form.staffName = this.$store.state.user.nickName;
@@ -534,18 +467,6 @@ export default {
       this.open = true;
       this.title = "添加行动";
     },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      this.operatingState = "Update";
-      const id = row.id || this.ids
-      getBehavior(id).then(response => {
-        this.form = response.data;
-        
-        this.open = true;
-        this.title = "修改行动";
-      });
-    },
     /** 查看按钮操作 */
     handleBrowse(row) {
       this.reset();
@@ -593,16 +514,6 @@ export default {
         }
       });
     },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.id || this.ids;
-      this.$modal.confirm('是否确认删除行动编号为"' + ids + '"的数据项?').then(function() {
-        return delBehavior(ids);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("删除成功");
-      }).catch(() => {});
-    },
     // 触发联系人参照列表
     refereContact() {
       this.$refs.contactSelect.init()

+ 254 - 78
src/views/business/spd/bo/behavior/index.vue

@@ -14,18 +14,255 @@
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
+    <el-table v-loading="loading" :data="behaviorList">
+      <el-table-column label="负责人" align="center" prop="staffName" />
+      <el-table-column label="行动日期" align="center" prop="time" />
+      <el-form-item label="行动日期" prop="time">
+        <el-date-picker clearable
+          v-model="form.time"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="请选择行动日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-table-column label="联系人" align="center" prop="linkmanName" />
+      <el-table-column label="拜访效果" align="center" prop="result" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_behavior_res" :value="scope.row.result"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="是否上级协助" align="center" prop="assist" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.assist"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="协助内容" align="center" prop="assistContent" />
+      <el-table-column label="洽谈内容" align="center" prop="content" />
+      <el-table-column label="任务编码" align="center" prop="taskCode"/>
+      <el-table-column label="行动类型" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_behavior_type" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="客户" align="center" prop="customerName"/>
+      <el-table-column label="拜访目的" align="center" prop="purpose">
+        <template slot-scope="scope">
+            <dict-tag :options="dict.type.mk_bo_behavior_goal" :value="scope.row.purpose"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="销售组织" align="center" prop="salesOrgName"/>
+      <el-table-column label="部门" align="center" prop="deptName"/>
+      <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width">
+       <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleBrowse(scope.row)"
+          >查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+    <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="this.operatingState == 'Browse'">
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">基本信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="任务" prop="taskId" v-if="!(this.source == 'BoDetails')">
+              <el-input v-model="form.taskCode" placeholder="请输入任务" :disabled="this.source == 'TaskList'"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="行动类型" prop="type">
+              <el-select v-model="form.type" placeholder="请输入行动类型">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_behavior_type"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="行动日期" prop="time">
+              <el-date-picker clearable
+                v-model="form.time"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="请选择行动日期">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="客户" prop="customerName">
+              <el-input v-model="form.customerName" placeholder="请输入客户" disabled="this.source == 'BoDetails' || this.source == 'TaskList'"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="联系人" prop="linkmanName">
+              <el-input v-model="form.linkmanName" placeholder="请输入联系人" >
+                <el-button slot="append" icon="el-icon-more" @click="refereContact"></el-button>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="拜访目的" prop="purpose">
+              <el-select v-model="form.purpose" placeholder="请输入拜访目的">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_behavior_goal"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col  :span="8">
+            <el-form-item label="拜访效果" prop="result">
+              <el-select v-model="form.result" placeholder="请输入拜访效果">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_behavior_res"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="是否上级协助" prop="assist">
+              <el-select v-model="form.assist" placeholder="请输入是否上级协助">
+                <el-option
+                  v-for="dict in dict.type.sys_yes_no"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="协助内容" prop="assistContent" v-show="form.assist == 'Y'" :rules="form.assist == 'Y' ? rules.assistContent : [{require: false}]">
+              <el-input v-model="form.assistContent" placeholder="请输入协助内容" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="销售区域" prop="marketingAreaName">
+              <el-input v-model="form.marketingAreaName" placeholder="请输入销售区域">
+                <el-button slot="append" icon="el-icon-more" @click="refereSaleaea"></el-button>
+              </el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col  :span="8">
+            <el-form-item label="销售组织" prop="salesOrgName">
+              <el-input v-model="form.salesOrgName" placeholder="请输入销售组织" :disabled="true"/>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+             <el-form-item label="部门" prop="deptName">
+              <el-input v-model="form.deptName" placeholder="请输入部门" :disabled="true"/>
+            </el-form-item>
+          </el-col>
+          <el-col  :span="8">
+            <el-form-item label="负责人" prop="staffName">
+              <el-input v-model="form.staffName" placeholder="请输入负责人" :disabled="true"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">跟进内容</dev>
+        </el-divider>
+        <el-form-item label="内容" prop="content" >
+          <el-input
+            type="textarea"
+            :rows="2"
+            maxlength=900
+            placeholder="填写提示:今天拜访了谁,收集了什么述求,达成了什么结果,下一步计划。"
+            autosize
+            v-model="form.content">
+          </el-input>
+        </el-form-item>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">照片信息</dev>
+        </el-divider>
+
+        <el-upload
+          action="actionUrl"
+          list-type="picture-card"
+          :on-change="uploadPic"
+          :on-preview="handlePictureCardPreview"
+          :on-remove="handleRemove"
+          :auto-upload="false"
+          :file-list="fileList"
+          >
+          <i class="el-icon-plus"></i>
+        </el-upload>
+        <el-dialog :visible.sync="dialogVisible">
+          <img width="100%" :src="dialogImageUrl" alt="">
+        </el-dialog>
 
-    <BehaviorList :key="timer" :source = "'Behavior'" :bo="queryParams" :boAuthority="boAuthority" />
+        <div class="md-auditInfo">
+          <el-divider content-position="left">
+            <dev style="width: 50px; height: 40px; font-size: 18px">其它信息</dev>
+          </el-divider>
+          <el-form :inline="true" label-position="right" :model="form">
+            <el-row>
+              <el-col :span="6">
+                <el-form-item label="创建人">
+                  <el-input v-model="form.createByName" size="small" readonly></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="创建时间">
+                  <el-input v-model="form.createTime" size="small" readonly></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="修改人">
+                  <el-input v-model="form.updateByName" size="small" readonly></el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="修改时间">
+                  <el-input v-model="form.updateTime" size="small" readonly></el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </div>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { listBehavior, getBehavior, delBehavior, addBehavior, updateBehavior } from "@/api/business/spd/bo/behavior";
-import BehaviorList from '../behavior/behaviorList.vue'
+import { listBehavior, getBehavior} from "@/api/business/spd/bo/behavior";
 
 export default {
   name: "Behavior",
-  components: {BehaviorList},
+  dicts: ['mk_bo_behavior_res','mk_bo_behavior_type','sys_yes_no','mk_bo_behavior_goal'],
   data() {
     return {
       // 遮罩层
@@ -73,20 +310,6 @@ export default {
       },
       // 表单参数
       form: {},
-      // 表单校验
-      rules: {
-      },
-      //重新加载子组件参数
-      timer: '',
-      //行动权限写死
-      boAuthority:{
-        boAuthority:{
-          behaviorAdd:true,
-          behaviorEdit:true,
-          behaviorView:true,
-          behaviorDel:true,
-        }
-      },
     };
   },
   created() {
@@ -102,6 +325,18 @@ export default {
         this.loading = false;
       });
     },
+    /** 查看按钮操作 */
+    handleBrowse(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getBehavior(id).then(response => {
+        this.form = response.data;
+        this.fileList = this.form.behaviorPs;
+        this.open = true;
+        this.operatingState = "Browse";
+        this.title = "基础信息";
+      });
+    },
     // 取消按钮
     cancel() {
       this.open = false;
@@ -142,72 +377,13 @@ export default {
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
-      this.timer = new Date().getTime();
-      // this.getList();
+      this.getList();
     },
     /** 重置按钮操作 */
     resetQuery() {
       this.resetForm("queryForm");
       this.handleQuery();
     },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加行动";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const id = row.id || this.ids
-      getBehavior(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改行动";
-      });
-    },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          if (this.form.id != null) {
-            updateBehavior(this.form).then(response => {
-              this.$modal.msgSuccess("修改成功");
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            addBehavior(this.form).then(response => {
-              this.$modal.msgSuccess("新增成功");
-              this.open = false;
-              this.getList();
-            });
-          }
-        }
-      });
-    },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.id || this.ids;
-      this.$modal.confirm('是否确认删除行动编号为"' + ids + '"的数据项?').then(function() {
-        return delBehavior(ids);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("删除成功");
-      }).catch(() => {});
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      this.download('system/behavior/export', {
-        ...this.queryParams
-      }, `behavior_${new Date().getTime()}.xlsx`)
-    }
   }
 };
 </script>

+ 18 - 51
src/views/business/spd/bo/contact/contactList.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <el-row :gutter="10" class="mb8" v-if="this.source == 'BoDetails' ? this.bo.winningState == 0 ? true : false : true">
+    <el-row :gutter="10" class="mb8" v-if="this.bo.winningState == 0">
       <el-col :span="1.5">
         <el-button
           type="primary"
@@ -13,7 +13,7 @@
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
-    <el-table v-loading="loading" :data="contactList" @selection-change="handleSelectionChange">
+    <el-table v-loading="loading" :data="contactList">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="编号" align="center" prop="code" />
       <el-table-column label="姓名" align="center" prop="name" />
@@ -42,7 +42,6 @@
           <dict-tag :options="dict.type.mk_bo_contact_state" :value="scope.row.state"/>
         </template>
       </el-table-column>
-      <!-- v-if="this.source == 'BoDetails' ? this.bo.winningState == 0 ? true : false : true" -->
       <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width" >
         <template slot-scope="scope">
           <el-button
@@ -116,8 +115,8 @@
         <el-row>
           <el-col :span="8">
             <el-form-item label="所属客户" prop="customerName">
-              <el-input v-model="form.customerName" placeholder="请输入所属客户" :disabled="this.source == 'BoDetails'">
-                <el-button slot="append" icon="el-icon-more" @click="refereCustomer" :disabled="this.source == 'BoDetails'"></el-button>
+              <el-input v-model="form.customerName" placeholder="请输入所属客户" disabled>
+                <el-button slot="append" icon="el-icon-more" @click="refereCustomer" disabled></el-button>
               </el-input>
             </el-form-item>
           </el-col>
@@ -280,8 +279,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="邮件" prop="mail">
-              <el-input v-model="form.mail" placeholder="请输入邮件" />
+            <el-form-item label="微信" prop="mail">
+              <el-input v-model="form.mail" placeholder="请输入微信" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
@@ -450,15 +449,9 @@ export default {
     };
   },
   created() {
-    if(this.source == 'BoDetails'){
-      this.queryParams.customer = this.bo.customer;
-      let params = {"post":this.boAuthority.post};
-      this.queryParams.params = params;
-    }
-    if(this.source == 'Contact'){
-      this.queryParams = this.bo;
-    }
-    console.log('this.boAuthority',this.boAuthority);
+    this.queryParams.customer = this.bo.customer;
+    let params = {"post":this.boAuthority.post};
+    this.queryParams.params = params;
     this.getList();
   },
   methods: {
@@ -467,14 +460,12 @@ export default {
       this.loading = true;
       listContact(this.queryParams).then(response => {
         this.contactList = response.rows;
-        if(this.source == 'BoDetails'){
-          console.log('this.contactList',this.contactList);
-          for (var i = 0; i < this.contactList.length; i++) {
-            this.contactList[i].telephone = this.contactList[i].telephone.substring(0,3) + '******' + this.contactList[i].telephone.substring(this.contactList[i].telephone.length - 4,this.contactList[i].telephone.length);
-            this.contactList[i].customerName = this.contactList[i].customerName.substring(0,2) + '******' + this.contactList[i].customerName.substring(this.contactList[i].customerName.length - 2,this.contactList[i].customerName.length);
-            const start = new Array(this.contactList[i].name.length).join('*');
-            this.contactList[i].name = start + this.contactList[i].name.slice(-1);
-          }
+        console.log('this.contactList',this.contactList);
+        for (var i = 0; i < this.contactList.length; i++) {
+          this.contactList[i].telephone = this.contactList[i].telephone.substring(0,3) + '******' + this.contactList[i].telephone.substring(this.contactList[i].telephone.length - 4,this.contactList[i].telephone.length);
+          this.contactList[i].customerName = this.contactList[i].customerName.substring(0,2) + '******' + this.contactList[i].customerName.substring(this.contactList[i].customerName.length - 2,this.contactList[i].customerName.length);
+          const start = new Array(this.contactList[i].name.length).join('*');
+          this.contactList[i].name = start + this.contactList[i].name.slice(-1);
         }
         this.total = response.total;
         this.loading = false;
@@ -526,31 +517,13 @@ export default {
       };
       this.resetForm("form");
     },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
     /** 新增按钮操作 */
     handleAdd() {
       this.operatingState = "Insert";
       this.reset();
-      if(this.source == 'BoDetails'){
-        this.form.boId = this.bo.id;
-        this.form.customer = this.bo.customer;
-        this.form.customerName = this.bo.customerName;
-      }
+      this.form.boId = this.bo.id;
+      this.form.customer = this.bo.customer;
+      this.form.customerName = this.bo.customerName;
       this.form.state = '1';
       this.open = true;
       this.title = "添加联系人";
@@ -613,12 +586,6 @@ export default {
         this.$modal.msgSuccess("删除成功");
       }).catch(() => {});
     },
-    /** 导出按钮操作 */
-    handleExport() {
-      this.download('system/contact/export', {
-        ...this.queryParams
-      }, `contact_${new Date().getTime()}.xlsx`)
-    },
     // 触发客户参照列表
     refereCustomer() {
       this.$refs.customerSelect.init()

+ 363 - 247
src/views/business/spd/bo/contact/index.vue

@@ -1,198 +1,6 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <!-- <el-form-item label="创建日期" prop="createDate">
-        <el-date-picker clearable
-          v-model="queryParams.createDate"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择创建日期">
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item label="部门名称" prop="departmentName">
-        <el-input
-          v-model="queryParams.departmentName"
-          placeholder="请输入部门名称"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="部门编码" prop="departmentCode">
-        <el-input
-          v-model="queryParams.departmentCode"
-          placeholder="请输入部门编码"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="销售区域" prop="area">
-        <el-input
-          v-model="queryParams.area"
-          placeholder="请输入销售区域"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="销售组织" prop="organization">
-        <el-input
-          v-model="queryParams.organization"
-          placeholder="请输入销售组织"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="最佳拜访地点" prop="visitPlace">
-        <el-input
-          v-model="queryParams.visitPlace"
-          placeholder="请输入最佳拜访地点"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="最佳拜访时间" prop="visitTime">
-        <el-date-picker clearable
-          v-model="queryParams.visitTime"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择最佳拜访时间">
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item label="家庭地址" prop="address">
-        <el-input
-          v-model="queryParams.address"
-          placeholder="请输入家庭地址"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="邮件" prop="mail">
-        <el-input
-          v-model="queryParams.mail"
-          placeholder="请输入邮件"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="关键决策人" prop="decisionMaker">
-        <el-input
-          v-model="queryParams.decisionMaker"
-          placeholder="请输入关键决策人"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="擅长领域" prop="fieldExpertise">
-        <el-input
-          v-model="queryParams.fieldExpertise"
-          placeholder="请输入擅长领域"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="支持度" prop="support">
-        <el-input
-          v-model="queryParams.support"
-          placeholder="请输入支持度"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="决策力" prop="power">
-        <el-input
-          v-model="queryParams.power"
-          placeholder="请输入决策力"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="职称" prop="jobTitle">
-        <el-input
-          v-model="queryParams.jobTitle"
-          placeholder="请输入职称"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="职务" prop="position">
-        <el-input
-          v-model="queryParams.position"
-          placeholder="请输入职务"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="任职科室" prop="section">
-        <el-input
-          v-model="queryParams.section"
-          placeholder="请输入任职科室"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="上级联系人" prop="superiorContact">
-        <el-input
-          v-model="queryParams.superiorContact"
-          placeholder="请输入上级联系人"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="状态" prop="state">
-        <el-input
-          v-model="queryParams.state"
-          placeholder="请输入状态"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="业务爱好" prop="hobby">
-        <el-input
-          v-model="queryParams.hobby"
-          placeholder="请输入业务爱好"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="籍贯" prop="birthplace">
-        <el-input
-          v-model="queryParams.birthplace"
-          placeholder="请输入籍贯"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="生日" prop="birthday">
-        <el-date-picker clearable
-          v-model="queryParams.birthday"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择生日">
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item label="联系人分类" prop="contactClassification">
-        <el-input
-          v-model="queryParams.contactClassification"
-          placeholder="请输入联系人分类"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="所属客户编码" prop="customerCode">
-        <el-input
-          v-model="queryParams.customerCode"
-          placeholder="请输入所属客户编码"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="性别" prop="gander">
-        <el-input
-          v-model="queryParams.gander"
-          placeholder="请输入性别"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item> -->
       <el-form-item label="姓名" prop="name">
         <el-input
           v-model="queryParams.name"
@@ -222,17 +30,348 @@
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
-    <ContactList :key="timer" :source = "'Contact'" :bo="this.queryParams" :boAuthority="boAuthority" />
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table v-loading="loading" :data="contactList">
+      <el-table-column label="编号" align="center" prop="code" />
+      <el-table-column label="姓名" align="center" prop="name" />
+      <el-table-column label="性别" align="center" prop="gander" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.sys_user_sex" :value="scope.row.gander"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="联系电话" align="center" prop="telephone" />
+      <el-table-column label="所属客户" align="center" prop="customerName" />
+      <el-table-column label="部门名称" align="center" prop="departmentName" />
+      <el-table-column label="职务" align="center" prop="position" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_position" :value="scope.row.position"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="决策力" align="center" prop="power" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_power" :value="scope.row.power"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="兴趣爱好" align="center" prop="hobby" />
+      <el-table-column label="家庭地址" align="center" prop="address" />
+      <el-table-column label="状态" align="center" prop="state" >
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.mk_bo_contact_state" :value="scope.row.state"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" fixed="right" align="center" class-name="small-padding fixed-width" >
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleBrowse(scope.row)"
+          >查看</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改联系人管理对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="1100px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px" :disabled="this.operatingState == 'Browse'">
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">基本信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="系统自动生成编码" :disabled = "true"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="姓名" prop="name">
+              <el-input v-model="form.name" placeholder="请输入姓名" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="性别" prop="gander">
+              <el-select v-model="form.gander" placeholder="请输入性别">
+                <el-option
+                  v-for="dict in dict.type.sys_user_sex"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="所属客户" prop="customerName">
+              <dr-popover-select v-model="form.customerName" title="客户" type="CUSTOMER_PARAM_ZT" :dataMapping="{
+                  customer: 'id',
+                  customerName: 'name',
+                }" :source.sync="form">
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="联系人分类" prop="contactClassification">
+              <el-select v-model="form.contactClassification" placeholder="请输入联系人分类">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_contact_type"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="生日" prop="birthday">
+              <el-date-picker clearable
+                v-model="form.birthday"
+                type="date"
+                value-format="yyyy-MM-dd"
+                placeholder="请选择生日">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="籍贯" prop="birthplace">
+              <el-input v-model="form.birthplace" placeholder="请输入籍贯" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="兴趣爱好" prop="hobby">
+              <el-input v-model="form.hobby" placeholder="请输入业务爱好" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="状态" prop="state">
+              <el-select v-model="form.state" placeholder="请输入状态">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_contact_state"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">工作信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="上级联系人" prop="superiorContactName">
+              <dr-popover-select v-model="form.superiorContactName" title="上级联系人" type="LINKMAN_PARAM" :dataMapping="{
+                  superiorContact: 'id',
+                  superiorContactName: 'name',
+                }" :source.sync="form">
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="任职科室" prop="section">
+              <el-select v-model="form.section" placeholder="请输入任职科室">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_section"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="职务" prop="position">
+              <el-select v-model="form.position" placeholder="请输入职务">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_position"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="职称" prop="jobTitle">
+              <el-select v-model="form.jobTitle" placeholder="请输入职称">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_job_title"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="决策力" prop="power">
+              <el-select v-model="form.power" placeholder="请输入决策力">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_power"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="支持度" prop="support">
+              <el-select v-model="form.support" placeholder="请输入支持度">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_support"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="擅长领域" prop="fieldExpertise">
+              <el-select v-model="form.fieldExpertise" placeholder="请输入擅长领域">
+                <el-option
+                  v-for="dict in dict.type.mk_bo_field_expertise"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="关键决策人" prop="decisionMaker">
+              <el-select v-model="form.decisionMaker" placeholder="请输入关键决策人">
+                <el-option
+                  v-for="dict in dict.type.sys_yes_no"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+          </el-col>
+        </el-row>
+        <el-divider content-position="left">
+          <dev style="width: 50px; height: 40px; font-size: 18px">联系信息</dev>
+        </el-divider>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="联系电话" prop="telephone">
+              <el-input v-model="form.telephone" placeholder="请输入联系电话" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="微信" prop="mail">
+              <el-input v-model="form.mail" placeholder="请输入微信" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="家庭地址" prop="address">
+              <el-input v-model="form.address" placeholder="请输入家庭地址" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="最佳拜访时间" prop="visitTime">
+              <el-input v-model="form.visitTime" placeholder="请选择最佳拜访时间" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="最佳拜访地点" prop="visitPlace">
+              <el-input v-model="form.visitPlace" placeholder="请输入最佳拜访地点" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+          </el-col>
+        </el-row>
+        <el-tabs v-model="activeName" v-if="this.operatingState != 'Insert'">
+          <el-tab-pane label="学历信息" name="first">
+            <EducationList  :key="timer" :supForm="this.form" />
+          </el-tab-pane>
+          <el-tab-pane label="社会关系" name="second">
+            <RelationshipList :key="timer" :supForm="this.form" />
+          </el-tab-pane>
+        </el-tabs>
+        <div class="md-auditInfo">
+          <el-divider content-position="left">
+            <dev style="width: 50px; height: 40px; font-size: 18px">其它信息</dev>
+          </el-divider>
+          <el-form :inline="true" label-position="right" :model="form">
+            <el-form-item label="创建人">
+              <el-input v-model="form.createByName" size="small" readonly></el-input>
+            </el-form-item>
+            <el-form-item label="创建时间">
+              <el-input v-model="form.createTime" size="small" readonly></el-input>
+            </el-form-item>
+            <el-form-item label="修改人">
+              <el-input v-model="form.updateByName" size="small" readonly></el-input>
+            </el-form-item>
+            <el-form-item label="修改时间">
+              <el-input v-model="form.updateTime" size="small" readonly></el-input>
+            </el-form-item>
+          </el-form>
+        </div>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { listContact, getContact, delContact, addContact, updateContact } from "@/api/business/spd/bo/contact";
-import ContactList from '../contact/contactList.vue'
+import EducationList from '../education/educationList.vue';
+import RelationshipList from '../relationship/relationshipList.vue';
 
 export default {
   name: "Contact",
-  components: {ContactList},
+  dicts: ['sys_user_sex','mk_bo_contact_state','mk_bo_section','mk_bo_position','mk_bo_job_title','mk_bo_power','mk_bo_support','mk_bo_field_expertise','sys_yes_no','mk_bo_contact_type'],
+  components: {EducationList,RelationshipList},
   data() {
     return {
       // 遮罩层
@@ -257,35 +396,9 @@ export default {
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        boId: null,
-        createDate: null,
-        departmentName: null,
-        departmentCode: null,
-        area: null,
-        organization: null,
-        visitPlace: null,
-        visitTime: null,
-        address: null,
-        mail: null,
+        name: null,
         telephone: null,
-        decisionMaker: null,
-        fieldExpertise: null,
-        support: null,
-        power: null,
-        jobTitle: null,
-        position: null,
-        section: null,
-        superiorContact: null,
-        state: null,
-        hobby: null,
-        birthplace: null,
-        birthday: null,
-        contactClassification: null,
         customerName: null,
-        customerCode: null,
-        gander: null,
-        name: null,
-        code: null,
       },
       // 表单参数
       form: {},
@@ -333,15 +446,11 @@ export default {
       },
       //重新加载子组件参数
       timer: '',
-      //列表权限写死
-      boAuthority:{
-        boAuthority:{
-          contactAdd:true,
-          contactEdit:true,
-          contactView:true,
-          contactDel:true,
-        }
-      },
+      //当前操作状态
+      operatingState: '',
+      activeName: 'first',
+      //确定按钮是否可点
+      submitButtonEditStatus:false,
     };
   },
   created() {
@@ -404,40 +513,49 @@ export default {
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      console.log('this.queryParams',this.queryParams);
       this.queryParams.pageNum = 1;
       this.timer = new Date().getTime();
-      // this.getList();
+      this.getList();
     },
     /** 重置按钮操作 */
     resetQuery() {
       this.resetForm("queryForm");
       this.handleQuery();
     },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
-      this.multiple = !selection.length
-    },
     /** 新增按钮操作 */
     handleAdd() {
+      this.operatingState = "Insert";
       this.reset();
+      this.form.state = '1';
       this.open = true;
-      this.title = "添加联系人管理";
+      this.title = "添加联系人";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
+      this.operatingState = "Update";
+      this.reset();
+      const id = row.id || this.ids
+      getContact(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改联系人";
+        this.timer = new Date().getTime();
+      });
+    },
+    /** 查看按钮操作 */
+    handleBrowse(row) {
       this.reset();
       const id = row.id || this.ids
       getContact(id).then(response => {
         this.form = response.data;
         this.open = true;
-        this.title = "修改联系人管理";
+        this.operatingState = "Browse";
+        this.title = "基础信息";
       });
     },
     /** 提交按钮 */
     submitForm() {
+      this.submitButtonEditStatus = true;
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.form.id != null) {
@@ -445,14 +563,18 @@ export default {
               this.$modal.msgSuccess("修改成功");
               this.open = false;
               this.getList();
+              this.submitButtonEditStatus = false;
             });
           } else {
             addContact(this.form).then(response => {
               this.$modal.msgSuccess("新增成功");
               this.open = false;
               this.getList();
+              this.submitButtonEditStatus = false;
             });
           }
+        }else{
+          this.submitButtonEditStatus = false;
         }
       });
     },
@@ -466,12 +588,6 @@ export default {
         this.$modal.msgSuccess("删除成功");
       }).catch(() => {});
     },
-    /** 导出按钮操作 */
-    handleExport() {
-      this.download('system/contact/export', {
-        ...this.queryParams
-      }, `contact_${new Date().getTime()}.xlsx`)
-    }
   }
 };
 </script>

+ 899 - 0
src/views/business/spd/goal_management/AnnualSaleGoal.vue

@@ -0,0 +1,899 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="编码" prop="code">
+        <el-input
+          v-model="queryParams.code"
+          placeholder="请输入编码"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="目标名称" prop="goalName">
+        <el-input
+          v-model="queryParams.goalName"
+          placeholder="请输入年度销售目标名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="单据日期" prop="documentDate">
+        <el-date-picker
+          v-model="queryParams.documentDateRange"
+          type="daterange"
+          value-format="yyyy-MM-dd"
+          clearable
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          placeholder="请选择单据日期"
+          :picker-options="pickerOptions">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item label="年度" prop="annual">
+        <el-date-picker
+          v-model="queryParams.annual"
+          type="year"
+          value-format="yyyy"
+          placeholder="选择年度"
+          clearable
+          @keyup.enter.native="handleQuery">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="客户" prop="custom">
+        <el-popover-select-v2 v-model="queryParams.custom" title="客户" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ customCode: 'code', custom: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入客户" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="销售区域" prop="saleZone">
+        <el-popover-select-v2 v-model="queryParams.saleZone" title="销售区域" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入销售区域" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="制单人" prop="creator">
+        <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                              referName="CONTACTS_PARAM"
+                              :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入制单人" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="部门" prop="dept">
+        <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入部门" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['goal_management:annualSaleGoal:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['goal_management:annualSaleGoal:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['goal_management:annualSaleGoal:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="annualSaleGoalList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" fixed/>
+      <el-table-column label="编码" align="center" prop="code" width="180"/>
+      <el-table-column label="目标名称" align="center" prop="goalName" width="180"/>
+      <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度" align="center" prop="annual"/>
+      <el-table-column label="客户" align="center" prop="custom" width="180"/>
+      <el-table-column label="销售区域" align="center" prop="saleZone" width="180"/>
+      <el-table-column label="制单人" align="center" prop="creator"/>
+      <el-table-column label="部门" align="center" prop="dept" width="180"/>
+      <el-table-column label="目标合计" align="center" prop="goalTotal"/>
+      <el-table-column label="备注" align="center" prop="notes" width="180"/>
+      <el-table-column label="单据状态" align="center" prop="documentStatus"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['goal_management:annualSaleGoal:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['goal_management:annualSaleGoal:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="编码后端自动生成" clearable disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标名称" prop="goalName">
+              <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" clearable disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据日期" prop="documentDate">
+              <el-date-picker v-model="form.documentDate" type="date" format="yyyy-MM-dd"
+                              placeholder="选择日期"></el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="年度" prop="annual">
+              <el-date-picker v-model="form.annual" type="year" format="yyyy" placeholder="选择年度"></el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="客户" prop="custom">
+              <el-popover-select-v2 v-model="form.custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="form" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="销售区域" prop="saleZone">
+              <el-popover-select-v2 v-model="form.saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="form" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="制单人" prop="creator">
+              <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="form" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门" prop="dept">
+              <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM"
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="form" placeholder="请输入部门">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="目标合计" prop="goalTotal">
+              <el-input v-model="form.goalTotal" placeholder="目标合计自动计算" clearable disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="备注" prop="notes">
+              <el-input v-model="form.notes" placeholder="请输入备注" clearable/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据状态" prop="documentStatus">
+              <el-input v-model="form.documentStatus" placeholder="单据状态后端自动生成" clearable disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作">
+              <el-button type="primary" @click="submitForm" size="medium">确 定</el-button>
+              <el-button @click="cancel" size="medium">返 回</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div id="addDetails">
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增行</el-button>
+          </el-col>
+        </el-row>
+        <el-table v-loading="loading" :data="annualSaleGoalDetailsList" @selection-change="handleSelectionChange">
+          <el-table-column type="selection" width="55" align="center" fixed />
+          <el-table-column label="销售组织" align="center" prop="saleOrg" width="180" :render-header="addRedStar">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="annualSaleGoalDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    @blur="validateField(scope.row, 'saleOrg')"
+                                    :dataMapping="{ saleOrgCode: 'code', saleOrg: 'name'}"
+                                    :source.sync="annualSaleGoalDetailsList[scope.$index]" placeholder="请输入销售组织">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="销售区域" align="center" prop="saleZone" width="180" :render-header="addRedStar">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="annualSaleGoalDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="annualSaleGoalDetailsList[scope.$index]" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="客户" align="center" prop="custom" width="180" :render-header="addRedStar">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="annualSaleGoalDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="annualSaleGoalDetailsList[scope.$index]" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="负责人" align="center" prop="creator" width="180" :render-header="addRedStar">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="annualSaleGoalDetailsList[scope.$index].creator" title="负责人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="annualSaleGoalDetailsList[scope.$index]" placeholder="请输入负责人">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="一级分类" align="center" prop="oneLevelClassify" width="220" :render-header="addRedStar">
+            <template slot-scope="scope">
+              <el-select v-model="annualSaleGoalDetailsList[scope.$index].oneLevelClassify" size="mini" clearable
+                         @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '一级物料分类', scope.$index)"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="二级分类" align="center" prop="twoLevelClassify" width="220">
+            <template slot-scope="scope">
+              <el-select v-model="annualSaleGoalDetailsList[scope.$index].twoLevelClassify" size="mini" clearable
+                         @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '二级物料分类', scope.$index)"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </template>
+          </el-table-column>
+          <el-table-column label="物料" align="center" prop="material" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="annualSaleGoalDetailsList[scope.$index].material" title="物料" valueKey="name"
+                                    referName="MATERIAL_PARAM"
+                                    :dataMapping="{ materialCode: 'code', material: 'name'}"
+                                    :source.sync="annualSaleGoalDetailsList[scope.$index]" placeholder="请输入物料">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="合计" align="center" prop="totalGoal" width="180">
+            <template slot-scope="scope">
+              <el-input v-model="annualSaleGoalDetailsList[scope.$index].totalGoal" disabled></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="一月" align="center" prop="januaryGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].januaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="二月" align="center" prop="februaryGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].februaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="三月" align="center" prop="marchGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].marchGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="四月" align="center" prop="aprilGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].aprilGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="五月" align="center" prop="mayGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].mayGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="六月" align="center" prop="juneGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].juneGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="七月" align="center" prop="julyGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].julyGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="八月" align="center" prop="augustGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].augustGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="九月" align="center" prop="septemberGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].septemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="十月" align="center" prop="octoberGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].octoberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="十一月" align="center" prop="novemberGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].novemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="十二月" align="center" prop="decemberGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalDetailsList[scope.$index])" v-model="annualSaleGoalDetailsList[scope.$index].decemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                @click="handleDeleteDetails(scope.$index, scope.row)"
+              >删除</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                @click="handleCopyDetails(scope.row)"
+              >复制</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-drawer>
+
+    <TreeRefers ref="treeDetails" @doSubmit="selectionsToInputForDetails" :single="true"/>
+  </div>
+</template>
+
+<script>
+import {
+  listAnnualSaleGoal,
+  getAnnualSaleGoal,
+  delAnnualSaleGoal,
+  addAnnualSaleGoal,
+  updateAnnualSaleGoal
+} from "@/api/business/spd/goal_management/annualSaleGoal";
+
+import {
+  delAnnualSaleGoalDetails,
+  getAnnualSaleGoalDetails
+} from "@/api/business/spd/goal_management/annualSaleGoalDetails"
+
+// 树形参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+
+export default {
+  name: "AnnualSaleGoal",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 年度销售目标表格数据
+      annualSaleGoalList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        documentDateRange: null
+      },
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: '开立态',
+        deleteStatus: 0,
+        annualGoalMergeDetails: []
+      },
+      formDetails: {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        creator: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        totalGoal: null,
+        januaryGoal: null,
+        februaryGoal: null,
+        marchGoal: null,
+        aprilGoal: null,
+        mayGoal: null,
+        juneGoal: null,
+        julyGoal: null,
+        augustGoal: null,
+        septemberGoal: null,
+        octoberGoal: null,
+        novemberGoal: null,
+        decemberGoal: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{required: true, message: '单据日期不能为空', trigger: 'blur'}],
+        annual: [{required: true, message: '年度不能为空', trigger: 'blur'}],
+        custom: [{required: true, message: '客户不能为空', trigger: 'blur'}],
+        saleZone: [{required: true, message: '销售区域不能为空', trigger: 'blur'}],
+        creator: [{required: true, message: '制单人不能为空', trigger: 'blur'}],
+        dept: [{required: true, message: '部门不能为空', trigger: 'blur'}]
+      },
+      // 参照条件
+      referCondition: {type: '', isPage: true, title: '', index: null},
+      classOptions: [],
+      // 子表数组
+      annualSaleGoalDetailsList: []
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询年度销售目标列表 */
+    getList() {
+      this.loading = true;
+      listAnnualSaleGoal(this.queryParams).then(response => {
+        this.annualSaleGoalList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+        console.log(this.annualSaleGoalList);
+        for (const element of this.annualSaleGoalList) {
+          if (element.documentStatus === '0') {
+            element.documentStatus = '未提交'
+          } else if (element.documentStatus === '1') {
+            element.documentStatus = '审核中'
+          } else {
+            element.documentStatus = '已审核'
+          }
+        }
+      });
+    },
+    getListDetails() {
+      this.loading = true
+      getAnnualSaleGoalDetails(this.form.id).then(response => {
+        this.annualSaleGoalDetailsList = response.data
+        this.computeTotal()
+        this.form.annualGoalMergeDetails = this.annualSaleGoalDetailsList
+        updateAnnualSaleGoal(this.form).then(response => {})
+        this.loading = false
+      })
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        deleteStatus: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        documentDateRange: null
+      }
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.title = "添加年度销售目标";
+      this.annualSaleGoalDetailsList = []
+      this.open = true;
+    },
+    handleAddDetails() {
+      let list = {
+        id: null,
+        code: null,
+        saleOrg: this.form.saleZone,
+        saleZone: this.form.saleZone,
+        custom: this.form.custom,
+        creator: this.form.creator,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        totalGoal: 0,
+        januaryGoal: null,
+        februaryGoal: null,
+        marchGoal: null,
+        aprilGoal: null,
+        mayGoal: null,
+        juneGoal: null,
+        julyGoal: null,
+        augustGoal: null,
+        septemberGoal: null,
+        octoberGoal: null,
+        novemberGoal: null,
+        decemberGoal: null
+      }
+      this.annualSaleGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getAnnualSaleGoal(id).then(response => {
+        this.form = response.data;
+        this.annualSaleGoalDetailsList = this.form.annualGoalMergeDetails
+        this.open = true;
+        this.title = "修改年度销售目标";
+        if (this.form.documentStatus === '0') {
+          this.form.documentStatus = '未提交'
+        } else if (this.form.documentStatus === '1') {
+          this.form.documentStatus = '审批中'
+        } else if (this.form.documentStatus === '2') {
+          this.form.documentStatus = '已审核'
+        }
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      if (!this.justiceDetailsList()) {
+        return this.$message.error('子表有必填字段没有赋值')
+      }
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            if (this.form.documentStatus === '未提交') {
+              this.form.documentStatus = 0
+            } else if (this.form.documentStatus === '审批中') {
+              this.form.documentStatus = 1
+            } else {
+              this.form.documentStatus = 2
+            }
+            this.form.annualGoalMergeDetails = this.annualSaleGoalDetailsList
+            updateAnnualSaleGoal(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.annualGoalMergeDetails = this.annualSaleGoalDetailsList
+            addAnnualSaleGoal(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除年度销售目标编号为"' + ids + '"的数据项?').then(function () {
+        return delAnnualSaleGoal(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) {
+        this.annualSaleGoalDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else {
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除年度销售目标明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delAnnualSaleGoalDetails(row.id)
+          }).then(() => {
+            this.getListDetails()
+            this.$modal.msgSuccess('删除成功')
+          }).catch(() => {})
+        } else {
+          this.annualSaleGoalDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('goal_management/annualSaleGoal/export', {
+        ...this.queryParams
+      }, `annualSaleGoal_${new Date().getTime()}.xlsx`)
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+          this.reset()
+        })
+        .catch(_ => {
+        });
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: null,
+        code: row.code,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        creator: row.creator,
+        oneLevelClassifyCode: row.oneLevelClassifyCode,
+        oneLevelClassify: row.oneLevelClassify,
+        twoLevelClassifyCode: row.oneLevelClassifyCode,
+        twoLevelClassify: row.twoLevelClassify,
+        materialCode: row.materialCode,
+        material: row.material,
+        totalGoal: row.totalGoal,
+        januaryGoal: row.januaryGoal,
+        februaryGoal: row.februaryGoal,
+        marchGoal: row.marchGoal,
+        aprilGoal: row.aprilGoal,
+        mayGoal: row.mayGoal,
+        juneGoal: row.juneGoal,
+        julyGoal: row.julyGoal,
+        augustGoal: row.augustGoal,
+        septemberGoal: row.septemberGoal,
+        octoberGoal: row.octoberGoal,
+        novemberGoal: row.novemberGoal,
+        decemberGoal: row.decemberGoal
+      }
+      this.annualSaleGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    // 计算子表合计
+    computeTotalDetails(index, row) {
+      let array = [row.januaryGoal, row.februaryGoal, row.marchGoal, row.aprilGoal, row.mayGoal, row.juneGoal, row.julyGoal, row.augustGoal, row.septemberGoal, row.octoberGoal, row.novemberGoal, row.decemberGoal]
+      let sum = 0
+      for (const element of array) {
+        sum = (sum * 1000000 + element * 1000000) / 1000000
+      }
+      this.annualSaleGoalDetailsList[index].totalGoal = sum
+      this.computeTotal()
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.annualSaleGoalDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        sum = (sum * 1000000 + listElement.totalGoal * 1000000) / 1000000
+      }
+      this.form.goalTotal = sum
+    },
+    // 树形物料分类
+    chooseTreeReferForDetails(type, isPage, title, index) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.index = index
+      this.$refs.treeDetails.init(this.referCondition)
+    },
+    selectionsToInputForDetails(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类中选择')
+        }
+        if (selection.code !== this.annualSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          this.annualSaleGoalDetailsList[this.referCondition.index].twoLevelClassifyCode = null
+          this.annualSaleGoalDetailsList[this.referCondition.index].twoLevelClassify = null
+        }
+        this.annualSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode = selection.code
+        this.annualSaleGoalDetailsList[this.referCondition.index].oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类中选择')
+        } else if (selection.code[0] !== this.annualSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          return this.$message.error('所选择的二级物料分类不属于一级分类')
+        }
+        this.annualSaleGoalDetailsList[this.referCondition.index].twoLevelClassifyCode = selection.code
+        this.annualSaleGoalDetailsList[this.referCondition.index].twoLevelClassify = selection.name
+      }
+    },
+    // 给table添加必填项
+    addRedStar(h, { column }) {
+      return [
+        h('span', { style: 'color: #F56C6C' }, '*'),
+        h('span', '' + column.label)
+      ]
+    },
+    // 判断子表的字段是否都填了
+    justiceDetailsList() {
+      const arr = JSON.parse(JSON.stringify(this.annualSaleGoalDetailsList))
+      for (const element of arr) {
+        if (element.saleOrg === null || element.saleZone === null || element.custom === null || element.creator === null || element.oneLevelClassify === null) {
+          return false
+        }
+      }
+      return true
+    }
+  }
+};
+</script>

+ 1280 - 0
src/views/business/spd/goal_management/AnnualSaleGoalMerge.vue

@@ -0,0 +1,1280 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="编码" prop="code">
+        <el-input v-model="queryParams.code" placeholder="请输入编码" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="目标名称" prop="goalName">
+        <el-input v-model="queryParams.goalName" placeholder="请输入目标名称" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="单据日期" prop="documentDate">
+        <el-date-picker
+          v-model="documentDateRange"
+          type="daterange"
+          value-format="yyyy-MM-dd"
+          @change="setBeginAndEnd"
+          clearable
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          placeholder="请选择单据日期"
+          :picker-options="pickerOptions">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item label="年度" prop="annual">
+        <el-date-picker
+          v-model="queryParams.annual"
+          type="year"
+          value-format="yyyy"
+          placeholder="选择年度"
+          clearable
+          @keyup.enter.native="handleQuery">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="部门" prop="dept">
+        <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入部门" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="目标类型" prop="goalCategory">
+        <el-select v-model="queryParams.goalCategory" placeholder="请输入目标类型">
+          <el-option
+            v-for="item in [{ value: '销售区域', label: '销售区域' }, { value: '一级分类', label: '一级分类' }, { value: '二级分类', label: '二级分类' }]"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="销售区域" prop="saleZone">
+        <el-popover-select-v2 v-model="queryParams.saleZoneCode" title="销售区域" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入销售区域">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="制单人" prop="creator">
+        <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                              referName="CONTACTS_PARAM"
+                              :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入负责人">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="一级分类" prop="oneLevelClassify">
+        <el-select v-model="queryParams.oneLevelClassify" size="mini" clearable placeholder="请输入一级分类"
+                   @focus="chooseTreeReferForQuery('MATERIALCLASSIFY_PARAM', false, '一级物料分类')"
+                   style="width: 200px">
+          <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="二级分类" prop="twoLevelClassify">
+        <el-select v-model="queryParams.twoLevelClassify" size="mini" clearable placeholder="请输入二级分类"
+                   @focus="chooseTreeReferForQuery('MATERIALCLASSIFY_PARAM', false, '二级物料分类')"
+                   style="width: 200px">
+          <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['goal_management:annualSaleGoalMerge:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['goal_management:annualSaleGoalMerge:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['goal_management:annualSaleGoalMerge:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="annualSaleGoalMergeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="编码" align="center" prop="code" width="180"/>
+      <el-table-column label="目标名称" align="center" prop="goalName" width="180"/>
+      <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度" align="center" prop="annual" width="180"/>
+      <el-table-column label="制单人" align="center" prop="creator" width="180"/>
+      <el-table-column label="部门" align="center" prop="dept" width="180"/>
+      <el-table-column label="目标类型" align="center" prop="goalCategory" width="180"/>
+      <el-table-column label="目标值汇总" align="center" prop="goalTotal" width="180"/>
+      <el-table-column label="销售区域" align="center" prop="saleZone" width="220"/>
+      <el-table-column label="一级分类" align="center" prop="oneLevelClassify" width="180"/>
+      <el-table-column label="二级分类" align="center" prop="twoLevelClassify" width="180"/>
+      <el-table-column label="备注" align="center" prop="notes" width="180"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['goal_management:annualSaleGoalMerge:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['goal_management:annualSaleGoalMerge:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改年度销售目标明细对话框 -->
+    <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="编码后端自动生成" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标名称" prop="goalName">
+              <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据日期" prop="documentDate">
+              <el-date-picker v-model="form.documentDate" type="date" placeholder="选择单据日期" value-format="yyyy-MM-dd">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="年度" prop="annual">
+              <el-date-picker v-model="form.annual" type="year" placeholder="选择年度" value-format="yyyy">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="制单人" prop="creator">
+              <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="form" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门" prop="dept">
+              <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM"
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="form" placeholder="请输入部门">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标分类" prop="goalCategory">
+              <el-select v-model="form.goalCategory" placeholder="请选择" @change="changeGoalCategoryForm">
+                <el-option
+                  v-for="item in goalCategoryList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标值汇总" prop="goalTotal">
+              <el-input v-model="form.goalTotal" placeholder="目标值汇总自动计算" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="备注" prop="notes">
+              <el-input v-model="form.notes" placeholder="请输入备注" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item v-if="form.goalCategory === '销售区域'" label="销售区域" prop="saleZone">
+              <el-popover-select-v2 v-model="form.saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="form" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </el-form-item>
+            <el-form-item v-if="form.goalCategory === '一级分类'" label="一级分类" prop="oneLevelClassify">
+              <el-select v-model="form.oneLevelClassify" clearable
+                         @focus="chooseTreeReferForMain('MATERIALCLASSIFY_PARAM', false, '一级物料分类')"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+            <el-form-item v-if="form.goalCategory === '二级分类'" label="二级分类" prop="twoLevelClassify">
+              <el-select v-model="form.twoLevelClassify" clearable
+                         @focus="chooseTreeReferForMain('MATERIALCLASSIFY_PARAM', false, '二级物料分类')"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据状态" prop="documentStatus">
+              <el-input v-model="form.documentStatus" placeholder="新增页默认未提交" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作">
+              <el-button type="primary" @click="submitForm">确 定</el-button>
+              <el-button @click="cancel">取 消</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-row :gutter="10" class="mb8">
+<!--        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增 行</el-button>
+        </el-col>-->
+        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-folder-opened" size="mini" @click="clickMerge">合 并</el-button>
+        </el-col>
+      </el-row>
+      <el-tabs v-model="activeName" @tab-click="getNewTwoArray">
+        <el-tab-pane label="年销售目标合并明细" name="annualSaleGoalMergeDetails">
+          <el-table v-loading="loading" :data="annualSaleGoalMergeDetailsList">
+            <el-table-column label="序号" type="index" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="annualSaleGoalMergeDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleOrg: 'name'}"
+                                      :source.sync="annualSaleGoalMergeDetailsList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="annualSaleGoalMergeDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleZone: 'name'}"
+                                      :source.sync="annualSaleGoalMergeDetailsList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="客户" align="center" prop="custom" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="annualSaleGoalMergeDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{custom: 'name'}"
+                                      :source.sync="annualSaleGoalMergeDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="负责人" align="center" prop="creator" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="annualSaleGoalMergeDetailsList[scope.$index].creator" title="负责人" valueKey="name"
+                                      referName="CONTACTS_PARAM" disabled
+                                      :dataMapping="{creator: 'name'}"
+                                      :source.sync="annualSaleGoalMergeDetailsList[scope.$index]" placeholder="请输入负责人">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="一级分类" align="center" prop="oneLevelClassify" width="220">
+              <template slot-scope="scope">
+                <el-select v-model="annualSaleGoalMergeDetailsList[scope.$index].oneLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '一级物料分类', scope.$index)"
+                           style="width: 200px" disabled>
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="二级分类" align="center" prop="twoLevelClassify" width="220">
+              <template slot-scope="scope">
+                <el-select v-model="annualSaleGoalMergeDetailsList[scope.$index].twoLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '二级物料分类', scope.$index)"
+                           style="width: 200px" disabled>
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" prop="goalSum" width="180">
+              <template slot-scope="scope">
+                <el-input v-model="annualSaleGoalMergeDetailsList[scope.$index].totalGoal" disabled></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="一月" align="center" prop="januaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].januaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="二月" align="center" prop="februaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].februaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="三月" align="center" prop="marchGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].marchGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="四月" align="center" prop="aprilGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].aprilGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="五月" align="center" prop="mayGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].mayGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="六月" align="center" prop="juneGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].juneGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="七月" align="center" prop="julyGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].julyGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="八月" align="center" prop="augustGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].augustGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="九月" align="center" prop="septemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].septemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十月" align="center" prop="octoberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].octoberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十一月" align="center" prop="novemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].novemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十二月" align="center" prop="decemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotalDetails(scope.$index, annualSaleGoalMergeDetailsList[scope.$index])" v-model="annualSaleGoalMergeDetailsList[scope.$index].decemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+<!--            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDeleteDetails(scope.$index, scope.row)"
+                >删除</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleCopyDetails(scope.row)"
+                >复制</el-button>
+              </template>
+            </el-table-column>-->
+          </el-table>
+        </el-tab-pane>
+        <el-tab-pane label="区域目标汇总(年)" name="zoneGoalSum(year)">
+          <el-table v-loading="loading" :data="areaDetailList">
+            <el-table-column label="序号" type="index" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="areaDetailList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleOrg: 'name'}"
+                                      :source.sync="areaDetailList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="areaDetailList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleZone: 'name'}"
+                                      :source.sync="areaDetailList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="负责人" align="center" prop="creator" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="areaDetailList[scope.$index].creator" title="负责人" valueKey="name"
+                                      referName="CONTACTS_PARAM" disabled
+                                      :dataMapping="{creator: 'name'}"
+                                      :source.sync="areaDetailList[scope.$index]" placeholder="请输入负责人">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" prop="goalSum" width="180">
+              <template slot-scope="scope">
+                <el-input v-model="areaDetailList[scope.$index].totalGoal" disabled></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="一月" align="center" prop="januaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].januaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="二月" align="center" prop="februaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].februaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="三月" align="center" prop="marchGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].marchGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="四月" align="center" prop="aprilGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].aprilGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="五月" align="center" prop="mayGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].mayGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="六月" align="center" prop="juneGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].juneGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="七月" align="center" prop="julyGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].julyGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="八月" align="center" prop="augustGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].augustGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="九月" align="center" prop="septemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].septemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十月" align="center" prop="octoberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].octoberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十一月" align="center" prop="novemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].novemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十二月" align="center" prop="decemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="areaDetailList[scope.$index].decemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+        <el-tab-pane label="客户目标汇总(年)" name="customerGoalSum(year)">
+          <el-table v-loading="loading" :data="customerDetailList">
+            <el-table-column label="序号" type="index" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="customerDetailList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleOrg: 'name'}"
+                                      :source.sync="customerDetailList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="customerDetailList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{saleZone: 'name'}"
+                                      :source.sync="customerDetailList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="客户" align="center" prop="custom" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="customerDetailList[scope.$index].custom" title="客户" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{custom: 'name'}"
+                                      :source.sync="customerDetailList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" prop="goalSum" width="180">
+              <template slot-scope="scope">
+                <el-input v-model="customerDetailList[scope.$index].totalGoal" disabled></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="一月" align="center" prop="januaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].januaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="二月" align="center" prop="februaryGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].februaryGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="三月" align="center" prop="marchGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].marchGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="四月" align="center" prop="aprilGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].aprilGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="五月" align="center" prop="mayGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].mayGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="六月" align="center" prop="juneGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].juneGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="七月" align="center" prop="julyGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].julyGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="八月" align="center" prop="augustGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].augustGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="九月" align="center" prop="septemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].septemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十月" align="center" prop="octoberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].octoberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十一月" align="center" prop="novemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].novemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="十二月" align="center" prop="decemberGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number disabled v-model="customerDetailList[scope.$index].decemberGoal" :precision="2" :step="0.1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+
+    <TreeRefers ref="treeQuery" @doSubmit="selectionsToInputForQuery" :single="true"/>
+    <TreeRefers ref="treeMain" @doSubmit="selectionsToInputForMain" :single="true" />
+    <TreeRefers ref="treeDetails" @doSubmit="selectionsToInputForDetails" :single="true" />
+  </div>
+</template>
+
+<script>
+import {
+  addAnnualSaleGoalMerge,
+  delAnnualSaleGoalMerge,
+  getAnnualSaleGoalMerge,
+  listAnnualSaleGoalMerge,
+  updateAnnualSaleGoalMerge
+} from "@/api/business/spd/goal_management/annualSaleGoalMerge";
+import {
+  mergeAnnualSaleMergeDetails,
+  delAnnualSaleMergeDetails,
+  getAnnualSaleMergeDetails
+} from "@/api/business/spd/goal_management/annualSaleMergeDetails"
+import deepCopy from "@gby/deep-copy";
+
+// 树形参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+import log from "../../../monitor/job/log";
+
+export default {
+  name: "AnnualSaleGoalMerge",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 年度销售目标明细表格数据
+      annualSaleGoalMergeList: null,
+      annualSaleGoalMergeDetailsList: null,
+      areaDetailList: null,
+      customerDetailList: null,
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        params: { beginTime: null, endTime: null }
+      },
+      documentDateRange: null,
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        annualGoalMergeDetailsList: null
+      },
+      formDetails: {
+        id: null,
+        mergeCode: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        creator: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        totalGoal: null,
+        januaryGoal: null,
+        februaryGoal: null,
+        marchGoal: null,
+        aprilGoal: null,
+        mayGoal: null,
+        juneGoal: null,
+        julyGoal: null,
+        augustGoal: null,
+        septemberGoal: null,
+        octoberGoal: null,
+        novemberGoal: null,
+        decemberGoal: null,
+        delFlag: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{ required: true, message: '单据日期不能为空', trigger: 'blur' }],
+        annual: [{ required: true, message: '年度不能为空', trigger: 'blur' }],
+        creator: [{ required: true, message: '制单人不能为空', trigger: 'blur' }],
+        dept: [{ required: true, message: '部门不能为空', trigger: 'blur' }],
+        goalCategory: [{ required: true, message: '目标类型不能为空', trigger: 'blur' }],
+        saleZone: [],
+        oneLevelClassify: [],
+        twoLevelClassify: []
+      },
+      // 树形参照
+      referCondition: {type: '', isPage: true, title: '', index: null},
+      classOptions: [],
+      // 目标分类
+      goalCategoryList: [
+        {
+          label: '销售区域', value: '销售区域'
+        }, {
+          label: '一级分类', value: '一级分类'
+        }, {
+          label: '二级分类', value: '二级分类'
+        }],
+      activeName: 'annualSaleGoalMergeDetails'
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询年度销售目标明细列表 */
+    getList() {
+      this.loading = true;
+      listAnnualSaleGoalMerge(this.queryParams).then(response => {
+        this.annualSaleGoalMergeList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getListDetails() {
+      this.loading = true;
+      getAnnualSaleMergeDetails(this.form.id).then(response => {
+        console.log(response);
+        this.annualSaleGoalMergeDetailsList = response.data;
+        this.computeTotal()
+        this.form.annualGoalMergeDetailsList = this.annualSaleGoalMergeDetailsList
+        updateAnnualSaleGoalMerge(this.form).then(response => {
+          this.$modal.msgSuccess("目标值汇总修改成功");
+        });
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        detailsList: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalTotal: null,
+        notes: null,
+        documentStatus: null,
+        delFlag: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        params: { beginTime: null, endTime: null }
+      }
+      this.documentDateRange = null
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.annualSaleGoalMergeDetailsList = []
+      this.areaDetailList = []
+      this.customerDetailList = []
+      this.activeName = 'annualSaleGoalMergeDetails'
+      this.open = true;
+      this.title = "添加年度销售目标明细";
+    },
+    handleAddDetails() {
+      if (this.activeName !== 'annualSaleGoalMergeDetails') {
+        return this.$message.error('当前标签不是‘年度销售目标合并明细’')
+      }
+      let list = {
+        id: null,
+        mergeCode: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        creator: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        goalSum: null,
+        januaryGoal: null,
+        februaryGoal: null,
+        marchGoal: null,
+        aprilGoal: null,
+        mayGoal: null,
+        juneGoal: null,
+        julyGoal: null,
+        augustGoal: null,
+        septemberGoal: null,
+        octoberGoal: null,
+        novemberGoal: null,
+        decemberGoal: null,
+        delFlag: null
+      }
+      this.annualSaleGoalMergeDetailsList.push(list)
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      this.activeName = 'annualSaleGoalMergeDetails'
+      this.areaDetailList = []
+      this.customerDetailList = []
+      getAnnualSaleGoalMerge(id).then(response => {
+        console.log(response);
+        this.form = response.data;
+        this.annualSaleGoalMergeDetailsList = response.data.annualGoalMergeDetailsList
+        this.open = true;
+        this.title = "修改年度销售目标明细";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            this.form.annualGoalMergeDetailsList = this.annualSaleGoalMergeDetailsList
+            console.log(this.form);
+            updateAnnualSaleGoalMerge(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.annualGoalMergeDetailsList = this.annualSaleGoalMergeDetailsList
+            this.form.documentStatus = '未提交'
+            console.log(this.form);
+            addAnnualSaleGoalMerge(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除年度销售目标明细编号为"' + ids + '"的数据项?').then(function () {
+        return delAnnualSaleGoalMerge(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) { // 新增
+        this.annualSaleGoalMergeDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else { // 修改
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除年度销售目标明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delAnnualSaleMergeDetails(row.id);
+          }).then(() => {
+            this.getListDetails();
+            this.$modal.msgSuccess("删除成功");
+          }).catch(() => {
+          });
+        } else {
+          this.annualSaleGoalMergeDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('goal_management/annualSaleGoalMerge/export', {
+        ...this.queryParams
+      }, `annualSaleGoalMerge_${new Date().getTime()}.xlsx`)
+    },
+    // 树形参照
+    chooseTreeReferForQuery(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.treeQuery.init(this.referCondition)
+    },
+    selectionsToInputForQuery(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类下选择')
+        }
+        this.queryParams.oneLevelClassifyCode = selection.code
+        this.queryParams.oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类下选择')
+        }
+        this.queryParams.twoLevelClassifyCode = selection.code
+        this.queryParams.twoLevelClassify = selection.name
+      }
+    },
+    chooseTreeReferForMain(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.treeMain.init(this.referCondition)
+    },
+    selectionsToInputForMain(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类下选择')
+        }
+        this.form.oneLevelClassifyCode = selection.code
+        this.form.oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类下选择')
+        }
+        this.form.twoLevelClassifyCode = selection.code
+        this.form.twoLevelClassify = selection.name
+      }
+    },
+    chooseTreeReferForDetails(type, isPage, title, index) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.index = index
+      this.$refs.treeDetails.init(this.referCondition)
+    },
+    selectionsToInputForDetails(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类中选择')
+        }
+        if (selection.code !== this.annualSaleGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          this.annualSaleGoalMergeDetailsList[this.referCondition.index].twoLevelClassifyCode = null
+          this.annualSaleGoalMergeDetailsList[this.referCondition.index].twoLevelClassify = null
+        }
+        this.annualSaleGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode = selection.code
+        this.annualSaleGoalMergeDetailsList[this.referCondition.index].oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类中选择')
+        } else if (selection.code[0] !== this.annualSaleGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          return this.$message.error('所选择的二级物料分类不属于一级分类')
+        }
+        this.annualSaleGoalMergeDetailsList[this.referCondition.index].twoLevelClassifyCode = selection.code
+        this.annualSaleGoalMergeDetailsList[this.referCondition.index].twoLevelClassify = selection.name
+      }
+    },
+    changeGoalCategoryForm() {
+      let condition = this.form.goalCategory
+      if (condition === '销售区域') {
+        this.form.oneLevelClassifyCode = null
+        this.form.oneLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.rules.saleZone = [{ required: true, message: '销售区域不能为空', trigger: 'blur' }]
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = []
+      } else if (condition === '一级分类') {
+        this.form.saleZoneCode = null
+        this.form.saleZone = null
+        this.form.twoLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = [{ required: true, message: '一级分类不能为空', trigger: 'blur' }]
+        this.rules.twoLevelClassify = []
+      } else if (condition === '二级分类') {
+        this.form.saleZoneCode = null
+        this.form.saleZone = null
+        this.form.oneLevelClassifyCode = null
+        this.form.oneLevelClassify = null
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = [{ required: true, message: '二级分类不能为空', trigger: 'blur' }]
+      } else {
+        this.form.saleZoneCode = null
+        this.form.saleZone = null
+        this.form.oneLevelClassifyCode = null
+        this.form.oneLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = []
+      }
+    },
+    // 关闭抽屉
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+          this.resetQuery()
+        })
+        .catch(_ => {});
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: null,
+        mergeCode: row.mergeCode,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        creator: row.creator,
+        oneLevelClassifyCode: row.oneLevelClassifyCode,
+        oneLevelClassify: row.oneLevelClassify,
+        twoLevelClassifyCode: row.twoLevelClassifyCode,
+        twoLevelClassify: row.twoLevelClassify,
+        totalGoal: row.totalGoal,
+        januaryGoal: row.januaryGoal,
+        februaryGoal: row.februaryGoal,
+        marchGoal: row.marchGoal,
+        aprilGoal: row.aprilGoal,
+        mayGoal: row.mayGoal,
+        juneGoal: row.juneGoal,
+        julyGoal: row.julyGoal,
+        augustGoal: row.augustGoal,
+        septemberGoal: row.septemberGoal,
+        octoberGoal: row.octoberGoal,
+        novemberGoal: row.novemberGoal,
+        decemberGoal: row.decemberGoal,
+        delFlag: row.delFlag
+      }
+      this.annualSaleGoalMergeDetailsList.push(list)
+      this.computeTotal()
+    },
+    // 计算子表合计
+    computeTotalDetails(index, row) {
+      let array = [row.januaryGoal, row.februaryGoal, row.marchGoal, row.aprilGoal, row.mayGoal, row.juneGoal, row.julyGoal, row.augustGoal, row.septemberGoal, row.octoberGoal, row.novemberGoal, row.decemberGoal]
+      let sum = 0
+      for (const element of array) {
+        sum = (sum * 1000000 + element * 1000000) / 1000000
+      }
+      this.annualSaleGoalMergeDetailsList[index].totalGoal = sum
+      this.computeTotal()
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.annualSaleGoalMergeDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        if (listElement.totalGoal === null) {
+          listElement.totalGoal = 0
+        }
+        sum = (sum * 1000000 + listElement.totalGoal * 1000000) / 1000000
+      }
+      this.form.goalTotal = sum
+    },
+    // 合并数据
+    clickMerge() {
+      if (this.activeName !== 'annualSaleGoalMergeDetails') {
+        return this.$message.error('当前标签不是年销售目标合并明细')
+      }
+      let classify = this.form.goalCategory
+      let classifyValue;
+      if (classify === null || classify === '') {
+        return this.$message.error('请输入目标分类')
+      } else if (classify === '销售区域') {
+        classifyValue = this.form.saleZone
+        if (classifyValue === null) {
+          return this.$message.error('请输入销售区域')
+        }
+      } else if (classify === '一级分类') {
+        classifyValue = this.form.oneLevelClassify
+        if (classifyValue === null) {
+          return this.$message.error('请输入一级分类')
+        }
+      } else if (classify === '二级分类') {
+        classifyValue = this.form.twoLevelClassify
+        if (classifyValue === null) {
+          return this.$message.error('请输入二级分类')
+        }
+      }
+      let query = { classify: classify, classifyValue: classifyValue }
+      mergeAnnualSaleMergeDetails(query).then(response => {
+        console.log(response);
+        this.annualSaleGoalMergeDetailsList = response.data.consolidatedDetail
+        this.computeTotal()
+      })
+    },
+    // 获得区域目标汇总or客户目标汇总
+    getNewTwoArray() {
+      let arr = JSON.parse(JSON.stringify(this.annualSaleGoalMergeDetailsList))
+      // 如果子表标签是annualSaleGoalMergeDetails 或者 主表的目标分类是“销售区域”
+      if (this.activeName === 'annualSaleGoalMergeDetails' || this.form.goalCategory !== '销售区域') {
+        this.areaDetailList = null
+        this.customerDetailList = null
+        return
+      }
+      // 根据某三个属性进行合并并相加totalGoal的函数
+      const mergeAndSumTotalGoal = (array) => {
+        return Array.from(array.reduce((map, obj) => {
+          let key = null
+          if (this.activeName === 'zoneGoalSum(year)') {
+            key = `${obj.saleOrg}-${obj.saleZone}-${obj.creator}`
+          } else if (this.activeName === 'customerGoalSum(year)') {
+            key = `${obj.saleOrg}-${obj.saleZone}-${obj.custom}`
+          }
+          console.log(key);
+          if (map.has(key)) {
+            const existingObj = map.get(key)
+            existingObj.totalGoal += obj.totalGoal
+          } else {
+            map.set(key, { ...obj })
+          }
+          return map
+        }, new Map()).values())
+      }
+      // 调用合并函数
+      const mergedArray = mergeAndSumTotalGoal(arr)
+      if (this.activeName === 'zoneGoalSum(year)') {
+        this.areaDetailList = mergedArray
+      } else if (this.activeName === 'customerGoalSum(year)') {
+        this.customerDetailList = mergedArray
+      }
+    },
+    setBeginAndEnd() {
+      let array = this.documentDateRange
+      if (array !== null) {
+        this.queryParams.params.beginTime = array[0]
+        this.queryParams.params.endTime = array[1]
+      } else {
+        this.queryParams.beginTime = null
+        this.queryParams.endTime = null
+      }
+    },
+  }
+};
+</script>

+ 1067 - 0
src/views/business/spd/goal_management/MonthGoalMerge.vue

@@ -0,0 +1,1067 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="编码" prop="code">
+        <el-input v-model="queryParams.code" placeholder="请输入编码" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="目标名称" prop="goalName">
+        <el-input v-model="queryParams.goalName" placeholder="请输入目标名称" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="单据日期" prop="documentDate">
+        <el-date-picker
+          v-model="documentDateRange"
+          @change="setBeginAndEnd"
+          type="daterange"
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd"
+          @keyup.enter.native="handleQuery"
+          :picker-options="pickerOptions">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item label="年度" prop="annual">
+        <el-date-picker
+          v-model="queryParams.annual"
+          type="year"
+          clearable
+          value-format="yyyy"
+          @keyup.enter.native="handleQuery"
+          placeholder="请输入年度">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="月份" prop="monthly">
+        <el-date-picker
+          v-model="queryParams.monthly"
+          type="month"
+          clearable
+          value-format="yyyy-MM"
+          @keyup.enter.native="handleQuery"
+          placeholder="请输入月份">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="制单人" prop="creator">
+        <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                              referName="CONTACTS_PARAM"
+                              :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入制单人">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="部门" prop="dept">
+        <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入部门">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="目标类型" prop="goalCategory">
+        <el-select v-model="queryParams.goalCategory" placeholder="请输入目标类型" @change="changeGoalCategoryQuery" @keyup.enter.native="handleQuery">
+          <el-option
+            v-for="item in goalCategoryList"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="queryParams.goalCategory === '客户维度'" label="客户" prop="custom">
+        <el-popover-select-v2 v-model="queryParams.custom" title="客户" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ customCode: 'code', custom: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入客户">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item v-if="queryParams.goalCategory === '销售区域'" label="销售区域" prop="saleZone">
+        <el-popover-select-v2 v-model="queryParams.saleZoneCode" title="销售区域" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入销售区域">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item v-if="queryParams.goalCategory === '一级分类'" label="一级分类" prop="oneLevelClassify">
+        <el-select v-model="queryParams.oneLevelClassify" size="mini" clearable
+                   @focus="chooseTreeReferForQuery('MATERIALCLASSIFY_PARAM', false, '一级物料分类')"
+                   style="width: 200px">
+          <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-if="queryParams.goalCategory === '二级分类'" label="二级分类" prop="custom">
+        <el-select v-model="queryParams.twoLevelClassify" size="mini" clearable
+                   @focus="chooseTreeReferForQuery('MATERIALCLASSIFY_PARAM', false, '二级物料分类')"
+                   style="width: 200px">
+          <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['goal_management:monthGoalMerge:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['goal_management:monthGoalMerge:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['goal_management:monthGoalMerge:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="monthGoalMergeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="编码" align="center" prop="code"/>
+      <el-table-column label="目标名称" align="center" prop="goalName"/>
+      <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度" align="center" prop="annual"/>
+      <el-table-column label="月份" align="center" prop="monthly"/>
+      <el-table-column label="客户" align="center" prop="custom"/>
+      <el-table-column label="制单人" align="center" prop="creator"/>
+      <el-table-column label="部门" align="center" prop="dept"/>
+      <el-table-column label="目标类型" align="center" prop="goalCategory"/>
+      <el-table-column label="目标值合计" align="center" prop="goalSum"/>
+      <el-table-column label="单据状态" align="center" prop="documentStatus"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['goal_management:monthGoalMerge:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['goal_management:monthGoalMerge:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改月销售目标合并抽屉 -->
+    <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="编码后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标名称" prop="goalName">
+              <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据日期" prop="documentDate">
+              <el-date-picker clearable
+                              v-model="form.documentDate"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="请选择单据日期">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="年度" prop="annual">
+              <el-date-picker clearable
+                              v-model="form.annual"
+                              type="year"
+                              value-format="yyyy"
+                              placeholder="请输入年度">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="月份" prop="monthly">
+              <el-date-picker clearable
+                              v-model="form.monthly"
+                              type="month"
+                              value-format="yyyy-MM"
+                              placeholder="请输入月份">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="制单人" prop="creator">
+              <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="form" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门" prop="dept">
+              <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM"
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="form" placeholder="请输入部门">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标类型" prop="goalCategory">
+              <el-select v-model="form.goalCategory" placeholder="请输入目标类型" @change="changeGoalCategoryForm" @keyup.enter.native="handleQuery">
+                <el-option
+                  v-for="item in goalCategoryList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="目标值合计" prop="goalSum">
+              <el-input v-model="form.goalSum" placeholder="目标值合计自动计算" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item v-if="form.goalCategory === '客户维度'" label="客户" prop="custom">
+              <el-popover-select-v2 v-model="form.custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="form" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </el-form-item>
+            <el-form-item v-if="form.goalCategory === '销售区域'" label="销售区域" prop="saleZone">
+              <el-popover-select-v2 v-model="form.saleZoneCode" title="销售区域" valueKey="name"
+                                    referName="ORG_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="form" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </el-form-item>
+            <el-form-item v-if="form.goalCategory === '一级分类'" label="一级分类" prop="oneLevelClassify">
+              <el-select v-model="form.oneLevelClassify" size="mini" clearable
+                         @focus="chooseTreeReferForMain('MATERIALCLASSIFY_PARAM', false, '一级物料分类')"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+            <el-form-item v-if="form.goalCategory === '二级分类'" label="二级分类" prop="custom">
+              <el-select v-model="form.twoLevelClassify" size="mini" clearable
+                         @focus="chooseTreeReferForMain('MATERIALCLASSIFY_PARAM', false, '二级物料分类')"
+                         style="width: 200px">
+                <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作">
+              <el-button type="primary" @click="submitForm">确 定</el-button>
+              <el-button @click="cancel">取 消</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+
+      <el-row :gutter="10" class="mb8">
+<!--        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增 行</el-button>
+        </el-col>-->
+        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-folder-opened" size="mini" @click="clickMerge">合 并</el-button>
+        </el-col>
+      </el-row>
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="月销售目标合并明细" name="monthGoalMergeDetails">
+          <el-table v-loading="loading" :data="monthGoalMergeDetailsList" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{ saleOrgCode: 'code', saleOrg: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="客户" align="center" prop="custom" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                      referName="CUSTOMER_PARAM" disabled
+                                      :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="部门" align="center" prop="dept" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].dept" title="部门" valueKey="name"
+                                      referName="DEPT_PARAM" disabled
+                                      :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="制单人" align="center" prop="creator" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].creator" title="负责人" valueKey="name"
+                                      referName="CONTACTS_PARAM" disabled
+                                      :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入负责人">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="科室" align="center" prop="department" width="180">
+              <template slot-scope="scope">
+                <el-input v-model="monthGoalMergeDetailsList[scope.$index].department" placeholder="请输入科室" disabled></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="一级分类" align="center" prop="oneLevelClassify" width="220">
+              <template slot-scope="scope">
+                <el-select v-model="monthGoalMergeDetailsList[scope.$index].oneLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '一级物料分类', scope.$index)"
+                           style="width: 200px" disabled>
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="二级分类" align="center" prop="twoLevelClassify" width="220">
+              <template slot-scope="scope">
+                <el-select v-model="monthGoalMergeDetailsList[scope.$index].twoLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '二级物料分类', scope.$index)"
+                           style="width: 200px" disabled>
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="物料" align="center" prop="material" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthGoalMergeDetailsList[scope.$index].material" title="物料" valueKey="name"
+                                      referName="MATERIAL_PARAM" disabled
+                                      :dataMapping="{ materialCode: 'code', material: 'name'}"
+                                      :source.sync="monthGoalMergeDetailsList[scope.$index]" placeholder="请输入物料">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="月份" align="center" prop="monthly" width="250">
+              <template slot-scope="scope">
+                <el-date-picker disabled v-model="monthGoalMergeDetailsList[scope.$index].monthly" value-format="yyyy-MM" type="month" placeholder="选择月份">
+                </el-date-picker>
+              </template>
+            </el-table-column>
+            <el-table-column label="目标值" align="center" prop="totalGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotal" v-model="monthGoalMergeDetailsList[scope.$index].goalValue" :precision="2" :step="1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+<!--            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDeleteDetails(scope.$index, scope.row)"
+                >删除</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleCopyDetails(scope.row)"
+                >复制</el-button>
+              </template>
+            </el-table-column>-->
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+
+    <TreeRefers ref="treeQuery" @doSubmit="selectionsToInputForQuery" :single="true"/>
+    <TreeRefers ref="treeMain" @doSubmit="selectionsToInputForMain" :single="true"/>
+    <TreeRefers ref="treeDetails" @doSubmit="selectionsToInputForDetails" :single="true"/>
+  </div>
+</template>
+
+<script>
+import {
+  listMonthGoalMerge,
+  getMonthGoalMerge,
+  delMonthGoalMerge,
+  addMonthGoalMerge,
+  updateMonthGoalMerge
+} from "@/api/business/spd/goal_management/monthGoalMerge";
+import {
+  getMonthGoalMergeDetails,
+  delMonthGoalMergeDetails,
+  mergeMonthSaleMergeDetails
+} from "@/api/business/spd/goal_management/monthGoalMergeDetails"
+
+// 树形参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+
+export default {
+  name: "MonthGoalMerge",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 月销售目标合并表格数据
+      monthGoalMergeList: [],
+      monthGoalMergeDetailsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        params: { beginTime: null, endTime: null }
+      },
+      documentDateRange: null,
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        monthMergeDetailsList: null
+      },
+      formDetails: {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        dept: null,
+        creator: null,
+        department: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        monthly: null,
+        goalValue: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{ required: true, message: '单据日期不能为空', trigger: 'blur' }],
+        annual: [{ required: true, message: '年度不能为空', trigger: 'blur' }],
+        monthly: [{ required: true, message: '月份不能为空', trigger: 'blur' }],
+        creator: [{ required: true, message: '制单人不能为空', trigger: 'blur' }],
+        dept: [{ required: true, message: '部门不能为空', trigger: 'blur' }],
+        goalCategory: [{ required: true, message: '目标类型不能为空', trigger: 'blur' }],
+        custom: [],
+        saleZone: [],
+        oneLevelClassify: [],
+        twoLevelClassify: []
+      },
+      // 目标类型列表
+      goalCategoryList: [
+        { value: '客户维度', label: '客户维度' },
+        { value: '销售区域', label: '销售区域' },
+        { value: '一级分类', label: '一级分类' },
+        { value: '二级分类', label: '二级分类' }
+      ],
+      // 树形参照
+      referCondition: { type: '', isPage: true, title: '', index: null },
+      classOptions: [],
+      activeName: 'monthGoalMergeDetails'
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询月销售目标合并列表 */
+    getList() {
+      this.loading = true;
+      listMonthGoalMerge(this.queryParams).then(response => {
+        this.monthGoalMergeList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getListDetails() {
+      this.loading = true;
+      getMonthGoalMergeDetails(this.form.id).then(response => {
+        this.monthGoalMergeDetailsList = response.data;
+        this.computeTotal()
+        this.form.monthMergeDetailsList = this.monthGoalMergeDetailsList
+        updateMonthGoalMerge(this.form).then(response => {})
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        saleZoneCode: null,
+        saleZone: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        params: { beginTime: null, endTime: null }
+      }
+      this.documentDateRange = null
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.monthGoalMergeDetailsList = []
+      this.open = true;
+      this.title = "添加月销售目标合并";
+    },
+    handleAddDetails() {
+      let list = {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        dept: null,
+        creator: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        department: null,
+        num: null,
+        monthly: null,
+        goalValue: null
+      }
+      this.monthGoalMergeDetailsList.push(list)
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getMonthGoalMerge(id).then(response => {
+        this.form = response.data;
+        this.monthGoalMergeDetailsList = this.form.monthMergeDetailsList
+        this.open = true;
+        this.title = "修改月销售目标合并";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id !== null) {
+            this.form.monthMergeDetailsList = this.monthGoalMergeDetailsList
+            updateMonthGoalMerge(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.documentStatus = '未提交'
+            this.form.monthMergeDetailsList = this.monthGoalMergeDetailsList
+            console.log(this.form);
+            addMonthGoalMerge(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除月销售目标合并编号为"' + ids + '"的数据项?').then(function () {
+        return delMonthGoalMerge(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) {
+        this.monthGoalMergeDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else {
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除月销售目标合并明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delMonthGoalMergeDetails(row.id);
+          }).then(() => {
+            this.getListDetails();
+            this.$modal.msgSuccess("删除成功");
+          }).catch(() => {
+          });
+        } else {
+          this.monthGoalMergeDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('goal_management/monthGoalMerge/export', {
+        ...this.queryParams
+      }, `monthGoalMerge${new Date().getTime()}.xlsx`)
+    },
+    // 树形参照
+    chooseTreeReferForQuery(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.treeQuery.init(this.referCondition)
+    },
+    chooseTreeReferForMain(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.treeMain.init(this.referCondition)
+    },
+    chooseTreeReferForDetails(type, isPage, title, index) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.index = index
+      this.$refs.treeDetails.init(this.referCondition)
+    },
+    selectionsToInputForQuery(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类下选择')
+        }
+        this.queryParams.oneLevelClassifyCode = selection.code
+        this.queryParams.oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类下选择')
+        }
+        this.queryParams.twoLevelClassifyCode = selection.code
+        this.queryParams.twoLevelClassify = selection.name
+      }
+    },
+    selectionsToInputForMain(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类下选择')
+        }
+        this.form.oneLevelClassifyCode = selection.code
+        this.form.oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类下选择')
+        }
+        this.form.twoLevelClassifyCode = selection.code
+        this.form.twoLevelClassify = selection.name
+      }
+    },
+    selectionsToInputForDetails(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类中选择')
+        }
+        if (selection.code !== this.monthGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          this.monthGoalMergeDetailsList[this.referCondition.index].twoLevelClassifyCode = null
+          this.monthGoalMergeDetailsList[this.referCondition.index].twoLevelClassify = null
+        }
+        this.monthGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode = selection.code
+        this.monthGoalMergeDetailsList[this.referCondition.index].oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类中选择')
+        } else if (selection.code[0] !== this.monthGoalMergeDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          return this.$message.error('所选择的二级物料分类不属于一级分类')
+        }
+        this.monthGoalMergeDetailsList[this.referCondition.index].twoLevelClassifyCode = selection.code
+        this.monthGoalMergeDetailsList[this.referCondition.index].twoLevelClassify = selection.name
+      }
+    },
+    // 改变查询表单的目标分类
+    changeGoalCategoryQuery() {
+      let condition = this.queryParams.goalCategory
+      if (condition === null) {
+        this.queryParams.custom = null
+        this.queryParams.customCode = null
+        this.queryParams.saleZone = null
+        this.queryParams.saleZoneCode = null
+        this.queryParams.oneLevelClassify = null
+        this.queryParams.oneLevelClassifyCode = null
+        this.queryParams.twoLevelClassify = null
+        this.queryParams.twoLevelClassifyCode = null
+      } else if (condition === '客户维度') {
+        this.queryParams.saleZone = null
+        this.queryParams.saleZoneCode = null
+        this.queryParams.oneLevelClassify = null
+        this.queryParams.oneLevelClassifyCode = null
+        this.queryParams.twoLevelClassify = null
+        this.queryParams.twoLevelClassifyCode = null
+      } else if (condition === '销售区域') {
+        this.queryParams.custom = null
+        this.queryParams.customCode = null
+        this.queryParams.oneLevelClassify = null
+        this.queryParams.oneLevelClassifyCode = null
+        this.queryParams.twoLevelClassify = null
+        this.queryParams.twoLevelClassifyCode = null
+      } else if (condition === '一级分类') {
+        this.queryParams.custom = null
+        this.queryParams.customCode = null
+        this.queryParams.saleZone = null
+        this.queryParams.saleZoneCode = null
+        this.queryParams.twoLevelClassify = null
+        this.queryParams.twoLevelClassifyCode = null
+      } else if (condition === '二级分类') {
+        this.queryParams.custom = null
+        this.queryParams.customCode = null
+        this.queryParams.saleZone = null
+        this.queryParams.saleZoneCode = null
+        this.queryParams.oneLevelClassify = null
+        this.queryParams.oneLevelClassifyCode = null
+      }
+    },
+    changeGoalCategoryForm() {
+      let condition = this.form.goalCategory
+      if (condition === null) {
+        this.form.custom = null
+        this.form.customCode = null
+        this.form.saleZone = null
+        this.form.saleZoneCode = null
+        this.form.oneLevelClassify = null
+        this.form.oneLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.rules.custom = []
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = []
+      } else if (condition === '客户维度') {
+        this.form.saleZone = null
+        this.form.saleZoneCode = null
+        this.form.oneLevelClassify = null
+        this.form.oneLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.rules.custom = [{ required: true, message: '客户不能为空', trigger: 'blur' }]
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = []
+      } else if (condition === '销售区域') {
+        this.form.custom = null
+        this.form.customCode = null
+        this.form.oneLevelClassify = null
+        this.form.oneLevelClassifyCode = null
+        this.form.twoLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.rules.custom = []
+        this.rules.saleZone = [{ required: true, message: '销售区域不能为空', trigger: 'blur' }]
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = []
+      } else if (condition === '一级分类') {
+        this.form.custom = null
+        this.form.customCode = null
+        this.form.saleZone = null
+        this.form.saleZoneCode = null
+        this.form.twoLevelClassify = null
+        this.form.twoLevelClassifyCode = null
+        this.rules.custom = []
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = [{ required: true, message: '一级分类不能为空', trigger: 'blur' }]
+        this.rules.twoLevelClassify = []
+      } else if (condition === '二级分类') {
+        this.form.custom = null
+        this.form.customCode = null
+        this.form.saleZone = null
+        this.form.saleZoneCode = null
+        this.form.oneLevelClassify = null
+        this.form.oneLevelClassifyCode = null
+        this.rules.custom = []
+        this.rules.saleZone = []
+        this.rules.oneLevelClassify = []
+        this.rules.twoLevelClassify = [{ required: true, message: '二级分类不能为空', trigger: 'blur' }]
+      }
+    },
+    // 关闭抽屉
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+          this.resetQuery()
+        })
+        .catch(_ => {});
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: null,
+        code: row.code,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        dept: row.dept,
+        creator: row.creator,
+        oneLevelClassifyCode: row.oneLevelClassifyCode,
+        oneLevelClassify: row.oneLevelClassify,
+        twoLevelClassifyCode: row.twoLevelClassifyCode,
+        twoLevelClassify: row.twoLevelClassify,
+        materialCode: row.materialCode,
+        material: row.material,
+        department: row.department,
+        num: row.num,
+        monthly: row.monthly,
+        goalValue: row.goalValue
+      }
+      this.monthGoalMergeDetailsList.push(list)
+      this.computeTotal()
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.monthGoalMergeDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        sum = (sum * 1000000 + listElement.goalValue * 1000000) / 1000000
+      }
+      this.form.goalSum = sum
+    },
+    // 合并数据
+    clickMerge() {
+      let classify = this.form.goalCategory
+      let classifyValue;
+      if (classify === null || classify === '') {
+        return this.$message.error('请输入目标分类')
+      } else if (classify === '销售区域') {
+        classifyValue = this.form.saleZone
+        if (classifyValue === null) {
+          return this.$message.error('请输入销售区域')
+        }
+      } else if (classify === '一级分类') {
+        classifyValue = this.form.oneLevelClassify
+        if (classifyValue === null) {
+          return this.$message.error('请输入一级分类')
+        }
+      } else if (classify === '二级分类') {
+        classifyValue = this.form.twoLevelClassify
+        if (classifyValue === null) {
+          return this.$message.error('请输入二级分类')
+        }
+      } else if (classify === '客户维度') {
+        classifyValue = this.form.custom
+        if (classifyValue === null) {
+          return this.$message.error('请输入客户')
+        }
+      }
+      let query = { classify: classify, classifyValue: classifyValue }
+      mergeMonthSaleMergeDetails(query).then(response => {
+        console.log(response);
+        this.monthGoalMergeDetailsList = response.data.monthGoalMergeDetails
+        this.computeTotal()
+      })
+    },
+    setBeginAndEnd() {
+      let array = this.documentDateRange
+      if (array !== null) {
+        this.queryParams.params.beginTime = array[0]
+        this.queryParams.params.endTime = array[1]
+      } else {
+        this.queryParams.beginTime = null
+        this.queryParams.endTime = null
+      }
+    }
+  }
+};
+</script>

+ 713 - 0
src/views/business/spd/goal_management/MonthReturnGoal.vue

@@ -0,0 +1,713 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="编码" prop="code">
+        <el-input
+          v-model="queryParams.code"
+          placeholder="请输入编码"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="目标名称" prop="goalName">
+        <el-input
+          v-model="queryParams.goalName"
+          placeholder="请输入目标名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="单据日期" prop="documentDate">
+        <el-date-picker
+          v-model="documentDateRange"
+          @change="setBeginAndEnd"
+          value-format="yyyy-MM-dd"
+          type="daterange"
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item label="年度" prop="annual">
+        <el-date-picker
+          v-model="queryParams.annual"
+          type="year"
+          value-format="yyyy"
+          placeholder="选择年度"
+          clearable
+          @keyup.enter.native="handleQuery">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="客户" prop="custom">
+        <el-popover-select-v2 v-model="queryParams.custom" title="客户" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ customCode: 'code', custom: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入客户" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="制单人" prop="creator">
+        <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                              referName="CONTACTS_PARAM"
+                              :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入制单人" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="销售区域" prop="saleZone">
+        <el-popover-select-v2 v-model="queryParams.saleZone" title="销售区域" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入销售区域" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="部门" prop="dept">
+        <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入部门" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['mk:monthReturnGoal:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['mk:monthReturnGoal:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['mk:monthReturnGoal:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table v-loading="loading" :data="monthReturnGoalList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="编码" align="center" prop="code"/>
+      <el-table-column label="目标名称" align="center" prop="goalName"/>
+      <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度" align="center" prop="annual"/>
+      <el-table-column label="客户" align="center" prop="custom"/>
+      <el-table-column label="制单人" align="center" prop="creator"/>
+      <el-table-column label="销售区域" align="center" prop="saleZone"/>
+      <el-table-column label="部门" align="center" prop="dept"/>
+      <el-table-column label="目标合计" align="center" prop="goalSum"/>
+      <el-table-column label="备注" align="center" prop="notes"/>
+      <el-table-column label="单据状态" align="center" prop="documentStatus"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['mk:monthReturnGoal:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['mk:monthReturnGoal:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="编码后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标名称" prop="goalName">
+              <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据日期" prop="documentDate">
+              <el-date-picker clearable
+                              v-model="form.documentDate"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="请选择单据日期">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="年度" prop="annual">
+              <el-date-picker
+                v-model="form.annual"
+                type="year"
+                value-format="yyyy"
+                placeholder="选择年度">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="客户" prop="custom">
+              <el-popover-select-v2 v-model="form.custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="form" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="制单人" prop="creator">
+              <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="form" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="销售区域" prop="saleZone">
+              <el-popover-select-v2 v-model="form.saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="form" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门" prop="dept">
+              <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM"
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="form" placeholder="请输入部门">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="目标合计" prop="goalSum">
+              <el-input v-model="form.goalSum" placeholder="目标合计自动计算" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="备注" prop="notes">
+              <el-input v-model="form.notes" placeholder="请输入备注"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据状态" prop="documentStatus">
+              <el-input v-model="form.documentStatus" placeholder="新增页默认'未提交'" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作">
+              <el-button type="primary" @click="submitForm">确 定</el-button>
+              <el-button @click="cancel">取 消</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增行</el-button>
+        </el-col>
+      </el-row>
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="月回款目标明细" name="monthReturnGoalDetails">
+          <el-table v-loading="loading" :data="monthReturnGoalDetailsList" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthReturnGoalDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{saleOrg: 'name'}"
+                                      :source.sync="monthReturnGoalDetailsList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthReturnGoalDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{saleZone: 'name'}"
+                                      :source.sync="monthReturnGoalDetailsList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="客户" align="center" prop="custom" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthReturnGoalDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{custom: 'name'}"
+                                      :source.sync="monthReturnGoalDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="部门" align="center" prop="dept" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthReturnGoalDetailsList[scope.$index].dept" title="部门" valueKey="name"
+                                      referName="DEPT_PARAM"
+                                      :dataMapping="{dept: 'name'}"
+                                      :source.sync="monthReturnGoalDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="制单人" align="center" prop="creator" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthReturnGoalDetailsList[scope.$index].creator" title="负责人" valueKey="name"
+                                      referName="CONTACTS_PARAM"
+                                      :dataMapping="{creator: 'name'}"
+                                      :source.sync="monthReturnGoalDetailsList[scope.$index]" placeholder="请输入负责人">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="月份" align="center" prop="monthly" width="250" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-date-picker v-model="monthReturnGoalDetailsList[scope.$index].monthly" value-format="yyyy-MM" type="month" placeholder="选择月份">
+                </el-date-picker>
+              </template>
+            </el-table-column>
+            <el-table-column label="目标值" align="center" prop="goalSum" width="220" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotal" v-model="monthReturnGoalDetailsList[scope.$index].goalSum" :precision="2" :step="1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDeleteDetails(scope.$index, scope.row)"
+                >删除</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleCopyDetails(scope.row)"
+                >复制</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+
+  </div>
+</template>
+
+<script>
+
+import {
+  listMonthReturnGoal,
+  getMonthReturnGoal,
+  addMonthReturnGoal,
+  updateMonthReturnGoal,
+  delMonthReturnGoal
+} from "@/api/business/spd/goal_management/monthReturnGoal";
+import {
+  getMonthReturnGoalDetails,
+  delMonthReturnGoalDetails
+} from "@/api/business/spd/goal_management/monthReturnGoalDetails"
+
+// 树形参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+
+export default {
+  name: "MonthReturnGoal",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 月回款目标填报表格数据
+      monthReturnGoalList: [],
+      monthReturnGoalDetailsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        saleZoneCode: null,
+        saleZone: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        params: { beginTime: null, endTime: null,}
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        saleZoneCode: null,
+        saleZone: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        monthReturnGoalDetailsList: null,
+      },
+      formDetails: {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        creator: null,
+        monthly: null,
+        goalSum: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{ required: true, message: '单据日期不能为空', trigger: 'blur' }],
+        annual: [{ required: true, message: '年度不能为空', trigger: 'blur' }],
+        custom: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
+        creator: [{ required: true, message: '制单人不能为空', trigger: 'blur' }],
+        saleZone: [{ required: true, message: '销售区域不能为空', trigger: 'blur' }],
+        dept: [{ required: true, message: '部门不能为空', trigger: 'blur' }],
+      },
+      // 子表导航名
+      activeName: 'monthReturnGoalDetails',
+      documentDateRange: null,
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      }
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 查询月销售目标填报列表 */
+    getList() {
+      this.loading = true;
+      listMonthReturnGoal(this.queryParams).then(response => {
+        this.monthReturnGoalList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getListDetails() {
+      this.loading = true
+      getMonthReturnGoalDetails(this.form.id).then(response => {
+        this.monthReturnGoalDetailsList = response.data
+        this.computeTotal()
+        this.form.monthReturnGoalDetailsList = this.monthReturnGoalDetailsList
+        updateMonthReturnGoal(this.form).then(response => {
+        })
+        this.loading = false
+      })
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        creatorCode: null,
+        creator: null,
+        saleZoneCode: null,
+        saleZone: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        monthReturnGoalDetailsList: null,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.monthReturnGoalDetailsList = []
+      this.open = true;
+      this.title = "添加--月回款目标填报";
+    },
+    handleAddDetails() {
+      let list = {
+        id: null,
+        code: null,
+        saleOrg: this.form.saleZone,
+        saleZone: this.form.saleZone,
+        custom: this.form.custom,
+        dept: this.form.dept,
+        creator: this.form.creator,
+        monthly: null,
+        goalSum: 0
+      }
+      this.monthReturnGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getMonthReturnGoal(id).then(response => {
+        this.form = response.data;
+        console.log(this.form);
+        this.monthReturnGoalDetailsList = JSON.parse(JSON.stringify(this.form.monthReturnGoalDetailsList))
+        this.open = true;
+        this.title = "修改--月回款目标填报";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      if (!this.justiceDetailsList()) {
+        return this.$message.error('子表中有必填字段未填')
+      }
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            this.form.monthReturnGoalDetailsList = this.monthReturnGoalDetailsList
+            updateMonthReturnGoal(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.documentStatus = '未提交'
+            this.form.monthReturnGoalDetailsList = this.monthReturnGoalDetailsList
+            console.log(this.form);
+            addMonthReturnGoal(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除月销售目标填报编号为"' + ids + '"的数据项?').then(function () {
+        return delMonthReturnGoal(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) {
+        this.monthReturnGoalDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else {
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除月销售目标填报明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delMonthReturnGoalDetails(row.id);
+          }).then(() => {
+            this.getListDetails();
+            this.$modal.msgSuccess("删除成功");
+          }).catch(() => {
+          });
+        } else {
+          this.monthReturnGoalDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('goal_management/monthReturnGoal/export', {
+        ...this.queryParams
+      }, `monthReturnGoal_${new Date().getTime()}.xlsx`)
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+        })
+        .catch(_ => {
+        });
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.monthReturnGoalDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        sum = (sum * 1000000 + listElement.goalSum * 1000000) / 1000000
+      }
+      this.form.goalSum = sum
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: null,
+        code: row.code,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        dept: row.dept,
+        creator: row.creator,
+        monthly: row.monthly,
+        goalSum: row.goalSum
+      }
+      this.monthReturnGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    setBeginAndEnd() {
+      let array = this.documentDateRange
+      if (array !== null) {
+        this.queryParams.params.beginTime = array[0]
+        this.queryParams.params.endTime = array[1]
+      } else {
+        this.queryParams.beginTime = null
+        this.queryParams.endTime = null
+      }
+    },
+    // 给table添加必填项
+    addRedStar(h, { column }) {
+      return [
+        h('span', { style: 'color: #F56C6C' }, '*'),
+        h('span', '' + column.label)
+      ]
+    },
+    // 判断子表的字段是否都填了
+    justiceDetailsList() {
+      const arr = JSON.parse(JSON.stringify(this.monthReturnGoalDetailsList))
+      for (const element of arr) {
+        if (element.saleOrg === null || element.saleZone === null || element.custom === null || element.dept === null || element.creator === null || element.monthly === null || element.goalSum === null) {
+          return false
+        }
+      }
+      return true
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 766 - 0
src/views/business/spd/goal_management/MonthReturnMerge.vue

@@ -0,0 +1,766 @@
+<template>
+<div class="app-container">
+  <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form-item label="编码" prop="code">
+      <el-input v-model="queryParams.code" placeholder="请输入编码" clearable @keyup.enter.native="handleQuery"/>
+    </el-form-item>
+    <el-form-item label="目标名称" prop="goalName">
+      <el-input v-model="queryParams.goalName" placeholder="请输入目标名称" clearable @keyup.enter.native="handleQuery"/>
+    </el-form-item>
+    <el-form-item label="单据日期" prop="documentDate">
+      <el-date-picker
+        v-model="documentDateRange"
+        @change="setBeginAndEnd"
+        type="daterange"
+        align="right"
+        unlink-panels
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        value-format="yyyy-MM-dd"
+        @keyup.enter.native="handleQuery"
+        :picker-options="pickerOptions">
+      </el-date-picker>
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+      <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+    </el-form-item>
+    <el-form-item label="年度" prop="annual">
+      <el-date-picker
+        v-model="queryParams.annual"
+        type="year"
+        clearable
+        value-format="yyyy"
+        @keyup.enter.native="handleQuery"
+        placeholder="请输入年度">
+      </el-date-picker>
+    </el-form-item>
+    <el-form-item label="月份" prop="monthly">
+      <el-date-picker
+        v-model="queryParams.monthly"
+        type="month"
+        clearable
+        value-format="yyyy-MM"
+        @keyup.enter.native="handleQuery"
+        placeholder="请输入月份">
+      </el-date-picker>
+    </el-form-item>
+    <el-form-item label="客户" prop="custom">
+      <el-popover-select-v2 v-model="queryParams.custom" title="客户" valueKey="name"
+                            referName="CUSTOMER_PARAM"
+                            :dataMapping="{ customCode: 'code', custom: 'name'}"
+                            :source.sync="queryParams" placeholder="请输入客户">
+      </el-popover-select-v2>
+    </el-form-item>
+    <el-form-item label="销售区域" prop="saleZone">
+      <el-popover-select-v2 v-model="queryParams.saleZoneCode" title="销售区域" valueKey="name"
+                            referName="DEPT_PARAM"
+                            :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                            :source.sync="queryParams" placeholder="请输入销售区域">
+      </el-popover-select-v2>
+    </el-form-item>
+    <el-form-item label="制单人" prop="creator">
+      <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                            referName="CONTACTS_PARAM"
+                            :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                            :source.sync="queryParams" placeholder="请输入制单人">
+      </el-popover-select-v2>
+    </el-form-item>
+    <el-form-item label="部门" prop="dept">
+      <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                            referName="DEPT_PARAM"
+                            :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                            :source.sync="queryParams" placeholder="请输入部门">
+      </el-popover-select-v2>
+    </el-form-item>
+  </el-form>
+  <el-row :gutter="10" class="mb8">
+    <el-col :span="1.5">
+      <el-button
+        type="primary"
+        plain
+        icon="el-icon-plus"
+        size="mini"
+        @click="handleAdd"
+        v-hasPermi="['mk:monthReturnMerge:add']"
+      >新增
+      </el-button>
+    </el-col>
+    <el-col :span="1.5">
+      <el-button
+        type="danger"
+        plain
+        icon="el-icon-delete"
+        size="mini"
+        :disabled="multiple"
+        @click="handleDelete"
+        v-hasPermi="['mk:monthReturnMerge:remove']"
+      >删除
+      </el-button>
+    </el-col>
+    <el-col :span="1.5">
+      <el-button
+        type="warning"
+        plain
+        icon="el-icon-download"
+        size="mini"
+        @click="handleExport"
+        v-hasPermi="['mk:monthReturnMerge:export']"
+      >导出
+      </el-button>
+    </el-col>
+    <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+  </el-row>
+  <el-table v-loading="loading" :data="monthReturnMergeList" @selection-change="handleSelectionChange">
+    <el-table-column type="selection" width="55" align="center"/>
+    <el-table-column label="编码" align="center" prop="code" width="180"/>
+    <el-table-column label="目标名称" align="center" prop="goalName" width="180"/>
+    <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+      <template slot-scope="scope">
+        <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+      </template>
+    </el-table-column>
+    <el-table-column label="年度" align="center" prop="annual" width="180"/>
+    <el-table-column label="月份" align="center" prop="monthly" width="180"/>
+    <el-table-column label="客户" align="center" prop="custom" width="180"/>
+    <el-table-column label="销售区域" align="center" prop="saleZone" width="180"/>
+    <el-table-column label="制单人" align="center" prop="creator" width="180"/>
+    <el-table-column label="部门" align="center" prop="dept" width="180"/>
+    <el-table-column label="目标类型" align="center" prop="goalCategory" width="180"/>
+    <el-table-column label="目标值合计" align="center" prop="goalSum" width="180"/>
+    <el-table-column label="单据状态" align="center" prop="documentStatus" width="180"/>
+    <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
+      <template slot-scope="scope">
+        <el-button
+          size="mini"
+          type="text"
+          icon="el-icon-edit"
+          @click="handleUpdate(scope.row)"
+          v-hasPermi="['mk:monthReturnMerge:edit']"
+        >修改
+        </el-button>
+        <el-button
+          size="mini"
+          type="text"
+          icon="el-icon-delete"
+          @click="handleDelete(scope.row)"
+          v-hasPermi="['mk:monthReturnMerge:remove']"
+        >删除
+        </el-button>
+      </template>
+    </el-table-column>
+  </el-table>
+  <pagination
+    v-show="total>0"
+    :total="total"
+    :page.sync="queryParams.pageNum"
+    :limit.sync="queryParams.pageSize"
+    @pagination="getList"
+  />
+
+  <!-- 添加或修改月销售目标合并抽屉 -->
+  <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-form-item label="编码" prop="code">
+            <el-input v-model="form.code" placeholder="编码后端自动生成" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="目标名称" prop="goalName">
+            <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="单据日期" prop="documentDate">
+            <el-date-picker clearable
+                            v-model="form.documentDate"
+                            type="date"
+                            value-format="yyyy-MM-dd"
+                            placeholder="请选择单据日期">
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="年度" prop="annual">
+            <el-date-picker clearable
+                            v-model="form.annual"
+                            type="year"
+                            value-format="yyyy"
+                            placeholder="请输入年度">
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-form-item label="月份" prop="monthly">
+            <el-date-picker clearable
+                            v-model="form.monthly"
+                            type="month"
+                            value-format="yyyy-MM"
+                            placeholder="请输入月份">
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="客户" prop="custom">
+            <el-popover-select-v2 v-model="form.custom" title="客户" valueKey="name"
+                                  referName="CUSTOMER_PARAM"
+                                  :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                  :source.sync="form" placeholder="请输入客户">
+            </el-popover-select-v2>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="销售区域" prop="saleZone">
+            <el-popover-select-v2 v-model="form.saleZoneCode" title="销售区域" valueKey="name"
+                                  referName="DEPT_PARAM"
+                                  :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                  :source.sync="form" placeholder="请输入销售区域">
+            </el-popover-select-v2>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="制单人" prop="creator">
+            <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                  referName="CONTACTS_PARAM"
+                                  :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                  :source.sync="form" placeholder="请输入制单人">
+            </el-popover-select-v2>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-form-item label="部门" prop="dept">
+            <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                  referName="DEPT_PARAM"
+                                  :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                  :source.sync="form" placeholder="请输入部门">
+            </el-popover-select-v2>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="目标类型" prop="goalCategory">
+            <el-input v-model="form.goalName" placeholder="客户维度" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="目标值合计" prop="goalSum">
+            <el-input v-model="form.goalSum" placeholder="目标值合计自动计算" disabled/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-form-item label="单据状态" prop="goalSum">
+            <el-input v-model="form.documentStatus" placeholder="新增页面默认'未提交'" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="操作">
+            <el-button type="primary" @click="submitForm">确 定</el-button>
+            <el-button @click="cancel">取 消</el-button>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+<!--      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增 行</el-button>
+      </el-col>-->
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-folder-opened" size="mini" @click="clickMerge">合 并</el-button>
+      </el-col>
+    </el-row>
+    <el-tabs v-model="activeName" @tab-click="getNewTwoArray">
+      <el-tab-pane label="月回款目标合并明细" name="monthReturnMergeDetails">
+        <el-table v-loading="loading" :data="monthReturnMergeDetailsList">
+          <el-table-column label="序号" type="index" width="55" align="center" fixed />
+          <el-table-column label="销售组织" align="center" prop="saleOrg" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="monthReturnMergeDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                    referName="CUSTOMER_PARAM" disabled
+                                    :dataMapping="{ saleOrgCode: 'code', saleOrg: 'name'}"
+                                    :source.sync="monthReturnMergeDetailsList[scope.$index]" placeholder="请输入销售组织">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="销售区域" align="center" prop="saleZone" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="monthReturnMergeDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM" disabled
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="monthReturnMergeDetailsList[scope.$index]" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="客户" align="center" prop="custom" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="monthReturnMergeDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM" disabled
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="monthReturnMergeDetailsList[scope.$index]" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="部门" align="center" prop="dept" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="monthReturnMergeDetailsList[scope.$index].dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM" disabled
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="monthReturnMergeDetailsList[scope.$index]" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="制单人" align="center" prop="creator" width="180">
+            <template slot-scope="scope">
+              <el-popover-select-v2 v-model="monthReturnMergeDetailsList[scope.$index].creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM" disabled
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="monthReturnMergeDetailsList[scope.$index]" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </template>
+          </el-table-column>
+          <el-table-column label="月份" align="center" prop="monthly" width="250">
+            <template slot-scope="scope">
+              <el-date-picker disabled v-model="monthReturnMergeDetailsList[scope.$index].monthly" value-format="yyyy-MM" type="month" placeholder="选择月份">
+              </el-date-picker>
+            </template>
+          </el-table-column>
+          <el-table-column label="目标值" align="center" prop="totalGoal" width="220">
+            <template slot-scope="scope">
+              <el-input-number @change="computeTotal" v-model="monthReturnMergeDetailsList[scope.$index].goalSum" :precision="2" :step="1" :min="0"></el-input-number>
+            </template>
+          </el-table-column>
+<!--          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                @click="handleDeleteDetails(scope.$index, scope.row)"
+              >删除</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                @click="handleCopyDetails(scope.row)"
+              >复制</el-button>
+            </template>
+          </el-table-column>-->
+        </el-table>
+      </el-tab-pane>
+      <el-tab-pane label="区域目标汇总(月回款)" name="zoneGoalSum(monthReturn)">
+        <el-table :data="zoneGoalSumList">
+          <el-table-column label="序号" type="index" width="55" align="center" fixed />
+          <el-table-column label="销售组织" align="center" prop="saleOrg" width="180" />
+          <el-table-column label="区域" align="center" prop="saleZone" width="180" />
+          <el-table-column label="制单人" align="center" prop="creator" width="180" />
+          <el-table-column label="月份" align="center" prop="monthly" width="180" />
+          <el-table-column label="目标值" align="center" prop="goalSum" width="180" />
+        </el-table>
+      </el-tab-pane>
+    </el-tabs>
+  </el-drawer>
+</div>
+</template>
+
+<script>
+import {
+  addMonthReturnMerge,
+  delMonthReturnMerge,
+  getMonthReturnMerge,
+  listMonthReturnMerge,
+  updateMonthReturnMerge
+} from "@/api/business/spd/goal_management/monthReturnMerge";
+import {
+  delMonthReturnMergeDetails,
+  getMonthReturnMergeDetails,
+  mergeMonthReturnMergeDetails
+} from "@/api/business/spd/goal_management/monthReturnMergeDetails"
+
+// 参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+
+export default {
+  name: "MonthReturnMerge",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data () {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 月销售目标合并表格数据
+      monthReturnMergeList: [],
+      monthReturnMergeDetailsList: [],
+      zoneGoalSumList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        params: { beginTime: null, endTime: null }
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        delFlag: null,
+        monthReturnMergeDetailsList: null
+      },
+      formDetails: {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        dept: null,
+        creator: null,
+        monthly: null,
+        goalSum: null,
+        delFlag: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{ required: true, message: '单据日期不能为空', trigger: 'blur' }],
+        annual: [{ required: true, message: '年度不能为空', trigger: 'blur' }],
+        monthly: [{ required: true, message: '月份不能为空', trigger: 'blur' }],
+        custom: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
+        saleZone: [{ required: true, message: '销售区域不能为空', trigger: 'blur' }],
+        creator: [{ required: true, message: '制单人不能为空', trigger: 'blur' }],
+        dept: [{ required: true, message: '部门不能为空', trigger: 'blur' }]
+      },
+      activeName: 'monthReturnMergeDetails',
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      documentDateRange: null
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 查询月销售目标合并列表 */
+    getList() {
+      this.loading = true;
+      listMonthReturnMerge(this.queryParams).then(response => {
+        this.monthReturnMergeList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getListDetails() {
+      this.loading = true;
+      getMonthReturnMergeDetails(this.form.id).then(response => {
+        this.monthGoalMergeDetailsList = response.data;
+        this.computeTotal()
+        this.form.monthReturnMergeDetailsList = this.monthReturnMergeDetailsList
+        updateMonthReturnMerge(this.form).then(response => {})
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        monthly: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalCategory: null,
+        goalSum: null,
+        documentStatus: null,
+        delFlag: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.activeName = 'monthReturnMergeDetails'
+      this.monthReturnMergeDetailsList = []
+      this.open = true;
+      this.title = "添加--月回款目标合并";
+    },
+    handleAddDetails() {
+      let list = {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        dept: null,
+        creator: null,
+        monthly: null,
+        goalSum: null
+      }
+      this.monthReturnMergeDetailsList.push(list)
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      this.activeName = 'monthReturnMergeDetails'
+      const id = row.id || this.ids
+      getMonthReturnMerge(id).then(response => {
+        this.form = response.data;
+        this.monthReturnMergeDetailsList = this.form.monthReturnMergeDetailsList
+        this.open = true;
+        this.title = "修改--月回款目标合并";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id !== null) {
+            this.form.monthReturnMergeDetailsList = this.monthReturnMergeDetailsList
+            updateMonthReturnMerge(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.documentStatus = '未提交'
+            this.form.goalCategory = '客户维度'
+            this.form.monthReturnMergeDetailsList = this.monthReturnMergeDetailsList
+            console.log(this.form);
+            addMonthReturnMerge(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除月销售目标合并编号为"' + ids + '"的数据项?').then(function () {
+        return delMonthReturnMerge(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) {
+        this.monthReturnMergeDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else {
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除月销售目标合并明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delMonthReturnMergeDetails(row.id);
+          }).then(() => {
+            this.getListDetails();
+            this.$modal.msgSuccess("删除成功");
+          }).catch(() => {
+          });
+        } else {
+          this.monthReturnMergeDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('mk/monthReturnMerge/export', {
+        ...this.queryParams
+      }, `monthReturnMerge${new Date().getTime()}.xlsx`)
+    },
+    // 关闭抽屉
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+          this.resetQuery()
+        })
+        .catch(_ => {});
+    },
+    // 合并数据
+    clickMerge() {
+      if (this.activeName !== 'monthReturnMergeDetails') {
+        return this.$message.error('当前页签不是月回款合并明细')
+      }
+      if (this.form.custom === null) {
+        return this.$message.error('请输入客户')
+      }
+      let classify = this.form.goalCategory
+      let classifyValue = this.form.custom
+      let query = { classify: classify, classifyValue: classifyValue }
+      mergeMonthReturnMergeDetails(query).then(response => {
+        console.log(response)
+        /*this.monthReturnMergeDetailsList = response.data
+        this.computeTotal()*/
+      })
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.monthReturnMergeDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        sum = (sum * 1000000 + listElement.goalSum * 1000000) / 1000000
+      }
+      this.form.goalSum = sum
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: row.id,
+        code: row.code,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        dept: row.dept,
+        creator: row.creator,
+        monthly: row.monthly,
+        goalSum: row.goalSum
+      }
+      this.monthReturnMergeDetailsList.push(list)
+      this.computeTotal()
+    },
+    // 设置查询的开始和结束时间
+    setBeginAndEnd() {
+      let array = this.documentDateRange
+      if (array !== null) {
+        this.queryParams.params.beginTime = array[0]
+        this.queryParams.params.endTime = array[1]
+      } else {
+        this.queryParams.beginTime = null
+        this.queryParams.endTime = null
+      }
+    },
+    getNewTwoArray() {
+      let arr = JSON.parse(JSON.parse(this.monthReturnMergeDetailsList))
+      if (this.activeName === 'monthReturnMergeDetails') {
+        this.zoneGoalSumList = null
+      }
+      // 根据销售组织,销售区域,制单人,月份进行合并,并相加goalSum
+      const mergeAndSumTotalGoal = (array) => {
+        return Array.from(array.reduce((map, obj) => {
+          const key = `${obj.saleOrg}-${obj.saleZone}-${obj.creator}-${obj.monthly}`
+          if (map.has(key)) {
+            const existingObj = map.get(key)
+            existingObj.goalSum += obj.goalSum
+          } else {
+            map.set(key, { ...obj })
+          }
+          return map
+        }, new Map()).values())
+      }
+      this.zoneGoalSumList = mergeAndSumTotalGoal(arr)
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 826 - 0
src/views/business/spd/goal_management/MonthSaleGoal.vue

@@ -0,0 +1,826 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="编码" prop="code">
+        <el-input
+          v-model="queryParams.code"
+          placeholder="请输入编码"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="目标名称" prop="goalName">
+        <el-input
+          v-model="queryParams.goalName"
+          placeholder="请输入目标名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="单据日期" prop="documentDate">
+        <el-date-picker
+          v-model="documentDateRange"
+          value-format="yyyy-MM-dd"
+          @change="setBeginAndEnd"
+          type="daterange"
+          align="right"
+          unlink-panels
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :picker-options="pickerOptions">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item label="年度" prop="annual">
+        <el-date-picker
+          v-model="queryParams.annual"
+          type="year"
+          value-format="yyyy"
+          placeholder="选择年度"
+          clearable
+          @keyup.enter.native="handleQuery">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="客户" prop="custom">
+        <el-popover-select-v2 v-model="queryParams.custom" title="客户" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ customCode: 'code', custom: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入客户" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="销售区域" prop="saleZone">
+        <el-popover-select-v2 v-model="queryParams.saleZone" title="销售区域" valueKey="name"
+                              referName="CUSTOMER_PARAM"
+                              :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入销售区域" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="制单人" prop="creator">
+        <el-popover-select-v2 v-model="queryParams.creator" title="制单人" valueKey="name"
+                              referName="CONTACTS_PARAM"
+                              :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入制单人" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+      <el-form-item label="部门" prop="dept">
+        <el-popover-select-v2 v-model="queryParams.dept" title="部门" valueKey="name"
+                              referName="DEPT_PARAM"
+                              :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                              :source.sync="queryParams" placeholder="请输入部门" @keyup.enter.native="handleQuery">
+        </el-popover-select-v2>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['goal_management:monthSaleGoal:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['goal_management:monthSaleGoal:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['goal_management:monthSaleGoal:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="monthSaleGoalList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="编码" align="center" prop="code"/>
+      <el-table-column label="目标名称" align="center" prop="goalName"/>
+      <el-table-column label="单据日期" align="center" prop="documentDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.documentDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度" align="center" prop="annual"/>
+      <el-table-column label="客户" align="center" prop="custom"/>
+      <el-table-column label="销售区域" align="center" prop="saleZone"/>
+      <el-table-column label="制单人" align="center" prop="creator"/>
+      <el-table-column label="部门" align="center" prop="dept"/>
+      <el-table-column label="目标合计" align="center" prop="goalSum"/>
+      <el-table-column label="备注" align="center" prop="notes"/>
+      <el-table-column label="单据状态" align="center" prop="documentStatus"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['goal_management:monthSaleGoal:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['goal_management:monthSaleGoal:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <el-drawer :title="title" :visible.sync="open" direction="rtl" :before-close="handleClose" size="100%">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="form.code" placeholder="编码后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="目标名称" prop="goalName">
+              <el-input v-model="form.goalName" placeholder="目标名称后端自动生成" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据日期" prop="documentDate">
+              <el-date-picker clearable
+                              v-model="form.documentDate"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="请选择单据日期">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="年度" prop="annual">
+              <el-date-picker
+                v-model="form.annual"
+                type="year"
+                value-format="yyyy"
+                placeholder="选择年度">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="客户" prop="custom">
+              <el-popover-select-v2 v-model="form.custom" title="客户" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                    :source.sync="form" placeholder="请输入客户">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="销售区域" prop="saleZone">
+              <el-popover-select-v2 v-model="form.saleZone" title="销售区域" valueKey="name"
+                                    referName="CUSTOMER_PARAM"
+                                    :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                    :source.sync="form" placeholder="请输入销售区域">
+              </el-popover-select-v2>
+            </el-form-item></el-col>
+          <el-col :span="6">
+            <el-form-item label="制单人" prop="creator">
+              <el-popover-select-v2 v-model="form.creator" title="制单人" valueKey="name"
+                                    referName="CONTACTS_PARAM"
+                                    :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                    :source.sync="form" placeholder="请输入制单人">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="部门" prop="dept">
+              <el-popover-select-v2 v-model="form.dept" title="部门" valueKey="name"
+                                    referName="DEPT_PARAM"
+                                    :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                    :source.sync="form" placeholder="请输入部门">
+              </el-popover-select-v2>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="目标合计" prop="goalSum">
+              <el-input v-model="form.goalSum" placeholder="目标合计自动计算" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="备注" prop="notes">
+              <el-input v-model="form.notes" placeholder="请输入备注"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="单据状态" prop="documentStatus">
+              <el-input v-model="form.documentStatus" placeholder="新增页默认'未提交'" disabled/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作">
+              <el-button type="primary" @click="submitForm">确 定</el-button>
+              <el-button @click="cancel">取 消</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddDetails">增行</el-button>
+        </el-col>
+      </el-row>
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="月销售目标明细" name="monthSaleGoalDetails">
+          <el-table v-loading="loading" :data="monthSaleGoalDetailsList" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="55" align="center" fixed />
+            <el-table-column label="销售组织" align="center" prop="saleOrg" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].saleOrg" title="销售组织" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{ saleOrgCode: 'code', saleOrg: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入销售组织">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="销售区域" align="center" prop="saleZone" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].saleZone" title="销售区域" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{ saleZoneCode: 'code', saleZone: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入销售区域">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="客户" align="center" prop="custom" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].custom" title="客户" valueKey="name"
+                                      referName="CUSTOMER_PARAM"
+                                      :dataMapping="{ customCode: 'code', custom: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入客户">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="部门" align="center" prop="dept" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].dept" title="部门" valueKey="name"
+                                      referName="DEPT_PARAM"
+                                      :dataMapping="{ deptCode: 'code', dept: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入部门">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="制单人" align="center" prop="creator" width="180" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].creator" title="制单人" valueKey="name"
+                                      referName="CONTACTS_PARAM"
+                                      :dataMapping="{ creatorCode: 'code', creator: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入制单人">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="一级分类" align="center" prop="oneLevelClassify" width="220" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-select v-model="monthSaleGoalDetailsList[scope.$index].oneLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '一级物料分类', scope.$index)"
+                           style="width: 200px">
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="二级分类" align="center" prop="twoLevelClassify" width="220" :render-header="addRedStar">
+              <template slot-scope="scope">
+                <el-select v-model="monthSaleGoalDetailsList[scope.$index].twoLevelClassify" size="mini" clearable
+                           @focus="chooseTreeReferForDetails('MATERIALCLASSIFY_PARAM', false, '二级物料分类', scope.$index)"
+                           style="width: 200px">
+                  <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.id" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="物料" align="center" prop="material" width="180">
+              <template slot-scope="scope">
+                <el-popover-select-v2 v-model="monthSaleGoalDetailsList[scope.$index].material" title="物料" valueKey="name"
+                                      referName="MATERIAL_PARAM"
+                                      :dataMapping="{ materialCode: 'code', material: 'name'}"
+                                      :source.sync="monthSaleGoalDetailsList[scope.$index]" placeholder="请输入物料">
+                </el-popover-select-v2>
+              </template>
+            </el-table-column>
+            <el-table-column label="科室" align="center" prop="department" width="180">
+              <template slot-scope="scope">
+                <el-input v-model="monthSaleGoalDetailsList[scope.$index].department" placeholder="请输入科室"></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="数量" align="center" prop="num" width="220">
+              <template slot-scope="scope">
+                <el-input-number v-model="monthSaleGoalDetailsList[scope.$index].num" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="月份" align="center" prop="monthly" width="250">
+              <template slot-scope="scope">
+                <el-date-picker v-model="monthSaleGoalDetailsList[scope.$index].monthly" value-format="yyyy-MM" type="month" placeholder="选择月份">
+                </el-date-picker>
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" prop="totalGoal" width="220">
+              <template slot-scope="scope">
+                <el-input-number @change="computeTotal" v-model="monthSaleGoalDetailsList[scope.$index].goalValue" :precision="2" :step="1" :min="0"></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px" fixed="right">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDeleteDetails(scope.$index, scope.row)"
+                >删除</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleCopyDetails(scope.row)"
+                >复制</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+
+    <TreeRefers ref="treeDetails" @doSubmit="selectionsToInputForDetails" :single="true"/>
+  </div>
+</template>
+
+<script>
+import {
+  listMonthSaleGoal,
+  getMonthSaleGoal,
+  delMonthSaleGoal,
+  addMonthSaleGoal,
+  updateMonthSaleGoal
+} from "@/api/business/spd/goal_management/monthSaleGoal";
+import {
+  getMonthSaleGoalDetails,
+  delMonthSaleGoalDetails
+} from "@/api/business/spd/goal_management/monthSaleGoalDetails"
+
+// 树形参照
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import ElPopoverSelectV2 from "@/components/popover-select-v2"
+import log from "../../../monitor/job/log";
+
+export default {
+  name: "MonthSaleGoal",
+  components: {
+    TreeRefers, ElPopoverSelectV2
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 月销售目标填报表格数据
+      monthSaleGoalList: [],
+      monthSaleGoalDetailsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        params: { beginTime: null, endTime: null }
+      },
+      documentDateRange: null,
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+            picker.$emit('pick', [start, end]);
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+            picker.$emit('pick', [start, end]);
+          }
+        }]
+      },
+      // 表单参数
+      form: {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        monthDetailsList: null
+      },
+      formDetails: {
+        id: null,
+        code: null,
+        saleOrg: null,
+        saleZone: null,
+        custom: null,
+        dept: null,
+        creator: null,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        department: null,
+        num: null,
+        monthly: null,
+        goalValue: null
+      },
+      // 表单校验
+      rules: {
+        documentDate: [{ required: true, message: '单据日期不能为空', trigger: 'blur' }],
+        annual: [{ required: true, message: '年度不能为空', trigger: 'blur' }],
+        custom: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
+        saleZone: [{ required: true, message: '销售区域不能为空', trigger: 'blur' }],
+        creator: [{ required: true, message: '销售区域不能为空', trigger: 'blur' }],
+        dept: [{ required: true, message: '部门不能为空', trigger: 'blur' }]
+      },
+      // 参照条件
+      referCondition: { type: '', isPage: true, title: '', index: null },
+      classOptions: [],
+      // 子表导航名
+      activeName: 'monthSaleGoalDetails'
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询月销售目标填报列表 */
+    getList() {
+      this.loading = true;
+      listMonthSaleGoal(this.queryParams).then(response => {
+        this.monthSaleGoalList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getListDetails() {
+      this.loading = true
+      getMonthSaleGoalDetails(this.form.id).then(response => {
+        this.monthSaleGoalDetailsList = response.data
+        this.computeTotal()
+        this.form.monthDetailsList = this.monthSaleGoalDetailsList
+        updateMonthSaleGoal(this.form).then(response => {
+        })
+        this.loading = false
+      })
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        monthDetailsList: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        code: null,
+        goalName: null,
+        documentDate: null,
+        annual: null,
+        customCode: null,
+        custom: null,
+        saleZoneCode: null,
+        saleZone: null,
+        creatorCode: null,
+        creator: null,
+        deptCode: null,
+        dept: null,
+        goalSum: null,
+        notes: null,
+        documentStatus: null,
+        params: { beginTime: null, endTime: null }
+      }
+      this.documentDateRange = null
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.monthSaleGoalDetailsList = []
+      this.open = true;
+      this.title = "添加月销售目标填报";
+    },
+    handleAddDetails() {
+      let list = {
+        id: null,
+        code: null,
+        saleOrg: this.form.saleZone,
+        saleZone: this.form.saleZone,
+        custom: this.form.custom,
+        dept: this.form.dept,
+        creator: this.form.creator,
+        oneLevelClassifyCode: null,
+        oneLevelClassify: null,
+        twoLevelClassifyCode: null,
+        twoLevelClassify: null,
+        materialCode: null,
+        material: null,
+        department: null,
+        num: null,
+        monthly: null,
+        goalValue: 0
+      }
+      this.monthSaleGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getMonthSaleGoal(id).then(response => {
+        this.form = response.data;
+        this.monthSaleGoalDetailsList = this.form.monthDetailsList
+        this.open = true;
+        this.title = "修改月销售目标填报";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      if (!this.justiceDetailsList()) {
+        return this.$message.error('子表有必填字段未填')
+      }
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            this.form.monthDetailsList = this.monthSaleGoalDetailsList
+            updateMonthSaleGoal(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            this.form.documentStatus = '未提交'
+            this.form.monthDetailsList = this.monthSaleGoalDetailsList
+            console.log(this.form);
+            addMonthSaleGoal(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除月销售目标填报编号为"' + ids + '"的数据项?').then(function () {
+        return delMonthSaleGoal(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    handleDeleteDetails(index, row) {
+      if (this.form.id === null) {
+        this.monthSaleGoalDetailsList.splice(index, 1)
+        this.computeTotal()
+      } else {
+        if (row.id !== null) {
+          this.$modal.confirm('是否确认删除月销售目标填报明细编号为"' + row.id + '"的数据项?').then(function () {
+            return delMonthSaleGoalDetails(row.id);
+          }).then(() => {
+            this.getListDetails();
+            this.$modal.msgSuccess("删除成功");
+          }).catch(() => {
+          });
+        } else {
+          this.monthSaleGoalDetailsList.splice(index, 1)
+          this.$message.success('删除成功')
+          this.computeTotal()
+        }
+      }
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('goal_management/monthSaleGoal/export', {
+        ...this.queryParams
+      }, `monthSaleGoal_${new Date().getTime()}.xlsx`)
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+        })
+        .catch(_ => {
+        });
+    },
+    // 复制明细
+    handleCopyDetails(row) {
+      let list = {
+        id: null,
+        code: row.code,
+        saleOrg: row.saleOrg,
+        saleZone: row.saleZone,
+        custom: row.custom,
+        dept: row.dept,
+        creator: row.creator,
+        oneLevelClassifyCode: row.oneLevelClassifyCode,
+        oneLevelClassify: row.oneLevelClassify,
+        twoLevelClassifyCode: row.twoLevelClassifyCode,
+        twoLevelClassify: row.twoLevelClassify,
+        materialCode: row.materialCode,
+        material: row.material,
+        department: row.department,
+        num: row.num,
+        monthly: row.monthly,
+        goalValue: row.goalValue
+      }
+      this.monthSaleGoalDetailsList.push(list)
+      this.computeTotal()
+    },
+    // 计算主表合计
+    computeTotal() {
+      let list = this.monthSaleGoalDetailsList
+      let sum = 0
+      for (const listElement of list) {
+        sum = (sum * 1000000 + listElement.goalValue * 1000000) / 1000000
+      }
+      this.form.goalSum = sum
+    },
+    // 树形物料分类
+    chooseTreeReferForDetails(type, isPage, title, index) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.index = index
+      this.$refs.treeDetails.init(this.referCondition)
+    },
+    selectionsToInputForDetails(selection) {
+      this.classOptions.push(selection)
+      if (this.referCondition.title === '一级物料分类') {
+        if (selection.code.length !== 1) {
+          return this.$message.info('请在一级分类中选择')
+        }
+        if (selection.code !== this.monthSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          this.monthSaleGoalDetailsList[this.referCondition.index].twoLevelClassifyCode = null
+          this.monthSaleGoalDetailsList[this.referCondition.index].twoLevelClassify = null
+        }
+        this.monthSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode = selection.code
+        this.monthSaleGoalDetailsList[this.referCondition.index].oneLevelClassify = selection.name
+      } else if (this.referCondition.title === '二级物料分类') {
+        if (selection.code.length !== 4) {
+          return this.$message.info('请在二级分类中选择')
+        } else if (selection.code[0] !== this.monthSaleGoalDetailsList[this.referCondition.index].oneLevelClassifyCode) {
+          return this.$message.error('所选择的二级物料分类不属于一级分类')
+        }
+        this.monthSaleGoalDetailsList[this.referCondition.index].twoLevelClassifyCode = selection.code
+        this.monthSaleGoalDetailsList[this.referCondition.index].twoLevelClassify = selection.name
+      }
+    },
+    // 子表table加必填标志
+    addRedStar(h, { column }) {
+      return [
+        h('span', { style: 'color: #F56C6C' }, '*'),
+        h('span', '' + column.label)
+      ]
+    },
+    justiceDetailsList() {
+      const arr = JSON.parse(JSON.stringify(this.monthSaleGoalDetailsList))
+      for (const element of arr) {
+        if (element.saleOrg === null || element.saleZone === null || element.custom === null || element.dept === null || element.creator === null || element.oneLevelClassify === null || element.twoLevelClassify === null) {
+          return false
+        }
+      }
+      return true
+    },
+    setBeginAndEnd() {
+      let array = this.documentDateRange
+      if (array !== null) {
+        this.queryParams.params.beginTime = array[0]
+        this.queryParams.params.endTime = array[1]
+      } else {
+        this.queryParams.beginTime = null
+        this.queryParams.endTime = null
+      }
+    }
+  }
+}
+</script>

+ 254 - 0
src/views/business/spd/target/targetMk/add.vue

@@ -0,0 +1,254 @@
+<template>
+  <div>
+    <el-card>
+      <el-form :model="form" :rules="rules" ref="form" label-width="auto" :disabled="this.pageStu == 'see'">
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+            <el-form-item label="单据编号" prop="code">
+              <el-input
+                v-model="form.code"
+                size="mini"
+                disabled
+                style="width: 200px"
+              />
+              <!-- <div>{{form.code}}</div> -->
+            </el-form-item>
+          </el-col>
+          <el-col :span="1.5">
+            <el-form-item label="单据日期" prop="date">
+              <el-date-picker
+                  v-model="form.date"
+                  clearable
+                  type="date"
+                  value-format="yyyy-MM-dd"
+                  size="mini"
+                  style="width: 200px"
+                >
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="1.5">
+            <el-form-item label="目标名称" prop="name">
+              <el-input
+                v-model="form.name"
+                size="mini"
+                style="width: 200px"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="1.5">
+            <el-form-item label="包含下级组织" >
+              <el-select v-model="form.includeOrg" size="mini" style="width: 200px">
+                <el-option
+                  v-for="dict in dict.type.sys_yes_no"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="1.5">
+            <el-form-item label="模板" prop="template">
+              <dr-popover-select size="mini" v-model="form.templateName" title="模板" type="MK_TARGET_TEMPLATE_PARAM" :dataMapping="{
+                  template: 'id',
+                  templateName: 'name',
+                }" :source.sync="form"
+              >
+              </dr-popover-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-card shadow="never">
+          <el-descriptions title="模板信息">
+            <el-descriptions-item label="年度">{{template.year}}</el-descriptions-item>
+            <el-descriptions-item label="开始日期">{{template.startTime}}</el-descriptions-item>
+            <el-descriptions-item label="结束日期">{{template.deadlineTime}}</el-descriptions-item>
+            <el-descriptions-item label="周期">
+              <div v-for="dict in dict.type.mk_periodic_unit" v-if="template.cycle == dict.value">
+                  <el-tag size="small">{{dict.label}}</el-tag>
+                </div>
+            </el-descriptions-item>
+            <el-descriptions-item label="维度">
+              <div v-for="d in template.dimensionalitys">
+                <!-- <el-tag size="small">{{d.dimensionality}}</el-tag> -->
+                <div v-for="dict in dict.type.mk_dimensionality" v-if="d.dimensionality == dict.value">
+                  <el-tag size="small">{{dict.label}}</el-tag>
+                </div>
+              </div>
+            </el-descriptions-item>
+            <el-descriptions-item label="指标">
+              <div v-for="d in template.indexs">
+                <!-- <el-tag size="small">{{d.target}}</el-tag> -->
+                <div v-for="dict in dict.type.mk_index_type" v-if="d.target == dict.value">
+                  <el-tag size="small">{{dict.label}}</el-tag>
+                </div>
+              </div>
+            </el-descriptions-item>
+            <el-descriptions-item label="展开方式">
+              <div v-for="dict in dict.type.mk_expansion_mode" v-if="template.unfold == dict.value">
+                  <el-tag size="small">{{dict.label}}</el-tag>
+                </div>
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-form>
+    </el-card>
+    <Item ref="child" v-if="isItem" :pageStu="pageStu" :template="template" :form="form" :columns="headers"></Item>
+    <el-card>
+      <div class="btn_group">
+        <el-col :span="1.5" style="margin: 0 10px;">
+          <el-button type="primary" size="mini" plain @click="useSave" v-if="pageStu == 'add' || pageStu == 'edit'">保存</el-button>
+        </el-col>
+        <el-col :span="1.5">
+          <el-button size="mini" plain @click="useBack">返回</el-button>
+        </el-col>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import Item from './item.vue'
+import { getTargetTemplate,getHeaderData } from "@/api/business/spd/starget/targetTemplate";
+import { getTarget,addTarget,updateTarget } from "@/api/business/spd/starget/target";
+export default {
+  name: 'add',
+  dicts: ['sys_yes_no','mk_periodic_unit','mk_dimensionality','mk_index_type','mk_expansion_mode'],
+  props: ['pageStu','row', 'disable'],
+  components: {Item},
+  model: {
+    prop: 'isList',
+    event: 'jugislist'
+  },
+  data() {
+    return {
+      template:{},
+      form:{},
+      //表单校验
+      rules: {
+        date: [
+          { required: true, message: "单据日期不能为空", trigger: "blur" },
+        ],
+        name: [
+          { required: true, message: "目标名称不能为空", trigger: "blur" },
+        ],
+        template: [
+          { required: true, message: "模板不能为空", trigger: "blur" },
+        ],
+      },
+      //子表表头数据
+      headers:[],
+      //遮罩
+      loading: false,
+      //是否展示Item组件
+      isItem:false,
+    }
+  },
+  async created() {
+    if(this.pageStu == 'edit' || this.pageStu == 'see') {
+      await this.fetchTarget(this.row);
+      await this.fetchTemplate(this.row.template);
+      await this.fetchHeaderData(this.row.template);
+      this.isItem = true;
+    }
+  },
+  watch: {
+	  'form.template': {
+      async handler(newVal) {
+        this.isItem = false;
+        await this.fetchTemplate(newVal);
+        await this.fetchHeaderData(newVal);
+        this.isItem = true;
+      },
+    }
+  },
+  methods: {
+    //保存
+    async useSave(){
+      let passrule = false;
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+            passrule = true;
+          }
+      });
+      if(passrule){
+        try {
+          this.form.items = this.$refs.child.merge();
+          if(!this.form.items.length){
+            this.$modal.msgError("子表数据不能为空!");
+            return;
+          }
+          console.log('this.form',this.form);
+          this.loading = true;
+          let res = null;
+          if(this.pageStu == 'add'){
+            res = await addTarget(this.form);
+          }
+          if(this.pageStu == 'edit'){
+            res = await updateTarget(this.form);
+          }
+          if (res.code === 200) {
+            this.$modal.msgSuccess("保存成功");
+            this.useBack();
+          }
+        } catch (err) {
+          // catch
+          console.error(err);
+        } finally {
+          this.loading = false;
+        }
+      }
+    },
+    //返回
+    useBack(){
+      this.$emit('jugislist', true)
+      this.$emit('refresh')
+    },
+    //查询目标模板
+    async fetchTemplate(id) {
+      try {
+        this.loading = true;
+        const { code, data } = await getTargetTemplate(id);
+        if (code === 200) {
+          this.template = data;
+          return true;
+        } else {
+          return false;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    //查询详情
+    async fetchTarget(row){
+      await getTarget(row.id).then(res => {
+        if (res.code === 200) {
+          this.form = res.data
+         }
+      })
+    },
+    //查询动态表头数据
+    async fetchHeaderData(id){
+      await getHeaderData(id).then(res => {
+        if (res.code === 200) {
+          this.headers = res.rows
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn_group {
+  width: 100%;
+  margin: 20px 0;
+  display: flex;
+  justify-content: center;
+} 
+</style>

+ 284 - 0
src/views/business/spd/target/targetMk/index.vue

@@ -0,0 +1,284 @@
+<template>
+  <div id="deliveryAddressList">
+    <div v-if="isList">
+      <el-card>
+        <el-form class="search_area" label-width="120px">
+          <el-row :gutter="10">
+            <el-col :span="1.5">
+              <el-form-item label="单据编号">
+                <el-input
+                  v-model="queryParams.code"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="1.5">
+              <el-form-item label="目标名称">
+                <el-input
+                  v-model="queryParams.name"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col>
+            <!-- <el-col :span="1.5">
+              <el-form-item label="模板">
+                <el-input
+                  v-model="queryParams.template"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="1.5">
+              <el-form-item label="年度">
+                <el-input
+                  v-model="queryParams.year"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col> -->
+            <el-col :span="1.5">
+              <el-form-item label="" label-width="20px">
+                <el-button type="primary" size="mini" icon="el-icon-search" plain @click="useSearch">搜索</el-button>
+                <el-button size="mini" icon="el-icon-refresh" plain @click="useReset">重置</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <CollapseTransition>
+            <div v-show="expanded">
+              
+            </div>
+          </CollapseTransition>
+        </el-form>
+        <el-divider class="lines"><i style="cursor: pointer;" :class="expanded?'el-icon-arrow-up':'el-icon-arrow-down'" @click="drop"></i></el-divider>
+      
+        <div class="btn_grooup">
+          <el-button type="primary" size="mini" @click="useAdd">新增</el-button>
+        </div>
+
+        <el-table 
+          :data="tableList" 
+          fit
+          max-height="480"
+          style="font-size: 12px;"
+          @selection-change="useSelectionRow"
+          @row-dblclick="useDoubleClick"
+        >
+          <el-table-column show-overflow-tooltip type="selection" width="55" />
+          <el-table-column show-overflow-tooltip label="单据编号" align="center" width="200" prop="code"/>
+          <el-table-column show-overflow-tooltip label="单据日期" align="center" width="200" prop="date"/>
+          <el-table-column show-overflow-tooltip label="目标名称" align="center" width="200" prop="name"/>
+          <el-table-column show-overflow-tooltip label="年度" align="center" width="200" prop="templateData.year"/>
+          <el-table-column show-overflow-tooltip label="模板" align="center" width="200" prop="templateData.name"/>
+          <el-table-column show-overflow-tooltip label="开始日期" align="center" width="200" prop="templateData.startTime" />
+          <el-table-column show-overflow-tooltip label="结束日期" align="center" width="200" prop="templateData.deadlineTime" />
+          <el-table-column show-overflow-tooltip label="周期" align="center" width="200" prop="templateData.cycle">
+            <template slot-scope="scope">
+              <dict-tag
+                :options="dict.type.mk_periodic_unit"
+                :value="scope.row.templateData.cycle"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column show-overflow-tooltip label="维度" align="center" min-width="200" prop="templateData.dimensionalitys">
+            <template slot-scope="scope">
+              <div style="display:flex;">
+                <span v-for="o in scope.row.templateData.dimensionalitys">
+                  <dict-tag
+                    :options="dict.type.mk_dimensionality"
+                    :value="o.dimensionality"
+                    />
+                  </span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column show-overflow-tooltip label="指标" align="center" min-width="200" prop="templateData.indexs">
+            <template slot-scope="scope">
+              <div style="display:flex;">
+                <span v-for="o in scope.row.templateData.indexs">
+                  <dict-tag
+                    :options="dict.type.mk_index_type"
+                    :value="o.target"
+                  />
+                </span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column show-overflow-tooltip label="创建人" align="center" width="200" prop="createByName" />
+          <el-table-column show-overflow-tooltip label="创建时间" align="center" width="200" prop="createTime" />
+          <el-table-column show-overflow-tooltip label="修改人" align="center" width="200" prop="updateByName" />
+          <el-table-column show-overflow-tooltip label="修改时间" align="center" width="200" prop="updateTime" />
+          <el-table-column fixed="right" label="操作" align="center" width="200">
+            <template slot-scope="scope">
+              <!-- <el-button type="text" size="mini" @click="useSubmit(scope.row)">提交</el-button> -->
+              <el-button type="text" size="mini" @click="useEdit(scope.row)">编辑</el-button>
+              <el-button type="text" size="mini" @click="useDel(scope.row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <el-pagination
+          background
+          @size-change="useChangePageSize"
+          @current-change="useCurrentChange"
+          :current-page="queryParams.pageNum"
+          :page-sizes="[10, 15, 20]"
+          :page-size="100"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total=total>
+        </el-pagination>
+      </el-card>
+    </div>
+    <Add v-model="isList" v-if="!isList" :pageStu="page" :disable="disable" :row="rowDetail" @refresh="useSearch"/>
+  </div>
+</template>
+
+<script>
+import Add from './add.vue'
+import CollapseTransition from '@/components/MyCollapse/collapse.vue'
+import { listTarget,delTarget } from "@/api/business/spd/starget/target";
+export default {
+  name: 'target',
+  dicts: [
+    "mk_periodic_unit","mk_dimensionality","mk_index_type"
+  ],
+  components: { Add,CollapseTransition},
+  data() {
+    return {
+      expanded: false,
+      // 页面配置
+      isList: true,
+      // 页面状态
+      page: '',
+      // 搜索框参数
+      queryParams: {
+        code: '',
+        name: '',
+        template:'',
+        year:'',
+        pageNum: 1,
+        pageSize: 10
+      },
+      //总条数
+      total: 0,
+      //列表数据
+      tableList:[],
+      disable: false,
+    }
+  },
+  created() {
+    this.getList(this.queryParams)
+  },
+  methods: {
+    //新增
+    useAdd(){
+      this.isList = false
+      this.page = 'add'
+      this.disable = false
+    },
+    //提交
+    useSubmit(){
+      
+    },
+    //修改
+    useEdit(row){
+      this.isList = false
+      this.page = 'edit'
+      this.rowDetail = row
+      this.disable = false
+    },
+    //删除
+    useDel(row){
+      this.$modal.confirm('确认删除选择数据').then(() => {
+        delTarget(row.id).then(res => {
+          if (res.code === 200) {
+            this.$modal.msgSuccess("删除成功");
+            this.getList(this.queryParams)
+          }
+        })
+      }).catch(() => {})
+    },
+    //查看
+    useSee(){
+
+    },
+    //选择列
+    useSelectionRow(){
+
+    },
+    //双击
+    useDoubleClick(row){
+      this.isList = false
+      this.page = 'see'
+      this.rowDetail = row
+      this.disable = false
+    },
+    //改变一页显示条数
+    useChangePageSize(val){
+      this.queryParams.pageSize = val
+      this.getList(this.queryParams)
+    },
+    //翻页
+    useCurrentChange(val){
+      this.queryParams.pageNum = val
+      this.getList(this.queryParams)
+    },
+    //搜索
+    useSearch() {
+      this.getList(this.queryParams)
+    },
+    //重置
+    useReset(){
+      this.queryParams = {
+        code: '',
+        name: '',
+        template:'',
+        year:'',
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList(this.queryParams)
+    },
+    //查询列表
+    getList(params){
+      listTarget(params).then(res => {
+        if (res.code === 200) {
+          this.tableList = res.rows
+          this.total = res.total
+        }
+      })
+    },
+    drop() {
+      this.expanded = !this.expanded
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+#deliveryAddressList {
+  height: calc(100vh - 84px);
+  padding: 12px;
+  box-sizing: border-box;
+  overflow-y: scroll;
+}
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+.lines {
+  margin-top: 0;
+}
+.el-pagination {
+  margin-top: 10px;
+  text-align: right;
+}
+</style>

+ 177 - 0
src/views/business/spd/target/targetMk/item.vue

@@ -0,0 +1,177 @@
+<template>
+  <div>
+    <el-card>
+      <el-row>
+        <div class="btn_add">
+          <el-button type="primary" size="mini" @click="useAdd" v-if="this.pageStu != 'see'">增行</el-button>
+        </div>
+      </el-row>
+      <!-- 渲染表头 -->
+      <el-table :data="items" style="width: 100%" height="500px">
+        <el-table-column label="序号" type="index" width="50" align="center" fixed>
+        </el-table-column>
+        <el-table-column v-for="head in headers" :prop="head.prop" :label="head.modelName" width="150" align="center">
+          <template slot-scope="scope">
+            <div v-if="pageStu == 'add' || pageStu == 'edit'">
+              <dr-popover-select size="mini" v-if="scope.row[head.prop].type == 'D'" v-model="scope.row[head.prop].valueName" title="参照选择" :type="scope.row[head.prop].model" :dataMapping="{
+                value: 'id',
+                valueName: 'name',
+              }" :source.sync="scope.row[head.prop]"></dr-popover-select>
+              <el-input size="mini" v-if="scope.row[head.prop].type == 'C' || scope.row[head.prop].type == 'I'" v-model="scope.row[head.prop].value"></el-input>
+            </div>
+            <div v-else-if="pageStu == 'see'">
+              <div v-if="scope.row[head.prop].type == 'D'">
+                {{scope.row[head.prop].valueName}}
+              </div>
+              <div v-else>
+                {{scope.row[head.prop].value}}
+              </div>
+            </div>
+          </template>
+          <el-table-column v-if="head.children" v-for="headChi in head.children" :prop="headChi.prop" :label="headChi.modelName" width="150" align="center">
+            <template slot-scope="scope">
+              <div v-if="pageStu == 'add' || pageStu == 'edit'">
+                <el-input size="mini" v-model="scope.row[headChi.prop].value"></el-input>
+              </div>
+              <div v-else-if="pageStu == 'see'">
+                {{scope.row[headChi.prop].value}}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column fixed="right" label="操作" align="center" width="100" v-if="this.pageStu != 'see'">
+          <template slot-scope="scope">
+            <el-button type="text" size="mini" @click="useDel(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getTargetItem } from "@/api/business/spd/starget/target";
+
+export default {
+  name: 'item',
+  props: ['pageStu','template','form','columns'],  
+  dicts: ['sys_yes_no','mk_periodic_unit','mk_dimensionality','mk_index_type','mk_expansion_mode'],
+  data() {
+    return {
+      items:[],
+      delItems:[],
+      headers:[],
+      itemTemplate:{},
+    }
+  },
+  async created() {
+    this.processHeadersData(this.template.unfold,this.columns);
+    this.itemTemplate = this.formatItem(this.columns);
+    console.log('this.itemTemplate',this.itemTemplate);
+    if(this.pageStu == 'edit' || this.pageStu == 'see'){
+      await this.fetchTargetItem(this.form.id);
+      console.log('this.items',this.items);
+    }
+  },
+  methods: {
+    //增行
+    useAdd(){
+      this.items.push(this.itemTemplate);
+      console.log('this.items',this.items);
+    },
+    //删行
+    useDel(index){
+      this.items[index].delFlag = '2';
+      if(this.items[index].id){
+        let delList = this.items.filter(item => {
+          return item.delFlag == '2'
+        })
+        this.delItems.push(...delList);
+      }
+      this.items.splice(index, 1);
+    },
+    //表头数据处理
+    processHeadersData(unfold,columns){
+      const array = [];
+      if("cycle/unfold" == unfold){
+        for(let i in columns){
+          if(columns[i].type == 'D'){
+            columns[i].prop = columns[i].model
+            array.push(columns[i]);
+          }else{
+            const arr = array.filter(element => element.model == columns[i].superiors);
+            if(arr.length > 0){
+              columns[i].prop = array[array.length - 1].model + '-' + columns[i].model;
+              array[array.length - 1].children.push(columns[i]);
+            }else{
+              columns[i].prop = columns[i].superiors + '-' + columns[i].model;
+              let c = {
+                type:'C',
+                model:columns[i].superiors,
+                modelName:columns[i].superiorsName,
+                children:[columns[i]]
+              }
+              array.push(c);
+            }
+          }
+        }
+        this.headers = array;
+      }else if("cycle" == unfold){
+        for(let i in columns){
+          columns[i].prop = columns[i].model
+          array.push(columns[i]);
+        }
+        this.headers = array;
+      }else if("unfold" == unfold){
+        for(let i in columns){
+          columns[i].prop = columns[i].model
+          array.push(columns[i]);
+        }
+        this.headers = array;
+      }else if("" == unfold){
+        for(let i in columns){
+          columns[i].prop = columns[i].model
+          array.push(columns[i]);
+        }
+        this.headers = array;
+      }
+      console.log('this.headers',this.headers);
+    },
+    //获取明细数据
+    async fetchTargetItem(id){
+      await getTargetItem(id).then(res => {
+        if (res.code === 200) {
+          this.items = res.rows
+        }
+      })
+    },
+    //格式化数据
+    formatItem(item){
+      let obj = {};
+      for(let i in item){
+        obj[item[i].prop] = item[i];
+      }
+      return obj;
+    },
+    //合并已存在和删除的数据
+    merge(){
+      this.items.push(...this.delItems);
+      return this.items;
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn_add{
+    margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+.btn_group {
+  width: 100%;
+  margin: 20px 0;
+  display: flex;
+  justify-content: center;
+} 
+</style>

+ 131 - 0
src/views/business/spd/target/targetTemplate/add/columns.js

@@ -0,0 +1,131 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    {
+      item: { key: "year", title: "年度", require: true },
+      attr: {
+        is: "el-date-picker",
+        type: "year",
+        valueFormat: "yyyy-MM-dd",
+      },
+    },
+    {
+      item: { key: "name", title: "模板名称", require: true },
+      attr: { is: "el-input" },
+    },
+    {
+      item: { key: "startTime", title: "开始日期", require: true },
+      attr: {
+        is: "el-date-picker",
+        valueFormat: "yyyy-MM-dd",
+      },
+    },
+    {
+      item: { key: "deadlineTime", title: "结束日期", require: true },
+      attr: {
+        is: "el-date-picker",
+        valueFormat: "yyyy-MM-dd",
+      },
+    },
+    {
+      item: { key: "cycle", title: "周期", require: true },
+      attr: {
+        is: "el-select",
+        dictName: "mk_periodic_unit",
+      },
+    },
+    {
+      item: { key: "unfold", title: "按列展开"},
+      attr: {
+        is: "el-select",
+        dictName: "mk_expansion_mode",
+        clearable: true,
+      },
+    },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+
+  const TabColumns = [
+    {
+      item: {
+        title: "指标",
+        key: "indexs",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "target", title: "指标", width: 'auto' },
+          attr: {
+            is: "el-select",
+            dictName: "mk_index_type",
+          },
+        },
+      ],
+    },
+    {
+      item: {
+        title: "维度",
+        key: "dimensionalitys"
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "dimensionality", title: "维度", width: 'auto' },
+          attr: {
+            is: "el-select",
+            dictName: "mk_dimensionality",
+          },
+        },
+      ],
+    },
+    {
+      item: {
+        title: "周期",
+        key: "cycles",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "name", title: "周期名称", require: true },
+          attr: { is: "el-input" },
+        },
+        {
+          item: {
+            key: "startTime",
+            title: "周期开始日期",
+            require: true,
+          },
+          attr: {
+            is: "el-date-picker",
+            valueFormat: "yyyy-MM-dd",
+            // value: new Date(),
+          },
+        },
+        {
+          item: {
+            key: "deadlineTime",
+            title: "周期结束日期",
+            require: true,
+            width: 'auto'
+          },
+          attr: {
+            is: "el-date-picker",
+            valueFormat: "yyyy-MM-dd",
+            // value: new Date(),
+          },
+        },
+      ],
+    },
+  ];
+
+  return { TableColumns, TabColumns };
+}

+ 350 - 0
src/views/business/spd/target/targetTemplate/add/index.vue

@@ -0,0 +1,350 @@
+<script>
+import useColumns from "./columns";
+import {
+  addTargetTemplate,
+  updateTargetTemplate,
+  getTargetTemplate,
+  checkQuote,
+} from "@/api/business/spd/starget/targetTemplate";
+export default {
+  name: "AddDrawer",
+  props: {
+    dict: {
+      type: Object,
+    },
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+    addType: {
+      type: String,
+      default: "add",
+    },
+  },
+  components: {
+    ElSuperForm: () => import("@/components/super-form/index.vue"),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+  },
+  data() {
+    const {
+      TabColumns,
+      TableColumns,
+      TabColumns: [
+        {
+          item: { key: tabName },
+        },
+      ],
+    } = useColumns();
+    const rules = this.$init.rules([...TabColumns, ...TableColumns]);
+    const params = this.$init.params([...TabColumns, ...TableColumns]);
+    return {
+      width: "100%",
+      visible: false,
+      loading: false,
+      rules: rules,
+      params: params,
+      tabName: tabName,
+      TabColumns: TabColumns,
+      TableColumns: TableColumns,
+    };
+  },
+  computed: {
+    title: {
+      get() {
+        const { addType } = this;
+        if (addType === "add") {
+          return "新 增";
+        }
+        if (addType === "edit") {
+          return "编 辑";
+        }
+      },
+      set() {},
+    },
+    disabled: {
+      get() {
+        const {
+          addType,
+          selectData,
+          selectData: [{ status } = {}],
+        } = this.$props;
+        if (addType === "add") {
+          return false;
+        }
+        if (addType === "edit") {
+          if (selectData.length !== 1) {
+            return true;
+          }
+          if (selectData.length === 1 && status === "1") {
+            return true;
+          }
+          if (selectData.length === 1 && status === "2") {
+            return true;
+          }
+        }
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {
+    changePuOrgName(prop) {
+      console.log("changePuOrgName", prop);
+    },
+    changeMaterialName(prop) {
+      console.log("changeMaterialName", prop);
+    },
+
+    //查询目标模板详情
+    async fetchTemplate(prop) {
+      try {
+        // try
+        this.loading = true;
+        const { code, data } = await getTargetTemplate(prop);
+        if (code === 200) {
+          this.params = data;
+          return true;
+        } else {
+          return false;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    //打开组件
+    async open() {
+      const { addType, selectData } = this.$props;
+      if (addType === "add") {
+        this.visible = true;
+      }
+      if (addType === "edit") {
+        const [{ id }] = selectData;
+        //校验目标模板是否存在引用
+        const { code, data } = await checkQuote(id);
+        if(code == '200'){
+          if(data){
+            this.$modal.msgError("该目标模板存在引用,无法修改!");
+            this.visible = false;
+            return;
+          }
+        }else{
+          this.$modal.msgError("校验该目标模板是否存在引用异常,无法修改!");
+          this.visible = false;
+          return;
+        }
+        this.visible = await this.fetchTemplate(id);
+        this.params.indexs = this.params.indexs.map((item) => ({ ...item }));
+        this.params.dimensionalitys = this.params.dimensionalitys.map(
+          (item) => ({ ...item })
+        );
+        this.params.cycles = this.params.cycles.map((item) => ({ ...item }));
+      }
+    },
+    //关闭页面
+    async hide() {
+      const {
+        TabColumns,
+        TableColumns,
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
+      this.visible = false;
+      this.tabName = tabName;
+      this.params = this.$init.params([...TabColumns, ...TableColumns]);
+    },
+    //增行
+    async useRowAdd(prop) {
+      const { TabColumns } = this;
+      const { TableColumns } = TabColumns.find(
+        ({ item: { key } }) => key === prop
+      );
+      console.log(prop, this.$init.params(TableColumns));
+      this.params[prop].push({
+        delFlag: "0",
+        ...this.$init.params(TableColumns),
+      });
+      console.log("this.params[prop]", this.params[prop]);
+    },
+    //删行
+    async useRowRemove(prop, scope) {
+      const { addType } = this.$props;
+      const {
+        row: { $index },
+      } = scope;
+      if (addType === "add") {
+        this.params[prop].splice($index, 1);
+      }
+      if (addType === "edit") {
+        this.params[prop] = this.params[prop].map((item, index) => ({
+          ...item,
+          delFlag: index === $index ? "2" : item.delFlag,
+        }));
+        console.log(this.params[prop]);
+      }
+    },
+    //确认
+    async useSubmit(prop) {
+      this.$refs[prop].$refs[prop].validate(async (valid) => {
+        if (valid) {
+          try {
+            this.loading = true;
+            // const {
+            //   params,
+            //   params: { paramsOrgs, paramsItems },
+            // } = this;
+            // if (this.addType === "edit") {
+            //   params.paramsOrgs = paramsOrgs.filter(
+            //     (item) => item.orgName
+            //   );
+            //   params.paramsItems = paramsItems.filter(
+            //     (item) => item.materialName
+            //   );
+            // }
+            const { addType } = this.$props;
+            let res = null;
+            if (addType === "add") {
+              res = await addTargetTemplate(this.params);
+            }
+            if (addType === "edit") {
+              res = await updateTargetTemplate(this.params);
+            }
+            if (res.code === 200) {
+              this.hide();
+              this.$emit("success");
+              this.$notify.success(res.msg);
+            }
+          } catch (err) {
+            // catch
+            console.error(err);
+          } finally {
+            // finally
+            this.loading = false;
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+  },
+  created() {
+    console.log("params", this.params);
+  },
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
+  >
+    {{ title }}
+    <el-drawer
+      :size="width"
+      :title="title"
+      :visible.sync="visible"
+      append-to-body
+      destroy-on-close
+      @close="hide"
+    >
+      <el-super-form
+        v-model="params"
+        :dict="dict"
+        :rules="rules"
+        :size="$attrs.size"
+        :columns="TableColumns"
+        ref="superForm"
+        label-width="auto"
+        label-position="right"
+        style="padding: 20px"
+      >
+        <!-- <template slot="puOrgName" slot-scope="scope">
+          <component
+            v-bind="scope.attr"
+            v-model="scope.row[scope.item.key]"
+            :size="$attrs.size"
+            :source.sync="scope.row"
+            @change="changePuOrgName({ ...scope, select: $event })"
+          >
+          </component
+        ></template> -->
+      </el-super-form>
+      <el-tabs v-model="tabName" style="padding: 0 20px 20px">
+        <el-tab-pane
+          v-for="({ item, TableColumns: columns }, index) in TabColumns"
+          :key="index"
+          :label="item.title"
+          :name="item.key"
+          lazy
+        >
+          <el-super-table
+            v-model="params[item.key]"
+            :dict="dict"
+            :ref="tabName"
+            :columns="columns"
+            :size="$attrs.size"
+          >
+            <!-- <template slot="materialName" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                @change="changeMaterialName(scope)"
+              >
+              </component>
+            </template> -->
+            <el-table-column fixed="right" label="操作" width="75">
+              <template slot="header" slot-scope="scope">
+                <el-button
+                  circle
+                  icon="el-icon-plus"
+                  :size="$attrs.size"
+                  @click="useRowAdd(tabName)"
+                >
+                </el-button>
+              </template>
+              <template slot-scope="scope">
+                <el-button
+                  circle
+                  icon="el-icon-minus"
+                  :size="$attrs.size"
+                  @click.native.prevent="useRowRemove(tabName, scope)"
+                >
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-super-table>
+        </el-tab-pane>
+      </el-tabs>
+      <div style="padding: 20px; text-align: right">
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useSubmit('superForm')"
+          >确 认</el-button
+        >
+      </div>
+    </el-drawer>
+  </el-button>
+</template>
+
+<style scoped>
+::v-deep .el-table__row.is-hidden {
+  display: none;
+}
+</style>

+ 38 - 0
src/views/business/spd/target/targetTemplate/columns.js

@@ -0,0 +1,38 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    { item: { key: "year", title: "年度" }, attr: {} },
+    { item: { key: "name", title: "模板名称" }, attr: {} },
+    { item: { key: "startTime", title: "开始日期" }, attr: {} },
+    { item: { key: "deadlineTime", title: "结束日期" }, attr: {} },
+    {
+      item: { key: "cycle", title: "周期" },
+      attr: { is: "el-dict-tag", dictName: "mk_periodic_unit" },
+    },
+    {
+      item: { key: "unfold", title: "按列展开" },
+      attr: { is: "el-dict-tag", dictName: "mk_expansion_mode" },
+    },
+    { item: { key: "createByName", title: "创建人" }, attr: {} },
+    { item: { key: "createTime", title: "创建时间" }, attr: {} },
+    { item: { key: "updateByName", title: "修改人" }, attr: {} },
+    { item: { key: "updateTime", title: "修改时间" }, attr: {} },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, fixed: false },
+  }));
+  const SearchColumns = [
+    { item: { key: "year", title: "年度",},attr: {
+      is: "el-date-picker",
+      type: "year",
+      valueFormat: "yyyy-MM-dd",
+    }, },
+    { item: { key: "name", title: "模板名称"},attr: { is: "el-input" }, },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+
+  return { TableColumns, SearchColumns };
+}

+ 94 - 0
src/views/business/spd/target/targetTemplate/delete/index.vue

@@ -0,0 +1,94 @@
+<script>
+import { delTargetTemplate,checkQuote, } from "@/api/business/spd/starget/targetTemplate";
+
+export default {
+  name: "DeleteDialog",
+  props: {
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+  },
+  data() {
+    return {
+      title: "删 除",
+    };
+  },
+  computed: {
+    disabled: {
+      get() {
+        const { selectData } = this;
+        if (selectData.length < 1) {
+          return true;
+        }
+        if (
+          selectData.length >= 1 &&
+          selectData.findIndex(({ status }) => status === "1") > -1
+        ) {
+          return true;
+        }
+        if (
+          selectData.length >= 1 &&
+          selectData.findIndex(({ status }) => status === "2") > -1
+        ) {
+          return true;
+        }
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {
+    //
+    open() {
+
+      this.$confirm(`是否删除数据项?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info",
+        beforeClose: async (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.confirmButtonText = "执行中...";
+            try {
+              // try
+              const { selectData } = this.$props;
+              const ids = selectData.map((item) => item.id).join(",");
+              const { msg, code } = await delTargetTemplate(ids);
+              if (code === 200) {
+                done();
+                this.$emit("success");
+                this.$notify.success(msg);
+              }
+            } catch (err) {
+              // catch
+              console.error(err);
+              instance.confirmButtonText = "确认";
+            } finally {
+              // finally
+              instance.confirmButtonLoading = false;
+            }
+          } else {
+            done();
+          }
+        },
+      })
+        .then(() => {})
+        .catch(() => {});
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
+  >
+    {{ title }}
+  </el-button>
+</template>

+ 14 - 0
src/views/business/spd/target/targetTemplate/dicts.js

@@ -0,0 +1,14 @@
+import { initDicts } from "@/utils/init.js";
+const modules = require.context("./", true, /columns.js$/);
+const columns = [];
+modules.keys().forEach((fileName) => {
+  const data = modules(fileName).default();
+  for (const key in data) {
+    if (key === "TabColumns") {
+      columns.push(...data[key].map((item) => item.TableColumns).flat());
+    } else {
+      columns.push(...data[key]);
+    }
+  }
+});
+export const dicts = initDicts(columns);

+ 158 - 0
src/views/business/spd/target/targetTemplate/index.vue

@@ -0,0 +1,158 @@
+<script>
+import { dicts } from "./dicts";
+import useColumns from "./columns";
+import { listTargetTemplate } from "@/api/business/spd/starget/targetTemplate";
+
+export default {
+  name: "targettemplate",
+  dicts: dicts,
+  components: {
+    SeeButton: () => import("./see/index.vue"),
+    AddButton: () => import("./add/index.vue"),
+    DeleButton: () => import("./delete/index.vue"),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElSuperSearch: () => import("@/components/super-search/index.vue"),
+  },
+  data() {
+    const { TableColumns, SearchColumns } = useColumns();
+    const params = this.$init.params(SearchColumns);
+    return {
+      size: "mini",
+      loading: false,
+      params: params,
+      tableData: [],
+      selectData: [],
+      SearchColumns: SearchColumns,
+      TableColumns: TableColumns,
+      page: { pageNum: 1, pageSize: 10, total: 0 },
+    };
+  },
+  created() {
+    console.log('this.$refs',this.$refs);
+    this.useQuery(this.params, this.page);
+  },
+  methods: {
+    async fetchList(prop, page) {
+      try {
+        this.loading = true;
+        const { code, rows, total } = await listTargetTemplate(
+          {...prop,...page}
+        );
+        if (code === 200) {
+          this.tableData = rows;
+          this.page.total = total;
+          console.log('this.tableData',this.tableData);
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    // 查 询
+    useQuery(prop, page) {
+      this.selectData = [];
+      this.fetchList(prop, page);
+    },
+    // 重 置
+    useReset() {
+      this.page.pageNum = 1;
+      this.page.pageSize = 10;
+      this.params = this.$init.params(this.SearchColumns);
+      this.useQuery(this.params, this.page);
+    },
+    // 选 择
+    useSelect(prop) {
+      this.selectData = prop;
+    },
+    // 明 细
+    async useSee(prop) {
+      const { open } = this.$refs.SeeButton;
+      await open([prop]);
+    },
+  },
+};
+</script>
+
+<template>
+  <el-card v-loading="loading" :body-style="{ padding: 0 }">
+    <el-super-search
+      v-model="params"
+      :size="size"
+      :dict="dict"
+      :columns="SearchColumns"
+      @reset="useReset"
+      @submit="useQuery(params, page)"
+    ></el-super-search>
+    <div style="margin: 0 0 20px 0; text-align: right">
+      <el-button-group>
+        <add-button
+          :size="size"
+          :select-data="[]"
+          :dict="dict"
+          add-type="add"
+          @success="useQuery(params, page)"
+        ></add-button>
+      </el-button-group>
+      <el-button-group>
+        <see-button
+          v-show="false"
+          :size="size"
+          :dict="dict"
+          :model="params"
+          :select-data="selectData"
+          ref="SeeButton"
+          @success="useQuery(params, page)"
+        ></see-button>
+        <add-button
+          :size="size"
+          :dict="dict"
+          :select-data="selectData"
+          add-type="edit"
+          @success="useQuery(params, page)"
+        ></add-button>
+        <dele-button
+          :size="size"
+          :select-data="selectData"
+          @success="useQuery(params, page)"
+        ></dele-button>
+      </el-button-group>
+    </div>
+    <el-super-table
+      v-model="tableData"
+      :size="size"
+      :dict="dict"
+      :columns="TableColumns"
+      stroage
+      hideOperationColumns
+      @row-dblclick="useSee"
+      @selection-change="useSelect"
+    >
+      <!-- <el-table-column fixed width="55" align="center" label="#" prop="$index">
+      </el-table-column> -->
+      
+      <el-table-column fixed width="55" align="center" type="selection">
+      </el-table-column>
+    </el-super-table>
+    <pagination
+      :total="page.total"
+      :page.sync="page.pageNum"
+      :limit.sync="page.pageSize"
+      @pagination="useQuery(params, page)"
+      style="height: 32px; margin: 20px 0 0 0; padding: 0 !important"
+    />
+  </el-card>
+</template>
+<style scoped lang="scss">
+.el-card {
+  width: calc(100% - 20px);
+  height: 100%;
+  margin: 10px;
+  padding: 20px;
+}
+.el-button-group + .el-button-group {
+  margin: 0 0 0 10px;
+}
+</style>

+ 110 - 0
src/views/business/spd/target/targetTemplate/see/columns.js

@@ -0,0 +1,110 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    {
+      item: { key: "year", title: "年度" },
+      attr: {},
+    },
+    {
+      item: { key: "name", title: "模板名称" },
+      attr: {},
+    },
+    {
+      item: { key: "startTime", title: "开始日期" },
+      attr: {},
+    },
+    {
+      item: { key: "deadlineTime", title: "结束日期" },
+      attr: {},
+    },
+    {
+      item: { key: "cycle", title: "周期" },
+      attr: {
+        is: "el-dict-tag",
+        dictName: "mk_periodic_unit",
+      },
+    },
+    {
+      item: { key: "unfold", title: "按列展开" },
+      attr: {
+        is: "el-dict-tag",
+        dictName: "mk_expansion_mode",
+      },
+    },
+    
+   
+  ];
+
+  const TabColumns = [
+    {
+      item: {
+        title: "指标",
+        key: "indexs",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "target", title: "指标" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "mk_index_type",
+          },
+        },
+      ],
+    },
+    {
+      item: {
+        title: "维度",
+        key: "dimensionalitys",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "dimensionality", title: "维度" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "mk_dimensionality",
+          },
+        },
+      ],
+    },
+    {
+      item: {
+        title: "周期",
+        key: "cycles",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "name", title: "周期名称", require: true },
+          attr: {},
+        },
+        {
+          item: {
+            key: "startTime",
+            title: "周期开始日期",
+            require: true,
+          },
+          attr: {},
+        },
+        {
+          item: {
+            key: "deadlineTime",
+            title: "周期结束日期",
+            require: true,
+          },
+          attr: {},
+        },
+      ],
+    },
+  ];
+
+  return { TableColumns, TabColumns };
+}

+ 170 - 0
src/views/business/spd/target/targetTemplate/see/index.vue

@@ -0,0 +1,170 @@
+<script>
+import useColumns from "./columns";
+import { getTargetTemplate } from "@/api/business/spd/starget/targetTemplate";
+
+export default {
+  name: "SeeDrawer",
+  components: {
+    ElSuperDescriptions: () =>
+      import("@/components/super-descriptions/index.vue"),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+  },
+  data() {
+    const {
+      TabColumns,
+      TableColumns,
+      TabColumns: [
+        {
+          item: { key: tabName },
+        },
+      ],
+    } = useColumns();
+    return {
+      width: "50%",
+      column: 2,
+      title: "明 细",
+      visible: false,
+      loading: false,
+      params: {},
+      tabName,
+      TabColumns: TabColumns,
+      TableColumns: TableColumns,
+    };
+  },
+  props: {
+    dict: {
+      type: Object,
+    },
+    model: {
+      type: Object,
+    },
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+  },
+  computed: {
+    disabled: {
+      get() {
+        const { selectData } = this;
+        if (selectData.length !== 1) {
+          return true;
+        }
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {
+    //
+    async fetchTemplate(id) {
+      try {
+        this.loading = true;
+        const { code, data } = await getTargetTemplate(id);
+        if (code === 200) {
+          this.params = data;
+          return true;
+        } else {
+          return false;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    //
+    async open(prop) {
+      this.visible = await this.fetchTemplate(prop[0].id);
+    },
+    //
+    async hide() {
+      const {
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
+      this.visible = false;
+      this.tabName = tabName;
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
+  >
+    {{ title }}
+    <el-drawer
+      :size="width"
+      :title="title"
+      :visible.sync="visible"
+      append-to-body
+      @close="hide(selectData)"
+    >
+      <div
+        style="
+          z-index: 6666;
+          position: fixed;
+          right: 20px;
+          top: 50%;
+          transform: translateY(-50%);
+          display: flex;
+          flex-direction: column;
+        "
+      >
+        <el-button
+          :size="$attrs.size"
+          :disabled="params.$index === 1"
+          circle
+          icon="el-icon-top"
+          @click="fetchItem(params.$index - 1)"
+          style="margin: 0 0 10px 0"
+        ></el-button>
+        <el-button
+          :size="$attrs.size"
+          :disabled="params.$index === params.$total"
+          circle
+          icon="el-icon-bottom"
+          @click="fetchItem(params.$index + 1)"
+          style="margin: 0"
+        ></el-button>
+      </div>
+      <el-super-descriptions
+        v-model="params"
+        :dict="dict"
+        :column="column"
+        :size="$attrs.size"
+        :columns="TableColumns"
+      >
+      </el-super-descriptions>
+      <el-tabs v-model="tabName" :size="$attrs.size" style="margin: 10px">
+        <el-tab-pane
+          v-for="({ item, TableColumns: columns }, index) in TabColumns"
+          :key="index"
+          :name="item.key"
+          :label="item.title"
+          lazy
+        >
+          <el-super-table
+            v-model="params[item.key]"
+            :size="$attrs.size"
+            :dict="dict"
+            :columns="columns"
+          >
+          </el-super-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+  </el-button>
+</template>

+ 604 - 0
src/views/business/spd/task_management/visitingPlan/add.vue

@@ -0,0 +1,604 @@
+<template>
+  <div id="addPlanList">
+    <el-card>
+      <span>基本信息</span>
+      <el-form :model="basicForm" :rules="basicRules" ref="basic" label-width="auto">
+        <el-row :gutter="10">
+          <el-col :span="1.5">
+              <el-form-item label="计划编码">
+                <el-input
+                  v-model="basicForm.planCode"
+                  size="mini"
+                  disabled
+                  style="width: 200px"
+                />
+              </el-form-item>
+          </el-col>
+
+          <el-col :span="1.5">
+            <el-form-item label="计划名称" prop="planName" :rules="{ required: true, message: '请填写名称', trigger: 'blur' }">
+              <el-input
+                v-model.trim="basicForm.planName"
+                size="mini"
+                :disabled="sonDisable"
+                clearable
+                style="width: 200px"
+              />
+            </el-form-item>
+         </el-col>
+
+         <el-col :span="1.5">
+            <el-form-item label="执行人" prop="chargerName">
+                <el-select clearable size="mini" v-model="basicForm.chargerName" :disabled="sonDisable" @focus="choose('CONTACTS_PARAM', true, '执行人')" style="width: 200px">
+                  <el-option v-for="item in personOptions" :key="item.id" :label="item.name" :value="item.code" />
+                </el-select>
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="1.5">
+            <el-form-item label="开始时间" prop="startDate" :rules="{ required: true, message: '请选择开始时间', trigger: 'blur' }">
+              <el-date-picker
+                v-model="basicForm.startDate"
+                :disabled="sonDisable"
+                clearable
+                type="date"
+                value-format="yyyy-MM-dd"
+                @change="changePlanDate"
+                size="mini"
+                style="width: 200px"
+              >
+              </el-date-picker>
+            </el-form-item>
+         </el-col>
+
+         <el-col :span="1.5">
+            <el-form-item label="截止时间" prop="deadlineTime" :rules="{ required: true, message: '请选择截止时间', trigger: 'blur' }">
+              <el-date-picker
+                v-model="basicForm.deadlineTime"
+                :disabled="sonDisable"
+                clearable
+                type="date"
+                value-format="yyyy-MM-dd"
+                @change="changePlanDate"
+                size="mini"
+                style="width: 200px"
+              >
+              </el-date-picker>
+            </el-form-item>
+         </el-col>
+
+         <el-col :span="1.5">
+            <el-form-item label="销售区域" prop="marketingAreaName">
+              <el-select clearable v-model="basicForm.marketingAreaName" size="mini" :disabled="sonDisable" @focus="choose('MK_SALESAREA_PARAM', true, '销售区域')" style="width: 200px">
+                <el-option
+                  v-for="item in deptOptions"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.code">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="1.5">
+            <el-form-item label="部门" prop="deptName">
+              <el-select clearable v-model="basicForm.deptName" size="mini" :disabled="sonDisable" @focus="choose('DEPT_PARAM', true, '部门')" style="width: 200px">
+                <el-option
+                  v-for="item in deptOptions"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.code">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="1.5">
+            <el-form-item label="确认状态" prop="state">
+              <el-select disabled v-model="basicForm.state" size="mini" style="width: 200px">
+                <el-option v-for="dict in dict.type.mk_plan_state" :key="dict.value" :label="dict.label" :value="dict.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <span>明细信息</span>
+        <div class="btn_grooup">
+          <el-button type="primary" size="mini" @click="addLine" v-if="!sonDisable">增行</el-button>
+        </div>
+
+        <el-table 
+          :data="basicForm.mkBoPlanItemList" 
+          fit
+          max-height="300"
+          style="font-size: 12px;"
+          @selection-change="handleSelectionChange"
+          :cell-class-name="cellClassName"
+        >
+        <el-table-column show-overflow-tooltip type="selection"/>
+        <el-table-column show-overflow-tooltip label="序号" type="index" align="center"/>
+        <el-table-column show-overflow-tooltip label="计划编号" prop="planCode" width="150"/>
+        <el-table-column show-overflow-tooltip label="日期"  prop="date" width="230px">
+          <template slot-scope="scope">
+            <el-form-item class="hang" :prop="'mkBoPlanItemList.' + scope.$index + '.' + 'date'" :rules="{ required: true, message: '请填写日期', trigger: 'blur' }">
+              <el-date-picker
+                v-model="scope.row.date"
+                :readonly="sonDisable"
+                clearable
+                type="date"
+                size="mini"
+                value-format="yyyy-MM-dd"
+                placeholder="选择日期">
+              </el-date-picker>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column show-overflow-tooltip label="客户名称" prop="customerName" min-width="230">
+          <template slot-scope="scope">
+            <el-form-item class="hang">
+              <el-select clearable size="mini" v-model="scope.row.customerName" :disabled="sonDisable" @focus="chooseSon(scope.$index, 'CUSTOMER_PARAM_ZT', true, '客户')" style="width: 200px">
+                <el-option v-for="item in customerOptions" :key="item.id" :label="item.name" :value="item.code" />
+              </el-select>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column show-overflow-tooltip label="联系人" prop="contactName" min-width="230">
+          <template slot-scope="scope">
+            <el-form-item class="hang">
+              <el-select clearable size="mini" v-model="scope.row.contactName" :disabled="sonDisable" @focus="chooseSon(scope.$index, 'LINKMAN_PARAM', true, '联系人', {})" style="width: 200px">
+                <el-option v-for="item in linkOptions" :key="item.id" :label="item.name" :value="item.code" />
+              </el-select>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column show-overflow-tooltip label="详细地址" prop="address" min-width="200">
+          <template slot-scope="scope">
+            <el-form-item class="hang">
+              <el-input clearable :readonly="sonDisable" size="mini" v-model="scope.row.address"/>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column show-overflow-tooltip label="拜访目的" prop="purpose" min-width="200">
+          <template slot-scope="scope">
+            <el-form-item class="hang">
+              <el-select clearable v-model="scope.row.purpose" size="mini">
+                <el-option v-for=" dict in dict.type.mk_bo_behavior_goal" :key="dict.value" :label="dict.label" :value="dict.value">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column show-overflow-tooltip label="商机" prop="boName" min-width="200"/>
+        <el-table-column show-overflow-tooltip label="营销活动" prop="marketingCampaign" min-width="200">
+          <template slot-scope="scope">
+            <el-form-item class="hang">
+              <el-input clearable :readonly="sonDisable" size="mini" v-model="scope.row.marketingCampaign"/>
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column
+            fixed="right"
+            label="操作"
+            align="center"
+            >
+          <template slot-scope="scope">
+            <el-button type="text" size="mini" :disabled="sonDisable" @click="delLine(scope.$index, scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+        </el-table>
+      </el-form>
+    </el-card>
+
+    <div class="btn_group">
+      <el-col :span="1.5">
+        <el-button type="primary" size="mini" plain @click="save" v-if="sonPageStu == 'add' || sonPageStu == 'edit'">保存</el-button>
+      </el-col>
+      <el-col :span="1.5" style="margin: 0 10px;">
+        <el-button type="primary" size="mini" plain @click="submit" v-if="sonPageStu == 'check' && (row.status == '0' || row.status == '3')">提交</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button size="mini" plain @click="back">返回</el-button>
+      </el-col>
+
+      <Refers ref="refer" @doSubmit="selectionsToInput" :single="true"/>
+
+      <!-- <popDialog ref="materialRefer" @doSubmit="selectMaterial" :single="true" /> -->
+
+    </div>
+  </div>
+</template>
+
+<script>
+import {addPlan, getPlanDetail, editPlan} from '@/api/business/spd/task_management/visitingPlan/visitingPlan.js'
+import Refers from '@/components/Refers/refers.vue'
+// 用于回显参照框数据
+import {getRefer} from '@/api/purchase/basic.js'
+// 明细行选择物料参照
+import popDialog from '@/components/PopDialog/index.vue'
+export default {
+  name: 'addPlanList',
+  props: ['pageStu','row', 'disable'],
+  dicts: ['mk_plan_state', 'mk_bo_behavior_goal'],
+  components: {
+    Refers,
+    popDialog
+  },
+  model: {
+    prop: 'isList',
+    event: 'jugislist'
+  },
+  data() {
+    return {
+      // 不能直接改变props传来的值
+      sonPageStu: this.pageStu,
+      sonDisable: this.disable,
+      dialog: {
+        config: false
+      },
+      basicForm: {
+        id: '',
+        planId: '',
+        planCode: '',
+        planName :'',
+        charger: '',
+        chargerName: '',
+        dept: '',
+        deptName: '',
+        startDate: '',
+        deadlineTime: '',
+        date: '',
+        marketingArea: '',
+        marketingAreaName: '',
+        state: '0',
+        customer: '',
+        customerName: '',
+        contact: '',
+        contactName: '',
+        address: '',
+        purpose: '',
+        bo: '',
+        boName: '',
+        marketingCampaign: '',
+        mkBoPlanItemList: []
+      },
+      delDemandItemList: [],
+      options: [{
+        value: 'Y', label: '是',
+      }, {
+        value: 'N', label: '否'
+      }],
+      basicRules: {},
+      tableList: [],
+      referCondition: {
+        type: '',
+        isPage: true,
+        title: '',
+      },
+      // referCondition: {
+      //   type: '',
+      //   isPage: true,
+      //   title: '',
+      // },
+      tableIndex: null,
+      ids: [],
+      linkOptions: [],
+      manOptions: [],
+      personOptions: [],
+      deptOptions: [],
+      customerOptions: [],
+      pickerOptionsEnd: {
+        disabledDate: (time) => {
+          return time.getTime() < Date.now() - 1 * 24 * 60 * 60 * 1000
+        }
+      },
+      isBDXQ: false,
+      isYl: false,
+    }
+  },
+  updated() {},
+  mounted() {},
+  created() {
+    if(this.pageStu == 'check') {
+      console.log('数据', this.row)
+      this.getDetails(this.row)
+    } else if(this.pageStu == 'edit') {
+      this.getDetails(this.row)
+    }
+  },
+  methods:{
+    // 改变单据日期时清空子表的日期
+    changePlanDate() {
+      this.basicForm.mkBoPlanItemList.forEach(item => {
+        item.deliveryDate = null
+      })
+    },
+    // 清空
+    cleanYLSL(scope) {
+      scope.row.reservedQty = ''
+      scope.row.reservedPeriod = ''
+    },
+    handleData() {
+      console.log('222')
+      // 复制新增把id,编码,创建人置为空,子表去掉id
+      this.basicForm.id = ''
+      this.basicForm.code = ''
+      this.basicForm.createBy = ''
+      this.basicForm.source = '4'
+      if (this.basicForm.mkBoPlanItemList.length !== 0) {
+        this.basicForm.mkBoPlanItemList.forEach(item => {
+          if (item.id) {
+            delete item.id
+          }
+          if (item.demandId) {
+            delete item.demandId
+          }
+          if (item.allotCode) {
+            delete item.allotCode
+          }
+        })
+      }
+    },
+    // 如果需要回显则调用详情接口
+    getDetails(row) {
+      getPlanDetail(row.id).then(res => {
+        if (res.code === 200) {
+          // console.log('res', res)
+          this.basicForm = res.data
+          for (let i = 0; i < this.basicForm.mkBoPlanItemList.length; i++) {
+            this.basicForm.mkBoPlanItemList[i].planCode = res.data.planCode
+          }
+          // console.log('this.basicForm.mkBoPlanItemList.planCode', this.basicForm.mkBoPlanItemList.planCode)
+        }
+      })
+    },
+    // getDetails(row) {
+    //   getPlanDetail(row.id).then(res => {
+    //     if (res.code === 200) {
+    //       // this.basicForm = res.data
+    //       console.log('res', res)
+    //       let reciveForm = res.data
+    //       let params = {...{id: row.id}, ...{pageNum:1, pageSize: 10}}
+    //       getPlanSonDetail(params.id).then(res => {
+    //         if (res.code === 200) {
+    //         reciveForm.mkBoPlanItemList = res.data
+    //         console.log('reciveForm',reciveForm)
+    //         this.basicForm = reciveForm
+    //         }
+    //       })
+    //     }
+    //   })
+    // },
+
+    async save() {
+      if(this.basicForm.mkBoPlanItemList.length !== 0) {
+        this.$refs['basic'].validate((valid) => {
+          if(valid) {
+            this.$modal.loading("保存中...");
+            if(this.sonPageStu == 'add') {
+              this.handleData()
+              addPlan(this.basicForm).then(res => {
+                console.log(333)
+                if (res.code === 200) {
+                  this.$modal.msgSuccess("保存成功");
+                  this.$modal.closeLoading();
+                  this.back()
+                }
+              }).catch(err => {
+                this.$modal.closeLoading();
+              })
+            } else if (this.sonPageStu == 'edit') {
+              let list = []
+              list.push(...this.basicForm.mkBoPlanItemList, ...this.delDemandItemList)
+              // 深拷贝一下参数对象
+              let param = JSON.parse(JSON.stringify(this.basicForm))
+              console.log('深拷贝对象',param);
+              param.mkBoPlanItemList = list
+              // this.basicForm.mkBoPlanItemList.push(...this.delDemandItemList)
+              editPlan(param).then(res => {
+                if (res.code === 200) {
+                  this.$modal.msgSuccess("编辑成功");
+                  this.$modal.closeLoading();
+                  this.back()
+                }
+              }).catch(err => {
+                this.$modal.closeLoading();
+              })
+            }
+          }
+        })
+      } else {
+        this.$modal.msgWarning("明细信息不能为空!");
+      }
+    },
+    submit() {
+      this.$modal.loading("提交中...");
+      submitDemand(this.basicForm).then(res => {
+        if (res.code === 200) {
+          this.$modal.msgSuccess("提交成功");
+          this.$modal.closeLoading();
+          this.back()
+        }
+      }).catch(err => {
+        this.$modal.closeLoading();
+      })
+    },
+    // 增行
+    addLine() {
+      const newLine = {
+        contacts: null,
+        id: null,
+        planId: null,
+        planCode: null,
+        date: null,
+        customer: null,
+        customerName: null,
+        contact: null,
+        contactName: null,
+        address: null,
+        purpose: null,
+        bo: null,
+        boName: null,
+        marketingCampaign: null,
+        tenantId: null,
+        revision: null,
+        createBy: null,
+        createByName: null,
+        createTime: null,
+        updateBy: null,
+        updateByName: null,
+        updateTime: null,
+        delFlag: 0,
+        // 新增字段
+        model: null,
+        storageCondition: null,
+        transportationCondition: null,
+      }
+      this.basicForm.mkBoPlanItemList.push(newLine)
+    },
+    delLine(index, row) {
+      console.log('删除行:', index)
+      console.log('改变行:', row)
+      // this.basicForm.mkBoPlanItemList = this.basicForm.mkBoPlanItemList.filter(item => {
+      //   return item.id !== row.id
+      // })
+      row.delFlag = '2'
+      // this.basicForm.mkBoPlanItemList.splice(index,1)
+      let delList = []
+      delList = this.basicForm.mkBoPlanItemList.filter(item => {
+        return item.delFlag == '2'
+      })
+      this.basicForm.mkBoPlanItemList = this.basicForm.mkBoPlanItemList.filter(item => {
+        return item.delFlag == '0'
+      })
+      this.delDemandItemList.push(...delList)
+      console.log('删除的数组',this.delDemandItemList)
+    },
+
+    back() {
+      this.$emit('jugislist', true)
+      // let queryParams = {
+      //   pageNum: 1,
+      //   pageSize: 10
+      // }
+      this.$emit('refresh')
+    },
+    // 单元格标红
+    cellClassName({row, column, rowIndex, columnIndex}) {
+      if(this.basicForm.isSpeical == 'N' && column.label == '需求可用周期' && Number(row.demandPeriod) > 1.5 && Number(row.demandPeriod) > Number(row.minOrderQty)) {
+        return 'success-row';
+      }
+    },
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item =>{
+        return item.id
+      })
+      console.log('选中数组', this.ids)
+    },
+    // 回显参照框
+    reBackRefer(type, id, title) {
+      getRefer({type: type, id: id}).then(res => {
+        if(type == 'LINKMAN_PARAM') {
+          this.linkOptions = res.rows
+        }
+        if (type == 'CUSTOMER_PARAM_ZT') {
+          this.customerOptions = res.rows
+        }
+        if (type == 'CONTACTS_PARAM') {
+          this.personOptions = res.rows
+        }
+        if (type == 'DEPT_PARAM') {
+          this.deptOptions = res.rows
+        }
+        if (type == 'MK_SALESAREA_PARAM') {
+          this.deptOptions = res.rows
+        }
+      })
+    },
+    // 基本信息选择参照带出数据
+    choose(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.refer.init(this.referCondition)
+    },
+    // 明细行选择参照带出数据
+    chooseSon(index, type, isPage, title, parame) {
+      this.tableIndex = index
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.parame = parame
+      this.$refs.refer.init(this.referCondition)
+    },
+    selectionsToInput(selection) {
+      if(this.referCondition.type == 'CUSTOMER_PARAM_ZT') {
+        this.customerOptions = selection
+        this.basicForm.mkBoPlanItemList[this.tableIndex].customer = selection[0].id
+        this.basicForm.mkBoPlanItemList[this.tableIndex].customerName = selection[0].name
+      }
+      if(this.referCondition.type == 'CONTACTS_PARAM') {
+        this.personOptions = selection
+        this.basicForm.charger = selection[0].id
+        this.basicForm.chargerName = selection[0].name
+      }
+      if(this.referCondition.type == 'MK_SALESAREA_PARAM') {
+        this.personOptions = selection
+        this.basicForm.marketingArea = selection[0].id
+        this.basicForm.marketingAreaName = selection[0].name
+      }
+      if(this.referCondition.type == 'DEPT_PARAM') {
+        this.deptOptions = selection
+        this.basicForm.dept = selection[0].id
+        this.basicForm.deptName = selection[0].name
+      }
+      if(this.referCondition.type == 'LINKMAN_PARAM') {
+        this.linkOptions = selection
+        this.basicForm.mkBoPlanItemList[this.tableIndex].contact = selection[0].id
+        this.basicForm.mkBoPlanItemList[this.tableIndex].contactName = selection[0].name
+      }
+    },
+    // tableRowClassName({ row, rowIndex }) {
+    //   row.index = rowIndex;
+    // },
+    // rowClick(row){
+    //   this.tableIndex = row.index;
+    //   console.log("row.index",row.index);
+    // }
+  }
+}
+
+</script>
+
+<style lang="scss" scoped>
+.btn_group {
+  width: 100%;
+  margin: 20px 0;
+  display: flex;
+  justify-content: center;
+} 
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+.hang {
+  margin: auto;
+}
+.hang ::v-deep .el-form-item__content{
+  margin-left: 0px !important;
+}
+.el-table ::v-deep .el-form-item__error{
+  padding-top: 0;
+  top: 70%
+}
+.el-table ::v-deep .success-row {
+  background: #f11616;
+}
+</style>

+ 658 - 0
src/views/business/spd/task_management/visitingPlan/index.vue

@@ -0,0 +1,658 @@
+<template>
+  <div id="PlanList">
+    <div v-if="isList">
+      <el-card>
+        <el-form class="search_area" label-width="100px">
+          <el-row :gutter="10">
+            <el-col :span="1.5">
+              <el-form-item label="计划编码">
+                <el-input
+                  v-model.trim="queryParams.planCode"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="1.5">
+              <el-form-item label="计划名称">
+                <el-input
+                  v-model.trim="queryParams.planName"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+              </el-form-item>
+            </el-col>
+            <!-- <el-col :span="1.5">
+              <el-form-item label="线路类型">
+                <el-select clearable size="mini" v-model="queryParams.type" @focus="chooseOrg('CONTACTS_PARAM', true, '线路类型')" style="width: 200px">
+                  <el-option v-for="item in typeOptions" :key="item.id" :label="item.name" :value="item.code" />
+                </el-select>
+              </el-form-item>
+            </el-col> -->
+            <el-col :span="1.5">
+              <el-form-item label="执行人">
+              <el-select clearable size="mini" v-model="queryParams.chargerName" @focus="chooseOrg('CONTACTS_PARAM', true, '执行人')" style="width: 200px">
+                <el-option v-for="item in personOptions" :key="item.id" :label="item.name" :value="item.code" />
+              </el-select>
+              </el-form-item>
+            </el-col>
+                            
+            <el-col :span="1.5">
+              <el-form-item label="确认状态">
+                <el-select clearable v-model="queryParams.state" size="mini" style="width: 200px">
+                  <el-option v-for=" dict in dict.type.mk_plan_state" :key="dict.value" :label="dict.label" :value="dict.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="1.5">
+              <el-form-item label="" label-width="20px">
+              <el-button type="primary" size="mini" icon="el-icon-search" plain @click="searchList">搜索</el-button>
+              <el-button size="mini" icon="el-icon-refresh" plain @click="resetList">重置</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <CollapseTransition>
+            <div v-show="expanded">
+              <el-row :gutter="10">
+                <el-col :span="1.5">
+                  <el-form-item label="开始时间">
+                    <el-date-picker
+                    v-model="queryParams.startDate"
+                    type="date"
+                    clearable
+                    value-format="yyyy-MM-dd"
+                    size="mini"
+                    style="width: 200px"
+                    >
+                    </el-date-picker>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-form-item label="截止时间">
+                    <el-date-picker
+                    v-model="queryParams.deadlineTime"
+                    type="date"
+                    clearable
+                    value-format="yyyy-MM-dd"
+                    size="mini"
+                    style="width: 200px"
+                    >
+                    </el-date-picker>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-form-item label="销售区域">
+                    <el-select clearable v-model="queryParams.marketingAreaName" size="mini" @focus="chooseOrg('DEPT_PARAM', true, '销售区域')" style="width: 200px">
+                      <el-option
+                        v-for="item in deptOptions"
+                        :key="item.id"
+                        :label="item.name"
+                        :value="item.id">
+                      </el-option>
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-form-item label="部门">
+                    <el-select clearable v-model="queryParams.deptName" size="mini" @focus="chooseOrg('DEPT_PARAM', true, '部门')" style="width: 200px">
+                      <el-option
+                        v-for="item in deptOptions"
+                        :key="item.id"
+                        :label="item.name"
+                        :value="item.id">
+                      </el-option>
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </div>
+          </CollapseTransition>
+        </el-form>
+
+        <el-divider class="lines"><i style="cursor: pointer;" :class="expanded?'el-icon-arrow-up':'el-icon-arrow-down'" @click="drop"></i></el-divider>
+  
+        <div class="btn_grooup">
+          <el-button type="primary" size="mini" @click="addDivision">新增</el-button>
+
+          <!-- <el-dropdown size="mini" @command="handleCommand">
+            <el-button size="mini" type="primary" style="margin-left: 10px;">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="数据导入">数据导入</el-dropdown-item>
+            <el-dropdown-item command="模板下载">模板下载</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown> -->
+
+          <el-dropdown size="mini" @command="handleExport">
+            <el-button size="mini" type="primary" style="margin: 0 10px;">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="选中导出">选中导出</el-dropdown-item>
+            <el-dropdown-item command="全部导出">全部导出</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+
+          <el-button type="primary" size="mini" @click="delItems">删除</el-button>
+          <!-- <el-button type="primary" size="mini">打印</el-button> -->
+        </div>
+
+        <el-table 
+        :data="tableList" 
+        fit
+        max-height="550"
+        style="font-size: 12px;"
+        @selection-change="handleSelectionChange"
+        >
+          <el-table-column show-overflow-tooltip type="selection" width="55" />
+          <el-table-column show-overflow-tooltip label="计划编码" align="center" min-width="200" prop="planCode"/>
+          <el-table-column show-overflow-tooltip label="计划名称" align="center" min-width="150" prop="planName"/>
+          <el-table-column show-overflow-tooltip label="执行人" align="center" min-width="150" prop="chargerName"/>
+          <el-table-column show-overflow-tooltip label="部门" align="center" min-width="150" prop="deptName"/>
+          <el-table-column show-overflow-tooltip label="开始时间" align="center" min-width="120" prop="startDate" />
+          <el-table-column show-overflow-tooltip label="截止时间" align="center" min-width="120" prop="deadlineTime" />
+          <el-table-column show-overflow-tooltip label="单据状态" align="center" min-width="120" prop="state" :formatter="formatterStatus"/>
+          <el-table-column
+          fixed="right"
+          label="操作"
+          align="center"
+          width="180"
+          >
+            <template slot-scope="scope">
+              <el-button type="text" size="mini" @click="check(scope.row)">查看</el-button>
+              <el-button type="text" size="mini" v-if="scope.row.state == '0'" @click="edit(scope.row)">编辑</el-button>
+              <el-button type="text" size="mini" v-if="scope.row.state == '0'" @click="commit(scope.row)">提交</el-button>
+              <el-button type="text" size="mini" @click="deleteids(scope.row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <el-pagination
+        background
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="queryParams.pageNum"
+        :page-sizes="[10, 15, 20]"
+        :page-size="100"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total=total>
+        </el-pagination>
+      </el-card>
+    </div>
+
+    <!-- 用户导入对话框 -->
+    <el-dialog title="数据导入" :visible.sync="upload.open" width="400px">
+      <el-upload
+      ref="upload"
+      :limit="1"
+      accept=".xlsx, .xls"
+      :headers="upload.headers"
+      :action="upload.url + '?updateSupport=' + upload.updateSupport"
+      :disabled="upload.isUploading"
+      :on-progress="handleFileUploadProgress"
+      :on-success="handleFileSuccess"
+      :on-error="errorFile"
+      :auto-upload="false"
+      drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <!-- <div class="el-upload__tip" slot="tip">
+          <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
+        </div> -->
+        <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button size="mini" type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button size="mini" @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 模板下载新增参数 -->
+    <el-dialog title="需求模板下载" :visible.sync="download.open" @close="clearDownload" width="400px">
+
+    <el-row style="margin-bottom: 20px;">
+      <span style="margin-right: 10px;">需求客户</span>
+      <el-select clearable size="mini" v-model="download.customer" @clear="download.customer = ''" @focus="chooseOrg('CUSTOMER_PARAM', true, '选择客户')">
+       <el-option v-for="item in mBcustomer" :key="item.id" :label="item.name" :value="item.code" />
+      </el-select>
+    </el-row>
+
+    <!-- <el-row style="margin-bottom: 20px;">
+      <span style="margin-right: 10px;">供应仓库</span>
+      <el-select clearable size="mini" v-model="download.warehouse" @clear="cleanMb" @focus="chooseOrg('WAREHOUSE_PARAM', true, '选择仓库')">
+        <el-option v-for="item in mBwarehouse" :key="item.id" :label="item.name" :value="item.code" />
+      </el-select>
+    </el-row> -->
+
+    <el-row style="margin-bottom: 20px;">
+      <span style="margin-right: 10px;">供应货位</span>
+      <el-select clearable size="mini" v-model="download.cargoSpace" @clear="download.cargoSpace = ''" @focus="mbHuowei('ALLOCATION_PARAM', true, '选择货位', download.warehouseId)">
+        <el-option v-for="item in mBcargoSpace" :key="item.id" :label="item.name" :value="item.code" />
+      </el-select>
+    </el-row>
+
+    <el-row style="margin-bottom: 20px;">
+      <span style="margin-right: 10px;">品类选择</span>
+      <el-select
+      v-model="download.category"
+      size="mini"
+      clearable
+      @focus="chooseTreeRefer('MATERIALCLASSIFY_PARAM', false, '选择品类')"
+      >
+       <el-option v-for="item in classOptions" :key="item.id" :label="item.name" :value="item.code" />
+      </el-select>
+    </el-row>
+
+    <div slot="footer" class="dialog-footer">
+      <el-button size="mini" type="primary" @click="mbDownload">模板下载</el-button>
+      <el-button size="mini" @click="download.open = false">取 消</el-button>
+    </div>
+    </el-dialog>
+
+    <Add v-model="isList" v-if="!isList" :pageStu="page" :disable="disable" :row="rowDetail" @refresh="searchList"/>
+
+    <Refers ref="refer" @doSubmit="selectionsToInput" :single="true"/>
+
+    <TreeRefers ref="tree" @doSubmit="selectionsToInput2" :single="true"/>
+  </div>
+</template>
+
+<script>
+// 导入的token
+import { getToken } from "@/utils/auth";
+import Add from './add.vue'
+import Refers from '@/components/Refers/refers.vue'
+import TreeRefers from '@/components/Refers/treeRefer.vue'
+import CollapseTransition from '@/components/MyCollapse/collapse.vue'
+import {getPlanList, delPlan, downLoadDemand, exportPlan, submitPlan } from '@/api/business/spd/task_management/visitingPlan/visitingPlan.js'
+export default {
+  name: 'PlanLise',
+  components: {
+    Add,
+    CollapseTransition,
+    Refers,
+    TreeRefers
+  },
+  dicts: ['mk_plan_state'],
+  data() {
+    return {
+      // 导入参数
+      upload: {
+        // 是否显示弹出层(导入)
+        open: false,
+        // 弹出层标题(导入)
+        title: "数据导入",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 1,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/pu/demand/import"
+      },
+      // 模板下载参数
+      download: {
+        open: false,
+        customer: '',
+        warehouse: '',
+        warehouseId: '',
+        cargoSpace: '',
+        category: ''
+      },
+      mBcustomer: [],
+      mBwarehouse: [],
+      mBcargoSpace: [],
+      classOptions: [],
+      // 下拉收起配置
+      expanded: false,
+      // 页面配置
+      isList: true,
+      // 页面状态
+      page: '',
+      queryParams: {
+        planCode: '',
+        planName: '',
+        charger: '',
+        chargerName: '',
+        dept: '',
+        deptName: '',
+        startDate: '',
+        deadlineTime: '',
+        type: '',
+        state: '',
+        marketingArea: '',
+        marketingAreaName: '',
+        pageNum: 1,
+        pageSize: 10
+      },
+      referCondition: {
+        type: '',
+        isPage: true,
+        title: ''
+      },
+      options: [{
+        value: 'Y', label: '是',
+      }, {
+        value: 'N', label: '否'
+      }],
+      customerOptions: [],
+      personOptions: [],
+      deptOptions: [],
+      tableList: [],
+      total: 0,
+      rowDetail: {},
+      disable: false,
+      ids: []
+    }
+  },
+  created() {
+    this.getList(this.queryParams)
+  },
+  methods: {
+    // 格式化表格内容
+    formatterStatus(row) {
+      switch(row.state){
+        case '0':
+          return '未确认'
+        case '1':
+          return '已确认'
+        case '2':
+          return '作废'
+      }
+    },
+    searchList() {
+      this.getList(this.queryParams)
+    },
+    resetList() {
+      this.queryParams = {
+        planCode: '',
+        planName: '',
+        charger: '',
+        chargerName: '',
+        dept: '',
+        deptName: '',
+        startDate: '',
+        deadlineTime: '',
+        type: '',
+        state: '',
+        marketingArea: '',
+        marketingAreaName: '',
+        pageNum: 1,
+        pageSize: 10
+      }
+      this.getList(this.queryParams)
+    },
+    getList(params){
+      getPlanList(params).then(res => {
+        if (res.code === 200) {
+          this.tableList = res.rows
+          this.total = res.total
+          console.log(res, 'res-------')
+        }
+      })
+    },
+    handleSelectionChange(selection) {
+      console.log('选中', selection)
+      this.ids = selection.map(item => item.id)
+      console.log('选中数组', this.ids.join())
+    },
+    mbDownload() {
+      downLoadDemand(this.download).then(res => {
+        console.log('下载的文件流', res)
+        const blob = new Blob([res], {
+          type: "application/vnd.ms-excel;charset=UTF-8",
+        });// 创建一个类文件对象:Blob对象表示一个不可变的、原始数据的类文件对象
+        const downloadElement = document.createElement("a"); //创建a标签
+        const href = window.URL.createObjectURL(blob); // 创建下载的链接
+        // var temp = res.headers["content-disposition"]; 
+        // var fileName = decodeURIComponent(temp.split("filename=")[1]); // 中文需要转码 (前端乱码)
+        // var name = fileName.split(";")[0]; //切割成文件名
+        downloadElement.href = href;  //下载地址
+        downloadElement.download = '模板'; // 下载后文件名
+        document.body.appendChild(downloadElement);
+        downloadElement.click(); // 点击下载
+        document.body.removeChild(downloadElement); // 下载完成移除元素
+        window.URL.revokeObjectURL(href); // 释放blob对象
+        this.download.open = false
+      })
+    },
+    // 关闭模板下载弹窗清空参数
+    clearDownload() {
+      // 模板下载参数
+      this.download =  {
+        open: false,
+        customer: '',
+        warehouse: '',
+        warehouseId: '',
+        cargoSpace: '',
+        category: ''
+      }
+    },
+    handleCommand(command) {
+      // alert(command)
+      if(command == '模板下载') {
+        this.download.open = true
+      }
+      if (command == '数据导入') {
+        this.upload.title = "用户导入"
+        this.upload.open = true
+      }
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
+      this.getList(this.queryParams);
+    },
+    errorFile(err) {
+      this.$modal.notifyError("文件已变动,请重新上传");
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit();
+    },
+    handleExport(command) {
+      if(command == '选中导出') {
+        if (this.ids.length == 0) {
+          this.$modal.msgWarning("请选中至少一条数据");
+        } else {
+          let param = {all: false, ids: this.ids}
+          exportPlan(param).then(res => {
+            const blob = new Blob([res], {
+              type: "application/vnd.ms-excel;charset=UTF-8",
+            });// 创建一个类文件对象:Blob对象表示一个不可变的、原始数据的类文件对象
+            const downloadElement = document.createElement("a"); //创建a标签
+            const href = window.URL.createObjectURL(blob); // 创建下载的链接
+            // var temp = res.headers["content-disposition"]; 
+            // var fileName = decodeURIComponent(temp.split("filename=")[1]); // 中文需要转码 (前端乱码)
+            // var name = fileName.split(";")[0]; //切割成文件名
+            downloadElement.href = href;  //下载地址
+            downloadElement.download = '选中导出'; // 下载后文件名
+            document.body.appendChild(downloadElement);
+            downloadElement.click(); // 点击下载
+            document.body.removeChild(downloadElement); // 下载完成移除元素
+            window.URL.revokeObjectURL(href); // 释放blob对象
+          })
+        }
+      } else {
+        let param2 = {all: true}
+        exportPlan(param2).then(res => {
+          const blob = new Blob([res], {
+            type: "application/vnd.ms-excel;charset=UTF-8",
+          });// 创建一个类文件对象:Blob对象表示一个不可变的、原始数据的类文件对象
+          const downloadElement = document.createElement("a"); //创建a标签
+          const href = window.URL.createObjectURL(blob); // 创建下载的链接
+          // var temp = res.headers["content-disposition"]; 
+          // var fileName = decodeURIComponent(temp.split("filename=")[1]); // 中文需要转码 (前端乱码)
+          // var name = fileName.split(";")[0]; //切割成文件名
+          downloadElement.href = href;  //下载地址
+          downloadElement.download = '全部导出'; // 下载后文件名
+          document.body.appendChild(downloadElement);
+          downloadElement.click(); // 点击下载
+          document.body.removeChild(downloadElement); // 下载完成移除元素
+          window.URL.revokeObjectURL(href); // 释放blob对象
+        })
+      }
+    },
+    addDivision() {
+      this.isList = false
+      this.page = 'add'
+      this.disable = false
+    },
+    check(row) {
+      this.isList = false
+      this.page = 'check'
+      this.rowDetail = row
+      this.disable = true
+    },
+    edit(row) {
+      this.isList = false
+      this.page = 'edit'
+      this.rowDetail = row
+      this.disable = false
+    },
+    commit(row) {
+      console.log('row', row)
+      this.$modal.loading("提交中...");
+      submitPlan(row).then(res => {
+        if (res.code === 200) {
+          this.$modal.msgSuccess("提交成功");
+          this.$modal.closeLoading();
+          this.getList(this.queryParams)
+        }
+      }).catch(err => {
+        this.$modal.closeLoading();
+      })
+    },
+    // 行内删除
+    deleteids(row) {
+      console.log('row', row)
+      this.$modal.confirm('确定删除选择数据?').then(() => {
+        delPlan(row.id).then(res => {
+          if (res.code === 200) {
+            this.$modal.msgSuccess("删除成功");
+            this.getList(this.queryParams)
+          }
+        })
+      }).catch(() => {})
+    },
+    // 批量删除按钮
+    delItems() {
+      if(this.ids.length == 0) {
+        this.$modal.msgWarning("请选中至少一条数据");
+      } else {
+        let param = this.ids.join()
+        this.$modal.confirm('确认信息').then(() => {
+        delPlan(param).then(res => {
+          if (res.code === 200) {
+            this.$modal.msgSuccess("删除成功");
+            this.getList(this.queryParams)
+          }
+        })
+        }).catch(() => {})
+      }
+    },
+    handleSizeChange(val) {
+      console.log(`每页 ${val} 条`);
+      this.queryParams.pageSize = val
+      this.getList(this.queryParams)
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      this.queryParams.pageNum = val
+      this.getList(this.queryParams)
+    },
+    drop() {
+      this.expanded = !this.expanded
+    },
+    // 搜索区参照选择
+    chooseOrg(type, isPage, title, stordocId) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.referCondition.stordocId = stordocId
+      this.$refs.refer.init(this.referCondition)
+    },
+    selectionsToInput(selection) {
+      // 搜索区选择客户
+      if (this.referCondition.type == 'CUSTOMER_PARAM' && this.referCondition.title == '需求客户') {
+        this.customerOptions = selection
+        this.queryParams.customer = selection[0].id
+      }
+      // 模板内选择客户
+      if (this.referCondition.type == 'CUSTOMER_PARAM' && this.referCondition.title == '选择客户') {
+        this.mBcustomer = selection
+        this.download.customer = selection[0].code
+      }
+      // 模板内选择仓库
+      if (this.referCondition.type == 'WAREHOUSE_PARAM' && this.referCondition.title == '选择仓库') {
+        this.mBwarehouse = selection
+        this.download.warehouse = selection[0].code
+        this.download.warehouseId = selection[0].id
+      }
+      // 模板内选择货位
+      if (this.referCondition.type == 'ALLOCATION_PARAM' && this.referCondition.title == '选择货位') {
+        this.mBcargoSpace = selection
+        this.download.cargoSpace = selection[0].code
+      }
+      if (this.referCondition.type == 'CONTACTS_PARAM') {
+        this.personOptions = selection
+        this.queryParams.charger = selection[0].name
+        this.queryParams.chargerName = selection[0].name
+      }
+      if (this.referCondition.type == 'DEPT_PARAM') {
+        this.deptOptions = selection
+        this.queryParams.demandDept = selection[0].id
+      }
+    },
+    // 搜索区树形选择
+    chooseTreeRefer(type, isPage, title) {
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.tree.init(this.referCondition)
+    },
+    selectionsToInput2(selection) {
+      this.classOptions.push(selection)
+      this.download.category = selection.code
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+#PlanLise {
+  height: calc(100vh - 84px);
+  padding: 12px;
+  box-sizing: border-box;
+  overflow-y: scroll;
+}
+.btn_grooup {
+  margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+.lines {
+  margin-top: 0;
+}
+.el-pagination {
+  margin-top: 10px;
+  text-align: right;
+}
+</style>

+ 3 - 3
vue.config.js

@@ -45,9 +45,9 @@ module.exports = {
         // target: `http://172.16.13.152:8000/drp-admin`, //豪哥本地
         // target: `http://172.16.13.47:8000/drp-admin`, //这是一个美女的本地
         // target: `http://172.16.13.113:8000/drp-admin`, //DWT本地
-        // target: `http://172.16.13.21:8000/drp-admin`, //DWT本地
-
-        //  target: `http://127.0.0.1:8000/drp-admin`,
+        // target: `http://172.16.13.21:8000/drp-admin`, //CKF本地
+        // target: `http://172.16.13.43:8000/drp-admin`, //lz's localhost
+         // target: `http://127.0.0.1:8000/drp-admin`,
         changeOrigin: true,
         pathRewrite: {
           ["^" + process.env.VUE_APP_BASE_API]: "",