浏览代码

Merge branch 'purchaseDev' of http://172.16.100.139/new-business/drp-web into purchaseDev

002201 1 年之前
父节点
当前提交
47cdb23f48
共有 74 个文件被更改,包括 12157 次插入1736 次删除
  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. 8 0
      src/api/changeApply/basic.js
  18. 2 1
      src/assets/styles/sidebar.scss
  19. 15 0
      src/components/popover-select/components/CUSTOMER_PARAM_ZT.js
  20. 9 0
      src/components/popover-select/components/LINKMAN_PARAM.js
  21. 15 0
      src/components/popover-select/components/MANUFACTURER_PARAM.js
  22. 48 0
      src/components/popover-select/components/MATERIAL_PARAM.js
  23. 15 0
      src/components/popover-select/components/MK_SALESAREA_PARAM.js
  24. 9 0
      src/components/popover-select/components/MK_TARGET_CYCLE_PARAM.js
  25. 9 0
      src/components/popover-select/components/MK_TARGET_INDEX_PARAM.js
  26. 9 0
      src/components/popover-select/components/MK_TARGET_TEMPLATE_PARAM.js
  27. 2 2
      src/components/popover-tree-select/index.vue
  28. 2 0
      src/components/super-table/index.vue
  29. 2 1
      src/layout/index.vue
  30. 1 1
      src/utils/request.js
  31. 5 5
      src/views/business/spd/bo/basic/process.vue
  32. 19 108
      src/views/business/spd/bo/behavior/behaviorList.vue
  33. 254 78
      src/views/business/spd/bo/behavior/index.vue
  34. 18 51
      src/views/business/spd/bo/contact/contactList.vue
  35. 363 247
      src/views/business/spd/bo/contact/index.vue
  36. 937 0
      src/views/business/spd/goal_management/AnnualSaleGoal.vue
  37. 1324 0
      src/views/business/spd/goal_management/AnnualSaleGoalMerge.vue
  38. 1105 0
      src/views/business/spd/goal_management/MonthGoalMerge.vue
  39. 752 0
      src/views/business/spd/goal_management/MonthReturnGoal.vue
  40. 807 0
      src/views/business/spd/goal_management/MonthReturnMerge.vue
  41. 864 0
      src/views/business/spd/goal_management/MonthSaleGoal.vue
  42. 254 0
      src/views/business/spd/target/targetMk/add.vue
  43. 284 0
      src/views/business/spd/target/targetMk/index.vue
  44. 177 0
      src/views/business/spd/target/targetMk/item.vue
  45. 131 0
      src/views/business/spd/target/targetTemplate/add/columns.js
  46. 350 0
      src/views/business/spd/target/targetTemplate/add/index.vue
  47. 38 0
      src/views/business/spd/target/targetTemplate/columns.js
  48. 94 0
      src/views/business/spd/target/targetTemplate/delete/index.vue
  49. 14 0
      src/views/business/spd/target/targetTemplate/dicts.js
  50. 158 0
      src/views/business/spd/target/targetTemplate/index.vue
  51. 110 0
      src/views/business/spd/target/targetTemplate/see/columns.js
  52. 170 0
      src/views/business/spd/target/targetTemplate/see/index.vue
  53. 604 0
      src/views/business/spd/task_management/visitingPlan/add.vue
  54. 658 0
      src/views/business/spd/task_management/visitingPlan/index.vue
  55. 0 825
      src/views/material/changeApply/add.vue
  56. 399 0
      src/views/material/changeApply/add/column.js
  57. 432 0
      src/views/material/changeApply/add/index.vue
  58. 7 0
      src/views/material/changeApply/amendantRecord/column.js
  59. 102 0
      src/views/material/changeApply/amendantRecord/index.vue
  60. 128 0
      src/views/material/changeApply/batchImport/index.vue
  61. 77 0
      src/views/material/changeApply/columns.js
  62. 15 0
      src/views/material/changeApply/dicts.js
  63. 142 239
      src/views/material/changeApply/index.vue
  64. 289 0
      src/views/material/changeApply/see/index.vue
  65. 6 5
      src/views/purchase/DemandSummary/add.vue
  66. 4 4
      src/views/purchase/DemandSummary/index.vue
  67. 6 5
      src/views/purchase/MaterialClassDivision/index.vue
  68. 130 120
      src/views/purchase/PurchaseDemandList/add.vue
  69. 2 4
      src/views/purchase/PurchaseDemandList/index.vue
  70. 6 5
      src/views/purchase/deliveryAddress/index.vue
  71. 26 16
      src/views/purchase/purchase-order/index.vue
  72. 9 12
      src/views/purchase/transferOrder/add.vue
  73. 5 4
      src/views/purchase/transferOrder/index.vue
  74. 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'
+    })
+  }

+ 8 - 0
src/api/changeApply/basic.js

@@ -62,3 +62,11 @@ export function getProductFactory(data) {
     data: data
   })
 }
+// 获取生产厂家列表信息
+export function getRecordList(params) {
+  return request({
+    url: `/material/record/list`,
+    method: 'get',
+    params: params
+  })
+}

+ 2 - 1
src/assets/styles/sidebar.scss

@@ -4,7 +4,7 @@
     min-height: 100%;
     transition: margin-left .28s;
     margin-left: $base-sidebar-width;
-    margin-left: 0;
+    // margin-left: 0;
     position: relative;
   }
 
@@ -110,6 +110,7 @@
 
   .hideSidebar {
     .sidebar-container {
+      // display: none;
       width: 54px !important;
     }
 

+ 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/MANUFACTURER_PARAM.js

@@ -0,0 +1,15 @@
+// 生产厂家
+export default [
+  {
+    key: "code",
+    title: "编码",
+    type: "Input",
+    search: true,
+  },
+  {
+    key: "name",
+    title: "名称",
+    type: "Input",
+    search: true,
+  },
+];

+ 48 - 0
src/components/popover-select/components/MATERIAL_PARAM.js

@@ -45,4 +45,52 @@ export default [
       return prop.materialMedcine.isDrug == "0" ? "Y" : "N";
     },
   },
+  {
+    key: "isDrugNumber",
+    title: "药品",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.isDrug;
+    },
+  },
+  {
+    key: "oriRegistrationNo",
+    title: "注册证号/备案凭证编号",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.oriRegistrationNo;
+    },
+  },
+  {
+    key: "dosageFrom",
+    title: "剂型",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.dosageFrom;
+    },
+  },
+  {
+    key: "dosageFromName",
+    title: "剂型名称",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.dosageFromName;
+    },
+  },
+  {
+    key: "curingType",
+    title: "养护类型",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.curingType;
+    },
+  },
+  {
+    key: "medicalInstruments",
+    title: "医疗器械",
+    type: "ComputedInput",
+    formatter: (prop) => {
+      return prop.materialMedcine.medicalInstruments;
+    },
+  },
 ];

+ 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,
+  },
+];

+ 2 - 2
src/components/popover-tree-select/index.vue

@@ -154,9 +154,9 @@ export default {
         $props: { source, valueKey, dataMapping },
       } = this;
       for (let key in dataMapping) {
-        source[key] = prop[dataMapping[key]];
+        source[key] = prop[0][dataMapping[key]];
       }
-      this.innerValue = prop[valueKey];
+      this.innerValue = prop[0][valueKey];
       this.$emit("update:source", source);
       this.$emit("change", prop, this.$props);
     },

+ 2 - 0
src/components/super-table/index.vue

@@ -62,6 +62,8 @@ export default {
     ElPopoverMultipleSelectV2: () =>
       import("@/components/popover-select-v2/multiple.vue"),
     ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/index.vue"),
     ButtonHide: () => import("./hide.vue"),
     ButtonFreeze: () => import("./freeze.vue"),
     IconHide: () => import("./once/hide.vue"),

+ 2 - 1
src/layout/index.vue

@@ -10,10 +10,11 @@
         class="drawer-bg"
         @click="handleClickOutside"
       />
-      <sidebar v-if="!sidebar.hide" class="sidebar-container" />
+      <sidebar v-if="dev" class="sidebar-container" />
       <div
         :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }"
         class="main-container"
+        :style="`margin-left:${dev ? '54':'0'}px`"
       >
         <div :class="{ 'fixed-header': fixedHeader }">
           <!-- <navbar /> -->

+ 1 - 1
src/utils/request.js

@@ -17,7 +17,7 @@ const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分
   baseURL: process.env.VUE_APP_BASE_API,
   // 超时
-  timeout: 10000,
+  timeout: 300000,
 });
 
 // request拦截器

+ 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>

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

@@ -0,0 +1,937 @@
+<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"
+        >新增
+        </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>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-grape"
+          size="mini"
+          :disabled="multiple"
+        >提交
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="primary" size="mini" plain icon="el-icon-upload">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+            <el-dropdown-item command="import">导入</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="warning" plain icon="el-icon-download" size="mini">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="export">导出</el-dropdown-item>
+            <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </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)"
+          >修改
+          </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-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`)
+    },
+    handleExportDetails() {
+      this.download('goal_management/annualSaleGoalDetails/export', {
+        ...this.queryParams
+      }, `annualSaleGoalMerge_${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
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      }
+    }
+  }
+};
+</script>

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

@@ -0,0 +1,1324 @@
+<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"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-grape"
+          size="mini"
+          :disabled="multiple"
+        >提交
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="primary" size="mini" plain icon="el-icon-upload">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+            <el-dropdown-item command="import">导入</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="warning" plain icon="el-icon-download" size="mini">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="export">导出</el-dropdown-item>
+            <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+            <el-dropdown-item command="exportZoneSum">导出区域目标汇总</el-dropdown-item>
+            <el-dropdown-item command="exportCustomSum">导出客户目标汇总</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </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)"
+          >修改
+          </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-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,
+        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
+      },
+      // 表单校验
+      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`)
+    },
+    handleExportDetails() {
+      this.download('goal_management/annualSaleMergeDetails/export', {
+        ...this.queryParams
+      }, `annualSaleMergeDetails_${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
+      }
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      } else if (command === 'exportZoneSum') {
+        console.log('导出区域目标汇总')
+      } else if (command === 'exportCustomSum') {
+        console.log('导出客户目标汇总')
+      }
+    }
+  }
+};
+</script>

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

@@ -0,0 +1,1105 @@
+<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"
+        >新增
+        </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>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-grape"
+          size="mini"
+          :disabled="multiple"
+        >提交
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="primary" size="mini" plain icon="el-icon-upload">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+            <el-dropdown-item command="import">导入</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="warning" plain icon="el-icon-download" size="mini">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="export">导出</el-dropdown-item>
+            <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </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)"
+          >修改
+          </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-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`)
+    },
+    handleExportDetails() {
+      this.download('goal_management/monthGoalMergeDetails/export', {
+        ...this.queryParams
+      }, `monthSaleMergeDetails_${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
+      }
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      }
+    }
+  }
+};
+</script>

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

@@ -0,0 +1,752 @@
+<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"
+        >新增
+        </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>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-grape"
+          size="mini"
+          :disabled="multiple"
+        >提交
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="primary" size="mini" plain icon="el-icon-upload">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+            <el-dropdown-item command="import">导入</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="warning" plain icon="el-icon-download" size="mini">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="export">导出</el-dropdown-item>
+            <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </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)"
+          >修改
+          </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-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,
+        dept: 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('mk/monthReturnGoal/export', {
+        ...this.queryParams
+      }, `monthReturnGoal_${new Date().getTime()}.xlsx`)
+    },
+    handleExportDetails() {
+      this.download('mk/monthReturnGoalDetails/export', {
+        ...this.queryParams
+      }, `monthReturnGoalDetails_${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
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

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

@@ -0,0 +1,807 @@
+<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"
+      >新增
+      </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>
+    <el-col :span="1.5">
+      <el-button
+        type="primary"
+        plain
+        icon="el-icon-grape"
+        size="mini"
+        :disabled="multiple"
+      >提交
+      </el-button>
+    </el-col>
+    <el-col :span="1.5">
+      <el-dropdown @command="handleCommand">
+        <el-button type="primary" size="mini" plain icon="el-icon-upload">
+          导入<i class="el-icon-arrow-down el-icon--right"></i>
+        </el-button>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+          <el-dropdown-item command="import">导入</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </el-col>
+    <el-col :span="1.5">
+      <el-dropdown @command="handleCommand">
+        <el-button type="warning" plain icon="el-icon-download" size="mini">
+          导出<i class="el-icon-arrow-down el-icon--right"></i>
+        </el-button>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item command="export">导出</el-dropdown-item>
+          <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </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="120" fixed="right">
+      <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-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-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="dept" 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"
+import log from "../../../monitor/job/log";
+
+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`)
+    },
+    handleExportDetails() {
+      this.download('mk/monthReturnMergeDetails/export', {
+        ...this.queryParams
+      }, `monthReturnMergeDetails_${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.monthReturnMergeDetails
+        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.stringify(this.monthReturnMergeDetailsList))
+      console.log(arr);
+      if (this.activeName === 'monthReturnMergeDetails') {
+        return this.zoneGoalSumList = []
+      }
+      // 根据**进行合并,并相加goalSum
+      const mergeAndSumTotalGoal = (array) => {
+        return Array.from(array.reduce((map, obj) => {
+          const key = `${obj.saleOrg}-${obj.saleZone}-${obj.custom}-${obj.dept}-${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)
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

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

@@ -0,0 +1,864 @@
+<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"
+        >新增
+        </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>
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-grape"
+          size="mini"
+          :disabled="multiple"
+        >提交
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="primary" size="mini" plain icon="el-icon-upload">
+            导入<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="importModel">导入模板</el-dropdown-item>
+            <el-dropdown-item command="import">导入</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </el-col>
+      <el-col :span="1.5">
+        <el-dropdown @command="handleCommand">
+          <el-button type="warning" plain icon="el-icon-download" size="mini">
+            导出<i class="el-icon-arrow-down el-icon--right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="export">导出</el-dropdown-item>
+            <el-dropdown-item command="exportDetails">导出明细</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </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)"
+          >修改
+          </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-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`)
+    },
+    handleExportDetails() {
+      this.download('goal_management/monthSaleGoalDetails/export', {
+        ...this.queryParams
+      }, `monthSaleGoalDetails_${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
+      }
+    },
+    handleCommand(command) {
+      // 执行对应的功能
+      if (command === 'importModel') {
+        // 执行选项1的功能
+        console.log('导入模板');
+      } else if (command === 'import') {
+        // 执行选项2的功能
+        console.log('导入');
+      } else if (command === 'export') {
+        console.log('导出主表');
+        this.handleExport()
+      } else if (command === 'exportDetails') {
+        console.log('导出明细');
+        this.handleExportDetails()
+      }
+    }
+  }
+}
+</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>

+ 0 - 825
src/views/material/changeApply/add.vue

@@ -1,825 +0,0 @@
-<template>
-  <div class="apply_add">
-    <el-tabs type="border-card" v-model="tabValue" @tab-click="handleClick">
-      <el-tab-pane label="基本信息" name="first">
-        <el-form :model="basicForm" :rules="basicRules" ref="basic" label-width="170px">
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="单据编码" prop="code">
-                <el-input disabled v-model="basicForm.code"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="所属组织" prop="orgId">
-                <el-input disabled v-model="basicForm.orgId"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="物料编码" prop="materialCode">
-                <el-input readonly :disabled="disable" v-model="basicForm.materialCode">
-                  <el-button :disabled="disable" slot="append" icon="el-icon-more" @click="test01"></el-button>
-                </el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="物料名称" prop="materialName">
-                <el-input :disabled="disable" v-model="basicForm.materialName"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="医药物料" prop="medicineMaterial">
-                <el-select v-model="basicForm.medicineMaterial" placeholder="医药物料" clearable :disabled="disable"
-                           @change="controlMedic">
-                  <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="生产许可证" prop="remark">
-                <el-input :disabled="disable" v-model="basicForm.productionPermit"></el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="规格" prop="specification">
-                <el-input :disabled="disable" v-model="basicForm.specification"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="型号" prop="model">
-                <el-input :disabled="disable" v-model="basicForm.model"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="生产厂家/代理人" prop="factory">
-                <el-select ref="factoryOrman" v-model="basicForm.factory" placeholder="生产厂家/代理人" clearable
-                           :disabled="disable" @focus="chooseFactory">
-                  <el-option v-for="item in factoryOptions" :key="item.id" :label="item.name" :value="item.id"/>
-                </el-select>
-                <!-- <el-input :disabled="disable" v-model="basicForm.factory">
-                  <el-button :disabled="disable" slot="append" icon="el-icon-more" @click="test02"></el-button>
-                </el-input> -->
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="注册人/上市许可持有人" prop="registrant">
-                <el-input :disabled="disable" v-model="basicForm.registrant"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="存储条件" prop="storageConditions">
-                <el-select v-model="basicForm.storageConditions" placeholder="存储条件" clearable :disabled="disable">
-                  <el-option v-for="dict in dict.type.sys_storage_condition" :key="dict.value" :label="dict.label"
-                             :value="dict.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="运输条件" prop="transportCondition">
-                <el-select v-model="basicForm.transportCondition" placeholder="运输条件" clearable :disabled="disable">
-                  <el-option v-for="dict in dict.type.sys_conditions_carriage" :key="dict.value" :label="dict.label"
-                             :value="dict.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <!--            <el-col :span="8">-->
-            <!--              <el-form-item label="交货周期" prop="leadTime">-->
-            <!--                <el-input type="number" min="0" :disabled="disable" v-model="basicForm.leadTime"></el-input>-->
-            <!--              </el-form-item>-->
-            <!--            </el-col>-->
-            <!--            <el-col :span="8">-->
-            <!--              <el-form-item label="业务线" prop="businessLine"-->
-            <!--                            :rules="{ required: isOneClass, message: '骨科、介入、检验、普耗、设备类物料产线必须输入对应的业务线', trigger: 'blur' }">-->
-            <!--                <el-select ref="lines" v-model="basicForm.businessLine" placeholder="请选择" clearable :disabled="disable"-->
-            <!--                           @focus="chooseLine">-->
-            <!--                  <el-option v-for="item in lineOptions" :key="item.id" :label="item.name" :value="item.id"/>-->
-            <!--                </el-select>-->
-            <!--              </el-form-item>-->
-            <!--            </el-col>-->
-            <!--            <el-col :span="8">-->
-            <!--              <el-form-item label="物料分类" prop="materialClassifyId">-->
-            <!--                <el-input readonly :disabled="disable" v-model="basicForm.fourClass">-->
-            <!--                  <el-button :disabled="disable" slot="append" icon="el-icon-more" @click="chooseFourClass"></el-button>-->
-            <!--                </el-input>-->
-            <!--                <el-input v-show="false" readonly :disabled="disable" v-model="basicForm.materialClassifyId"></el-input>-->
-            <!--              </el-form-item>-->
-            <!--            </el-col>-->
-            <el-col :span="8">
-              <el-form-item label="DI码" prop="remark">
-                <el-input :disabled="disable" v-model="basicForm.diCode"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="备注" prop="remark">
-                <el-input :disabled="disable" v-model="basicForm.remark"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="一级分类" prop="oneClass">
-                <el-input readonly disabled v-model="basicForm.oneClass"></el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="二级分类" prop="twoClass">
-                <el-input readonly disabled v-model="basicForm.twoClass"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="三级分类" prop="threeClass">
-                <el-input readonly disabled v-model="basicForm.threeClass"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="四级分类" prop="fourClass">
-                <el-input readonly disabled v-model="basicForm.fourClass">
-                </el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-form>
-      </el-tab-pane>
-
-      <el-tab-pane label="医药属性" name="second">
-        <el-form :model="basicForm2" ref="basic2" label-width="160px">
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="药品" prop="drug"
-                            :rules="{ required: !isControl, message: '请选择是否药品', trigger: 'blur' }">
-                <el-select v-model="basicForm2.drug" placeholder="请选择" clearable :disabled="disable || isControl">
-                  <el-option v-for="dict in dict.type.sys_medicine" :key="dict.value" :label="dict.label"
-                             :value="dict.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="注册证号/备案凭证编号" prop="registrationNo">
-                <el-input :disabled="disable || isControl" v-model="basicForm2.registrationNo"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="医疗器械" prop="medicalDevices">
-                <el-select v-model="basicForm2.medicalDevices" placeholder="请选择" clearable
-                           :disabled="disable || isControl">
-                  <el-option v-for="dict in dict.type.medical_instruments" :key="dict.value" :label="dict.label"
-                             :value="dict.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="养护类型" prop="maintenanceType">
-                <el-select v-model="basicForm2.maintenanceType" placeholder="请选择" clearable
-                           :disabled="disable || isControl">
-                  <el-option v-for="dict in dict.type.curing_type" :key="dict.value" :label="dict.label"
-                             :value="dict.value"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="剂型" prop="dosageFrom"
-                            :rules="{ required: !isControl, message: '请选择剂型', trigger: 'blur' }">
-                <el-select ref="doses" v-model="basicForm2.dosageFrom" placeholder="请选择" clearable
-                           :disabled="disable || isControl" @focus="chooseDose">
-                  <el-option v-for="item in doseOptions" :key="item.id" :label="item.name" :value="item.id"/>
-                </el-select>
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-form>
-        <!-- <el-row style="margin-bottom: 12px;">
-          <span>物料类别</span>
-        </el-row>
-        <el-row style="margin-bottom: 12px;">
-          <el-button type="primary" size="small" plain @click="addLine">新增</el-button>
-          <el-button type="primary" size="small" plain @click="handleDelete">删除</el-button>
-          <el-button type="primary" size="small" plain @click="testsave">暂存</el-button>
-        </el-row> -->
-        <!-- <el-row>
-          <el-col :span="12">
-            <el-table
-            :data="basicForm2.medicineTypeChanges"
-            class="request-table"
-            @selection-change="handleSelectionChange"
-            >
-              <el-table-column type="selection" width="55" />
-              <el-table-column label="序号" align="center" prop="sort">
-                <template slot-scope="scope">
-                  <el-input v-model="scope.row.sort"></el-input>
-                </template>
-              </el-table-column>
-              <el-table-column label="物料类别" align="center" prop="medicineCode">
-                <template slot-scope="scope">
-                  <el-input v-model="scope.row.medicineCode"></el-input>
-                </template>
-              </el-table-column>
-              <el-table-column label="类别名称" align="center" prop="medicineName">
-                <template slot-scope="scope">
-                  <el-input v-model="scope.row.medicineName"></el-input>
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-col>
-        </el-row> -->
-      </el-tab-pane>
-
-      <el-tab-pane label="修改记录" name="third">
-        <el-table :data="basicForm.changeRecords" class="request-table">
-          <el-table-column label="字段名称" align="center" prop="pageCondtion"/>
-          <el-table-column label="变更前" align="center" prop="beforeChangeValue"/>
-          <el-table-column label="变更后" align="center" prop="afterChangeValue"/>
-        </el-table>
-      </el-tab-pane>
-
-      <el-tab-pane label="单据信息" name="fourth">
-        <el-form :model="basicForm" ref="info" label-width="160px">
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="申请人" prop="createByName">
-                <el-input disabled v-model="basicForm.createByName"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="申请时间" prop="createTime">
-                <el-input disabled v-model="basicForm.createTime"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="创建人" prop="createByName">
-                <el-input disabled v-model="basicForm.createByName"></el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="创建时间" prop="createTime">
-                <el-input disabled v-model="basicForm.createTime"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="最后修改人" prop="updateByName">
-                <el-input disabled v-model="basicForm.updateByName"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="最后修改时间" prop="updateTime">
-                <el-input disabled v-model="basicForm.updateTime"></el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <!-- <el-col :span="8">
-              <el-form-item label="最后审核人" prop="approver">
-                <el-input disabled v-model="basicForm.approver"></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="最后审核时间" prop="approvalTime">
-                <el-input disabled v-model="basicForm.approvalTime"></el-input>
-              </el-form-item>
-            </el-col> -->
-            <el-col :span="8">
-              <el-form-item label="单据状态" prop="status">
-                <el-select v-model="basicForm.status" size="small" disabled>
-                  <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value">
-                  </el-option>
-                </el-select>
-                <!-- <el-input disabled v-model="basicForm.status"></el-input> -->
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-form>
-      </el-tab-pane>
-    </el-tabs>
-
-    <div class="btn_group">
-      <el-col :span="1.5">
-        <el-button type="primary" size="small" plain @click="save"
-                   v-if="pageStu == 'add' || pageStu == 'edit'">保存
-        </el-button>
-      </el-col>
-      <el-col :span="1.5" style="margin: 0 10px;">
-        <el-button type="primary" size="small" plain @click="submit" v-if="pageStu == 'check' && (row.status == '0' || row.status == '3')">提交</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button type="primary" size="small" plain @click="back">返回</el-button>
-      </el-col>
-    </div>
-
-    <popDialog ref="contractSelect" @doSubmit="selectionsToInput" :selectData="selectData" :single="true"/>
-
-    <factory ref="factory" @doSubmit="acceptFactory" :selectData="selectData2" :single="true"/>
-
-    <fourClass ref="fourClass" @doSubmit="acceptFourClass" :selectData="selectData3" :single="true"/>
-
-    <dose ref="dose" @doSubmit="acceptDose" :selectData="selectData9" :single="true"/>
-    <serviceline ref="line" @doSubmit="acceptLine" :selectData="selectData8" :single="true"/>
-  </div>
-</template>
-
-<script>
-  import popDialog from '@/components/PopDialog/index.vue'
-  import factory from '@/components/PopDialog/productFactory.vue'
-  import {addChangeList, getMaterialDetails, getChangeDetails, editChangeList} from '@/api/changeApply/basic'
-  import {getDose, getLine} from '@/api/requisition/basic'
-  // 生产厂商/代理人调用用于回显
-  import {getProductFactory} from '@/api/changeApply/basic'
-  // 四级分类
-  import fourClass from '@/components/PopDialog/fourClass.vue'
-  import dose from '@/components/PopDialog/dose.vue'
-  import serviceline from '@/components/PopDialog/serviceline.vue'
-  // 调用物料分类详情接口用于数据回显
-  import {getDetail} from '@/api/classify/basic';
-
-  export default {
-    name: 'applyAdd',
-    dicts: ['sys_storage_condition', 'sys_conditions_carriage', 'sys_medicine', 'medical_instruments', 'curing_type'],
-    components: {
-      popDialog,
-      factory,
-      dose,
-      serviceline,
-      fourClass
-    },
-    props: ['pageStu', 'row', 'disable'],
-    model: {
-      prop: 'isList',
-      event: 'jugislist'
-    },
-    data() {
-      return {
-        factoryOptions: [],
-        // 剂型
-        doseOptions: [],
-        selectData9: [],
-        selectData8: [],
-        tabValue: 'first',
-        isControl: true,
-        // 业务线
-        lineOptions: [],
-        isOneClass: false,
-        basicForm: {
-          code: '',
-          orgId: '德荣集团',
-          // 物料id
-          materialId: '',
-          materialCode: '',
-          materialName: '',
-          materialClassifyId: '',
-          medicineMaterial: '2',
-          oneClass: '',
-          twoClass: '',
-          threeClass: '',
-          fourClass: '',
-          specification: '',
-          model: '',
-          factory: '',
-          registrant: '',
-          storageConditions: '',
-          transportCondition: '',
-          leadTime: '',
-          remark: '',
-          // 修改记录
-          changeRecords: [],
-          // 单据信息字段
-          createBy: '',
-          applicationTime: '',
-          createTime: '',
-          updateBy: '',
-          updateTime: '',
-          approver: '',
-          approvalTime: '',
-          status: '',
-          // 业务线
-          businessLine: '',
-          // 生产许可证/经营许可证/备案号
-          productionPermit: '',
-          // di码
-          diCode: ''
-        },
-        options: [{
-          value: '0',
-          label: '是'
-        }, {
-          value: '2',
-          label: '否'
-        }],
-        statusOptions: [{
-          value: '0', label: '未提交'
-        }, {
-          value: '1', label: '审批中'
-        }, {
-          value: '2', label: '已完成'
-        }, {
-          value: '3', label: '已驳回'
-        },],
-        basicRules: {
-          materialCode: [{required: true, message: '请选择物料编码', trigger: 'blur'}],
-          materialName: [{required: true, message: '请填写物料名称', trigger: 'blur'}],
-          specification: [{required: true, message: '请填写规格', trigger: 'blur'}],
-          // materialClassifyId: [{required: true, message: '请选择物料分类', trigger: 'blur'}],
-          // model: [{required: true, message: '请填写型号', trigger: 'blur'}],
-          factory: [{required: true, message: '请选择生产厂家/代理人', trigger: 'blur'}],
-          registrant: [{required: true, message: '请填写注册人/上市许可持有人', trigger: 'blur'}],
-          storageConditions: [{required: true, message: '请选择存储条件', trigger: 'blur'}],
-          // transportCondition: [{required: true, message: '请选择运输条件', trigger: 'blur'}],
-          // leadTime: [{required: true, message: '请填写交货周期', trigger: 'blur'}],
-        },
-        basicForm2: {
-          drug: '',
-          registrationNo: '',
-          medicalDevices: '',
-          maintenanceType: '',
-          // 剂型
-          dosageFrom: ''
-          // 医药属性子表
-          // medicineTypeChanges:[
-          // ],
-        },
-        // tableList: [],
-        // 子表选中
-        ids: [],
-        // 弹窗
-        name: '',
-        selectData: [],
-        selectData2: [],
-        selectData3: []
-      }
-    },
-    // watch: {
-    //   value: {
-    //     handler (newVal) {
-    //       this.selectData = []
-    //       if (newVal) {
-    //         newVal.split(',').forEach((id) => { // 回显拿数据
-    //           this.contractService.queryById(id).then(({data}) => {
-    //             if (data && data.id !== '') {
-    //               this.selectData.push(data)
-    //             }
-    //           })
-    //         })
-    //       }
-    //     },
-    //     immediate: true,
-    //     deep: false
-    //   },
-    //   selectData: {
-    //     handler (newVal) {
-    //       this.name = newVal.map(contract => contract.contractName).join(',')
-    //     },
-    //     immediate: false,
-    //     deep: false
-    //   }
-    // },
-    mounted() {
-      this.$nextTick(() => {
-        // console.log('页面状态',this.pageStu)
-        if (this.pageStu == 'check') {
-          // alert('详情页面:')
-          console.log('页面状态', this.pageStu)
-          console.log('数据', this.row)
-          this.getDetails(this.row)
-          // 生产厂家代理人用于回显
-          if (this.row.factory) {
-            this.getFactoryDetails(this.row.factory)
-          }
-        } else if (this.pageStu == 'edit') {
-          // alert('修改页面')
-          console.log('页面状态', this.pageStu)
-          console.log('数据', this.row)
-          this.getDetails(this.row)
-          // 控制医药属性是否能够填写
-          if (this.row.medicineMaterial == '0') {
-            this.isControl = false
-          } else {
-            this.isControl = true
-          }
-          // 生产厂家代理人用于回显
-          if (this.row.factory) {
-            this.getFactoryDetails(this.row.factory)
-          }
-        } else if (this.pageStu == 'add') {
-          // alert('新增页面')
-          console.log('页面状态', this.pageStu)
-        }
-      })
-    },
-    methods: {
-      // 剂型显示列表
-      chooseDose() {
-        this.$refs.doses.blur()
-        this.$refs.dose.init()
-      },
-      // 选择剂型-树形
-      acceptDose(selections) {
-        this.doseOptions.push(selections)
-        this.basicForm2.dosageFrom = selections.id
-        this.getDoseDetails(selections.id)
-      },
-      // 剂型回显
-      getDoseDetails(id) {
-        getDose({id: id}).then(res => {
-          console.log('剂型', res)
-          if (res.code === 200) {
-            this.doseOptions = res.data.tableBody
-          }
-        })
-      },
-      // 生产厂家/代理人用于回显
-      getFactoryDetails(id) {
-        getProductFactory({id: id}).then(res => {
-          if (res.code === 200) {
-            this.factoryOptions = res.data.tableBody
-          }
-        })
-      },
-      // 选择是否医药物料时控制医药属性
-      controlMedic(val) {
-        console.log('val', val)
-        if (val == '0') {
-          this.isControl = false
-          // 初始化剂型为其他
-          this.basicForm2.dosageFrom = '0001A11000000000BX7Z'
-          this.getDoseDetails(this.basicForm2.dosageFrom)
-        } else {
-          this.basicForm2.drug = ''
-          this.basicForm2.registrationNo = ''
-          this.basicForm2.medicalDevices = ''
-          this.basicForm2.maintenanceType = ''
-          this.isControl = true
-        }
-      },
-      handleClick(tab, event) {
-        console.log(tab, event);
-        console.log('页面状态', this.pageStu)
-      },
-      // 如果是详情进入,则调用详情接口
-      getDetails(row) {
-        getChangeDetails(row.id).then(res => {
-          if (res.code === 200) {
-            this.basicForm = res.data
-            if (res.data.medicineChange) {
-              this.basicForm2 = res.data.medicineChange
-            }
-            // 剂型回显
-            if (res.data.medicineChange && res.data.medicineChange.dosageFrom) {
-              this.getDoseDetails(res.data.medicineChange.dosageFrom)
-            }
-            // 业务线回显
-            if (res.data.businessLine) {
-              this.getLineDetails(res.data.businessLine)
-            }
-          }
-        })
-      },
-      save() {
-        // alert('保存传status:0')
-        let sparams = {...this.basicForm, ...{status: 0}}
-        sparams.medicineChange = this.basicForm2
-        console.log('保存参数', sparams)
-        this.$refs['basic'].validate((valid) => {
-          if (valid) {
-            this.$refs['basic2'].validate(valid => {
-              if (valid) {
-                this.$modal.loading("保存中...");
-                addChangeList(sparams).then(res => {
-                  if (res.code === 200) {
-                    this.$message({
-                      message: res.msg,
-                      type: 'success'
-                    });
-                    this.$modal.closeLoading();
-                    this.back()
-                  }
-                }).catch(err => {
-                this.$modal.closeLoading();
-                })
-              }
-            })
-          }
-        })
-      },
-      submit() {
-        // alert('提交传status:1')
-        let sparams = {...this.basicForm, ...{status: 1}}
-        sparams.medicineChange = this.basicForm2
-        console.log('提交参数', sparams)
-        this.$refs['basic'].validate((valid) => {
-          if (valid) {
-            this.$refs['basic2'].validate(valid => {
-              if (valid) {
-                this.$modal.loading("提交中...");
-                editChangeList(sparams).then(res => {
-                  if (res.code === 200) {
-                    this.$message({
-                      message: res.msg,
-                      type: 'success'
-                    });
-                    this.$modal.closeLoading();
-                    this.back()
-                  }
-                }).catch(err => {
-                this.$modal.closeLoading();
-                })
-              }
-            })
-          }
-        })
-      },
-      back() {
-        this.$emit('jugislist', true)
-        // let queryParams = {
-        //   pageNum: 1,
-        //   pageSize: 10
-        // }
-        this.$emit('refresh')
-      },
-      // 子表增删行
-      // handleSelectionChange(val) {
-      //   this.ids = val
-      //   console.log('this.ids',this.ids)
-      // },
-      // addLine() {
-      //   //添加行数
-      //   let newValue = {
-      //     sort:'',
-      //     medicineCode: '',
-      //     medicineName: '',
-      //   };
-      //   this.basicForm2.medicineTypeChanges.push(newValue);
-      // },
-      // handleDelete(index) {
-      //   if(this.ids.length == 0) {
-      //     this.$message({
-      //       message: '请选择删除条目',
-      //       type: 'warning'
-      //     });
-      //   } else {
-      //     // console.log('index',index)
-      //     // this.basicForm2.medicineTypeChanges.splice(index, 1);
-      //     this.basicForm2.medicineTypeChanges = this.basicForm2.medicineTypeChanges.filter(item =>
-      //      !this.ids.some(ele =>
-      //      ele.sort == item.sort))
-      //   }
-      // },
-      // testsave() {
-      //   console.log('暂存表格:', this.basicForm2.medicineTypeChanges)
-      //   console.log('暂存表单1', this.basicForm)
-      //   let params = {...this.basicForm, ...this.basicForm2}
-      //   console.log('暂存总表单', params)
-      // },
-      // 设置选中
-      selectionsToInput(selections) {
-        console.log('父组件拿到的:', selections)
-        this.selectData = selections
-        this.$emit('getInfo', this.selectData)
-        getMaterialDetails(selections[0].id).then(res => {
-          console.log('res', res)
-          if (res.code === 200) {
-            let data = res.data.data
-            // 物料id
-            this.basicForm.materialId = data.id
-            // 物料分类Id
-            // this.basicForm.materialClassifyId = data.classifyId
-            this.basicForm.materialCode = data.code
-            this.basicForm.materialName = data.name
-            this.basicForm.medicineMaterial = data.isMedicine
-            this.basicForm.oneClass = data.oneClass
-            this.basicForm.twoClass = data.twoClass
-            this.basicForm.threeClass = data.threeClass
-            this.basicForm.fourClass = data.fourClass
-            this.basicForm.specification = data.specification
-            this.basicForm.model = data.model
-            this.basicForm.factory = data.manufacturerId
-            this.basicForm.registrant = data.registrant
-            this.basicForm.storageConditions = data.storageCondition
-            this.basicForm.transportCondition = data.transportationCondition
-            this.basicForm.leadTime = data.deliveryPeriod
-            this.basicForm.diCode = data.diCode
-            this.basicForm.businessLine = data.businessLine
-            this.basicForm.productionPermit = data.productionPermit
-            if (data.manufacturerId) {
-              this.getFactoryDetails(data.manufacturerId)
-            }
-            if (data.businessLine) {
-              this.getLineDetails(data.businessLine)
-            }
-            if (data.medcines.length !== 0) {
-              this.basicForm2.drug = data.medcines[0].isDrug
-              this.basicForm2.registrationNo = data.medcines[0].registrationNo
-              this.basicForm2.medicalDevices = data.medcines[0].medicalInstruments
-              this.basicForm2.maintenanceType = data.medcines[0].curingType
-              this.basicForm2.dosageFrom = data.medcines[0].dosageFrom
-              if (data.medcines[0].dosageFrom) {
-                this.getDoseDetails(data.medcines[0].dosageFrom)
-              }
-            }
-            // 控制医药属性是否能够填写
-            if (this.basicForm.medicineMaterial == '0') {
-              this.isControl = false
-            } else {
-              this.isControl = true
-            }
-          }
-        })
-      },
-      // selectionsToInput2 (selections) {
-      //   console.log('选择的数据',selections)
-      //   this.basicForm.factory = selections[0].manufactureName
-      // },
-      // 显示列表
-      test01() {
-        console.log('测试点击')
-        this.$refs.contractSelect.init()
-      },
-      // test02() {
-      //   console.log('测试弹窗2');
-      //   this.$refs.contractSelect2.init()
-      // },
-      // 选择生产厂家/代理人
-      acceptFactory(selections) {
-        console.log('选择的数据', selections)
-        this.factoryOptions = selections
-        this.basicForm.factory = selections[0].id
-        this.getFactoryDetails(selections[0].id)
-      },
-      // 生产厂家/代理人显示列表
-      chooseFactory() {
-        this.$refs.factoryOrman.blur()
-        this.$refs.factory.init()
-      },
-      // 选择四级分类
-      acceptFourClass(selections) {
-        console.log('收到的四级分类', selections)
-        this.basicForm.materialClassifyId = selections.id
-        this.getTreeDetails(selections.id)
-      },
-      // 四级分类显示列表
-      chooseFourClass() {
-        this.$refs.fourClass.init(basicForm.materialClassifyId)
-      },
-      // 选择四级分类后需要根据id再次查询一下123级分类
-      getTreeDetails(id) {
-        getDetail(id).then(res => {
-          if (res.code === 200) {
-            this.basicForm.oneClass = res.data.oneClass
-            this.basicForm.twoClass = res.data.twoClass
-            this.basicForm.threeClass = res.data.threeClass
-            this.basicForm.fourClass = res.data.fourClass
-            const classjudge = res.data.oneClass
-            if (classjudge.includes('介入耗材&5') || classjudge.includes('骨科耗材&2') || classjudge.includes('普通耗材&3') || classjudge.includes('医用设备&1') || classjudge.includes('体外诊断&4')) {
-              this.isOneClass = true
-            } else {
-              this.isOneClass = false
-            }
-          }
-        })
-      },
-      // 选择业务线
-      acceptLine(selections) {
-        this.lineOptions = selections
-        this.basicForm.businessLine = selections[0].id
-        this.getLineDetails(selections[0].id)
-      },
-      // 业务线显示列表
-      chooseLine() {
-        this.$refs.lines.blur()
-        this.$refs.line.init()
-      },
-      // 业务线回显
-      getLineDetails(id) {
-        getLine({id: id}).then(res => {
-          console.log('业务线', res)
-          if (res.code === 200) {
-            this.lineOptions = res.data.tableBody
-          }
-        })
-      },
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-  .apply_add {
-    height: calc(100vh - 84px);
-    padding: 12px;
-    box-sizing: border-box;
-    overflow-y: auto;
-  }
-
-  .btn_group {
-    width: 100%;
-    margin: 20px 0;
-    display: flex;
-    justify-content: center;
-  }
-</style>

+ 399 - 0
src/views/material/changeApply/add/column.js

@@ -0,0 +1,399 @@
+export default function useColumns(){
+
+  const TableColumns = [
+    {
+      item:{
+        key:'code',
+        title:'单据编码',
+      },
+      attr:{
+        is: "el-input",
+        disabled:true,
+      },
+    },
+    {
+      item:{
+        key:'orgName',
+        title:'所属组织',
+      },
+      attr:{
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "ORG_PARAM",
+        dataMapping: {
+          orgId:'id'
+        },
+        disabled:true,
+      },
+    },
+    {
+      item:{
+        key:'status',
+        title:'单据状态',
+      },
+      attr:{
+        is: "el-select",
+        dictName: "documents_status", // 字典名
+        disabled:true,
+      },
+    },
+    // {
+    //   item:{
+    //     key:'approver',
+    //     title:'申请人',
+    //   },
+    //   attr:{
+    //     is: "el-input",
+    //     disabled:true,
+    //   },
+      
+    // },
+    {
+      item:{
+        key:'applicationTime',
+        title:'申请时间',
+      },
+      attr:{
+        is: "el-date-picker",
+        valueFormat: "yyyy-MM-dd HH:mm:ss",
+        disabled:true,
+      },
+  
+    },
+    {
+      item:{
+        key:'createByName',
+        title:'创建人',
+      },
+      attr:{
+        is: "el-input",
+        disabled:true,
+      },
+  
+    },
+    {
+      item:{
+        key:'createTime',
+        title:'创建时间',
+      },
+      attr:{
+        is: "el-date-picker",
+        valueFormat: "yyyy-MM-dd HH:mm:ss",
+        disabled:true,
+      },
+  
+    },
+    {
+      item:{
+        key:'updateByName',
+        title:'最后修改人',
+      },
+      attr:{
+        is: "el-input",
+        disabled:true,
+      },
+  
+    },
+    {
+      item:{
+        key:'updateTime',
+        title:'最后修改时间',
+      },
+      attr:{
+        is: "el-date-picker",
+        valueFormat: "yyyy-MM-dd HH:mm:ss",
+        disabled:true,
+      },
+  
+    },
+    
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+  
+  const TabColumns = [
+    {
+      item:{
+        key:'materialBasic',
+        title:'物料信息',
+      },
+      attr:{
+        value:[]
+      },
+      TableColumns:[
+        {
+          item:{
+            key:'materialCode',
+            title:'物料编码',
+            require: true,
+          },
+          attr:{
+            is: "el-input",
+            disabled:true,
+          },
+         
+        },
+        {
+          item:{
+            key:'materialName',
+            title:'物料名称',
+            require: true,
+          },
+          attr:{
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "MATERIAL_PARAM",
+            dataMapping: {
+              materialId: "id",
+              materialCode: "code",
+              materialName: "name",
+              diCode:'diCode',
+              remark:'remark',
+              model: "model",
+              materialClassifyId:'classifyId',
+              productionPermit:'productionPermit',
+              specification: "specification",
+              storageConditions:'storageCondition',
+              transportCondition:'transportationCondition',
+              medicineMaterial:'isMedicine',
+              factory:'manufacturerId',
+              factoryName:'manufacturerIdName',
+              registrant:'registrant',
+              oneClass:'oneClass',
+              twoClass:'twoClass',
+              threeClass:'threeClass',
+              fourClass:'fourClass',
+              drug:'isDrugNumber',
+              registrationNo:'oriRegistrationNo',
+              dosageFrom:'dosageFrom',
+              dosageFromName:'dosageFromName',
+              maintenanceType:'curingType',
+              medicalDevices:'medicalInstruments',
+            },
+
+          },
+         
+        },
+        {
+          item:{
+            key:'medicineMaterial',
+            title:'医药物料',
+          },
+          attr:{
+            is: "el-select",
+            dictName: "sys_number_yes_no", // 字典名
+          },
+         
+        },
+        {
+          item:{
+            key:'productionPermit',
+            title:'生产许可证',
+          },
+          attr:{
+            is: "el-input",
+          },
+          
+        },
+        {
+          item:{
+            key:'specification',
+            title:'规格',
+            require: true,
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'model',
+            title:'型号',
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'factoryName',
+            title:'生产厂家/代理人',
+            require: true,
+          },
+          attr:{
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "MANUFACTURER_PARAM",
+            dataMapping: {
+              factory:'id'
+            }
+          },
+          
+        },
+        {
+          item:{
+            key:'registrant',
+            title:'注册人/上市许可持有人',
+            require: true,
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'storageConditions',
+            title:'存储条件',
+            require: true,
+          },
+          attr:{
+            is: "el-select",
+            dictName: "sys_storage_condition", // 字典名
+          },
+          
+        },
+        {
+          item:{
+            key:'transportCondition',
+            title:'运输条件',
+          },
+          attr:{
+            is: "el-select",
+            dictName: "sys_conditions_carriage", // 字典名
+          },
+         
+        },
+        {
+          item:{
+            key:'diCode',
+            title:'DI码',
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'remark',
+            title:'备注',
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'oneClass',
+            title:'一级分类',
+          },
+          attr:{
+            is: "el-input",
+            disabled:true,
+          },
+          
+        },
+        {
+          item:{
+            key:'twoClass',
+            title:'二级分类',
+          },
+          attr:{
+            is: "el-input",
+            disabled:true,
+          },
+         
+        },
+        {
+          item:{
+            key:'threeClass',
+            title:'三级分类',
+          },
+          attr:{
+            is: "el-input",
+            disabled:true,
+          },
+          
+        },
+        {
+          item:{
+            key:'fourClass',
+            title:'四级分类',
+          },
+          attr:{
+            is: "el-input",
+            disabled:true,
+          },
+         
+        },
+        {
+          item:{
+            key:'drug',
+            title:'药品',
+          },
+          attr:{
+            is: "el-select",
+            dictName: "sys_medicine", // 字典名
+          },
+         
+        },
+        {
+          item:{
+            key:'registrationNo',
+            title:'注册证号/备案凭证编号',
+          },
+          attr:{
+            is: "el-input",
+          },
+         
+        },
+        {
+          item:{
+            key:'medicalDevices',
+            title:'医疗器械',
+          },
+          attr:{
+            is: "el-select",
+            dictName: "medical_instruments", // 字典名
+          },
+          
+        },
+        {
+          item:{
+            key:'maintenanceType',
+            title:'养护类型',
+          },
+          attr:{
+            is: "el-select",
+            dictName: "curing_type", // 字典名
+          },
+         
+        },
+        {
+          item:{
+            key:'dosageFromName',
+            title:'剂型',
+          },
+          attr:{
+            is: "el-popover-tree-select",
+            referName: "DOSAGEFORM_PARAM",
+            valueKey: "name",
+            dataMapping: {
+              dosageFrom:'id'
+            }
+          },
+          
+        },
+  
+      ]
+    }, 
+  ]
+
+  return {TableColumns,TabColumns}
+}
+

+ 432 - 0
src/views/material/changeApply/add/index.vue

@@ -0,0 +1,432 @@
+<!-- 批量新增 -->
+<script>
+import useColumns from "./column";
+import {addChangeList, getMaterialDetails, getChangeDetails, editChangeList} from '@/api/changeApply/basic';
+
+
+export default {
+  name: "AddChangeOrders",
+  props: {
+    dict: {
+      type: Object,
+    },
+    addType: {
+      type: String,
+      default: "add",
+    },
+  },
+  components: {
+    AmendantRecord: () => import("../amendantRecord/index.vue"),
+    ElSuperForm: () => import("@/components/super-form/index.vue"),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/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,
+      params,
+      tabName: tabName,
+      TabColumns: TabColumns,
+      TableColumns: TableColumns,
+    };
+  },
+  computed: {
+    title: {
+      get() {
+        const { addType } = this;
+        if (addType === "add") {
+          return "新 增";
+        }
+        if (addType === "edit") {
+          return "编 辑";
+        }
+      },
+      set() {},
+    },
+    materialInfo:{
+      get(){
+        const { materialBasic } = this.params;
+        this.params.materialBasic = materialBasic.map((item, index) => ({
+          ...item,
+          $index: index,
+        }));
+
+        return {
+          materialBasic: this.params.materialBasic.filter(
+            ({ delFlag }) => delFlag !== "2"
+          ),
+        }
+      },
+      set(){},
+    }
+  
+  },
+  watch: {
+    
+  },
+  methods: {
+    setVisible(prop){
+      this.visible = prop;
+    },
+    beforeOpen(){
+      if(this.addType === 'add'){
+        let {name,nickName} = this.$store.state.user;
+        this.params.createBy = name;
+        this.params.createByName = nickName;
+        this.params.createTime =  new Date().Format('yyyy-MM-dd HH:mm:ss');
+        this.params.updateBy = name;
+        this.params.updateByName = nickName;
+        this.params.updateTime =  new Date().Format('yyyy-MM-dd HH:mm:ss');
+        // this.params.approver = name;
+        this.params.applicationTime =  new Date().Format('yyyy-MM-dd HH:mm:ss');
+        this.params.status = '0';
+        console.log(this.$store.state.user,'user');
+        this.params.orgName = '德荣集团';
+        this.useRowAdd(this.tabName);
+      }
+    },
+
+    //
+    async fetchItem(prop) {
+      console.log(prop,'prop----------------');
+      try {
+        // try
+        this.loading = true;
+
+        let { code, data } = await getChangeDetails(prop.id);
+
+        if(code == 200){
+          this.params = data;
+        }
+        
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    
+    //
+    async hide() {
+      const {
+        TabColumns,
+        TableColumns,
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
+      this.visible = false;
+      this.$emit('success');
+      this.tabName = tabName;
+      this.params = this.$init.params([...TabColumns, ...TableColumns]);
+    },
+    //
+    async useRowAdd(prop) {
+      
+      const { TableColumns } = this.TabColumns.find(
+        ({ item: { key } }) => key === prop
+      );
+      this.params[prop].push({
+        delFlag: "0",
+        materialClassifyId:null,
+        ...this.$init.params(TableColumns),
+      });
+    },
+    //
+    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,
+        })).filter(item =>( item.id  || (!item.id && item.delFlag === '0')) )
+        ;
+      }
+    },
+    handleSubmitValidate(prop,cb){
+
+      this.$refs[prop].$refs[prop].validate(async (valid) => {
+        if (valid) {
+          try {
+            this.loading = true;
+
+            let validList = this.params['materialBasic'].filter(item => item.delFlag === '0');
+
+            if(validList.length){
+              await cb();
+            }else{
+              this.$notify.error({
+                message:'物料信息不能不为空!'
+              })
+            }
+            
+          } catch (err) {
+            // catch
+            console.error(err);
+          } finally {
+            // finally
+            this.loading = false;
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    //
+    async useSubmit(prop) {
+      console.log(this.params,'this.params');
+      this.handleSubmitValidate(prop,async()=>{
+
+        try {
+          this.loading = true;
+          const {code,msg} = await addChangeList(this.params);
+
+          if(code == 200){
+
+            this.hide();
+            this.$notify.success({
+              title: msg,
+            });
+          }
+          
+        } catch (error) {}
+        finally{
+          this.loading = false;
+        }
+
+        
+        // await;
+      })
+    },
+  },
+  created() {
+  },
+  mounted() {},
+  destroyed() {},
+};
+</script>
+
+<template>
+    <el-drawer
+      v-bind="$attrs"
+      v-on="$listeners"
+      :size="width"
+      :visible.sync="visible"
+      destroy-on-close
+      :show-close="false"
+      @close="hide"
+      @open="beforeOpen"
+      v-loading="loading"
+    >
+      <div 
+        slot="title" 
+        style="display: flex;
+            justify-content: space-between;
+            align-items: center;"
+      >
+        <h3>{{title}}</h3>
+        <div>
+          <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useSubmit('superForm')"
+          >确 认</el-button
+        >
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
+        >
+        </div>
+      </div>
+      <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"
+          >
+          </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="materialInfo[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"
+              >
+              </component>
+            </template>
+            <!-- 判断是否禁用 -->
+            <template slot="drug" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                :disabled="!(scope.row.medicineMaterial ==='0') "
+              >
+              <el-option
+                  v-for="item in dict.type[scope.attr.dictName]"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </component>
+            </template>
+
+            <template slot="registrationNo" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                :disabled="!(scope.row.medicineMaterial ==='0') "
+              >
+              </component>
+            </template>
+
+            <template slot="medicalDevices" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                :disabled="!(scope.row.medicineMaterial ==='0') "
+              >
+              <el-option
+                  v-for="item in dict.type[scope.attr.dictName]"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </component>
+            </template>
+            <template slot="maintenanceType" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                :disabled="!(scope.row.medicineMaterial ==='0') "
+              >
+              <el-option
+                  v-for="item in dict.type[scope.attr.dictName]"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </component>
+            </template>
+            <template slot="dosageFromName" slot-scope="scope">
+              <component
+                v-bind="scope.attr"
+                v-model="scope.row[scope.item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+                :disabled="!(scope.row.medicineMaterial ==='0') "
+              >
+              </component>
+            </template>
+            
+
+            <el-table-column fixed="right" label="操作" width="120" align="center">
+              <template slot="header" slot-scope="scope">
+                <el-button
+                  type="text"
+                  :size="$attrs.size"
+                  @click="useRowAdd(tabName)"
+                >
+                  增行
+                </el-button>
+              </template>
+              <template slot-scope="scope">
+                <el-button
+                  type="text"
+                  :size="$attrs.size"
+                  @click.native.prevent="useRowRemove(tabName, scope)"
+                >
+                删除
+                </el-button>
+                <AmendantRecord
+                  v-if=" tabName ==='materialBasic' && addType === 'edit' && scope.row.id"
+                  v-model="scope.row"
+                ></AmendantRecord>
+              </template>
+            </el-table-column>
+          </el-super-table>
+        </el-tab-pane>
+      </el-tabs>
+
+      
+     
+    </el-drawer>
+</template>
+
+<style scoped>
+::v-deep .el-table__row.is-hidden {
+  display: none;
+}
+</style>
+
+

+ 7 - 0
src/views/material/changeApply/amendantRecord/column.js

@@ -0,0 +1,7 @@
+export const recordColumns = [
+  { item: { key: "pageCondtion", title: "字段名称" }, attr: {} },
+  { item: { key: "afterChangeValue", title: "变更前" }, attr: {} },
+  {
+    item: { key: "beforeChangeValue", title: "变更后" },attr: {},
+  },
+];

+ 102 - 0
src/views/material/changeApply/amendantRecord/index.vue

@@ -0,0 +1,102 @@
+<!-- 修改记录 -->
+<script>
+import {recordColumns} from './column';
+import {getRecordList} from '@/api/changeApply/basic';
+
+export default {
+  name:'AmendantRecord',
+  components:{
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+  },
+  dicts:[],
+  props:{
+    type:{
+      type:String,
+      default:'text',
+    },
+    value:{
+      type:Object,
+      require:true,
+    },
+    size:{
+      type:String,
+      default:'mini'
+    }
+  },
+  data(){
+
+    return {
+      title:'修改记录',
+      visible:false,
+      loading:false,
+      tableData:[],
+      TableColumns:recordColumns,
+      
+
+    }
+  },
+  methods:{
+    async beforeOpen(){
+      try {
+        let {id} = this.value;
+
+        this.loading = true;
+
+        let {code,rows} = await getRecordList({changeId:id});
+
+        if(code == 200){
+          this.tableData = rows;
+        }
+        
+      } catch (error) {
+        
+      }finally{
+        this.loading = false;
+      }
+    },
+    // 
+    handleClose(){},
+    handleClick(){
+      this.visible = true;
+    },
+  },
+  created(){},
+}
+</script>
+
+<template>
+
+  <el-button 
+    v-bind="$attrs"
+    v-on="$listeners"
+    :type="type"
+    @click="handleClick"
+    :size="size"
+  >
+    {{ title }}
+    <el-drawer
+      :title="title"
+      v-loading="loading"
+      width="50%"
+      @open="beforeOpen"
+      :visible.sync="visible"
+      append-to-body
+      direction="rtl"
+      :size="size"
+    >
+
+      <div style="padding: 10px;">
+
+        <el-super-table
+          v-model="tableData"
+          :dict="dict"
+          :columns="TableColumns"
+          :size="size"
+          >
+        </el-super-table>
+      </div>
+
+    </el-drawer>
+  </el-button>
+
+</template>

+ 128 - 0
src/views/material/changeApply/batchImport/index.vue

@@ -0,0 +1,128 @@
+<script>
+import { importData, fileImport} from '@/api/requisition/basic';
+export default {
+  name:'BatchImport',
+  props:{},
+  data(){
+    return {
+      title:'批量导入',
+      visible:false,
+      fileData:[]
+    }
+  },
+  methods:{
+    beforeColse(){},
+    handleClick(){
+      this.visible = true;
+    },
+    confirmUpdate(){
+  if (this.fileData.length) {
+
+    let formData = new FormData();
+
+    formData.append('file', this.fileData[0].raw);
+    importData(formData).then(res => {
+      if (res.code == 200) {
+        this.visible = false;
+        this.fileData = [];
+        if (res.data.flag) {
+          this.failLoad = true;
+          console.log(res.data.datas)
+          let param = {failDatas: res.data.datas}
+          if (null != param) {
+
+            fileImport(param).then(res => {
+              console.log('res',res)
+              const isBlob = blobValidate(res);
+              if (isBlob) {
+                const blob = new Blob([res]);
+                saveAs(blob, '导入失败的物料申请单数据.xlsx');
+              }
+              this.failLoad = false;
+            })
+          }
+        }
+        this.$notify({
+          message: res.data.msg,
+          type: res.data.flag ? 'warning' : 'success'
+        });
+      } else {
+        this.$notify({
+          message: res.msg,
+          type: res.code == 200 ? 'success' : 'warning'
+        });
+      }
+    })
+      } else {
+      this.$notify({
+        title:'警告',
+        message: '请上传文件之后在确认!',
+        type: 'warning'
+      });
+      }
+    },
+  
+    handleDownTemplate(){},
+    handleFileRemove(file, fileList) {
+        console.log('删除文件', file, 'file', fileList, 'fileList');
+        this.fileData = fileList;
+      },
+    handleChangeFile(file, fileList){
+      this.fileData = fileList;
+    },
+    cancal(){
+      this.fileData = [];
+      this.visible = false;
+    },
+  },
+  created(){},
+}
+</script>
+
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    type="primary"
+    @click="handleClick"
+    :size="size"
+  >
+    {{ title }}
+    <el-dialog 
+      :title="title" 
+      :visible.sync="visible"
+      width="35%" 
+      center
+      append-to-body
+      :before-close="beforeColse"
+    >
+      <div>
+        <el-upload 
+          accept=".xls, .xlsx" 
+          ref="upload" 
+          action="#" 
+          :on-remove="handleFileRemove"
+          :file-list="fileData" 
+          :auto-upload="false" 
+          :on-change="handleChangeFile" 
+          :limit="1"
+        >
+          <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
+          <el-button 
+            style="margin-left: 10px;" 
+            size="small" 
+            type="success"
+            @click="handleDownTemplate"
+          >下载模板
+          </el-button>
+          <div slot="tip" class="el-upload__tip">只能上传Excel文件</div>
+        </el-upload>
+
+      </div>
+      <span slot="footer">
+        <el-button @click="cancal">取 消</el-button>
+        <el-button type="primary" @click="confirmUpdate">确 定</el-button>
+      </span>
+    </el-dialog>
+  </el-button>
+</template>

+ 77 - 0
src/views/material/changeApply/columns.js

@@ -0,0 +1,77 @@
+export default function useColumns() {
+
+  const TableColumns = [
+    { item: { key: "orgName", title: "所属组织" }, attr: {} },
+    { item: { key: "code", title: "单据编码" }, attr: {} },
+    {
+      item: { key: "applicationTime", title: "申请时间" },
+      attr: { },
+    },
+    { item: { key: "status", title: "单据状态",width:120, }, 
+      attr: {
+        
+        is: "el-dict-tag",
+        dictName: "documents_status", // 字典名
+      } 
+    },
+    // { item: { key: "materialCode", title: "物料编码" }, attr: {} },
+    // {
+    //   item: { key: "materialName", title: "物料名称" },
+    //   attr: {},
+    // },
+    { item: { key: "approver", title: "最后审批人" }, attr: {} },
+    { item: { key: "approvalTime", title: "最后审核时间" }, attr: {} },
+    { item: { key: "createByName", title: "创建人" ,width:150, }, attr: {} },
+    { item: { key: "createTime", title: "创建时间" }, attr: {} },
+    {
+      item: { key: "updateByName", title: "最后修改人" ,width:150, },
+      attr: {  },
+    },
+    { item: { key: "updateTime", title: "最后修改时间" }, attr: {} },
+   
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, fixed: false },
+  }));
+
+  const SearchColumns = [
+    {
+      item: { key: "materialCode", title: "物料编码" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "MATERIAL_PARAM",
+        valueKey: "code",
+        clearable:true,
+        dataMapping: { 
+          materialName: "name",
+        },
+      },
+    },
+    {
+      item: { key: "materialName", title: "物料名称" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "MATERIAL_PARAM",
+        valueKey: "name",
+        clearable:true,
+        dataMapping: { 
+          materialCode: "code",
+        },
+      },
+    },
+    {
+      item: { key: "status", title: "单据状态" },
+      attr: {
+        is: "el-select",
+        dictName: "documents_status",
+        clearable: true,
+      },
+    },
+  
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+
+  return { TableColumns, SearchColumns };
+}

+ 15 - 0
src/views/material/changeApply/dicts.js

@@ -0,0 +1,15 @@
+import { initDicts } from "@/utils/init.js";
+
+const modules = require.context("./add/", true, /column.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);

+ 142 - 239
src/views/material/changeApply/index.vue

@@ -1,278 +1,181 @@
 <template>
-  <div class="changeApply">
-    <div class="applyList" v-if="isList">
-      <el-row :gutter="10" class="mb10">
-          <!-- <el-select size="small" v-model="textValue" placeholder="请选择">
-          <el-option
-            v-for="item in text"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value">
-          </el-option>
-        </el-select>
 
-        <el-select size="small" v-model="ruleValue" placeholder="请选择">
-          <el-option
-            v-for="item in rule"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value">
-          </el-option>
-        </el-select> -->
-        <el-col :span="1.5">
-          <span style="font-size: 14px;margin-right: 5px;">物料编码</span>
-          <el-input
-            v-model="queryParams.materialCode"
-            size="small"
-            placeholder="请输入物料编码查询"
-            clearable
-            style="width: 240px"
-          />
-        </el-col>
+  <el-card 
+    v-loading="loading" 
+    style="width: calc(100% - 24px); height: 100%; margin: 10px;padding: 10px;" 
+    :body-style="{ padding: 0 }"
+  >
 
-        <el-col :span="1.5">
-          <span style="font-size: 14px;margin-right: 5px;">物料名称</span>
-          <el-input
-            v-model="queryParams.materialName"
-            size="small"
-            placeholder="请输入物料名称查询"
-            clearable
-            style="width: 240px"
-          />
-        </el-col>
+    <AddChangeOrders
+      ref="addChangeOrders"
+      :size="size"
+      :dict="dict"
+      :add-type="optionType"
+      @success="useReset"
+    ></AddChangeOrders>
+    <SeeChangeOrders
+      ref="seeChangeOrders"
+      :size="size"
+      :dict="dict"
+      @success="useReset"
+    ></SeeChangeOrders>
 
-        <el-col :span="1.5">
-          <span style="font-size: 14px;margin-right: 5px;">单据状态</span>
-          <el-select 
-            v-model="queryParams.status"
-            size="small"
-            placeholder="请选择单据状态"
-            clearable
-            style="width: 240px">
-            <el-option
-              v-for="item in options"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value">
-            </el-option>
-          </el-select>
-        </el-col>
+    <div>
 
+      <el-super-search
+        v-model="params"
+        :size="size"
+        :dict="dict"
+        :columns="SearchColumns"
+        @reset="useReset"
+        @row-dblclick="useSee"
+        @submit="useQuery(params, page)"
+      ></el-super-search>
+
+      <el-row 
+        :gutter="10" 
+        class="mb10" 
+        type="flex" 
+        justify="end"
+        style="margin-top: 20px;"
+      >
         <el-col :span="1.5">
-          <el-button type="primary" size="small" plain @click="getList(queryParams)">查询</el-button>
-        </el-col>
-        <!-- <el-col :span="1.5">
-          <el-button type="primary" size="small" plain>高级查询</el-button>
-        </el-col> -->
-        <el-col :span="1.5">
-          <el-button type="primary" size="small" plain @click="reset">重置</el-button>
+          <el-button type="primary" size="small" @click="newAdd">新增</el-button>
+          
         </el-col>
-
       </el-row>
 
-    <el-row :gutter="10" class="mb10">
-      <el-col :span="1.5">
-        <el-button type="primary" size="small" plain @click="newAdd">新增</el-button>
-      </el-col>
-      <!-- <el-col :span="1.5">
-        <el-button type="primary" size="small" plain>导入</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button type="primary" size="small" plain>导出</el-button>
-      </el-col> -->
-      <!-- <el-col :span="1.5">
-        <el-button type="primary" size="small" plain>批量提交</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button type="primary" size="small" plain>批量删除</el-button>
-      </el-col> -->
-    </el-row>
 
-    <el-card>
-      <el-table 
-        :data="tableList" 
-        class="request-table"
-        fit
-        max-height="680"
-        @selection-change="handleSelectionChange"
+      <el-super-table
+        v-model="tableList"
+        :dict="dict"
+        :columns="TableColumns"
+        :size="size"
+        pagination
+        :page="page"
+        @pagination="useQuery(params, page)"
+        @row-dblclick="useSee"
       >
-        <!-- <el-table-column type="selection" width="55" /> -->
-        <el-table-column label="序号" align="center" type="index" width="50" />
-        <el-table-column label="所属组织" align="center" width="200" prop="orgId" />
-        <el-table-column label="单据编码" align="center" width="200" prop="code" />
-        <el-table-column label="申请时间" align="center" width="150" prop="createTime" />
-        <el-table-column label="单据状态" align="center" prop="status" :formatter="statusJug" />
-        <el-table-column label="物料编码" align="center" width="150" prop="materialCode" />
-        <el-table-column label="物料名称" align="center" width="150" prop="materialName" />
-        <!-- <el-table-column label="最后审批人" align="center" width="120" prop="approver" />
-        <el-table-column label="最后审核时间" align="center" width="150" prop="approvalTime" /> -->
-        <el-table-column label="创建人" align="center" prop="createByName" />
-        <el-table-column label="创建时间" align="center" width="150" prop="createTime" />
-        <el-table-column label="最后修改人" align="center" width="120" prop="updateByName" />
-        <el-table-column label="最后修改时间" align="center" width="150" prop="updateTime" />
-        <el-table-column
-          fixed="right"
-          label="操作"
-          align="center"
-          width="150"
-          >
+        <el-table-column fixed="right" label="操作" width="150" align="center">
           <template slot-scope="scope">
-            <el-button type="text" size="small" @click="check(scope.row)">查看</el-button>
-            <el-button @click="edit(scope.row)" v-if="scope.row.status == 0 || scope.row.status == 3" type="text" size="small">编辑</el-button>
+            <el-button type="text" size="small" @click="useSee(scope.row)">查看</el-button>
+            <el-button @click="handleEdit(scope.row)" v-if="scope.row.status == 0 || scope.row.status == 3" type="text" size="small">编辑</el-button>
             <el-button type="text" size="small" @click="deleteRow(scope.row)" v-if="scope.row.status == 0 || scope.row.status == 3">删除</el-button>
           </template>
         </el-table-column>
-      </el-table>
-
-      <el-pagination
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-        :page-sizes="[5, 10, 15, 20]"
-        :page-size=queryParams.pageSize
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        style="text-align: center;">
-      </el-pagination>
-    </el-card>
+      </el-super-table>
     </div>
+</el-card>
 
-    <component :is="isComponent" v-model="isList" :pageStu="page" :disable="disable" :row="rowDetail" @refresh="getList" v-if="!isList"/>
-  </div>
 </template>
 
 <script>
-import addApply from './add.vue';
-import { getChangeList , deleteChangeList} from '@/api/changeApply/basic'
+import { dicts } from "./dicts";
+import { getChangeList , deleteChangeList} from '@/api/changeApply/basic';
+import useColumns from './columns';
 export default {
   name: 'changeApply',
+  dicts:dicts,
   components: {
-    addApply
+    AddChangeOrders:() => import('./add/index.vue'),
+    SeeChangeOrders:() => import('./see/index.vue'),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElSuperSearch: () => import("@/components/super-search/index.vue"),
   },
-  data() {
-    return{
+
+  data(){
+    const {TableColumns,SearchColumns} = useColumns();
+    const params = this.$init.params(SearchColumns);
+    return {
+      loading:false,
+      size:'mini',
       tableList: [],
-      queryParams: {
-        materialCode: '',
-        materialName: '',
-        status: '',
-        pageNum: 1,
-        pageSize: 10
-      },
-      options: [{
-        value: 0, label: '未提交'
-      },{
-        value: 1, label: '审批中'
-      },{
-        value: 2, label: '已完成'
-      },{
-        value: 3, label: '已驳回'
-      },],
-      total:0,
-      // isComponent
-      isComponent:'addApply',
-      isList: true,
-      // 页面状态
-      page: '',
-      rowDetail: {},
-      disable: false
+      TableColumns:TableColumns,
+      page: { pageNum: 1, pageSize: 10, total: 0 },
+      params:params,
+      SearchColumns:SearchColumns,
+      optionType:'add',
+
+
     }
   },
-  created() {
+  methods:{
     
-  },
-  mounted() {
-    this.getList(this.queryParams)
-  },
-  methods: {
-    reset() {
-      this.queryParams.materialCode = ''
-      this.queryParams.materialName = ''
-      this.queryParams.pageNum = 1
-      this.queryParams.status = ''
-      this.getList(this.queryParams)
-    },
-    newAdd() {
-      this.isList = false
-      this.isComponent = 'addApply'
-      this.page = 'add'
-      this.disable = false
+    useReset(){
+      this.page.pageNum = 1;
+      this.page.pageSize = 10;
+      this.params = this.$init.params(this.SearchColumns);
+      this.useQuery(this.params, this.page);
     },
-    getList(val) {
-      console.log('val',val)
-      getChangeList(val).then(res => {
-        if (res.code === 200) {
-          this.tableList = res.rows
-          this.total = res.total
-        }
-      })
+    
+    // 
+    openAddChangeOrders(row) {
+    
+      const {setVisible,fetchItem} = this.$refs.addChangeOrders;
+
+      setVisible(true);
+
+      row && fetchItem(row);
     },
-    // 表格内状态栏判断值
-    statusJug(row) {
-      if (row.status == 0) {
-        return '未提交'
-      } else if (row.status == 1) {
-        return '审批中'
-      } else if (row.status == 2) {
-        return '已完成'
-      } else if (row.status == 3) {
-        return '已驳回'
-      }
+
+    async newAdd(){
+      this.optionType = 'add';
+      await this.openAddChangeOrders();
     },
-    // 
-    handleSelectionChange () {
+
+    async handleEdit(row){  
+      this.optionType = 'edit';
+      await this.openAddChangeOrders(row);
 
     },
-    check(row) {
-      console.log('查看详情', row)
-      this.isList = false
-      this.isComponent = 'addApply'
-      this.page = 'check'
-      this.rowDetail = row
-      this.disable = true
+
+    async useQuery(params,page) {
+      try {
+        this.loading = true;
+        let {code,rows,total} = await getChangeList({...params,...page});
+        if (code === 200) {
+          this.tableList = rows
+          this.page.total = total;
+        }
+      } catch (error) {
+        
+      }finally{
+        this.loading = false;
+      }
     },
-    edit(row) {
-      console.log('修改先加载详情', row)
-      this.isList = false
-      this.isComponent = 'addApply'
-      this.page = 'edit'
-      this.rowDetail = row
-      this.disable = false
+   
+
+    async useSee(row){
+      const {setVisible,fetchItem} = this.$refs.seeChangeOrders;
+      await setVisible(true);
+      await fetchItem(row);
+
     },
-    deleteRow(row) {
+    deleteRow(row){
       this.$confirm('是否删除此条数据?', '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          deleteChangeList({id: row.id}).then(res => {
-            if(res.code === 200) {
-              this.$message({
-                message: res.msg,
-                type: 'success'
-              });
-              this.getList(this.queryParams)
-            }
-          })
-        }).catch(() => {})
-    },
-    handleSizeChange(val) {
-      console.log(`每页 ${val} 条`);
-      this.queryParams.pageSize = val
-      this.getList(this.queryParams)
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async() => {
+
+        try {
+          let {code,msg} = await deleteChangeList({id: row.id});
+
+          if(code == 200){
+            this.$notify.success({
+              // title: '成功',
+              message: msg,
+            });
+            await this.useQuery(this.params, this.page);
+          }
+        } catch (error) {}
+      })
     },
-    handleCurrentChange(val) {
-      console.log(`当前页: ${val}`);
-      this.queryParams.pageNum = val
-      this.getList(this.queryParams)
-    }
-  }
+ 
+  },
+  created(){
+    this.useQuery(this.params, this.page);
+  },
 }
-</script>
 
-<style scoped lang="scss">
-.changeApply {
-  height: calc(100vh - 84px);
-  padding: 12px;
-  box-sizing: border-box;
-}
-</style>
+</script>

+ 289 - 0
src/views/material/changeApply/see/index.vue

@@ -0,0 +1,289 @@
+<!-- 批量新增 -->
+<script>
+import useColumns from "../add/column";
+import {addChangeList, getMaterialDetails, getChangeDetails, editChangeList} from '@/api/changeApply/basic';
+
+
+export default {
+  name: "SeeChangeOrders",
+  props: {
+    dict: {
+      type: Object,
+    },
+  },
+  components: {
+    AmendantRecord: () => import("../amendantRecord/index.vue"),
+    ElSuperForm: () => import("@/components/super-form/index.vue"),
+    ElSuperTable: () => import("@/components/super-table/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/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]);
+    let tabColumns = _.cloneDeep(TabColumns);
+    tabColumns =  tabColumns.map(item =>( 
+
+      {...item,
+        TableColumns: [...item.TableColumns.map(column =>({
+          item:{...column.item,disabled:true},
+          attr:{
+            ...column.attr,
+            disabled:true
+          }
+        }))]
+      }
+      )
+
+    )
+
+    console.log(tabColumns,'tabColumns');
+    
+    return {
+      width: "100%",
+      visible: false,
+      loading:false,
+      title:'查看',
+      rules,
+      params,
+      tabName: tabName,
+      TabColumns: tabColumns,
+      TableColumns: TableColumns,
+    };
+  },
+  computed: {
+   
+    materialInfo:{
+      get(){
+        const { materialBasic } = this.params;
+        this.params.materialBasic = materialBasic.map((item, index) => ({
+          ...item,
+          $index: index,
+        }));
+
+        return {
+          materialBasic: this.params.materialBasic.filter(
+            ({ delFlag }) => delFlag !== "2"
+          ),
+        }
+      },
+      set(){},
+    }
+  
+  },
+  watch: {
+    
+  },
+  methods: {
+    setVisible(prop){
+      this.visible = prop;
+    },
+    beforeOpen(){
+    },
+    //
+    async fetchItem(prop) {
+      try {
+        // try
+        this.loading = true;
+
+        let { code, data } = await getChangeDetails(prop.id);
+
+        if(code == 200){
+          this.params = data;
+        }
+        
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    
+    //
+    async hide() {
+      const {
+        TabColumns,
+        TableColumns,
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
+      this.visible = false;
+      this.tabName = tabName;
+      this.$emit('success');
+      this.params = this.$init.params([...TabColumns, ...TableColumns]);
+    },
+   
+    async handleSubmit(){
+      this.params = {...this.params,status:'1'};
+      console.log(this.params,'this.params');
+      try {
+          this.loading = true;
+          
+          const {code,msg} = await addChangeList(this.params);
+
+          if(code == 200){
+
+            this.hide();
+            this.$notify.success({
+              message: msg,
+            });
+          }
+          
+        } catch (error) {}
+        finally{
+          this.loading = false;
+        }
+    },
+    handleSubmitValidate(prop,cb){
+
+      this.$refs[prop].$refs[prop].validate(async (valid) => {
+        if (valid) {
+          try {
+            this.loading = true;
+
+            await cb();
+            
+          } catch (err) {
+            // catch
+            console.error(err);
+          } finally {
+            // finally
+            this.loading = false;
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+  },
+  created() {
+  },
+  mounted() {},
+  destroyed() {},
+};
+</script>
+
+<template>
+    <el-drawer
+      v-bind="$attrs"
+      v-on="$listeners"
+      :size="width"
+      :visible.sync="visible"
+      destroy-on-close
+      :show-close="false"
+      @close="hide"
+      @open="beforeOpen"
+      v-loading="loading"
+    >
+      <div 
+        slot="title" 
+        style="display: flex;
+            justify-content: space-between;
+            align-items: center;"
+      >
+        <h3>{{title}}</h3>
+        <div>
+          <el-button 
+            v-if="params.status === '0' || params.status === '3'"
+            type="primary"
+            :size="$attrs.size" 
+            :loading="loading" 
+            @click="handleSubmit"
+          >
+            提 交
+          </el-button>
+          <el-button :size="$attrs.size" :loading="loading" @click="hide"
+            >取 消</el-button>
+        </div>
+      </div>
+      <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="materialInfo[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="120" align="center">
+                
+                <template slot-scope="scope">
+                  <AmendantRecord
+                    v-if=" tabName ==='materialBasic' "
+                    v-model="scope.row"
+                  ></AmendantRecord>
+                  
+                </template>
+              </el-table-column>
+            </el-super-table>
+          </el-tab-pane>
+        </el-tabs>
+     
+    </el-drawer>
+</template>
+
+<style scoped>
+::v-deep .el-table__row.is-hidden {
+  display: none;
+}
+</style>
+
+

+ 6 - 5
src/views/purchase/DemandSummary/add.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="checkDemandSummary">
-    <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+    <el-card style="position: relative;">
       <span>采购需求处理详情</span>
       <div class="btn_grooup">
         <el-button type="primary" size="mini" @click="editLine">编辑</el-button>
@@ -17,7 +17,7 @@
           :header-cell-style="{ borderColor: '#c0c0c0' }"
           class="exporttable"
           border
-          max-height="680"
+          max-height="580"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
         >
@@ -309,9 +309,10 @@ export default {
         reloadBatch(param).then(res => {
           if (res.code === 200) {
             this.$modal.notifySuccess("操作成功");
-            let param = JSON.parse(JSON.stringify(this.query))
-            param.sumFlag = this.row.sumFlag
-            this.getDetails(param)
+            let params = JSON.parse(JSON.stringify(this.query))
+            params.sumFlag = this.row.sumFlag
+            params.demandItemId = this.row.demandItemId
+            this.getDetails(params)
           }
         })
       }).catch(() =>{})

+ 4 - 4
src/views/purchase/DemandSummary/index.vue

@@ -228,7 +228,8 @@
           border
           show-summary
           :summary-method="getSummaries"
-          max-height="550"
+          height="355"
+          max-height="355"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
           :key="isUpdate"
@@ -344,7 +345,7 @@
 </template>
 
 <script>
-import Add from './add.vue'
+import Add from './add'
 import Refers from '@/components/Refers/refers.vue'
 import TreeRefers from '@/components/Refers/treeRefer.vue'
 import popDialog from '@/components/PopDialog/index.vue'
@@ -783,7 +784,6 @@ export default {
 
 <style lang="scss" scoped>
 #demandSummary {
-  height: calc(100vh - 84px);
   padding: 12px;
   box-sizing: border-box;
   overflow-y: scroll;
@@ -810,7 +810,7 @@ export default {
   border: none;
 }
  ::v-deep .el-card .el-form-item {
-  margin-bottom: 10px;
+  margin-bottom: 3px;
 }
 </style>
 <style>

+ 6 - 5
src/views/purchase/MaterialClassDivision/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="MaterialClassDivision">
     <div v-if="isList">
-      <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+      <el-card style="position: relative;">
       <el-form class="search_area" label-width="130px">
         <el-row :gutter="10">
           <el-col :span="1.5">
@@ -215,11 +215,13 @@
           :header-cell-style="{ borderColor: '#c0c0c0' }"
           class="exporttable"
           border
-          max-height="480"
+          height="390"
+          max-height="390"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
         >
-          <el-table-column show-overflow-tooltip type="selection" width="55" />
+          <el-table-column show-overflow-tooltip type="selection" width="55" fixed="left"/>
+          <el-table-column show-overflow-tooltip label="序号" type="index" align="center" width="50px" fixed="left"/>
           <el-table-column show-overflow-tooltip label="物料分类编码" align="center" width="120" prop="materialClassify"/>
           <!-- <el-table-column show-overflow-tooltip label="物料分类名称" align="center" width="200" prop="materialClassifyName" /> -->
           <el-table-column show-overflow-tooltip label="一级分类名称" align="center" width="120" prop="materialClassifyOneName" />
@@ -484,7 +486,6 @@ export default {
 
 <style lang="scss" scoped>
 #MaterialClassDivision {
-  height: calc(100vh - 84px);
   padding: 12px;
   box-sizing: border-box;
   overflow-y: scroll;
@@ -501,7 +502,7 @@ export default {
   border: none;
 }
  ::v-deep .el-card .el-form-item {
-  margin-bottom: 10px;
+  margin-bottom: 3px;
 }
 .el-pagination {
   margin-top: 10px;

+ 130 - 120
src/views/purchase/PurchaseDemandList/add.vue

@@ -1,18 +1,123 @@
 <template>
   <div id="addDemandList">
-  <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+  <el-card style="position: relative;">
     <span>基本信息</span>
-    <el-form :model="basicForm" :rules="basicRules" ref="basic" label-width="auto">
+    <el-form :model="basicForm" :rules="basicRules" ref="basic" label-width="auto" :show-message="false">
       <el-row :gutter="10">
         <el-col :span="1.5">
-            <el-form-item label="编码">
-              <el-input
-                v-model="basicForm.code"
-                size="mini"
-                disabled
-                style="width: 200px"
-              />
-            </el-form-item>
+          <el-form-item label="业务类型" prop="billType" :rules="{ required: true, message: '请选择业务类型', trigger: 'blur' }">
+            <el-select clearable v-model="basicForm.billType" @change="changeBillType" :disabled="sonDisable" size="mini" style="width: 200px">
+              <el-option v-for=" dict in dict.type.sys_business" :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="需求客户">
+            <el-select clearable size="mini" v-model="basicForm.customer" :disabled="sonDisable" @clear="cleanCustomer" @focus="chooseOrg('CUSTOMER_PARAM', true, '选择客户')" style="width: 200px">
+              <el-option v-for="item in customerOptions" :key="item.id" :label="item.name" :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="1.5">
+          <el-form-item label="需求人员">
+              <el-select clearable size="mini" v-model="basicForm.demandPersonal" :disabled="sonDisable" @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="basicForm.demandDept" size="mini" :disabled="sonDisable" @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 v-model="basicForm.planType" size="mini" style="width: 200px">
+              <el-option v-for="dict in dict.type.sys_plan_type" :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="demandDate" :rules="{ required: true, message: '请选择需求日期', trigger: 'blur' }">
+            <el-date-picker
+              v-model="basicForm.demandDate"
+              :disabled="sonDisable"
+              clearable
+              type="date"
+              value-format="yyyy-MM-dd"
+              @change="changeDemandDate"
+              size="mini"
+              style="width: 200px"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="1.5">
+          <el-form-item label="制单日期" prop="createTime">
+            <el-date-picker
+              v-model="basicForm.createTime"
+              :disabled="sonDisable"
+              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="是否客户指定">
+            <el-select clearable v-model="basicForm.isSpeical" :disabled="sonDisable" size="mini" style="width: 200px">
+              <el-option v-for=" item in options" :key="item.value" :label="item.label" :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="1.5">
+          <el-form-item label="备注">
+            <el-input
+              v-model.trim="basicForm.remark"
+              size="mini"
+              :disabled="sonDisable"
+              clearable
+              style="width: 200px"
+            />
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="1.5">
+          <el-form-item label="需求客户名称">
+            <el-input disabled v-model="basicForm.customerName" size="mini" style="width: 200px"></el-input>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="1.5">
+          <el-form-item label="编码">
+            <el-input
+              v-model="basicForm.code"
+              size="mini"
+              disabled
+              style="width: 200px"
+            />
+          </el-form-item>
          </el-col>
 
         <!-- <el-col :span="1.5">
@@ -33,20 +138,6 @@
           </el-col>
 
          <el-col :span="1.5">
-            <el-form-item label="需求客户">
-              <el-select clearable size="mini" v-model="basicForm.customer" :disabled="sonDisable" @clear="cleanCustomer" @focus="chooseOrg('CUSTOMER_PARAM', true, '选择客户')" style="width: 200px">
-                <el-option v-for="item in customerOptions" :key="item.id" :label="item.name" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-
-         <el-col :span="1.5">
-            <el-form-item label="需求客户名称">
-              <el-input disabled v-model="basicForm.customerName" size="mini" style="width: 200px"></el-input>
-            </el-form-item>
-          </el-col>
-
-         <el-col :span="1.5">
             <el-form-item label="客户负责人">
               <el-select disabled size="mini" v-model="basicForm.customerPrincipal" style="width: 200px">
                 <el-option v-for="item in manOptions" :key="item.id" :label="item.name" :value="item.code"/>
@@ -54,43 +145,6 @@
             </el-form-item>
           </el-col>
 
-         <el-col :span="1.5">
-            <el-form-item label="需求人员">
-                <el-select clearable size="mini" v-model="basicForm.demandPersonal" :disabled="sonDisable" @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="basicForm.demandDept" size="mini" :disabled="sonDisable" @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="需求日期" prop="demandDate" :rules="{ required: true, message: '请选择需求日期', trigger: 'blur' }">
-              <el-date-picker
-                v-model="basicForm.demandDate"
-                :disabled="sonDisable"
-                clearable
-                type="date"
-                value-format="yyyy-MM-dd"
-                @change="changeDemandDate"
-                size="mini"
-                style="width: 200px"
-              >
-              </el-date-picker>
-            </el-form-item>
-         </el-col>
-
           <el-col :span="1.5">
             <el-form-item label="单据来源">
               <el-select v-model="basicForm.source" disabled size="mini" style="width: 200px">
@@ -99,51 +153,6 @@
               </el-select>
             </el-form-item>
          </el-col>
-
-         <el-col :span="1.5">
-            <el-form-item label="业务类型" prop="billType" :rules="{ required: true, message: '请选择业务类型', trigger: 'blur' }">
-              <el-select clearable v-model="basicForm.billType" @change="changeBillType" :disabled="sonDisable" size="mini" style="width: 200px">
-                <el-option v-for=" dict in dict.type.sys_business" :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="是否客户指定">
-              <el-select clearable v-model="basicForm.isSpeical" :disabled="sonDisable" size="mini" style="width: 200px">
-                <el-option v-for=" item in options" :key="item.value" :label="item.label" :value="item.value">
-                </el-option>
-              </el-select>
-            </el-form-item>
-         </el-col>
-
-          <el-col :span="1.5">
-            <el-form-item label="制单日期" prop="createTime">
-              <el-date-picker
-                v-model="basicForm.createTime"
-                :disabled="sonDisable"
-                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="备注">
-              <el-input
-                v-model.trim="basicForm.remark"
-                size="mini"
-                :disabled="sonDisable"
-                clearable
-                style="width: 200px"
-              />
-            </el-form-item>
-         </el-col>
       </el-row>
 
 
@@ -164,8 +173,8 @@
           :cell-style="{ borderColor: '#c0c0c0' }"
           :header-cell-style="{ borderColor: '#c0c0c0' }"
           class="exporttable"
-          height="290"
-          max-height="290"
+          height="410"
+          max-height="410"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
           :cell-class-name="cellClassName"
@@ -182,7 +191,7 @@
           <el-table-column show-overflow-tooltip label="行状态" align="center" prop="status" :formatter="hangStatus" width="100px"/>
           <el-table-column show-overflow-tooltip label="物料编码" align="center" prop="materialCode" width="220px" :render-header="addRedStar">
             <template slot-scope="scope">
-              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'materialCode'" :rules="{ required: true, message: '请选择物料编码', trigger: 'blur' }">
+              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'materialCode'" :show-message="false" :rules="{ required: true, message: '请选择物料编码', trigger: 'blur' }">
                 <el-input clearable :disabled="sonDisable" size="mini" v-model="scope.row.materialCode" @paste.native="pasteMe($event, scope, scope.$index)">
                   <el-button size="mini" :disabled="sonDisable" slot="append" icon="el-icon-more" @click="chooseMaterial(scope.$index)"></el-button>
                 </el-input>
@@ -197,7 +206,7 @@
           <el-table-column show-overflow-tooltip label="最小包装" align="center"  prop="minPackage" width="100px"/>
           <el-table-column show-overflow-tooltip label="实际(业务)需求量" align="center"  prop="qty" width="150px" :render-header="addRedStar">
             <template slot-scope="scope">
-              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'qty'" :rules="{ required: true, message: '请填写实际(业务)需求量', trigger: 'blur' }">
+              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'qty'" :show-message="false" :rules="{ required: true, message: '请填写实际(业务)需求量', trigger: 'blur' }">
                 <el-input type="number" min="0" clearable :disabled="sonDisable" size="mini" v-model="scope.row.qty" @input="getYLSL(scope)"/>
               </el-form-item>
             </template>
@@ -357,7 +366,7 @@
           <el-table-column show-overflow-tooltip label="详细地址" align="center"  prop="address" width="200px"/>
           <el-table-column show-overflow-tooltip label="价格类型" align="center"  prop="priceType" width="120px">
             <template slot-scope="scope">
-              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'priceType'" :rules="{ required: true, message: '请选择价格类型', trigger: 'blur' }">
+              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'priceType'" :show-message="false" :rules="{ required: true, message: '请选择价格类型', trigger: 'blur' }">
                 <el-select clearable :disabled="sonDisable" size="mini" v-model="scope.row.priceType">
                   <el-option v-for=" dict in dict.type.sys_price_type" :key="dict.value" :label="dict.label" :value="dict.value">
                   </el-option>
@@ -522,7 +531,7 @@ import popDialog from '@/components/PopDialog/index.vue'
 export default {
   name: 'addDemandList',
   props: ['pageStu','row', 'disable'],
-  dicts: ['sys_processing_mode', 'sys_status', 'sys_bill_source', 'sys_business','sys_reserve_ratio', 'sys_period_unit', 'sys_price_type'],
+  dicts: ['sys_processing_mode', 'sys_plan_type', 'sys_status', 'sys_bill_source', 'sys_business','sys_reserve_ratio', 'sys_period_unit', 'sys_price_type'],
   components: {
     Reserved,
     Refers,
@@ -554,6 +563,7 @@ export default {
         customerPrincipal: '',
         demandPersonal: this.$store.state.user.name,
         demandDept: this.$store.state.user.deptId,
+        planType: '1',
         demandDate: '',
         createTime: '',
         source: '4',
@@ -640,12 +650,10 @@ export default {
       if (this.basicForm.billType == 'BDXQ' && this.basicForm.puDemandItemList.length != 0) {
         this.isBDXQ = true
         this.BDZT = false
-        this.anotherRedStar()
         this.basicForm.puDemandItemList.forEach(item => {item.isReplenishment = 'Y'})
       } else {
         this.isBDXQ = false
         this.BDZT = true
-        this.anotherRedStar()
         this.basicForm.puDemandItemList.forEach(item => {
           item.isReplenishment = 'N'
           item.additionalSupplier = null
@@ -701,6 +709,10 @@ export default {
       this.basicForm.createBy = ''
       this.basicForm.source = '4'
       this.basicForm.isSpeical = 'N'
+      this.basicForm.demandPersonal = this.$store.state.user.name
+      this.basicForm.demandDept = this.$store.state.user.deptId
+      if (this.basicForm.demandPersonal) { this.reBackRefer('CONTACTS_PARAM', this.basicForm.demandPersonal, '需求人员') }
+      if (this.basicForm.demandDept) { this.reBackRefer('DEPT_PARAM', this.basicForm.demandDept) }
       this.basicForm.puDemandItemList.forEach(item => {
         item.status = ''
         item.buyerName = ''
@@ -979,11 +991,9 @@ export default {
               if(this.basicForm.billType == 'BDXQ') {
                  this.BDZT = false
                  this.isBDXQ = true
-                 this.anotherRedStar()
               } else {
                  this.BDZT = true
                  this.isBDXQ = false
-                 this.anotherRedStar()
               }
             }
           })
@@ -1754,10 +1764,10 @@ export default {
 .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 .el-form-item__error{
+//   padding-top: 0;
+//   top: 70%
+// }
 .el-table ::v-deep .success-row {
   background: #f11616;
 }

+ 2 - 4
src/views/purchase/PurchaseDemandList/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="PurchaseDemandList">
     <div v-if="isList">
-      <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+      <el-card style="position: relative;">
         <el-form class="search_area" label-width="100px">
           <el-row :gutter="10">
             <el-col :span="1.5">
@@ -165,9 +165,8 @@
           :cell-style="{ borderColor: '#c0c0c0' }"
           :header-cell-style="{ borderColor: '#c0c0c0' }"
           class="exporttable"
+          max-height="410"
           border
-          height="430"
-          max-height="430"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
         >
@@ -710,7 +709,6 @@ export default {
 
 <style lang="scss" scoped>
 #PurchaseDemandList {
-  height: calc(100vh - 84px);
   padding: 12px;
   box-sizing: border-box;
   overflow-y: scroll;

+ 6 - 5
src/views/purchase/deliveryAddress/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="deliveryAddressList">
     <div v-if="isList">
-      <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+      <el-card style="position: relative;">
       <el-form class="search_area" label-width="100px">
         <el-row :gutter="10">
           <el-col :span="1.5">
@@ -176,11 +176,13 @@
           :header-cell-style="{ borderColor: '#c0c0c0' }"
           class="exporttable"
           border
-          max-height="480"
+          height="430"
+          max-height="430"
           style="font-size: 12px;"
           @selection-change="handleSelectionChange"
         >
-          <el-table-column show-overflow-tooltip type="selection" width="55" />
+          <el-table-column show-overflow-tooltip type="selection" width="55" fixed="left"/>
+          <el-table-column show-overflow-tooltip label="序号" type="index" align="center" width="50px" fixed="left"/>
           <el-table-column show-overflow-tooltip label="仓库属性" align="center" width="120" prop="warehouseProperty" :formatter="formatterWarehouseProperty"/>
           <el-table-column show-overflow-tooltip label="仓库档案名称" align="center" width="180" prop="warehouseName"/>
           <el-table-column show-overflow-tooltip label="收货仓库编码" align="center" prop="code" width="150"/>
@@ -498,7 +500,6 @@ export default {
 
 <style lang="scss" scoped>
 #deliveryAddressList {
-  height: calc(100vh - 84px);
   padding: 12px;
   box-sizing: border-box;
   overflow-y: scroll;
@@ -519,7 +520,7 @@ export default {
   border: none;
 }
  ::v-deep .el-card .el-form-item {
-  margin-bottom: 10px;
+  margin-bottom: 3px;
 }
 </style>
 <style>

+ 26 - 16
src/views/purchase/purchase-order/index.vue

@@ -61,8 +61,8 @@ export default {
     },
   },
   created() {
-    // this.fetchList(this.params, this.page);
-    this.handleRefreshList();
+    this.fetchList(this.params, this.page);
+    // this.handleRefreshList();
   },
   methods: {
     async fetchList(data, params) {
@@ -115,10 +115,19 @@ export default {
       this.page.pageNum = 1;
 
       this.page.pageSize = 10;
+      console.log(this,'this-------------------');
 
-      this.checkedList = [];
+      this.$refs.purchaseTable.$refs.superTable.clearSelection();
+
+      for (const key in this.tabTableDatas) {
+        this.tabTableDatas[key] = []
+      }
+
+      this.$refs.puOrderItemList[0].$refs.superTable.clearSelection();
+
+      // this.checkedList = [];
               
-      this.checkedTabList = [];
+      // this.checkedTabList = [];
 
       this.primaryResource = {};
 
@@ -188,9 +197,11 @@ export default {
       await fetchItem(id);
       
     },
+    
     // 获取子表信息
      handleDetailsData(row) {
 
+      
       window.clearTimeout(this.timeOut);
 
       this.timeOut = setTimeout(async () =>{
@@ -465,6 +476,9 @@ export default {
       console.log(this.checkedList, 'this.checkedList');
 
     },
+    handleSelectionChange(selection){
+      this.checkedList = selection;
+    },
     // 子表Select框
     handleTabSelect(selection, row){
 
@@ -472,6 +486,9 @@ export default {
 
       console.log(this.checkedTabList, 'this.checkedTabList');
     },
+    handleTabSelectionChange(selection){
+      this.checkedTabList = selection;
+    },
     // 保留两位小数,补位
     keepTwoDecimalStr(num) {
 
@@ -582,6 +599,7 @@ export default {
 
     <el-super-table
       v-model="tableData"
+      ref="purchaseTable"
       max-height="480"
       :dict="dict"
       :columns="tableColumns"
@@ -593,11 +611,9 @@ export default {
       @pagination="fetchList(params, page)"
       @row-dblclick="handleOpenSeeDrawer" 
       @row-click="handleDetailsData" 
+      @selection-change="handleSelectionChange"
       @select="handleSelect"
     >
-
-      <!-- <el-table-column type="selection" width="45" fixed></el-table-column>
-      <el-table-column type="index" width="50" label="序号"></el-table-column> -->
       
       <el-table-column fixed="right" label="操作" width="120">
           <template slot-scope="scope">
@@ -637,15 +653,6 @@ export default {
     
     </el-super-table>
 
-    <!-- <pagination
-      v-show="page.total>0"
-      :total="page.total"
-      :page.sync="page.pageNum"
-      :limit.sync="page.pageSize"
-      :page-sizes="[10,20,50,100,500,1000]"
-      @pagination="fetchList(params, page)"
-    />
-    -->
     <div style="position: relative; padding-top: 10px;" v-loading="tabLoading">
       <el-row style="position: absolute; top: 30px; right: 20px;z-index: 10;">
         <el-button 
@@ -664,6 +671,7 @@ export default {
         >
           <el-super-table
             v-model="tabTableDatas[column.key]"
+            :ref="column.key"
             max-height="200"
             :dict="dict"
             :columns="column.tableColumns"
@@ -671,6 +679,8 @@ export default {
             :checkbox="setTabSelectable()"
             :iconOperation="false"
             @select="handleTabSelect"
+            @selection-change="handleTabSelectionChange"
+
           >
             <!-- <el-table-column
               v-if=" tabName === 'puOrderItemList'" 

+ 9 - 12
src/views/purchase/transferOrder/add.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="addOder">
-    <el-card style="height: calc(100vh - 15vh);position: relative;overflow: scroll;">
+    <el-card style="position: relative;">
       <span>基本信息</span>
       <el-form
         :model="basicForm"
@@ -17,7 +17,7 @@
                 v-model="basicForm.deliveryInventoryOrg"
                 :disabled="sonDisable"
                 @clear="clean('调出库存组织')"
-                @change="controlCk"
+                @change="controlCk('调出库存组织')"
                 @focus="chooseRefer('ORG_PARAM', true, '调出库存组织')"
                 style="width: 200px"
               >
@@ -124,7 +124,7 @@
                 v-model="basicForm.storageInventoryOrg"
                 :disabled="sonDisable"
                 @clear="clean('调入库存组织')"
-                @change="controlCk"
+                @change="controlCk('调入库存组织')"
                 @focus="chooseRefer('ORG_PARAM', true, '调入库存组织')"
                 style="width: 200px"
               >
@@ -452,7 +452,7 @@
               :data="materialInfo"
               fit
               border
-              max-height="480"
+              max-height="280"
               style="font-size: 12px"
               :row-class-name="rowClassName"
             >
@@ -935,7 +935,7 @@
               :data="receiveInfo"
               fit
               border
-              max-height="480"
+              max-height="280"
               style="font-size: 12px"
             >
               <el-table-column
@@ -1136,7 +1136,7 @@
               :data="priceList"
               fit
               border
-              max-height="480"
+              max-height="280"
               style="font-size: 12px"
             >
               <el-table-column
@@ -1267,7 +1267,7 @@
               :data="resultList"
               fit
               border
-              max-height="480"
+              max-height="280"
               style="font-size: 12px"
             >
               <el-table-column
@@ -1704,12 +1704,9 @@ export default {
       });
     },
     // 控制先选调出库存组织和调入库存组织再选调出部门和调入调出仓库
-    controlCk() {
+    controlCk(val) {
       console.log("进了吗");
-      if (
-        this.basicForm.deliveryInventoryOrg &&
-        this.basicForm.storageInventoryOrg
-      ) {
+      if (this.basicForm.deliveryInventoryOrg && this.basicForm.storageInventoryOrg){
         this.isOrg = false;
       } else {
         this.basicForm.deliveryDept = "";

+ 5 - 4
src/views/purchase/transferOrder/index.vue

@@ -78,7 +78,8 @@
           show-summary
           :summary-method="getSummaries"
           highlight-current-row
-          max-height="680"
+          height="280"
+          max-height="280"
           style="font-size: 12px;"
           ref="multipleTable"
           @row-click="select"
@@ -150,7 +151,8 @@
             :header-cell-style="{ borderColor: '#c0c0c0' }"
             class="exporttable"
             border
-            max-height="380"
+            height="125"
+            max-height="125"
             style="font-size: 12px;"
             >
             <el-table-column show-overflow-tooltip label="行号" align="center" prop="rowno"/>
@@ -542,7 +544,6 @@ export default {
 
 <style lang="scss" scoped>
 #transferOrder {
-  height: calc(100vh - 84px);
   padding: 12px;
   box-sizing: border-box;
   overflow-y: scroll;
@@ -563,7 +564,7 @@ export default {
   border: none;
 }
  ::v-deep .el-card .el-form-item {
-  margin-bottom: 10px;
+  margin-bottom: 3px;
 }
 </style>
 <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]: "",