Browse Source

Merge remote-tracking branch 'origin/purchaseDev' into goalManagementDev

# Conflicts:
#	vue.config.js
002637 1 year ago
parent
commit
95a9b8dc2a
100 changed files with 4016 additions and 3334 deletions
  1. 0 1
      .gitignore
  2. 1 0
      package.json
  3. 12 1
      src/api/business/purchase/purchase-order.js
  4. 25 14
      src/api/material/basic.js
  5. 11 0
      src/assets/styles/element-ui.scss
  6. 4 2
      src/components/DictTag/index.vue
  7. 5 0
      src/components/FileUpload/index.vue
  8. 1 1
      src/components/PopDialog/dose.vue
  9. 1 1
      src/components/PopDialog/drug.vue
  10. 1 1
      src/components/PopDialog/fourClass.vue
  11. 1 1
      src/components/PopDialog/index.vue
  12. 1 1
      src/components/PopDialog/innerPackingUnit.vue
  13. 1 1
      src/components/PopDialog/midPack.vue
  14. 1 1
      src/components/PopDialog/organization.vue
  15. 1 1
      src/components/PopDialog/place.vue
  16. 1 1
      src/components/PopDialog/productFactory.vue
  17. 1 1
      src/components/PopDialog/serviceline.vue
  18. 1 1
      src/components/PopDialog/staff.vue
  19. 1 1
      src/components/PopDialog/tax.vue
  20. 1 1
      src/components/PopDialog/unit.vue
  21. 1 1
      src/components/Refers/batchRefer.vue
  22. 46 4
      src/components/Refers/refers.vue
  23. 1 1
      src/components/Refers/treeRefer.vue
  24. 7 5
      src/components/computed-input-v2/index.vue
  25. 3 1
      src/components/computed-input/index.vue
  26. 51 0
      src/components/draggable/index.vue
  27. 3 2
      src/components/file-preview/index.vue
  28. 26 37
      src/components/popover-select-v2/index.vue
  29. 28 45
      src/components/popover-select-v2/multiple.vue
  30. 4 4
      src/components/popover-select/components/CUSTOMERDEPT_PARAM.js
  31. 0 22
      src/components/popover-tree-select/components/MATERIALCLASSIFY_PARAM.js
  32. 126 220
      src/components/popover-tree-select/index.vue
  33. 283 0
      src/components/popover-tree-select/multiple.vue
  34. 77 0
      src/components/super-descriptions/index.vue
  35. 133 0
      src/components/super-form/index.vue
  36. 235 0
      src/components/super-search/index.vue
  37. 309 0
      src/components/super-table/index.vue
  38. 9 0
      src/main.js
  39. 18 6
      src/utils/request.js
  40. 158 133
      src/views/WMS/historical-route/index.vue
  41. 1 1
      src/views/business/spd/bo/authority/index.vue
  42. 1 1
      src/views/business/spd/bo/basic/accessoryList.vue
  43. 2 2
      src/views/business/spd/bo/basic/details.vue
  44. 1 1
      src/views/business/spd/bo/basic/filemanager copy.vue
  45. 1 1
      src/views/business/spd/bo/basic/index.vue
  46. 1 1
      src/views/business/spd/bo/behavior/behaviorList.vue
  47. 1 1
      src/views/business/spd/bo/contact/contactList.vue
  48. 1 1
      src/views/business/spd/bo/education/educationList.vue
  49. 1 1
      src/views/business/spd/bo/filetemplate/index.vue
  50. 1 1
      src/views/business/spd/bo/pojpsn/pojpsnList.vue
  51. 1 1
      src/views/business/spd/bo/refer/contact/index.vue
  52. 1 1
      src/views/business/spd/bo/refer/customer/index.vue
  53. 1 1
      src/views/business/spd/bo/refer/dept/index.vue
  54. 1 1
      src/views/business/spd/bo/refer/org/index.vue
  55. 1 1
      src/views/business/spd/bo/refer/saleaea/index.vue
  56. 1 1
      src/views/business/spd/bo/refer/staff/index.vue
  57. 1 1
      src/views/business/spd/bo/relationship/relationshipList.vue
  58. 1 1
      src/views/business/spd/bo/task/index.vue
  59. 1 1
      src/views/business/spd/bo/task/taskList.vue
  60. 1 1
      src/views/marketing/dealer-authorization/authprivAdd.vue
  61. 1 1
      src/views/marketing/dealer-authorization/authprivSee.vue
  62. 195 106
      src/views/material/basicFile/details.vue
  63. 410 387
      src/views/material/basicFile/index.vue
  64. 21 1
      src/views/material/basicFile/init/index.js
  65. 16 8
      src/views/material/changeApply/add.vue
  66. 1 1
      src/views/material/label/label-add-dialog.vue
  67. 1 1
      src/views/material/label/label-auto-bind-dialog.vue
  68. 1 1
      src/views/material/label/label-bind-dialog.vue
  69. 1 1
      src/views/material/label/label-edit-dialog.vue
  70. 1 1
      src/views/material/label/label-hand-bind-dialog.vue
  71. 47 25
      src/views/material/requisition/add.vue
  72. 0 173
      src/views/material/requisition/index copy.vue
  73. 8 1
      src/views/material/requisition/index.vue
  74. 0 217
      src/views/material/requisition/index_bak.vue
  75. 0 62
      src/views/material/requisition/list.vue
  76. 1 1
      src/views/material/specialAttr/index.vue
  77. 33 2
      src/views/monitor/job/index.vue
  78. 1 1
      src/views/monitor/job/log.vue
  79. 1 1
      src/views/monitor/operlog/index.vue
  80. 22 4
      src/views/purchase/DemandSummary/add.vue
  81. 33 66
      src/views/purchase/DemandSummary/index.vue
  82. 26 5
      src/views/purchase/MaterialClassDivision/add.vue
  83. 190 31
      src/views/purchase/PurchaseDemandList/add.vue
  84. 37 26
      src/views/purchase/PurchaseDemandList/index.vue
  85. 0 312
      src/views/purchase/apply/add/column.js
  86. 322 0
      src/views/purchase/apply/add/columns.js
  87. 385 213
      src/views/purchase/apply/add/index.vue
  88. 0 94
      src/views/purchase/apply/column.js
  89. 109 0
      src/views/purchase/apply/columns.js
  90. 63 17
      src/views/purchase/apply/delete/index.vue
  91. 14 0
      src/views/purchase/apply/dicts.js
  92. 0 313
      src/views/purchase/apply/edit/index.vue
  93. 0 24
      src/views/purchase/apply/hooks/data.js
  94. 0 55
      src/views/purchase/apply/hooks/function.js
  95. 0 46
      src/views/purchase/apply/hooks/watch.js
  96. 82 282
      src/views/purchase/apply/index.vue
  97. 210 0
      src/views/purchase/apply/see/columns.js
  98. 111 174
      src/views/purchase/apply/see/index.vue
  99. 63 17
      src/views/purchase/apply/submit/index.vue
  100. 0 131
      src/views/purchase/catalogue/column.js

+ 0 - 1
.gitignore

@@ -22,4 +22,3 @@ selenium-debug.log
 package-lock.json
 yarn.lock
 vue.config.js
-vue.config.js

+ 1 - 0
package.json

@@ -62,6 +62,7 @@
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
     "vue-meta": "2.4.0",
+    "vue-print-nb": "^1.7.5",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",
     "vuex": "3.6.0"

+ 12 - 1
src/api/business/purchase/purchase-order.js

@@ -74,6 +74,16 @@ const getPrice = (data) => {
   });
 }
 
+// 采购订单-计算金额
+const calculateOrderAmount = (data) => {
+  return request({
+    url: `/pu/order/calculateOrderAmount`,
+    method: "post",
+    data,
+  });
+}
+
+
 // 采购订单退回
 const documentsReturn = (data) => {
   return request({
@@ -83,7 +93,7 @@ const documentsReturn = (data) => {
   });
 }
 
-// 采购订单退回
+// 采购订单整单关闭
 const close = (data) => {
   return request({
     url: `/pu/order/close`,
@@ -144,6 +154,7 @@ export default {
   revision,
   remove,
   getPrice,
+  calculateOrderAmount,
   documentsReturn,
   close,
   toNc,

+ 25 - 14
src/api/material/basic.js

@@ -42,7 +42,7 @@ const medcineDetails = (id) => {
   })
 }
 
-// 根据物料id获取医药行业信息详细信息  
+// 根据物料id获取医药行业信息详细信息
 const medcineDetailsInfo = (id) => {
   return request({
     url: `/system/medcine/detailsInfo/${id}`,
@@ -69,7 +69,7 @@ const costList = (data) => {
   })
 }
 
-// 成本信息详情 
+// 成本信息详情
 const costDetails = (id) => {
   return request({
     url: `/system/cost/details/${id}`,
@@ -144,7 +144,7 @@ const planList = (data) => {
   })
 }
 
-// 查询计划信息详情 
+// 查询计划信息详情
 const planDetails = (id) => {
   return request({
     url: `/system/plan/details/${id}`,
@@ -153,7 +153,7 @@ const planDetails = (id) => {
   })
 }
 
-// 获取利润中心信息列表 
+// 获取利润中心信息列表
 const centerList = (data) => {
   return request({
     url: `/system/center/list`,
@@ -162,7 +162,7 @@ const centerList = (data) => {
   })
 }
 
-// 获取利润中心详细信息 
+// 获取利润中心详细信息
 const centerDetails = (id) => {
   return request({
     url: `/system/center/details/${id}`,
@@ -171,7 +171,7 @@ const centerDetails = (id) => {
   })
 }
 
-// 获取采购信息列表  
+// 获取采购信息列表
 const purchaseList = (data) => {
   return request({
     url: `/system/purchase/list`,
@@ -180,7 +180,7 @@ const purchaseList = (data) => {
   })
 }
 
-// 获取采购详细信息 
+// 获取采购详细信息
 const purchaseDetails = (id) => {
   return request({
     url: `/system/purchase/details/${id}`,
@@ -189,7 +189,7 @@ const purchaseDetails = (id) => {
   })
 }
 
-// 获取库存信息列表  
+// 获取库存信息列表
 const inventoryList = (data) => {
   return request({
     url: `/system/inventory/list`,
@@ -198,7 +198,7 @@ const inventoryList = (data) => {
   })
 }
 
-// 获取库存详细信息 
+// 获取库存详细信息
 const inventoryDetails = (id) => {
   return request({
     url: `/system/inventory/details/${id}`,
@@ -232,7 +232,7 @@ const materialEdit = (data) => {
   })
 }
 
-// 修改医药行业信息 /dev-api/drp-admin/system/medcine/edit   
+// 修改医药行业信息 /dev-api/drp-admin/system/medcine/edit
 const medcineEdit = (data) => {
   return request({
     url: `/system/medcine/edit `,
@@ -278,7 +278,7 @@ const medcineitemBatchSave = (data) => {
   })
 }
 
-// 修改财务信息 /dev-api/drp-admin/system/finance/edit 
+// 修改财务信息 /dev-api/drp-admin/system/finance/edit
 const financeEdit = (data) => {
   return request({
     url: `/system/finance/edit `,
@@ -432,7 +432,15 @@ const saveVersions = (data) => {
     data,
   })
 }
-
+// 物料导出
+export function exportMartial(data) {
+  return request({
+    url: `/system/material/downloadFailData`,
+    method: 'post',
+    data: data,
+    responseType: 'blob'
+  })
+}
 export default {
   // 查询
   materialList,
@@ -485,5 +493,8 @@ export default {
   delPurchase,
   // 维护新版本
   versions,
-  saveVersions
-}
+  saveVersions,
+
+  //导出
+  exportMartial
+}

+ 11 - 0
src/assets/styles/element-ui.scss

@@ -94,4 +94,15 @@
 
 .el-autocomplete-suggestion .el-autocomplete-suggestion__wrap{
   padding: 10px 0 0 0;
+}   
+
+ .el-super-table {
+  width: 100%;
+  margin: 20px 0 0 0;
+}
+ .el-super-table .el-table__cell {
+  height: 50px;
+}
+ .el-super-table td.el-table__cell {
+  border-right: 0;
 }

+ 4 - 2
src/components/DictTag/index.vue

@@ -2,12 +2,14 @@
   <div>
     <template v-for="(item, index) in options">
       <template v-if="values.includes(item.value)">
-        <span
+        <el-tag
           v-if="item.raw.listClass == 'default' || item.raw.listClass == ''"
+          type="primary"
+          :size="size"
           :key="item.value"
           :index="index"
           :class="item.raw.cssClass"
-          >{{ item.label }}</span
+          >{{ item.label }}</el-tag
         >
         <el-tag
           v-else

+ 5 - 0
src/components/FileUpload/index.vue

@@ -235,6 +235,11 @@ export default {
   },
 };
 </script>
+<style lang="scss">
+.el-form-item.is-error .el-upload-dragger {
+  border: 1px dashed #ff4949;
+}
+</style>
 
 <style scoped lang="scss">
 .upload-file-uploader {

+ 1 - 1
src/components/PopDialog/dose.vue

@@ -35,7 +35,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/drug.vue

@@ -39,7 +39,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/fourClass.vue

@@ -46,7 +46,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/index.vue

@@ -39,7 +39,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button size="small" @click="visible = false" icon="el-icon-circle-close">关闭</el-button>
         <el-button size="small" type="primary" icon="el-icon-circle-check" @click="doSubmit()">确定</el-button>
       </span>

+ 1 - 1
src/components/PopDialog/innerPackingUnit.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/midPack.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/organization.vue

@@ -35,7 +35,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/place.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/productFactory.vue

@@ -103,7 +103,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/serviceline.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/staff.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/tax.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/PopDialog/unit.vue

@@ -95,7 +95,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/components/Refers/batchRefer.vue

@@ -34,7 +34,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button size="small" @click="visible = false" icon="el-icon-circle-close">关闭</el-button>
         <el-button size="small" type="primary" icon="el-icon-circle-check" @click="doSubmit()">确定</el-button>
       </span>

+ 46 - 4
src/components/Refers/refers.vue

@@ -20,17 +20,22 @@
             <el-table :data="dataList" v-loading="loading" size="small" border ref="contractTable"
               @select="handleSelectionChange" @row-click="rowSelect" height="calc(100% - 40px)">
               <el-table-column show-overflow-tooltip type="selection" header-align="center" align="center" width="50"/>
-              <el-table-column show-overflow-tooltip prop="id" header-align="center" align="center" min-width="90" :label="reciveForm.title + 'id'"/>
-              <el-table-column show-overflow-tooltip prop="code" header-align="center" align="center" min-width="90" :label="reciveForm.title + '编码'"/>
-              <el-table-column show-overflow-tooltip prop="name" header-align="center" align="center" min-width="90" :label="reciveForm.title + '名称'"/>
+              <!-- <el-table-column show-overflow-tooltip prop="id" header-align="center" align="center" min-width="90" :label="reciveForm.title + 'id'"/> -->
+              <el-table-column show-overflow-tooltip prop="code" header-align="center" align="center" min-width="90" label="编码"/>
+              <el-table-column show-overflow-tooltip prop="name" header-align="center" align="center" min-width="90" label="名称"/>
+              <el-table-column show-overflow-tooltip v-if="warehouseAttributes" prop="warehouseAttributes" header-align="center" align="center" min-width="90" label="仓库属性"/>
               <el-table-column show-overflow-tooltip v-if="orgName" prop="orgName" header-align="center" align="center" min-width="90" label="所属组织"/>
               <el-table-column show-overflow-tooltip v-if="warehouseCode" prop="warehouseCode" header-align="center" align="center" min-width="90" label="所属仓库编码"/>
               <el-table-column show-overflow-tooltip v-if="warehouseName" prop="warehouseName" header-align="center" align="center" min-width="90" label="所属仓库"/>
+              <el-table-column show-overflow-tooltip v-if="warehouseProperty" prop="warehouseProperty" header-align="center" align="center" min-width="90" label="仓库属性" :formatter="cksx"/>
               <el-table-column show-overflow-tooltip v-if="contactsName" prop="contactsName" header-align="center" align="center" min-width="90" label="联系人"/>
               <el-table-column show-overflow-tooltip v-if="contactsPhone" prop="contactsPhone" header-align="center" align="center" min-width="90" label="联系人电话"/>
               <el-table-column show-overflow-tooltip v-if="address" prop="address" header-align="center" align="center" min-width="90" label="详细地址"/>
               <el-table-column show-overflow-tooltip v-if="materialClassifyName" prop="materialClassifyName" header-align="center" align="center" min-width="90" label="物料分类"/>
               <el-table-column show-overflow-tooltip v-if="remark" prop="remark" header-align="center" align="center" min-width="90" label="备注"/>
+              <el-table-column show-overflow-tooltip v-if="shortName" prop="shortName" header-align="center" align="center" min-width="90" label="简称"/>
+              <el-table-column show-overflow-tooltip v-if="mneCode" prop="mneCode" header-align="center" align="center" min-width="90" label="助记码"/>
+              <el-table-column show-overflow-tooltip v-if="deptName" prop="deptName" header-align="center" align="center" min-width="90" label="部门"/>
             </el-table>
             <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
               :current-page="searchForm.pageNo" :page-sizes="[5, 10, 15, 20]" :page-size="searchForm.pageSize"
@@ -39,7 +44,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button size="small" @click="visible = false" icon="el-icon-circle-close">关闭</el-button>
         <el-button size="small" type="primary" icon="el-icon-circle-check" @click="doSubmit()">确定</el-button>
       </span>
@@ -63,13 +68,18 @@ export default {
       dataList: [],
       total: 0,
       orgName: false,
+      deptName: false,
+      warehouseAttributes: false,
       warehouseCode: false,
       warehouseName: false,
+      warehouseProperty: false,
       contactsName: false,
       contactsPhone: false,
       address: false,
       materialClassifyName: false,
       remark: false,
+      shortName: false,
+      mneCode: false,
       orders: [],
       loading: false,
       visible: false,
@@ -89,6 +99,20 @@ export default {
     }
   },
   methods: {
+    cksx(row) {
+      switch (row.warehouseProperty) {
+        case '1':
+          return '电商库存'
+        case '2':
+          return '区域分仓公共库存'
+        case '3':
+          return '各项目仓库存'
+        case '4':
+          return '中心仓公共库存'
+        case '5':
+          return '事业发展部仓库'
+      }
+    },
     init(val) {
       this.visible = true;
       console.log("🚀 ~ file: refers.vue:79 ~ init ~ init(val):", val)
@@ -110,8 +134,16 @@ export default {
         // 仓库里面加组织
         if(res.rows.length !== 0 && res.rows[0].orgName) {
           this.orgName = true
+          this.warehouseAttributes = true
         } else {
           this.orgName = false
+          this.warehouseAttributes = false
+        }
+        // 人员内加部门
+        if(res.rows.length !== 0 && res.rows[0].deptId) {
+          this.deptName = true
+        } else {
+          this.deptName = false
         }
         // 选择货位里面加仓库
         if(res.rows.length !== 0 && res.rows[0].warehouseCode) {
@@ -125,16 +157,26 @@ export default {
         if(res.rows.length !== 0 && res.rows[0].contactsName) {
           this.contactsName = true
           this.contactsPhone = true
+          this.warehouseProperty = true
           this.address = true
           this.materialClassifyName = true
           this.remark = true
         } else {
           this.contactsName = false
           this.contactsPhone = false
+          this.warehouseProperty = false
           this.address = false
           this.materialClassifyName = false
           this.remark = false
         }
+        // 补单供应商档案
+        if (res.rows.length !== 0 && res.rows[0].mneCode) {
+          this.shortName = true
+          this.mneCode = true
+        } else {
+          this.shortName = false
+          this.mneCode = false
+        }
         this.loading = false;
         this.$nextTick(() => {
           this.setSelectRow();

+ 1 - 1
src/components/Refers/treeRefer.vue

@@ -21,7 +21,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button size="small" @click="visible = false" icon="el-icon-circle-close">关闭</el-button>
         <el-button size="small" type="primary" icon="el-icon-circle-check" @click="doSubmit()">确定</el-button>
       </span>

+ 7 - 5
src/components/computed-input-v2/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <span v-on="$listeners">{{ innerValue || "- -" }}</span>
+  <span v-on="$listeners">{{ innerValue || "--" }}</span>
 </template>
 
 <script>
@@ -17,6 +17,10 @@ export default {
       default: () => {},
       require: true,
     },
+    // formatter
+    source: {
+      type: Object,
+    },
   },
   data() {
     return {};
@@ -24,15 +28,13 @@ export default {
   computed: {
     innerValue: {
       get() {
-        return this.formatter(this.value);
+        return this.formatter(this.source || this.value);
       },
     },
   },
   watch: {},
   methods: {},
-  created() {
-    console.log("formatter", this, (this.$parent.row.customerName = "D"));
-  },
+  created() {},
   mounted() {},
   destroyed() {},
 };

+ 3 - 1
src/components/computed-input/index.vue

@@ -42,7 +42,9 @@ export default {
     },
   },
   methods: {},
-  created() {},
+  created() {
+   
+  },
   mounted() {},
   destroyed() {},
 };

+ 51 - 0
src/components/draggable/index.vue

@@ -0,0 +1,51 @@
+<template>
+  <draggable
+    v-bind="$attrs"
+    v-on="$listeners"
+    v-model="innerValue"
+    animation="250"
+    forceFallback="true"
+  >
+    <transition-group>
+      <slot></slot>
+    </transition-group>
+  </draggable>
+</template>
+
+<script>
+import draggable from "vuedraggable";
+export default {
+  name: "Draggable",
+  props: {
+    // v-model
+    value: {
+      type: [Array],
+      require: true,
+    },
+    group: {
+      type: [String, Object],
+      require: true,
+    },
+  },
+  components: { draggable },
+  data() {
+    return {};
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+  },
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>

+ 3 - 2
src/components/file-preview/index.vue

@@ -1,10 +1,10 @@
 <template>
-  <div class="file-preview">
+  <div v-if="fileList.length" class="file-preview">
     <el-button
       :size="size"
       type="text"
       @click="visible = true"
-      style="font-size: 12px"
+      style="font-size: 12px; padding: 0"
     >
       附 件
     </el-button>
@@ -41,6 +41,7 @@
       </div>
     </el-dialog>
   </div>
+  <span v-else>--</span>
 </template>
 
 <script>

+ 26 - 37
src/components/popover-select-v2/index.vue

@@ -60,7 +60,19 @@ export default {
       },
       set(value) {
         this.$emit("input", value);
-        if (!value) {
+      },
+    },
+    TableColumns() {
+      const { referName } = this.$props;
+      return require(`../popover-select/components/${referName}`).default.filter(
+        (document) => document.key
+      );
+    },
+  },
+  watch: {
+    innerValue: {
+      handler: function (newValue) {
+        if (!newValue) {
           const {
             $props: { source, dataMapping },
           } = this;
@@ -71,14 +83,7 @@ export default {
         }
       },
     },
-    tableColumns() {
-      const { referName } = this.$props;
-      return require(`../popover-select/components/${referName}`).default.filter(
-        (document) => document.key
-      );
-    },
   },
-  watch: {},
   methods: {
     // open dialog
     async open() {
@@ -144,7 +149,7 @@ export default {
     },
     // select
     useSelect(prop) {
-      this.selectData = prop;
+      this.selectData = prop[0];
     },
     // confirm
     useConfirm(prop) {
@@ -202,39 +207,23 @@ export default {
     </el-autocomplete>
     <el-dialog
       :width="width"
-      :show-close="false"
       :visible.sync="visible"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
       append-to-body
     >
-      <template slot="title">
-        <div
-          style="
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-          "
+      <div slot="footer">
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
         >
-          <span>选 择</span>
-          <span>
-            <el-button
-              :size="size"
-              circle
-              icon="el-icon-check"
-              @click="useConfirm(selectData[0])"
-            >
-            </el-button>
-            <el-button
-              :size="size"
-              circle
-              type="danger"
-              icon="el-icon-close"
-              @click="hide"
-            ></el-button>
-          </span>
-        </div>
-      </template>
+        <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useConfirm(selectData)"
+          >确 认</el-button
+        >
+      </div>
       <el-form
         v-loading="loading"
         :size="size"
@@ -262,7 +251,7 @@ export default {
           @row-click="useSelect([$event])"
         >
           <el-table-column
-            v-for="(column, index) in tableColumns"
+            v-for="(column, index) in TableColumns"
             :key="index"
             :prop="column.key"
             :label="column.title"

+ 28 - 45
src/components/popover-select-v2/multiple.vue

@@ -17,7 +17,7 @@ export default {
     },
     // 作为 value 唯一标识的键名,绑定值
     valueKey: {
-      type: [String, Array],
+      type: [String, null, undefined],
     },
     // 默认查询参数
     queryParams: {
@@ -62,14 +62,23 @@ export default {
         this.$emit("input", value);
       },
     },
-    tableColumns() {
-      const { referName } = this.$props;
-      return require(`../popover-select/components/${referName}`).default.filter(
-        (document) => document.key
-      );
+    tableColumns: {
+      get() {
+        const { referName } = this.$props;
+        const {
+          default: d,
+        } = require(`../popover-select/components/${referName}`);
+        return d.filter(({ key }) => key);
+      },
+    },
+  },
+  watch: {
+    innerValue: {
+      handler: function (newValue) {
+        if (!newValue) this.lastSelectData = [];
+      },
     },
   },
-  watch: {},
   methods: {
     // open dialog
     async open() {
@@ -138,16 +147,6 @@ export default {
       if (typeof valueKey === "string") {
         this.innerValue = prop.map((item) => item[valueKey]);
       }
-      // array
-      else if (Array.isArray(valueKey)) {
-        this.innerValue = prop.map((item) => {
-          const object = {};
-          valueKey.forEach((cItem) => {
-            object[cItem] = item[cItem];
-          });
-          return object;
-        });
-      }
       // null
       else {
         this.innerValue = prop;
@@ -174,39 +173,23 @@ export default {
     </el-input>
     <el-dialog
       :width="width"
-      :show-close="false"
       :visible.sync="visible"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
       append-to-body
     >
-      <template slot="title">
-        <div
-          style="
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-          "
+      <div slot="footer">
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useConfirm(selectData)"
+          >确 认</el-button
         >
-          <span>选 择</span>
-          <span>
-            <el-button
-              :size="size"
-              circle
-              icon="el-icon-check"
-              @click="useConfirm(selectData)"
-            >
-            </el-button>
-            <el-button
-              :size="size"
-              circle
-              type="danger"
-              icon="el-icon-close"
-              @click="useCancel"
-            ></el-button>
-          </span>
-        </div>
-      </template>
+      </div>
       <el-form
         v-loading="loading"
         :inline="true"
@@ -281,7 +264,7 @@ export default {
         @close="useDelete(index)"
         style="margin-right: 5px"
       >
-        {{ tag[valueKey] }}
+        {{ tag.name || tag[valueKey] }}
       </el-tag>
     </el-scrollbar>
   </div>

+ 4 - 4
src/components/popover-select/components/CUSTOMERDEPT_PARAM.js

@@ -1,9 +1,9 @@
 // 客户部门
 export default [
-  {
-    key: "id",
-    title: "客户ID",
-  },
+  // {
+  //   key: "id",
+  //   title: "客户ID",
+  // },
   {
     key: "code",
     title: "客户编码",

+ 0 - 22
src/components/popover-tree-select/components/MATERIALCLASSIFY_PARAM.js

@@ -1,22 +0,0 @@
-// 客户部门 tree
-export default [
-  {
-    key: "id",
-    title: "客户部门ID",
-    type: "Input",
-    search: true,
-  },
-  {
-    key: "code",
-    title: "客户部门编码",
-    type: "Input",
-    search: true,
-  },
-  {
-    key: "name",
-    title: "客户部门名称",
-    type: "Input",
-    search: true,
-  },
-];
-

+ 126 - 220
src/components/popover-tree-select/index.vue

@@ -1,82 +1,55 @@
 <script>
 import { REFER } from "./api/index";
-import deepCopy from "@gby/deep-copy";
+
 export default {
   name: "PopoverTreeSelect",
   props: {
-    // 参照类型 ,对应后端
-    type: {
-      type: String,
-      require: true,
-    },
     // v-model
     value: {
       type: [Array, String],
       require: true,
     },
-    // 参照弹窗标题
-    title: {
+    // 参照类型 ,对应后端
+    referName: {
       type: String,
-      default: "TITLE",
+      require: true,
     },
     // 作为 value 唯一标识的键名,绑定值
     valueKey: {
       type: String,
-      default: "code",
+      dafault: () => {
+        return "code";
+      },
     },
     // 默认查询参数
     queryParams: {
       type: Function,
       default: () => {},
     },
-    // 组件大小
-    size: {
-      type: String,
-      default: "mini",
-    },
-    // 提示
-    placeholder: {
-      type: String,
-      default: "",
-    },
-    // 是否可读
-    readonly: {
-      type: Boolean,
-      default: false,
-    },
-    // 是否禁止
-    disabled: {
-      type: Boolean,
-      default: false,
-    },
-    // 是否清除
-    clearable: {
-      type: Boolean,
-      default: false,
-    },
-    // 是否多选
-    multiple: {
-      type: Boolean,
-      default: false,
-    },
     // 需映射源数据
-    source: Object,
+    source: {
+      type: Object,
+      default: () => ({}),
+    },
     // 参照内外映射
-    dataMapping: Object,
+    dataMapping: {
+      type: Object,
+      default: () => ({}),
+    },
   },
   components: {},
   data() {
     return {
+      size: "mini",
       width: "50%",
       visible: false,
       loading: false,
-      params: {
+      model: {
         search: "",
-        isPage: true,
+        isPage: false,
       },
       data: [],
       selectData: [],
-      lastSelectData: [],
       defaultProps: {
         label: "name",
         children: "children",
@@ -84,30 +57,36 @@ export default {
     };
   },
   computed: {
-    innerValue() {
-      const { value, multiple } = this.$props;
-      return multiple ? "" : value;
-    },
-    TableColumnTemp() {
-      const { type } = this.$props;
-      const documents = require(`./components/${type}`).default;
-      return documents.filter((document) => document.key);
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
     },
   },
   watch: {
-    "$props.value": {
-      handler: function (newProp) {
-        if (!newProp) this.lastSelectData = [];
+    innerValue: {
+      handler: function (newValue) {
+        if (!newValue) {
+          const {
+            $props: { source, dataMapping },
+          } = this;
+          for (let key in dataMapping) {
+            source[key] = undefined;
+          }
+          this.$emit("update:source", source);
+        }
       },
-      immediate: true,
     },
+    // "model.search": {
+    //   handler: function (newValue) {
+    //     this.$refs.tree.filter(newValue);
+    //   },
+    // },
   },
   methods: {
-    //
-    emitChange(prop) {
-      const { type, source, multiple } = this.$props;
-      this.$emit("change", multiple ? prop : prop[0], source, type);
-    },
     // open dialog
     async open() {
       this.visible = true;
@@ -121,7 +100,12 @@ export default {
     async fetchList(prop) {
       try {
         this.loading = true;
-        const { code, rows } = await REFER(prop);
+        const { referName: type, source, queryParams } = this.$props;
+        const { code, rows } = await REFER({
+          ...prop,
+          ...queryParams(source),
+          type: type,
+        });
         if (code === 200) {
           this.data = rows;
         }
@@ -135,73 +119,46 @@ export default {
     },
     // reset list
     async useReset() {
-      const { type, source, queryParams } = this.$props;
-      this.model = {
-        type,
-        search: "",
-        ...this.model,
-        ...queryParams(source),
-      };
+      this.data = [];
+      this.model.search = null;
       await this.fetchList(this.model);
     },
     // query list
-    async useQuery() {
-      await this.fetchList(this.model);
-    },
-    // cancel
-    useCancel(prop) {
-      const { multiple } = this.$props;
-      this.useUpdate(multiple ? prop : prop[0]);
-      this.hide();
+    async useQuery(value) {
+      await this.$refs.tree.filter(value);
+      // await this.fetchList(this.model);
     },
-    // confirm
-    useConfirm(prop) {
-      const { multiple } = this.$props;
-      this.useUpdate(multiple ? prop : prop[0]);
-      this.emitChange(this.selectData);
-      this.lastSelectData = deepCopy(this.selectData);
-      this.hide();
-    },
-    // delete tag
-    useDelete(prop) {
-      this.selectData.splice(prop, 1);
-      this.useUpdate(this.selectData);
-      this.emitChange(this.selectData);
-      this.lastSelectData = deepCopy(this.selectData);
-    },
-    // update
-    useUpdate(prop) {
-      const { source, multiple, valueKey, dataMapping, type } = this.$props;
-      // update data mapping
-      if (multiple) {
-        const vModel = prop.map((item) => item[valueKey]);
-        this.$emit("input", vModel);
+    // auto
+    async useAutocomplete(prop, cb) {
+      if (prop) {
+        this.model.search = prop;
+        await this.fetchList(this.model);
+        await cb(this.data);
       } else {
-        const vModel = prop[valueKey];
-        this.$emit("input", vModel);
-        for (let key in dataMapping) {
-          source[key] = prop[dataMapping[key]];
-        }
-        this.$emit("update:source", source);
+        cb([]);
       }
     },
-    // click select row data
-    onceSelect(prop) {
-      if (prop) this.selectData = [prop];
+    // select
+    useSelect(prop) {
+      this.selectData = [prop];
     },
-    // double click select row data and confirm
-    doubleSelect(prop) {
-      this.useConfirm([prop]);
+    // filter
+    useTreeFilter(value, data) {
+      if (!value) return true;
+      return data.name.indexOf(value) !== -1;
     },
-    // multiple select row data
-    selectionChange(prop, data) {
-      if (prop) {
-        this.selectData.push(data);
-      } else {
-        const { code } = data;
-        const index = this.selectData.findIndex((item) => item.code === code);
-        this.selectData.splice(index, 1);
+    // confirm
+    useConfirm(prop) {
+      this.hide();
+      const {
+        $props: { source, valueKey, dataMapping },
+      } = this;
+      for (let key in dataMapping) {
+        source[key] = prop[dataMapping[key]];
       }
+      this.innerValue = prop[valueKey];
+      this.$emit("update:source", source);
+      this.$emit("change", prop, this.$props);
     },
   },
   created() {},
@@ -211,136 +168,85 @@ export default {
 </script>
 <template>
   <div class="popover-tree-select">
-    <el-input
+    <el-autocomplete
+      v-bind="$attrs"
       v-model="innerValue"
-      :size="size"
-      :disabled="disabled"
-      :readonly="readonly"
-      :clearable="clearable"
-      :placeholder="placeholder"
+      :value-key="valueKey"
+      :fetch-suggestions="useAutocomplete"
+      @select="useConfirm"
+      style="width: 100%"
     >
-      <el-button
-        :disabled="disabled"
-        slot="append"
-        icon="el-icon-search"
-        @click="open"
-      ></el-button>
-    </el-input>
+      <i class="el-icon-search" slot="suffix" @click="open"> </i>
+      <template slot-scope="{ item }">
+        <p
+          style="
+            text-overflow: ellipsis;
+            overflow: hidden;
+            line-height: 15px;
+            margin: 5px 0;
+          "
+        >
+          {{ item.name }}
+        </p>
+        <p
+          style="
+            font-size: 12px;
+            color: #b4b4b4;
+            line-height: 15px;
+            margin: 5px 0;
+          "
+        >
+          {{ item.code }}
+        </p>
+      </template>
+    </el-autocomplete>
 
     <el-dialog
-      :title="`${title}(${multiple ? '多选' : '单选'})`"
       :width="width"
+      :show-close="false"
       :visible.sync="visible"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
       append-to-body
-      @close="hide"
     >
+      <div slot="footer">
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useConfirm(selectData)"
+          >确 认</el-button
+        >
+      </div>
       <el-form
         v-loading="loading"
         :size="size"
         :inline="true"
-        :model="params"
+        :model="model"
         @submit.native.prevent
       >
         <el-form-item prop="search">
-          <el-input
-            v-model="params.search"
-            @keydown.enter="useQuery"
-            @change="useQuery"
-          >
-          </el-input>
+          <el-input v-model="model.search" @change="useQuery"> </el-input>
         </el-form-item>
         <el-form-item>
           <el-button icon="el-icon-refresh" @click="useReset"></el-button>
         </el-form-item>
-      </el-form>
-      <el-tree
-        v-if="multiple"
-        :data="data"
-        :props="defaultProps"
-        accordion
-        node-key="id"
-      >
-        <div slot-scope="{ node, data }">
-          <el-checkbox
-            v-model="data.checked"
-            @click.native.stop
-            @change="selectionChange($event, data)"
-            style="margin: 0 5px 0 0"
-          >
-          </el-checkbox>
-          <span> {{ data.name }}</span>
-        </div>
-      </el-tree>
-      <el-radio-group v-else v-model="radio" style="width: 100%">
         <el-tree
           v-loading="loading"
           :data="data"
           :props="defaultProps"
+          :filter-node-method="useTreeFilter"
+          ref="tree"
           accordion
           node-key="id"
+          @node-click="useSelect"
         >
-          <div slot-scope="{ node, data }">
-            <el-radio
-              :label="data.code"
-              @click.native.stop="onceSelect(data)"
-              @dblclick.native.stop="doubleSelect(data)"
-              style="margin: 0 5px 0 0"
-            >
-              {{ data.name }}
-            </el-radio>
-          </div>
         </el-tree>
-      </el-radio-group>
-      <div style="margin-top: 20px; text-align: right">
-        <el-button :size="size" @click="visible = false">取 消</el-button>
-        <el-button :size="size" type="primary" @click="useConfirm(selectData)"
-          >确 定</el-button
-        >
-      </div>
+      </el-form>
     </el-dialog>
-    <div
-      style="
-        position: absolute;
-        left: 10px;
-        top: 50%;
-        transform: translateY(-50%);
-        padding-right: 30px;
-        overflow: hidden;
-      "
-    >
-      <div v-if="multiple && lastSelectData.length">
-        <el-popover
-          :offset="-10"
-          :width="width"
-          :visible-arrow="false"
-          title=""
-          content=""
-          trigger="click"
-          placement="bottom-start"
-        >
-          <el-tag slot="reference" :size="size" style="margin-right: 10px">
-            + {{ lastSelectData.length }}
-          </el-tag>
-          <el-tag
-            v-for="(tag, index) in lastSelectData"
-            :size="size"
-            hit
-            closable
-            :style="{
-              display: 'flex',
-              justifyContent: 'space-between',
-              alignItems: 'center',
-              margin: lastSelectData.length - 1 === index ? '0' : '0 0 5px 0',
-            }"
-            @close="useDelete(index)"
-          >
-            {{ tag.name }}
-          </el-tag>
-        </el-popover>
-      </div>
-    </div>
   </div>
 </template>
 <style scoped></style>

+ 283 - 0
src/components/popover-tree-select/multiple.vue

@@ -0,0 +1,283 @@
+<script>
+import { REFER } from "./api/index";
+import deepCopy from "@gby/deep-copy";
+
+export default {
+  name: "PopoverTreeSelect",
+  props: {
+    // v-model
+    value: {
+      type: [Array, String],
+      require: true,
+    },
+    // 参照类型 ,对应后端
+    referName: {
+      type: String,
+      require: true,
+    },
+    // 作为 value 唯一标识的键名,绑定值
+    valueKey: {
+      type: String,
+      dafault: () => {
+        return "code";
+      },
+    },
+    // 默认查询参数
+    queryParams: {
+      type: Function,
+      default: () => {},
+    },
+    // 需映射源数据
+    source: {
+      type: Object,
+      default: () => ({}),
+    },
+    // 参照内外映射
+    dataMapping: {
+      type: Object,
+      default: () => ({}),
+    },
+  },
+  components: {},
+  data() {
+    return {
+      size: "mini",
+      width: "50%",
+      visible: false,
+      loading: false,
+      model: {
+        search: "",
+        isPage: false,
+      },
+      data: [],
+      selectData: [],
+      lastSelectData: [],
+      defaultProps: {
+        label: "name",
+        children: "children",
+      },
+    };
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+  },
+  watch: {
+    innerValue: {
+      handler: function (newValue) {
+        if (!newValue) this.lastSelectData = [];
+      },
+    },
+  },
+  methods: {
+    // open dialog
+    async open() {
+      this.visible = true;
+      await this.useReset();
+    },
+    // hide dialog
+    async hide() {
+      this.visible = false;
+    },
+    // fetch list
+    async fetchList(prop) {
+      try {
+        this.loading = true;
+        const { referName: type, source, queryParams } = this.$props;
+        const { code, rows } = await REFER({
+          ...prop,
+          ...queryParams(source),
+          type: type,
+        });
+        if (code === 200) {
+          this.data = rows;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        this.loading = false;
+      }
+    },
+    // reset list
+    async useReset() {
+      this.data = [];
+      this.model.search = null;
+      await this.fetchList(this.model);
+    },
+    // query list
+    async useQuery() {
+      await this.fetchList(this.model);
+    },
+    // auto
+    async useAutocomplete(prop, cb) {
+      if (prop) {
+        this.model.search = prop;
+        await this.fetchList(this.model);
+        await cb(this.data);
+      } else {
+        cb([]);
+      }
+    },
+    // select
+    useSelect(prop) {
+      this.selectData = prop;
+    },
+    // delete
+    useDelete(prop) {
+      this.selectData.splice(prop, 1);
+      this.useConfirm(this.selectData);
+    },
+    // confirm
+    useConfirm(prop) {
+      const {
+        $props: { valueKey },
+      } = this;
+      // string
+      if (typeof valueKey === "string") {
+        this.innerValue = prop.map((item) => item[valueKey]);
+      }
+      // null
+      else {
+        this.innerValue = prop;
+      }
+      //
+      this.hide();
+      this.lastSelectData = deepCopy(prop);
+      this.$emit("change", prop, this.$props);
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template>
+  <div class="popover-tree-select popover-tree-select--multiple">
+    <el-input v-bind="$attrs" @focus="open">
+      <i class="el-icon-search" slot="suffix" @click="open"> </i>
+      <template slot-scope="{ item }">
+        <p
+          style="
+            text-overflow: ellipsis;
+            overflow: hidden;
+            line-height: 15px;
+            margin: 5px 0;
+          "
+        >
+          {{ item.name }}
+        </p>
+        <p
+          style="
+            font-size: 12px;
+            color: #b4b4b4;
+            line-height: 15px;
+            margin: 5px 0;
+          "
+        >
+          {{ item.code }}
+        </p>
+      </template>
+    </el-input>
+
+    <el-dialog
+      :width="width"
+      :show-close="false"
+      :visible.sync="visible"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+    >
+      <div slot="footer">
+        <el-button :size="$attrs.size" :loading="loading" @click="hide"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          :size="$attrs.size"
+          :loading="loading"
+          @click="useConfirm(selectData)"
+          >确 认</el-button
+        >
+      </div>
+      <el-form
+        v-loading="loading"
+        :size="size"
+        :inline="true"
+        :model="model"
+        @submit.native.prevent
+      >
+        <el-form-item prop="search">
+          <el-input
+            v-model="model.search"
+            @change="useQuery"
+            @keydown.enter="useQuery"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button icon="el-icon-refresh" @click="useReset"></el-button>
+        </el-form-item>
+        <el-tree
+          v-loading="loading"
+          :data="data"
+          :props="defaultProps"
+          accordion
+          show-checkbox
+          check-strictly
+          highlight-current
+          ref="tree"
+          node-key="id"
+          @check="useSelect($refs.tree.getCheckedNodes())"
+        >
+        </el-tree>
+      </el-form>
+    </el-dialog>
+    <el-scrollbar
+      v-if="lastSelectData.length"
+      :viewStyle="{
+        display: 'flex',
+        alignItems: 'center',
+        padding: '5px 0 0 5px',
+      }"
+      class="popover-tree-select_tags"
+    >
+      <el-tag
+        v-for="(tag, index) in lastSelectData"
+        :size="size"
+        hit
+        closable
+        @close="useDelete(index)"
+        style="margin-right: 5px"
+      >
+        {{ tag.name || tag[valueKey] }}
+      </el-tag>
+    </el-scrollbar>
+  </div>
+</template>
+<style scoped>
+.popover-tree-select .el-input {
+  width: inherit;
+}
+.popover-tree-select .el-input .el-icon-search {
+  cursor: pointer;
+}
+.popover-tree-select .popover-tree-select_tags {
+  position: absolute;
+  left: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  width: calc(100% - 40px);
+  height: 100%;
+}
+::v-deep .el-table--mini .el-table__cell {
+  height: 50px;
+}
+</style>

+ 77 - 0
src/components/super-descriptions/index.vue

@@ -0,0 +1,77 @@
+<script>
+export default {
+  name: "SuperDescriptions",
+  props: {
+    value: {
+      type: [Object],
+      require: true,
+    },
+    dict: {
+      type: [Object],
+      require: true,
+    },
+    columns: {
+      type: [Array],
+      require: true,
+    },
+  },
+  components: {
+    ElDictTag: () => import("@/components/DictTag/index.vue"),
+    ElFilePreview: () => import("@/components/file-preview/index.vue"),
+    ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped></style>
+<template>
+  <el-descriptions
+    v-bind="$attrs"
+    v-on="$listeners"
+    border
+    style="margin: 10px"
+  >
+    <el-descriptions-item
+      v-if="innerValue[item.key]"
+      v-for="{ item, attr } in columns"
+      :key="item.key"
+      :label="item.title"
+      :labelStyle="{ width: '150px' }"
+      :contentStyle="{ width: 'auto' }"
+    >
+      <component
+        v-if="attr.is === 'el-dict-tag'"
+        v-bind="attr"
+        v-model="innerValue[item.key]"
+        :size="$attrs.size"
+        :options="dict.type[attr.dictName]"
+      ></component>
+      <component
+        v-else-if="attr.is === 'el-file-preview'"
+        v-bind="attr"
+        v-model="innerValue[item.key]"
+      ></component>
+      <component
+        v-else-if="attr.is === 'el-computed-input-v2'"
+        v-bind="attr"
+        v-model="innerValue[item.key]"
+      ></component>
+      <component is="span" v-else>{{ innerValue[item.key] }}</component>
+    </el-descriptions-item>
+  </el-descriptions>
+</template>

+ 133 - 0
src/components/super-form/index.vue

@@ -0,0 +1,133 @@
+<script>
+export default {
+  name: "SuperForm",
+  props: {
+    value: {
+      type: [Object],
+      require: true,
+    },
+    dict: {
+      type: [Object],
+      require: true,
+    },
+    columns: {
+      type: [Array],
+      require: true,
+    },
+  },
+  components: {
+    ElFileUpload: () => import("@/components/FileUpload/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElPopoverMultipleSelectV2: () =>
+      import("@/components/popover-select-v2/multiple.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/index.vue"),
+    ElPopoverMultipleTreeSelect: () =>
+      import("@/components/popover-tree-select/multiple.vue"),
+  },
+  data() {
+    const { columns } = this.$props;
+    const innerColumns = columns;
+    return {
+      drawer: false,
+      visible: false,
+      innerColumns: innerColumns,
+    };
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+  },
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+
+<template>
+  <el-form
+    ref="superForm"
+    v-bind="$attrs"
+    v-on="$listeners"
+    :model="innerValue"
+    @submit.native.prevent
+  >
+    <el-row :gutter="24" style="display: flex; flex-wrap: wrap">
+      <el-col
+        v-for="({ item, attr }, index) in innerColumns"
+        :key="index"
+        :span="item.span"
+      >
+        <el-form-item :prop="item.key" :label="item.title">
+          <slot :name="item.key" :row="innerValue" :item="item" :attr="attr">
+            <component
+              v-if="attr.is === 'el-select'"
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              style="width: 100%"
+            >
+              <template>
+                <el-option
+                  v-for="item in dict.type[attr.dictName]"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </template>
+            </component>
+            <component
+              v-else-if="attr.is === 'el-popover-select-v2'"
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              :source.sync="innerValue"
+              style="width: 100%"
+            >
+            </component>
+            <component
+              v-else-if="attr.is === 'el-popover-multiple-select-v2'"
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              :source.sync="innerValue"
+              style="width: 100%"
+            >
+            </component>
+            <component
+              v-else-if="attr.is === 'el-popover-tree-select'"
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              :source.sync="innerValue"
+              style="width: 100%"
+            >
+            </component>
+            <component
+              v-else-if="attr.is === 'el-popover-multiple-tree-select'"
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              :source.sync="innerValue"
+              style="width: 100%"
+            >
+            </component>
+            <component
+              v-else
+              v-bind="attr"
+              v-model="innerValue[item.key]"
+              style="width: 100%"
+            >
+            </component>
+          </slot>
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<style scoped></style>

+ 235 - 0
src/components/super-search/index.vue

@@ -0,0 +1,235 @@
+<script>
+export default {
+  name: "SuperSearch",
+  props: {
+    value: {
+      type: [Object],
+      require: true,
+    },
+    dict: {
+      type: [Object],
+      require: true,
+    },
+    columns: {
+      type: [Array],
+      require: true,
+    },
+  },
+  components: {
+    ElDraggable: () => import("@/components/draggable/index.vue"),
+    ElFileUpload: () => import("@/components/FileUpload/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElPopoverMultipleSelectV2: () =>
+      import("@/components/popover-select-v2/multiple.vue"),
+    ElPopoverTreeSelect: () =>
+      import("@/components/popover-tree-select/index.vue"),
+    ElPopoverMultipleTreeSelect: () =>
+      import("@/components/popover-tree-select/multiple.vue"),
+  },
+  data() {
+    const { columns } = this.$props;
+    const stroageKey = (
+      this.$parent.$parent.$options.name + "_search"
+    ).toUpperCase();
+    const loaclColumns = JSON.parse(localStorage.getItem(stroageKey));
+    const innerColumns = !!loaclColumns ? loaclColumns : columns;
+    return {
+      drawer: false,
+      visible: false,
+      stroageKey: stroageKey,
+      innerColumns: innerColumns,
+    };
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    showColumns: {
+      get() {
+        const columns = this.innerColumns.filter(({ item }) => item.hidden);
+        return this.visible ? columns : columns.slice(0, 4);
+      },
+      set() {},
+    },
+  },
+  watch: {},
+  methods: {
+    changeColumns() {
+      const { stroageKey, innerColumns } = this;
+      localStorage.setItem(stroageKey, JSON.stringify(innerColumns));
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+
+<template>
+  <el-form
+    ref="superForm"
+    v-bind="$attrs"
+    v-on="$listeners"
+    :model="innerValue"
+    label-width="auto"
+    label-position="right"
+    @submit.native.prevent
+  >
+    <el-row :gutter="20">
+      <el-col :span="20">
+        <el-row :gutter="20" style="display: flex; flex-wrap: wrap">
+          <el-col
+            v-for="({ item, attr }, index) in showColumns"
+            :key="index"
+            :span="item.span"
+          >
+            <el-form-item :prop="item.key" :label="item.title">
+              <component
+                v-if="attr.is === 'el-input'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                @keyup.enter.native="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+              <component
+                v-if="attr.is === 'el-select'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+                <template>
+                  <el-option
+                    v-for="item in dict.type[attr.dictName]"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </template>
+              </component>
+              <component
+                v-if="attr.is === 'el-date-picker'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+              <component
+                v-if="attr.is === 'el-popover-select-v2'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                :source.sync="innerValue"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+              <component
+                v-if="attr.is === 'el-popover-multiple-select-v2'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                :source.sync="innerValue"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+              <component
+                v-if="attr.is === 'el-popover-tree-select'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                :source.sync="innerValue"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+              <component
+                v-if="attr.is === 'el-popover-multiple-tree-select'"
+                v-bind="attr"
+                v-model="innerValue[item.key]"
+                :source.sync="innerValue"
+                @change="$emit('submit')"
+                style="width: 100%"
+              >
+              </component>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-col>
+      <el-col :span="4" style="text-align: right">
+        <el-button
+          :size="$attrs.size"
+          type="primary"
+          icon="el-icon-search"
+          @click="$emit('submit')"
+        >
+          查 询
+        </el-button>
+        <el-button
+          :size="$attrs.size"
+          icon="el-icon-refresh"
+          @click="$emit('reset')"
+        >
+          重 置
+        </el-button>
+        <!-- <el-button
+          :size="$attrs.size"
+          icon="el-icon-setting"
+          @click="drawer = true"
+        >
+        </el-button> -->
+      </el-col>
+    </el-row>
+    <el-divider>
+      <i
+        v-if="innerColumns.length > 4"
+        :class="visible ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"
+        style="cursor: pointer"
+        @click="visible = !visible"
+      ></i>
+    </el-divider>
+    <!-- <el-drawer size="25%" title="操作列" append-to-body :visible.sync="drawer">
+      <el-row :gutter="20" style="margin: 0">
+        <el-draggable
+          v-model="innerColumns"
+          :group="{ item: 'key' }"
+          @change="changeColumns"
+        >
+          <el-col
+            v-for="({ item }, index) in innerColumns"
+            :key="index"
+            :span="24"
+            style="
+              display: flex;
+              justify-content: space-between;
+              padding: 15px 20px;
+            "
+          >
+            <span style="cursor: move">
+              <i class="el-icon-rank"></i>
+              {{ item.title }}
+            </span>
+            <div>
+              <el-radio-group
+                v-model="item.hidden"
+                :size="$attrs.size"
+                @change="changeColumns"
+              >
+                <el-radio-button :label="true">显</el-radio-button>
+                <el-radio-button :label="false">隐</el-radio-button>
+              </el-radio-group>
+            </div>
+          </el-col>
+        </el-draggable>
+      </el-row>
+    </el-drawer> -->
+  </el-form>
+</template>
+
+<style scoped></style>

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

@@ -0,0 +1,309 @@
+<script>
+export default {
+  name: "SuperTable",
+  props: {
+    value: {
+      type: [Array],
+      require: true,
+    },
+    dict: {
+      type: [Object],
+      require: true,
+    },
+    columns: {
+      type: [Array],
+      require: true,
+    },
+    stroage: {
+      type: Boolean,
+      default: false,
+    },
+    hideOperationColumns: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  components: {
+    ElDictTag: () => import("@/components/DictTag/index.vue"),
+    ElDraggable: () => import("@/components/draggable/index.vue"),
+    ElFilePreview: () => import("@/components/file-preview/index.vue"),
+    ElComputedInput: () => import("@/components/computed-input/index.vue"),
+    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    ElComputedInputV2: () => import("@/components/computed-input-v2/index.vue"),
+  },
+  data() {
+    const { columns, stroage } = this.$props;
+    const stroageKey = (
+      this.$parent.$parent.$options.name + "_table"
+    ).toUpperCase();
+    const loaclColumns = JSON.parse(localStorage.getItem(stroageKey));
+    const innerColumns = stroage && !!loaclColumns ? loaclColumns : columns;
+    return {
+      drawer: false,
+      visible: false,
+      top: 0,
+      left: 0,
+      stroageKey: stroageKey,
+      innerColumns: innerColumns,
+      currentData: {},
+    };
+  },
+  computed: {
+    innerValue: {
+      get() {
+        return this.value;
+      },
+      set(value) {
+        this.$emit("input", value);
+      },
+    },
+    showColumns: {
+      get() {
+        const { stroage, hideOperationColumns } = this.$props;
+        return stroage && hideOperationColumns
+          ? this.innerColumns.filter(({ item }) => item.hidden)
+          : this.innerColumns;
+      },
+    },
+  },
+  watch: {
+    visible(value) {
+      if (value) {
+        document.body.addEventListener("click", this.hideContextmenu);
+        document.body.addEventListener("keydown", this.hideContextmenu);
+      } else {
+        document.body.removeEventListener("click", this.hideContextmenu);
+        document.body.removeEventListener("keydown", this.hideContextmenu);
+      }
+    },
+  },
+  methods: {
+    setColumns() {
+      const { stroageKey, innerColumns } = this;
+      this.$nextTick(() => {
+        this.$refs.superTable.doLayout();
+        localStorage.setItem(stroageKey, JSON.stringify(innerColumns));
+      });
+    },
+    resetColumns() {
+      const { stroageKey, innerColumns } = this;
+      this.innerColumns = innerColumns.map(({ item, attr }) => ({
+        attr,
+        item: { ...item, hidden: true, fixed: false },
+      }));
+      this.$nextTick(() => {
+        this.$refs.superTable.doLayout();
+        localStorage.removeItem(stroageKey);
+      });
+    },
+    openContextmenu(row, column, event) {
+      this.visible = true;
+      this.currentData = { row, column };
+      this.$nextTick(() => {
+        // 鼠标坐标
+        const { x, y } = event;
+        // 侧边栏宽度
+        const [{ clientWidth: sideWidth }] =
+          document.getElementsByClassName("sidebar-container");
+        // 导航栏宽度
+        const { clientHeight: navHeight } =
+          document.getElementsByClassName("main-container")[0].firstChild;
+        // 菜单宽度
+        const [{ clientWidth: contextmenuWidth }] =
+          document.getElementsByClassName("el-super-table_contextmenu");
+        // 最大Y轴偏差
+        const maxLeft = this.$el.offsetWidth - contextmenuWidth;
+        if (x > maxLeft) {
+          this.left = maxLeft + 10;
+        } else {
+          this.left = x - sideWidth;
+        }
+        this.top = y - navHeight;
+      });
+    },
+    hideContextmenu(event) {
+      const { type } = event;
+      if (type === "click") {
+        this.visible = false;
+      }
+      if (type === "keydown") {
+        const { keyCode } = event;
+        if (keyCode === 27) this.visible = false;
+      }
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+
+<template>
+  <div class="el-super-table" @contextmenu.prevent.stop>
+    <el-table
+      v-bind="$attrs"
+      v-on="$listeners"
+      :data="innerValue"
+      border
+      ref="superTable"
+      @row-contextmenu="openContextmenu"
+    >
+      <slot></slot>
+      <el-table-column
+        v-for="({ item, attr }, index) in showColumns"
+        :key="index"
+        :prop="item.key"
+        :label="item.title"
+        :fixed="item.fixed"
+        :width="item.width || 250"
+        show-overflow-tooltip
+      >
+        <template slot-scope="scope">
+          <slot :name="item.key" v-bind="scope" :item="item" :attr="attr">
+            <template v-if="attr.is">
+              <component
+                v-if="attr.is === 'el-dict-tag'"
+                v-bind="attr"
+                :size="$attrs.size"
+                :value="scope.row[item.key]"
+                :options="dict.type[attr.dictName]"
+              ></component>
+              <component
+                v-else-if="attr.is === 'el-popover-select-v2'"
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :size="$attrs.size"
+                :source.sync="scope.row"
+              >
+              </component>
+              <component
+                v-else-if="attr.is === 'el-select'"
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :size="$attrs.size"
+              >
+                <template>
+                  <el-option
+                    v-for="item in dict.type[attr.dictName]"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </template>
+              </component>
+              <component
+                v-else
+                v-bind="attr"
+                v-model="scope.row[item.key]"
+                :size="$attrs.size"
+              >
+              </component
+            ></template>
+            <template v-else>
+              <component v-if="attr.formatter" is="span">{{
+                attr.formatter(scope.row)
+              }}</component>
+              <component v-else is="span">{{
+                scope.row[item.key] || "--"
+              }}</component>
+            </template>
+          </slot>
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-drawer :visible.sync="drawer" size="25%" title="操作列" append-to-body>
+      <el-row :gutter="20" style="margin: 0">
+        <el-draggable
+          v-model="innerColumns"
+          :group="{ item: 'key' }"
+          @change="setColumns"
+        >
+          <el-col
+            v-for="({ item }, index) in innerColumns"
+            :key="index"
+            :span="24"
+            style="
+              display: flex;
+              justify-content: space-between;
+              padding: 15px 20px;
+            "
+          >
+            <span style="cursor: move">
+              <i class="el-icon-rank"></i>
+              {{ item.title }}
+            </span>
+            <div>
+              <el-radio-group
+                v-model="item.hidden"
+                :size="$attrs.size"
+                style="margin: 0 15px 0 0"
+                @change="setColumns"
+              >
+                <el-radio-button :label="true">显</el-radio-button>
+                <el-radio-button :label="false">隐</el-radio-button>
+              </el-radio-group>
+              <el-radio-group
+                v-model="item.fixed"
+                :size="$attrs.size"
+                @change="setColumns"
+              >
+                <el-radio-button :label="false">不</el-radio-button>
+                <el-radio-button label="left">左</el-radio-button>
+                <el-radio-button label="right">右</el-radio-button>
+              </el-radio-group>
+            </div>
+          </el-col>
+        </el-draggable>
+      </el-row>
+    </el-drawer>
+    <transition name="el-fade-in-linear">
+      <ul
+        v-show="visible"
+        :style="{ left: left + 'px', top: top + 'px' }"
+        class="el-super-table_contextmenu"
+      >
+        <li v-if="hideOperationColumns" @click="drawer = true">
+          <i class="el-icon-setting"></i>
+          <span>设置布局</span>
+        </li>
+        <li v-if="hideOperationColumns" @click="resetColumns">
+          <i class="el-icon-refresh"></i>
+          <span>重置布局</span>
+        </li>
+        <slot name="contextmenu" v-bind="currentData"> </slot>
+      </ul>
+    </transition>
+  </div>
+</template>
+
+<style lang="scss">
+.el-super-table .el-table {
+  overflow: hidden;
+  border-radius: 5px;
+}
+.el-super-table_contextmenu {
+  margin: 0;
+  background: #fff;
+  z-index: 3000;
+  position: absolute;
+  list-style-type: none;
+  padding: 5px 0;
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 400;
+  color: #333;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  li {
+    margin: 0;
+    padding: 7px 16px;
+    cursor: pointer;
+    &:hover {
+      background: #ddd;
+    }
+    span {
+      margin: 0 0 0 5px;
+    }
+  }
+}
+</style>

+ 9 - 0
src/main.js

@@ -29,6 +29,7 @@ import {
   selectDictLabels,
   handleTree,
 } from "@/utils/ruoyi";
+import { initParams, initRules, initDicts } from "@/utils/init.js";
 // 分页组件
 import Pagination from "@/components/Pagination";
 // 自定义表格工具组件
@@ -55,6 +56,8 @@ import PopoverTreeSelect from "@/components/popover-tree-select";
 import ComputedInput from "@/components/computed-input";
 // 附件标签组件
 import FilePreview from "@/components/file-preview";
+//打印
+import Print from "vue-print-nb";
 
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts;
@@ -66,6 +69,11 @@ Vue.prototype.selectDictLabel = selectDictLabel;
 Vue.prototype.selectDictLabels = selectDictLabels;
 Vue.prototype.download = download;
 Vue.prototype.handleTree = handleTree;
+Vue.prototype.$init = {
+  params: initParams,
+  dicts: initDicts,
+  rules: initRules,
+};
 
 // 全局组件挂载
 Vue.component("DictTag", DictTag);
@@ -83,6 +91,7 @@ Vue.component("DrFilePreview", FilePreview);
 Vue.use(directive);
 Vue.use(plugins);
 Vue.use(VueMeta);
+Vue.use(Print); //注册
 DictData.install();
 
 /**

+ 18 - 6
src/utils/request.js

@@ -28,7 +28,8 @@ service.interceptors.request.use(
     // 是否需要防止数据重复提交
     const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
     // 是否存在列表查询
-    const isQueryList = config.url.includes("/list") || config.url.includes("/query");
+    const isQueryList =
+      config.url.includes("/list") || config.url.includes("/query");
     if (getToken() && !isToken) {
       config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
     }
@@ -40,7 +41,8 @@ service.interceptors.request.use(
       config.url = url;
     }
     if (
-      !isRepeatSubmit && !isQueryList &&
+      !isRepeatSubmit &&
+      !isQueryList &&
       (config.method === "post" || config.method === "put")
     ) {
       const requestObj = {
@@ -122,16 +124,26 @@ service.interceptors.response.use(
       }
       return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
     } else if (code === 500) {
-      Notification.error({ title: "error", message: msg });
+      Notification.error({
+        title: "error",
+        message: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
+        dangerouslyUseHTMLString: true,
+      });
       // Message({ message: msg, type: "error" });
       return Promise.reject(new Error(msg));
     } else if (code === 601) {
-      Notification.warning({ title: "error", message: msg });
+      Notification.warning({
+        title: "error",
+        message: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
+        dangerouslyUseHTMLString: true,
+      });
       // Message({ message: msg, type: "warning" });
       return Promise.reject("error");
     } else if (code !== 200) {
-      console.log("code", code);
-      Notification.error({ title: msg });
+      Notification.error({
+        title: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
+        dangerouslyUseHTMLString: true,
+      });
       return Promise.reject("error");
     } else {
       return res.data;

+ 158 - 133
src/views/WMS/historical-route/index.vue

@@ -1,141 +1,136 @@
 <template>
-  <el-tabs v-model="activeName" type="border-card" @tab-click="handleClick" stretch="true" >
-
+  <el-tabs v-model="activeName" type="border-card" @tab-click="handleClick" stretch="true">
     <el-tab-pane label="温湿度信息" name="first">
-      <!-- 单据信息 -->
-      <el-timeline>
+      <div id="body" :style="{width: width - 300 + 'px'}">
+        <!-- 单据信息 -->
+        <el-timeline>
+          <el-timeline>
+            <el-descriptions>
+              <el-descriptions-item label="订单编号">{{this.basicData.billCode}}</el-descriptions-item>
+              <el-descriptions-item label="车牌号">{{this.basicData.plateNumber}}</el-descriptions-item>
+            </el-descriptions>
+            <el-descriptions>
+              <el-descriptions-item label="开始时间">{{this.basicData.startTime}}</el-descriptions-item>
+              <el-descriptions-item label="结束时间">{{this.basicData.endTime}}</el-descriptions-item>
+            </el-descriptions>
+          </el-timeline>
+        </el-timeline>
+        <el-timeline>
+         	<!--导出按钮-->
+           <el-button class="OutCss" v-print="'#body'" type="primary">导出</el-button>  
+          <!-- 数据表 -->
+          <h2>订单温湿度列表</h2>
+          <el-table
+            :data="tableData2"
+            stripe
+            border
+            style="width: 97%">
+            <el-table-column
+            prop="temperature"
+            label="温度"
+            align="center"
+            min-width="300">
+            </el-table-column>
+            <el-table-column
+            prop="hisDate"
+            label="时间点"
+            align="center"
+            min-width="400">
+            </el-table-column>
+            <el-table-column
+            prop="address"
+            label="地址"
+            min-width="500">
+            </el-table-column>
+          </el-table>
+        </el-timeline>
+      </div>
+      <br>
+      <div id="body" :style="{width: width - 300 + 'px'}">
+        <el-timeline>
+          <h2>订单温度折线图</h2>
+          <div class="echart" id="mychart" :style="myChartStyle"></div>
+        </el-timeline>
+      </div>
+    </el-tab-pane>
+    <el-tab-pane label="运输信息" name="second">
+      <div id="body" :style="{width: width - 300 + 'px'}">
+        <!-- 单据信息 -->
         <el-timeline>
-          <el-descriptions>
-            <el-descriptions-item label="订单编号">{{this.basicData.billCode}}</el-descriptions-item>
-            <el-descriptions-item label="车牌号">{{this.basicData.plateNumber}}</el-descriptions-item>
-          </el-descriptions>
-          <el-descriptions>
-            <el-descriptions-item label="开始时间">{{this.basicData.startTime}}</el-descriptions-item>
-            <el-descriptions-item label="结束时间">{{this.basicData.endTime}}</el-descriptions-item>
-          </el-descriptions>
+          <el-timeline>
+            <el-descriptions>
+              <el-descriptions-item label="订单编号">{{this.basicData.billCode}}</el-descriptions-item>
+              <el-descriptions-item label="车牌号">{{this.basicData.plateNumber}}</el-descriptions-item>
+            </el-descriptions>
+            <el-descriptions>
+              <el-descriptions-item label="开始时间">{{this.basicData.startTime}}</el-descriptions-item>
+              <el-descriptions-item label="结束时间">{{this.basicData.endTime}}</el-descriptions-item>
+            </el-descriptions>
+          </el-timeline>
         </el-timeline>
-      </el-timeline>
       
-      <el-timeline>
-        <!-- 数据表 -->
-        <h2>订单温湿度列表</h2>
-        <el-table
-          :data="tableData2"
-          stripe
-          height="300"
-          border
+        <!-- 地图 -->
+        <div id="container"></div>
+
+        <!-- 订单温湿度列表 -->
+        <el-timeline>
+          <br>
+          <h2>订单温湿度列表</h2>
+          <el-table
+          :data="tableData1"
+          height="200"
           style="width: 97%">
           <el-table-column
-          prop="temperature"
-          label="温度"
+          prop="maxTemperature"
+          label="温度最大值"
           align="center"
-          width="300">
+          min-width="100">
           </el-table-column>
           <el-table-column
-          prop="humidity"
-          label="湿度"
+          prop="avgTemperature"
+          label="温度平均值"
           align="center"
-          width="300">
+          min-width="100">
           </el-table-column>
           <el-table-column
-          prop="hisDate"
-          label="时间点"
+          prop="minTemperature"
+          label="温度最小值"
           align="center"
-          width="400">
+          min-width="100">
           </el-table-column>
           <el-table-column
-          prop="address"
-          label="地址">
+          prop="maxHumidity"
+          label="湿度最大值"
+          align="center"
+          min-width="100">
           </el-table-column>
-        </el-table>
-        <br><br><br>
-        <!-- 折线图 -->
-        <h2>订单的温湿度折线图</h2>
-
-      </el-timeline>
-
-      <div class="echart" id="mychart" :style="myChartStyle"></div>
-
-    </el-tab-pane>
-
-    <el-tab-pane label="运输信息" name="second">
-
-      <!-- 单据信息 -->
-      <el-timeline>
-        <el-timeline>
-          <el-descriptions>
-            <el-descriptions-item label="订单编号">{{this.basicData.billCode}}</el-descriptions-item>
-            <el-descriptions-item label="车牌号">{{this.basicData.plateNumber}}</el-descriptions-item>
-          </el-descriptions>
-          <el-descriptions>
-            <el-descriptions-item label="开始时间">{{this.basicData.startTime}}</el-descriptions-item>
-            <el-descriptions-item label="结束时间">{{this.basicData.endTime}}</el-descriptions-item>
-          </el-descriptions>
+          <el-table-column
+          prop="avgHumidity"
+          label="湿度平均值"
+          align="center"
+          min-width="100">
+          </el-table-column>
+          <el-table-column
+          prop="minHumidity"
+          label="湿度最小值"
+          align="center"
+          min-width="100">
+          </el-table-column>
+          <el-table-column
+          prop="startTime"
+          label="开始时间"
+          align="center"
+          min-width="250">
+          </el-table-column>
+          <el-table-column
+          prop="endTime"
+          align="center"
+          label="结束时间"
+          min-width="250">
+          </el-table-column>
+          </el-table>
         </el-timeline>
-      </el-timeline>
-      
-      <!-- 地图 -->
-      <div id="container"></div>
-
-      <!-- 订单温湿度列表 -->
-      <el-timeline>
-        <br>
-        <h2>订单温湿度列表</h2>
-        <el-table
-        :data="tableData1"
-        height="200"
-        style="width: 97%">
-        <el-table-column
-        prop="maxTemperature"
-        label="温度最大值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="avgTemperature"
-        label="温度平均值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="minTemperature"
-        label="温度最小值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="maxHumidity"
-        label="湿度最大值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="avgHumidity"
-        label="湿度平均值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="minHumidity"
-        label="湿度最小值"
-        align="center"
-        width="150">
-        </el-table-column>
-        <el-table-column
-        prop="startTime"
-        label="开始时间"
-        align="center"
-        min-width="250">
-        </el-table-column>
-        <el-table-column
-        prop="endTime"
-        align="center"
-        label="结束时间"
-        min-width="250">
-        </el-table-column>
-        </el-table>
-      </el-timeline>
-
+     </div>
     </el-tab-pane>
 
   </el-tabs>
@@ -153,6 +148,8 @@ import * as echarts from "echarts";
 export default {
   data() {
     return {
+      width: document.documentElement.clientWidth - 10,
+      param: this.$route.query,
       basicData:{
         billCode: "",
         plateNumber: "",
@@ -203,7 +200,6 @@ export default {
     // this.initEcharts();
   },
   methods: {
-    //切换标签页时执行
     handleClick(tab, event) {
       console.log(tab, event);
       this.handleGeocodeRepo(this.carMessage);
@@ -264,19 +260,19 @@ export default {
               fontSize: 16
             }
           },
-        },
-        {
-          name: "湿度/100",
-          data: this.humidityData,
-          type: "line", // 类型设置为折线图
-          label: {
-            show: true,
-            position: "bottom",
-            textStyle: {
-              fontSize: 16
-            }
-          }
         }
+        // {
+        //   name: "湿度/100",
+        //   data: this.humidityData,
+        //   type: "line", // 类型设置为折线图
+        //   label: {
+        //     show: true,
+        //     position: "bottom",
+        //     textStyle: {
+        //       fontSize: 16
+        //     }
+        //   }
+        // }
         ]
       };
       this.windowSize();
@@ -440,5 +436,34 @@ export default {
   width: 1000;
   height: 800px;
 }
+.Button {
+padding-top:3px; 
+padding-left:1000px;
+padding-right:3px;
+padding-bottom:100px;
+}
+.OutCss {
+float: right; 
+}
+
+#body {
+  /* padding: 0px 200px 0px 200px; */
+  margin: 0 auto;
+
+}
+@media print {
+  @page {
+    margin: 0;
+    size: portrait;
+    /* size: A4 landscape; size: landscape横向,size: portrait;纵向,如果不设置,则页面有横向和纵向的选择框 */
+  }
+
+  #body {
+    /* margin: 20cm; */
+    margin: 0 auto;
+    /* 打印时缩放,防止页面溢出 */
+    zoom: 0.6;
+  }
+}
 </style>
 

+ 1 - 1
src/views/business/spd/bo/authority/index.vue

@@ -297,7 +297,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/basic/accessoryList.vue

@@ -83,7 +83,7 @@
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
       </el-upload>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitFileForm">确 定</el-button>
         <el-button @click="upload.open = false">取 消</el-button>
       </div>

+ 2 - 2
src/views/business/spd/bo/basic/details.vue

@@ -185,7 +185,7 @@
           <el-input v-model="winningStateData.winningStateRemark" style="width:220px" placeholder="关闭备注" />
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitWinningStateData">确 定</el-button>
         <el-button @click="cancelWinningStateData">取 消</el-button>
       </div>
@@ -205,7 +205,7 @@
           <el-radio v-model="allocationForm.isParticipant" :label='false'>否</el-radio>
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitAllocationForm">确 定</el-button>
         <el-button @click="cancelAllocation">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/basic/filemanager copy.vue

@@ -46,7 +46,7 @@
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
       </el-upload>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitFileForm">确 定</el-button>
         <el-button @click="upload.open = false">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/basic/index.vue

@@ -435,7 +435,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button
           type="primary"
           @click="submitForm"

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

@@ -291,7 +291,7 @@
           </el-form>
         </div>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

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

@@ -332,7 +332,7 @@
           </el-form>
         </div>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm" v-if="this.operatingState != 'Browse'" :disabled="submitButtonEditStatus">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/education/educationList.vue

@@ -121,7 +121,7 @@
           </el-select>
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm" :disabled="submitButtonEditStatus">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/filetemplate/index.vue

@@ -117,7 +117,7 @@
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
       </el-upload>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitFileForm">确 定</el-button>
         <el-button @click="upload.open = false">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/pojpsn/pojpsnList.vue

@@ -151,7 +151,7 @@
           </el-select>
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm" :disabled="submitButtonEditStatus">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/refer/contact/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/refer/customer/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/refer/dept/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/refer/org/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/refer/saleaea/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/refer/staff/index.vue

@@ -99,7 +99,7 @@
           </el-main>
         </el-container>
       </el-container>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button
           size="small"
           @click="visible = false"

+ 1 - 1
src/views/business/spd/bo/relationship/relationshipList.vue

@@ -112,7 +112,7 @@
           <el-input v-model="form.company" placeholder="请输入工作单位" />
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm" :disabled="submitButtonEditStatus">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/business/spd/bo/task/index.vue

@@ -392,7 +392,7 @@
           v-if="this.operatingState != 'Insert'"
         />
         
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button
           type="primary"
           @click="submitForm"

+ 1 - 1
src/views/business/spd/bo/task/taskList.vue

@@ -397,7 +397,7 @@
           v-if="this.operatingState != 'Insert'"
         />
         
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button
           type="primary"
           @click="submitForm"

+ 1 - 1
src/views/marketing/dealer-authorization/authprivAdd.vue

@@ -19,7 +19,7 @@
 
       </el-form-item>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button @click="handleCancel">取 消</el-button>
       <el-button type="primary" @click="handleConfirm('authprivAdd')">确 定</el-button>
     </div>

+ 1 - 1
src/views/marketing/dealer-authorization/authprivSee.vue

@@ -17,7 +17,7 @@
 
       </el-form-item>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button @click="setVisible(false)">取 消</el-button>
     </div>
   </el-dialog>

+ 195 - 106
src/views/material/basicFile/details.vue

@@ -142,7 +142,12 @@
                       <template v-if="f.show">
 
                         <!-- 多选框 -->
-                        <el-form-item v-if="f.attribute == 'checkbox'" style="text-align: left;" :prop="f.prop">
+                        <el-form-item 
+                          v-if="f.attribute == 'checkbox'" 
+                          style="text-align: left;" 
+                          :prop="f.prop"
+                          :key="f.required"
+                        >
 
                           <el-checkbox
                             :label="f.name" name="type"
@@ -159,6 +164,7 @@
                         <el-form-item v-else-if="f.attribute == 'select'"
                           :id="(updateButtonGroup && f.apiUrl) ? 'selected' : ''"
                           :prop="f.apiUrl ? `${f.prop}Name` : f.prop"
+                          :key="f.required"
                           :rules="[{ required: f.required ,message: `请选择${f.name}`, trigger: 'change' }]"
                         >
                           <template slot="label">
@@ -210,7 +216,7 @@
                         </el-form-item>
 
                         <!--attribute 文本 数字 文本域 为null -->
-                        <el-form-item v-else :prop="f.prop">
+                        <el-form-item v-else :prop="f.prop" :key="f.required">
                           <template slot="label">
                             <el-tooltip class="item" effect="dark" placement="top-start" :disabled="f.name.length < 10">
                               <span>{{ f.name }}</span>
@@ -220,8 +226,10 @@
                             </el-tooltip>
                           </template>
 
-                          <el-input size="mini" v-model="basicData.value[f.prop]" :type="f.attribute || 'text'"
-                                    :readonly="handleJudge(f)">
+                          <el-input size="mini" 
+                            v-model="basicData.value[f.prop]" 
+                            :type="f.attribute || 'text'"
+                            :readonly="handleJudge(f)">
                           </el-input>
                         </el-form-item>
 
@@ -232,8 +240,11 @@
                 </el-form>
 
                 <!-- 其他展示为列表 -->
-                <el-table v-else :data="mainMsg.value" @cell-dblclick="handleMaindbClick"
-                          @selection-change="handleMainChange">
+                <el-table v-else 
+                  :data="mainMsg.value" 
+                  @cell-dblclick="handleMaindbClick"
+                  @selection-change="handleMainChange"
+                  >
                   <el-table-column type="selection" width="55"/>
                   <el-table-column type="index" v-if="mainMsg.form.length" label="序号" width="55" align="center"/>
                   <el-table-column v-for="m in  mainMsg.form" v-if="m.show" :label="m.name" align="center"
@@ -261,6 +272,7 @@
                     <el-form v-if="activeViceTab == 'material_medcine'" 
                       :inline="true" 
                       label-position="right"
+                      ref="medcineRef"
                       :model="medcineData.value" 
                       class="md-vice-content"
                       :rules="medcineRules"
@@ -649,7 +661,7 @@
   import materialApi from '@/api/material/basic';
   import {getDicts as getDicts} from '@/api/system/dict/data'
   import arrayUtils from '../tools/arrayUtils';
-  import { initRules} from './init/index';
+  import { initRules, initParams} from './init/index';
   import { getDetail } from '@/api/classify/basic';
 
   export default {
@@ -816,7 +828,7 @@
           return !(this.updateButtonGroup && attribute.edit && this.basicData.value['isInventoryStatus'] == '0');
         }
           // 效期管理(expiryDateManagerment):控制一下几个是否可编辑
-        // expiryUnitId 效期单位  usefulLife 有效期 usefulLifeUnitId 有效期至单位  "recentWarningPeriod" 近效期预警天数
+        // expiryUnitId 效期单位  usefulLife 有效期 usefulLifeUnitId 有效期至单位  
 
         else if (attribute.prop == 'expiryUnitId'
           || attribute.prop == 'usefulLife'
@@ -879,6 +891,7 @@
         this.activeMainTab = detailsTabs[e.index].code;
 
         this.collapseActive.splice(1, 1, this.activeMainTab);
+
         console.log(this.collapseActive, 'this.collapseActive');
 
         this.handleOtherListRefresh();
@@ -1015,9 +1028,10 @@
         })
       },
       // 获取物料基本信息详细信息
-      getMaterialDetails(id, templateCode) {
+      async getMaterialDetails(id, templateCode) {
+
         let _this = this;
-        materialApi.materialDetails(
+        await materialApi.materialDetails(
           id,
           templateCode,
         ).then(res => {
@@ -1026,7 +1040,7 @@
           let {code, data} = res;
           if (code == 200) {
 
-            _this.basicData.value = data.data;
+            _this.basicData.value ={... _this.basicData.value,...data.data};
 
             for (const key in data.data) {
               _this.basicData.value[key] = (typeof data.data[key] === 'number') ? String(data.data[key]) : data.data[key];
@@ -1088,58 +1102,87 @@
 
 
       // 查询财务信息列表
-      getFinanceList(materialId) {
-        materialApi.financeList({materialId}).then(res => {
-          console.log(res, '查询财务信息列表');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getFinanceList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.financeList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+          
+        } catch (error) {
+          
+        }finally{
+          this.loading = false;
+        }
       },
       // 查询计划信息列表
-      getPlanList(materialId) {
-        materialApi.planList({materialId}).then(res => {
-          console.log(res, '查询计划信息列表');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getPlanList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.planList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+        } catch (error) {
+          
+        }finally{
+          this.loading = false;
+        }
       },
       // 查询成本信息列表
-      getCostList(materialId) {
-        materialApi.costList({materialId}).then((res) => {
-          console.log(res, '成本信息列表+表头');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getCostList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.costList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+        } catch (error) {
+          
+        }finally{
+          this.loading = false;
+        }
       },
       // 查询利润中心列表
-      getCenterList(materialId) {
-        materialApi.centerList({materialId}).then(res => {
-          console.log(res, '查询利润中心信息');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getCenterList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.centerList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+        } catch (error) {
+          
+        }finally{
+          this.loading = false;
+        }
       },
       // 查询采购中心列表
-      getPurchaseList(materialId) {
-        materialApi.purchaseList({materialId}).then(res => {
-          console.log(res, '查询采购中心');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getPurchaseList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.purchaseList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+        } catch (error) {
+          
+        }finally{
+          this.loading = false;
+        }
       },
       // 获取库存信息列表
-      getInventoryList(materialId) {
-        materialApi.inventoryList({materialId}).then(res => {
-          console.log(res, '获取库存信息列表');
-          if (res.code == 200) {
-            this.mainMsg.value = res.data.tableBody.rows;
+      async getInventoryList(materialId) {
+        try {
+          this.loading = true;
+          let {code,data} = await materialApi.inventoryList({materialId});
+          if (code == 200) {
+            this.mainMsg.value = data.tableBody.rows;
           }
-        })
+        } catch (error) {}finally{
+          this.loading = false;
+        }
       },
 
       // 查询其他标签页列表详情
@@ -1440,61 +1483,62 @@
         }
       },
       // 其他标签页刷新
-      handleOtherListRefresh() {
-        switch (this.activeMainTab) {
+     async handleOtherListRefresh() {
+          switch (this.activeMainTab) {
 
-          // 基本信息
-          case 'material':
-            this.getTagList('material', (form) => {
-              this.basicData.form = form;
-              this.getMaterialDetails(this.materialId, 'material');
-            })
-            break;
-          // 财物信息
-          case 'material_finance':
-            this.getTagList('material_finance', (form) => {
-              this.mainMsg.form = form;
-              this.getFinanceList(this.materialId);
-            });
-            break;
-          // 利润中心信息
-          case 'profit_center':
-            this.getTagList('profit_center', (form) => {
-              this.mainMsg.form = form;
-              this.getCenterList(this.materialId);
-            });
-            break;
-          // 采购信息
-          case 'material_purchase':
-            this.getTagList('material_purchase', (form) => {
-              this.mainMsg.form = form;
-              this.getPurchaseList(this.materialId);
-            });
-            break;
-          // 库存信息
-          case 'material_inventory':
-            this.getTagList('material_inventory', (form) => {
-              this.mainMsg.form = form;
-              this.getInventoryList(this.materialId);
-            });
-            break;
-          // 计划信息
-          case 'material_plan':
-            this.getTagList('material_plan', (form) => {
-              this.mainMsg.form = form;
-              this.getPlanList(this.materialId);
-            });
-            break;
-          // 成本信息
-          case 'material_cost':
-            this.getTagList('material_cost', (form) => {
-              this.mainMsg.form = form;
-              this.getCostList(this.materialId);
-            });
-            break;
-          default:
-            break;
-        }
+            // 基本信息
+            case 'material':
+              await this.getTagList('material', async(form) => {
+                this.basicData.form = [...form];
+                await  this.getMaterialDetails(this.materialId, 'material');
+              })
+              break;
+            // 财物信息
+            case 'material_finance':
+              await this.getTagList('material_finance', async(form) => {
+                this.mainMsg.form = [...form];
+                await this.getFinanceList(this.materialId);
+              });
+              break;
+            // 利润中心信息
+            case 'profit_center':
+              await this.getTagList('profit_center', async(form) => {
+                this.mainMsg.form = [...form];
+                await this.getCenterList(this.materialId);
+              });
+              break;
+            // 采购信息
+            case 'material_purchase':
+              await this.getTagList('material_purchase', async(form) => {
+                this.mainMsg.form = [...form];
+                await this.getPurchaseList(this.materialId);
+              });
+              break;
+            // 库存信息
+            case 'material_inventory':
+              await this.getTagList('material_inventory', async(form) => {
+                this.mainMsg.form = [...form];
+                await  this.getInventoryList(this.materialId);
+              });
+              break;
+            // 计划信息
+            case 'material_plan':
+            await this.getTagList('material_plan', async(form) => {
+                this.mainMsg.form = [...form];
+                await this.getPlanList(this.materialId);
+              });
+              break;
+            // 成本信息
+            case 'material_cost':
+              await this.getTagList('material_cost',async(form) => {
+                this.mainMsg.form = [...form];
+                await this.getCostList(this.materialId);
+              });
+              break;
+            default:
+              break;
+          }
+       
       },
       // 修改
       handleBasicEdit() {
@@ -1525,6 +1569,9 @@
       // 刷新
       handleRefresh() {
         console.log('刷新');
+
+        this.$refs.basicMessageRef.clearValidate();
+        this.$refs.medcineRef.clearValidate();
         this.handleRest();
       },
       // 过滤
@@ -1814,7 +1861,7 @@
         console.log('更新导入');
       },
       // 确认弹窗操作
-      handleComfirmOption() {
+      async handleComfirmOption() {
         console.log('确认弹窗操作');
 
         this.optionDialog.show = false;
@@ -1822,7 +1869,12 @@
         // 取消基本信息修改
         if (this.updateButtonGroup) {
           this.updateButtonGroup = false;
-          this.handleRest();
+          // this.handleRest();
+          await this.getMaterialDetails(this.materialId, 'material');
+       
+          await this.getMedcineDetails(this.materialId, 'material_medcine');
+          this.$refs.basicMessageRef.clearValidate();
+          this.$refs.medcineRef.clearValidate();
 
         }
 
@@ -2096,14 +2148,37 @@
         })
       },
 
+      judgeIsRequriedByProps(message){
+        // condiition:条件,tergetNames:目标porps数组,formName:表单,formRef:表单ref名,
+
+        this[message.formName].form.forEach(formItem => {
+
+          let target = message.tergetNames.filter(t => t === formItem.prop);
+
+          if(target && target.length){
+
+            (formItem.required = message.condiition ? false : true);
+          }
+
+        })
+
+        this.rules = initRules(this[message.formName].form);
+
+        this.$nextTick( ()=> {
+
+          message.condiition && this.$refs[message.formRef].clearValidate(message.tergetNames);
+        })
+
+      },
 
       // 重新加载
       async handleRest() {
         this.loading = true;
         // 基本信息
         await this.getTagList('material', (form) => {
-          this.basicData.form = form;
+          this.basicData.form = [...form];
           this.rules = initRules(form);
+          this.basicData.value = initParams(this.basicData.form,'prop')
           this.getMaterialDetails(this.materialId, 'material');
         })
         // 医疗行业
@@ -2112,12 +2187,13 @@
             this.medcineData.value[item.prop] = ''
           })
           this.medcineData.form = form;
+          this.medcineData.value = initParams(this.medcineData.form,'prop')
           this.medcineRules = initRules(form);
           this.getMedcineDetails(this.materialId, 'material_medcine');
         })
 
       },
-
+      
     },
 
     watch: {
@@ -2156,7 +2232,7 @@
 
           this.basicData.form = this.basicData.form.map(formItem => {
 
-            if (formItem.prop === "businessLine") {
+            if (formItem.prop === "businessLine" && nVal) {
 
               if ( nVal.includes('介入耗材&5') || nVal.includes('骨科耗材&2') ||
                   nVal.includes('普通耗材&3') || nVal.includes('医用设备&1') ||
@@ -2202,7 +2278,20 @@
         },
         deep: true,
       },
+      // 效期管理 expiryDateManagerment 控制 expiryUnitId 效期单位  usefulLife 有效期 usefulLifeUnitId 有效期至单位 必填
+      "basicData.value.expiryDateManagerment":{
+
+        handler(nVal, oVal) {
 
+          this.judgeIsRequriedByProps({
+            condiition:(nVal === '2'),
+            tergetNames:['expiryUnitId','usefulLife','usefulLifeUnitId','recentWarningPeriod'],
+            formName:'basicData',
+            formRef:'basicMessageRef',
+          })
+        },
+        deep: true,
+      },
     },
 
     created() {

+ 410 - 387
src/views/material/basicFile/index.vue

@@ -1,6 +1,7 @@
 <!-- 物料信息基础档案 -->
+<script src="../../../main.js"></script>
 <template>
-  <div class="material-basic">
+  <div class="material-basic" v-loading="failLoad">
 
     <!-- 操作栏 -->
     <div>
@@ -39,7 +40,7 @@
         <el-col :span="1.5">
           <el-button-group>
             <el-button size="small" @click="handleIsInvoke" :disabled="checkedList.length != 1"
-              v-hasPermi="['system:material:add']">
+                       v-hasPermi="['system:material:add']">
               <!-- 0:启用  2:停用 -->
               {{ handleJudgeIsUsing() ? '停用' : '启用' }}
             </el-button>
@@ -95,33 +96,33 @@
     <!-- 主体列表 -->
     <el-card class="material-list" v-loading="loading">
       <el-table :data="taskList" ref="materialTable" @cell-dblclick="handledbClick" :row-key="getRowKey"
-        @selection-change="handleSelectionChange" @select="handleSelect" @select-all="handleSelectAll">
+                @selection-change="handleSelectionChange" @select="handleSelect" @select-all="handleSelectAll">
         <!--  -->
-        <el-table-column type="selection" width="30" :reserve-selection="true" />
-        <el-table-column type="index" label="序号" width="55" align="center" />
+        <el-table-column type="selection" width="30" :reserve-selection="true"/>
+        <el-table-column type="index" label="序号" width="55" align="center"/>
         <el-table-column width="150" v-for="h in  tableHeader" v-if="h.show" :label="h.name" align="center"
-          show-overflow-tooltip>
+                         show-overflow-tooltip>
           <!-- :prop="h.attribute == 'select' ? `${h.prop}Name` : h.prop" -->
           <template slot-scope="scope">
             {{ h.attribute == 'select' ? scope.row[`${h.prop}Name`] :
-              (h.attribute == 'checkbox' ?
-                (scope.row[h.prop] == '0' ? '√' : '')
-                : scope.row[h.prop])
+            (h.attribute == 'checkbox' ?
+            (scope.row[h.prop] == '0' ? '√' : '')
+            : scope.row[h.prop])
             }}
           </template>
         </el-table-column>
       </el-table>
 
       <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
-        :current-page="queryParams.pageNum" :page-sizes="[10, 20, 50, 100]"
-        layout="total, sizes, prev, pager, next, jumper" :total="total">
+                     :current-page="queryParams.pageNum" :page-sizes="[10, 20, 50, 100]"
+                     layout="total, sizes, prev, pager, next, jumper" :total="total">
       </el-pagination>
     </el-card>
 
     <!-- 操作提示 -->
     <el-dialog title="操作提示" :visible.sync="optionDialog.show" width="30%" center>
       <span>是否确认{{ optionDialog.op }}?</span>
-      <span slot="footer" class="dialog-footer">
+      <span slot="footer">
         <el-button @click="handleOptionShow('option', false)">取 消</el-button>
         <el-button type="primary" @click="handleComfirmOption('cancal')">确 定</el-button>
       </span>
@@ -131,7 +132,7 @@
     <el-dialog title="批量导入" :visible.sync="importData.show" width="35%" center :before-close="handlefileDialogColse">
       <div class="mb-import">
         <el-upload class="upload-demo" accept=".xls, .xlsx" ref="upload" action="#" :on-remove="handleFileRemove"
-          :file-list="importData.list" :auto-upload="false" :on-change="handleChangeFile" :limit="1">
+                   :file-list="importData.list" :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>
@@ -148,94 +149,150 @@
 </template>
 
 <script>
-import './style/index.scss';
-import materialApi from '@/api/material/basic';
-
-export default {
-  name: "material-basic",
-  data() {
-    return {
-      // 物料基本信息数据
-      taskList: [],
-      // 查询表单字段
-      queryForm: {
-        name: '',
-        code: '',
-        isEnable: '',
-      },
-      // 总条数
-      total: 1,
-      loading: false,
-      importData: {
-        show: false,
-        list: []
-      },
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        code: null,
-        name: null
-      },
-      // 表头
-      tableHeader: [],
-      // 多选数组
-      checkedList: [],
-      // 列表选中数据
-      // checkedList: [],
-      // 操作弹窗
-      optionDialog: {
-        show: false,
-        op: ''
-      },
-    }
-  },
+  import './style/index.scss';
+  import materialApi from '@/api/material/basic';
 
-  methods: {
-    // 判读是否启用
-    handleJudgeIsUsing() {
-      return this.checkedList.length == 1 && this.checkedList[0].isEnable == '已启用';
-    },
-    // 改变分页大小
-    handleSizeChange(e) {
-      this.queryParams.pageSize = e;
-      this.handleQuery();
-    },
-    // 改变当前页
-    handleCurrentChange(e) {
-      this.queryParams.pageNum = e;
-      this.handleQuery();
-    },
-    // 新增
-    handleInster() {
-      this.$message({
-        message: '物料只能通过申请审批增加,不能在节点直接录入!',
-        type: 'warning'
-      });
+  export default {
+    name: "material-basic",
+    data() {
+      return {
+        failLoad: false,
+        // 物料基本信息数据
+        taskList: [],
+        // 查询表单字段
+        queryForm: {
+          name: '',
+          code: '',
+          isEnable: '',
+        },
+        // 总条数
+        total: 1,
+        loading: false,
+        importData: {
+          show: false,
+          list: []
+        },
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          code: null,
+          name: null
+        },
+        // 表头
+        tableHeader: [],
+        // 多选数组
+        checkedList: [],
+        // 列表选中数据
+        // checkedList: [],
+        // 操作弹窗
+        optionDialog: {
+          show: false,
+          op: ''
+        },
+      }
     },
-    // 修改
-    handleEdit() {
-      if (this.checkedList.length == 1) {
-        this.$router.push({
-          path: `/material/basicFile/detail/${this.checkedList[0].id}`,
-          query: {
-            isEdit: true
-          }
-        });
-      } else {
+
+    methods: {
+      // 判读是否启用
+      handleJudgeIsUsing() {
+        return this.checkedList.length == 1 && this.checkedList[0].isEnable == '已启用';
+      },
+      // 改变分页大小
+      handleSizeChange(e) {
+        this.queryParams.pageSize = e;
+        this.handleQuery();
+      },
+      // 改变当前页
+      handleCurrentChange(e) {
+        this.queryParams.pageNum = e;
+        this.handleQuery();
+      },
+      // 新增
+      handleInster() {
         this.$message({
-          message: `${this.checkedList.length > 1 ? '修改只能选择单个数据!' : '请选择需要修改的信息!'}`,
+          message: '物料只能通过申请审批增加,不能在节点直接录入!',
           type: 'warning'
         });
-      }
-    },
-    // 删除
-    handleDel() {
-      console.log('删除', this.checkedList);
-      // delMaterial
-      if (this.checkedList.length) {
-        let ids = this.checkedList.map(i => i.id);
-        materialApi.delMaterial(ids).then(res => {
+      },
+      // 修改
+      handleEdit() {
+        if (this.checkedList.length == 1) {
+          this.$router.push({
+            path: `/material/basicFile/detail/${this.checkedList[0].id}`,
+            query: {
+              isEdit: true
+            }
+          });
+        } else {
+          this.$message({
+            message: `${this.checkedList.length > 1 ? '修改只能选择单个数据!' : '请选择需要修改的信息!'}`,
+            type: 'warning'
+          });
+        }
+      },
+      // 删除
+      handleDel() {
+        console.log('删除', this.checkedList);
+        // delMaterial
+        if (this.checkedList.length) {
+          let ids = this.checkedList.map(i => i.id);
+          materialApi.delMaterial(ids).then(res => {
+            if (res.code == 200) {
+              this.handleRefresh();
+              // 清空选中数据
+              this.checkedList = [];
+              this.$refs.materialTable.clearSelection();
+            }
+          })
+        } else {
+          this.$message({
+            message: '请选择需要删除的数据!',
+            type: 'warning'
+          });
+        }
+
+      },
+      // 复制
+      handleCopy() {
+        console.log('复制');
+      },
+      //查询
+      handleQuery() {
+        this.getMaterialList('material');
+      },
+      // 重置查询条件
+      handleResetQuery() {
+        for (const key in this.queryForm) {
+
+          this.queryForm[key] = '';
+        }
+      },
+      // 刷新
+      handleRefresh() {
+        this.getMaterialList('material');
+        for (const key in this.queryForm) {
+          this.queryForm[key] = '';
+        }
+      },
+      // 过滤
+      handleFilter(e) {
+        console.log(e, '过滤');
+      },
+      filterCondition(type) {
+        return {
+          type
+        }
+      },
+      // 启用/停用
+      handleIsInvoke() {
+        // true   当前状态为启用,需要改为停用
+        // 0:启用  2:停用
+        let param = {
+          isEnable: this.handleJudgeIsUsing() ? '2' : '0',
+          id: this.checkedList[0].id
+        };
+        materialApi.updateEnableMaterial(param).then(res => {
           if (res.code == 200) {
             this.handleRefresh();
             // 清空选中数据
@@ -243,334 +300,300 @@ export default {
             this.$refs.materialTable.clearSelection();
           }
         })
-      } else {
-        this.$message({
-          message: '请选择需要删除的数据!',
-          type: 'warning'
-        });
-      }
 
-    },
-    // 复制
-    handleCopy() {
-      console.log('复制');
-    },
-    //查询 
-    handleQuery() {
-      this.getMaterialList('material');
-    },
-    // 重置查询条件
-    handleResetQuery() {
-      for (const key in this.queryForm) {
-
-        this.queryForm[key] = '';
-      }
-    },
-    // 刷新
-    handleRefresh() {
-      this.getMaterialList('material');
-      for (const key in this.queryForm) {
-        this.queryForm[key] = '';
-      }
-    },
-    // 过滤
-    handleFilter(e) {
-      console.log(e, '过滤');
-    },
-    filterCondition(type) {
-      return {
-        type
-      }
-    },
-    // 启用/停用
-    handleIsInvoke() {
-      // true   当前状态为启用,需要改为停用
-      // 0:启用  2:停用
-      let param = {
-        isEnable: this.handleJudgeIsUsing() ? '2' : '0',
-        id: this.checkedList[0].id
-      };
-      materialApi.updateEnableMaterial(param).then(res => {
-        if (res.code == 200) {
-          this.handleRefresh();
-          // 清空选中数据
-          this.checkedList = [];
-          this.$refs.materialTable.clearSelection();
-        }
-      })
-
-    },
-    isInvoke(val) {
-      return val;
-    },
-    // 申请单查询
-    handleQueryForm() {
-      console.log('申请单查询');
-    },
-    // 批量导入
-    handleImport() {
-      this.importData.show = true
-    },
-    // 导入弹窗关闭前
-    handlefileDialogColse(done) {
-      this.importData.list = [];
-      done();
-    },
-    // 导入弹窗操作
-    handleImportData(type) {
-      switch (type) {
-        // 取消
-        case 'cancal':
-          this.importData.list = [];
-          this.importData.show = false;
-          break;
-        // 确认
-        case 'confirm':
-          if (this.importData.list.length) {
-
-            let formData = new FormData();
-
-            formData.append('file', this.importData.list[0].raw);
-            materialApi.fileImport(formData).then(res => {
-              if (res.code == 200) {
-                this.importData.show = false;
-                this.importData.list = [];
-              }
+      },
+      isInvoke(val) {
+        return val;
+      },
+      // 申请单查询
+      handleQueryForm() {
+        console.log('申请单查询');
+      },
+      // 批量导入
+      handleImport() {
+        this.importData.show = true
+      },
+      // 导入弹窗关闭前
+      handlefileDialogColse(done) {
+        this.importData.list = [];
+        done();
+      },
+      // 导入弹窗操作
+      handleImportData(type) {
+        switch (type) {
+          // 取消
+          case 'cancal':
+            this.importData.list = [];
+            this.importData.show = false;
+            break;
+          // 确认
+          case 'confirm':
+            if (this.importData.list.length) {
+
+              let formData = new FormData();
+
+              formData.append('file', this.importData.list[0].raw);
+              materialApi.fileImport(formData).then(res => {
+                if (res.code == 200) {
+                  this.importData.show = false;
+                  this.importData.list = [];
+                  if (res.data.flag) {
+                    this.failLoad = true;
+                    console.log(res.data.datas)
+                    let param = {failDatas: res.data.datas}
+                    if (null != param) {
+                      materialApi.exportMartial(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); // 创建下载的链接
+                        downloadElement.href = href;  //下载地址
+                        downloadElement.download = '导入失败的物料基础档案数据.xlsx'; // 下载后文件名
+                        document.body.appendChild(downloadElement);
+                        downloadElement.click(); // 点击下载
+                        document.body.removeChild(downloadElement); // 下载完成移除元素
+                        window.URL.revokeObjectURL(href); // 释放blob对象
+                        this.failLoad = false;
+                      })
+                    }
+                  }
+                  this.$message({
+                    message: res.data.msg,
+                    type: res.data.flag ? 'warning' : 'success'
+                  });
+                } else {
+                  this.$message({
+                    message: res.msg,
+                    type: res.code == 200 ? 'success' : 'warning'
+                  });
+                }
+              })
+            } else {
               this.$message({
-                message: res.msg,
-                type: res.code == 200 ? 'success' : 'warning'
+                message: '请上传文件之后在确认!',
+                type: 'warning'
               });
-            })
-          } else {
-            this.$message({
-              message: '请上传文件之后在确认!',
-              type: 'warning'
-            });
-          }
-          break;
-      }
-    },
-
-    // 删除文件
-    handleFileRemove(file, fileList) {
-      console.log('删除文件', file, 'file', fileList, 'fileList');
-      this.importData.list = fileList;
-    },
-    // 文件发生改变
-    handleChangeFile(file, fileList) {
-      this.importData.list = fileList;
-    },
-    // 批量导出
-    handleExport() {
-
-      let ids = this.checkedList.length ? this.checkedList.map(i => i.id) : [];
-
-      if (ids.length) {
-
-        let params = {
-          // orgId: '1',
-          ids,
+            }
+            break;
         }
-        this.download('/system/material/export', params, `物料基本信息${new Date().getTime()}.xlsx`);
-      } else {
-        this.$message({
-          message: '请选择需要导出的数据!',
-          type: 'warning'
-        });
-      }
-
-    },
-    // 下载模板
-    handleDownTemplate() {
-      this.download('/system/material/download', {}, `物料基本信息模板.xlsx`)
-    },
-
+      },
 
-    // 操作弹窗显隐
-    handleOptionShow(type, val) {
-      switch (type) {
-        case 'option':
-          this.optionDialog.show = val;
-          break;
-      }
-    },
-    // 操作弹窗确认按钮
-    handleComfirmOption(op) {
-      switch (op) {
-        case 'cancal':
-          this.handleOptionShow('option', false);
-          break;
-      }
-    },
+      // 删除文件
+      handleFileRemove(file, fileList) {
+        console.log('删除文件', file, 'file', fileList, 'fileList');
+        this.importData.list = fileList;
+      },
+      // 文件发生改变
+      handleChangeFile(file, fileList) {
+        this.importData.list = fileList;
+      },
+      // 批量导出
+      handleExport() {
 
+        let ids = this.checkedList.length ? this.checkedList.map(i => i.id) : [];
 
+        if (ids.length) {
 
-    // 双击行
-    handledbClick(e) {
-      this.$router.push({
-        path: `/material/basicFile/detail/${e.id}`,
-      });
-    },
-    // 绑定row-key
-    getRowKey(row) {
-      return row.id;
-    },
-    // 对象数组去重
-    handleUnique(arr, key) {
-      // arr  需要去重的数组   type:作为去重依据的key
-      const res = new Map();
-      return arr.filter((arr) => !res.has(arr[key]) && res.set(arr[key], 1))
-    },
-    // 选中数据改变
-    handleSelectionChange(list) {
-      // this.checkedList = this.handleUnique([...this.checkedList, ...list], 'id');
-      // this.$emit('headerOption', JSON.stringify({ checkedList: [... this.checkedList] }))
-    },
-    // 行数据勾选操作 
-    handleSelect(selection, row) {
-      this.checkedList = selection;
-      // // true就是选中,0或者false是取消选中
-      // let selected = selection.length && selection.indexOf(row) !== -1
+          let params = {
+            // orgId: '1',
+            ids,
+          }
+          this.download('/system/material/export', params, `物料基本信息${new Date().getTime()}.xlsx`);
+        } else {
+          this.$message({
+            message: '请选择需要导出的数据!',
+            type: 'warning'
+          });
+        }
 
-    },
-    //手动勾选全选 
-    handleSelectAll(selection) {
-      this.checkedList = selection;
-    },
-    // 获取物料列表信息
-    getMaterialList(templateCode, query) {
-      let _this = this;
-      this.loading = true;
-      let page = {
-        pageNum: this.queryParams.pageNum,
-        pageSize: this.queryParams.pageSize,
-      }
+      },
+      // 下载模板
+      handleDownTemplate() {
+        this.download('/system/material/download', {}, `物料基本信息模板.xlsx`)
+      },
 
-      let param = {
-        templateCode,
-        ...this.queryForm
-      }
-      // console.log(param, 'param');
-      materialApi.materialList(param, page).then((res) => {
-        _this.loading = false;
-        console.log(res, '获取物料列表信息以及表头字段');
-        let { code, data } = res;
-        if (code == 200) {
-          _this.taskList = data.tableBody.rows;
-          _this.total = data.tableBody.total;
 
+      // 操作弹窗显隐
+      handleOptionShow(type, val) {
+        switch (type) {
+          case 'option':
+            this.optionDialog.show = val;
+            break;
         }
-      })
-    },
-    // 获取物料列表表头
-    getTagList(templateCode) {
-      materialApi.tagList({ templateCode }).then(res => {
-        console.log(res, '获取物料列表表头');
-        if (res.code == 200) {
-          this.tableHeader = res.data;
+      },
+      // 操作弹窗确认按钮
+      handleComfirmOption(op) {
+        switch (op) {
+          case 'cancal':
+            this.handleOptionShow('option', false);
+            break;
         }
-      })
-    },
+      },
 
 
+      // 双击行
+      handledbClick(e) {
+        this.$router.push({
+          path: `/material/basicFile/detail/${e.id}`,
+        });
+      },
+      // 绑定row-key
+      getRowKey(row) {
+        return row.id;
+      },
+      // 对象数组去重
+      handleUnique(arr, key) {
+        // arr  需要去重的数组   type:作为去重依据的key
+        const res = new Map();
+        return arr.filter((arr) => !res.has(arr[key]) && res.set(arr[key], 1))
+      },
+      // 选中数据改变
+      handleSelectionChange(list) {
+        // this.checkedList = this.handleUnique([...this.checkedList, ...list], 'id');
+        // this.$emit('headerOption', JSON.stringify({ checkedList: [... this.checkedList] }))
+      },
+      // 行数据勾选操作
+      handleSelect(selection, row) {
+        this.checkedList = selection;
+        // // true就是选中,0或者false是取消选中
+        // let selected = selection.length && selection.indexOf(row) !== -1
 
+      },
+      //手动勾选全选
+      handleSelectAll(selection) {
+        this.checkedList = selection;
+      },
+      // 获取物料列表信息
+      getMaterialList(templateCode, query) {
+        let _this = this;
+        this.loading = true;
+        let page = {
+          pageNum: this.queryParams.pageNum,
+          pageSize: this.queryParams.pageSize,
+        }
 
+        let param = {
+          templateCode,
+          ...this.queryForm
+        }
+        // console.log(param, 'param');
+        materialApi.materialList(param, page).then((res) => {
+          _this.loading = false;
+          console.log(res, '获取物料列表信息以及表头字段');
+          let {code, data} = res;
+          if (code == 200) {
+            _this.taskList = data.tableBody.rows;
+            _this.total = data.tableBody.total;
 
+          }
+        })
+      },
+      // 获取物料列表表头
+      getTagList(templateCode) {
+        materialApi.tagList({templateCode}).then(res => {
+          console.log(res, '获取物料列表表头');
+          if (res.code == 200) {
+            this.tableHeader = res.data;
+          }
+        })
+      },
 
-  },
-  created() {
-    // this.getMaterialList('material');
-    // this.getTagList('material');
-  },
-  beforeRouteEnter(to, from, next) {
 
-    next((vm) => {
-      if (from.name == 'materialDetail') {
-        // this.$store.getQuery(this.queryForm);
-        console.log(vm, 'queryValue', vm.$store);
-        vm.queryForm = vm.$store.state.query.queryVlue;
-        // 清空选中数据
-        vm.checkedList = [];
-        vm.$refs.materialTable.clearSelection();
+    },
+    created() {
+      // this.getMaterialList('material');
+      // this.getTagList('material');
+    },
+    beforeRouteEnter(to, from, next) {
+
+      next((vm) => {
+        if (from.name == 'materialDetail') {
+          // this.$store.getQuery(this.queryForm);
+          console.log(vm, 'queryValue', vm.$store);
+          vm.queryForm = vm.$store.state.query.queryVlue;
+          // 清空选中数据
+          vm.checkedList = [];
+          vm.$refs.materialTable.clearSelection();
+        }
+        vm.getTagList('material');
+        vm.getMaterialList('material');
+      });
+    },
+    // 进入详情,保留查询条件
+    beforeRouteLeave(to, from, next) {
+      if (to.name == 'materialDetail') {
+        this.$store.commit('SET_QUERY', this.queryForm);
+      } else {
+        this.$store.commit('SET_QUERY', {name: '', code: ''});
       }
-      vm.getTagList('material');
-      vm.getMaterialList('material');
-    });
-  },
-  // 进入详情,保留查询条件
-  beforeRouteLeave(to, from, next) {
-    if (to.name == 'materialDetail') {
-      this.$store.commit('SET_QUERY', this.queryForm);
-    } else {
-      this.$store.commit('SET_QUERY', { name: '', code: '' });
+      next();
     }
-    next();
-  }
 
-};
+  };
 </script>
 
 
 <style lang="scss">
-.material-list {
-  // height: calc(100% - 100px);
-  height: calc(100% - 70px);
-
-
-  .el-card__body {
-    height: 100%;
-    box-sizing: border-box;
-
-    .el-table {
-      height: calc(100% - 35px);
-      overflow: auto;
-
-      .el-table__body-wrapper {
-        // height: calc(100% - 150px);
-        height: calc(100% - 70px);
-        overflow-y: auto !important;
-        overflow-x: auto !important;
-        // .el-table__body {
-        //   height: 100%;
-        // }
+  .material-list {
+    // height: calc(100% - 100px);
+    height: calc(100% - 70px);
+
+
+    .el-card__body {
+      height: 100%;
+      box-sizing: border-box;
+
+      .el-table {
+        height: calc(100% - 35px);
+        overflow: auto;
+
+        .el-table__body-wrapper {
+          // height: calc(100% - 150px);
+          height: calc(100% - 70px);
+          overflow-y: auto !important;
+          overflow-x: auto !important;
+          // .el-table__body {
+          //   height: 100%;
+          // }
+        }
       }
     }
+
+    .el-pagination {
+      margin-top: 8px;
+      text-align: right;
+    }
   }
 
-  .el-pagination {
-    margin-top: 8px;
-    text-align: right;
+  .mb-import {
+    padding: 0 20%;
+    text-align: center;
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-around;
   }
-}
-
-.mb-import {
-  padding: 0 20%;
-  text-align: center;
-  display: flex;
-  align-items: flex-start;
-  justify-content: space-around;
-}
 </style>
 <style scoped>
-.el-dialog__header {
-  background-color: rgb(244, 244, 244);
-}
+  .el-dialog__header {
+    background-color: rgb(244, 244, 244);
+  }
 
-.mb-query>>>.el-form-item__label {
-  font-weight: normal;
-  font-size: 12px;
-}
+  .mb-query >>> .el-form-item__label {
+    font-weight: normal;
+    font-size: 12px;
+  }
 
-.mb-query>>>.el-form-item {
-  margin-bottom: 8px;
-}
+  .mb-query >>> .el-form-item {
+    margin-bottom: 8px;
+  }
 
-.mb-query>>>.el-select {
-  width: 90px;
-}
+  .mb-query >>> .el-select {
+    width: 90px;
+  }
 
-.mb-query>>>.el-scrollbar__wrap {
-  margin-bottom: -18px;
+  .mb-query >>> .el-scrollbar__wrap {
+    margin-bottom: -18px;
 
-}
+  }
 </style>

+ 21 - 1
src/views/material/basicFile/init/index.js

@@ -10,4 +10,24 @@ export const initRules = (prop) => {
       ];
     });
   return rules;
-};
+};
+
+export const initParams = (prop, key = "key", value = "value") =>
+  Object.fromEntries(prop.map((item) => [item[key], item[value]]));
+
+// export const initParams = (prop, key = "key", value = "value") => {
+//   // get params
+//   const object1 = Object.fromEntries(
+//     prop.map(({ item, attr }) => [item[key], attr[value]])
+//   );
+//   // get mapping params
+//   const object2 = {};
+//   prop
+//     .filter((item) => item.attr.dataMapping)
+//     .map(({ attr: { dataMapping } }) => {
+//       for (let key in dataMapping) {
+//         object2[key] = null;
+//       }
+//     });
+//   return { ...object1, ...object2 };
+// };

+ 16 - 8
src/views/material/changeApply/add.vue

@@ -153,7 +153,7 @@
           <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="药品" prop="drug"
-                            :rules="{ required: !isControl, message: '请选择是否药品', trigger: 'change' }">
+                            :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"/>
@@ -187,7 +187,7 @@
             </el-col>
             <el-col :span="8">
               <el-form-item label="剂型" prop="dosageFrom"
-                            :rules="{ required: !isControl, message: '请选择剂型', trigger: 'change' }">
+                            :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"/>
@@ -308,7 +308,7 @@
         </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 == 'edit'">提交</el-button>
+        <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>
@@ -590,14 +590,18 @@
           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();
                 })
               }
             })
@@ -613,14 +617,18 @@
           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();
                 })
               }
             })
@@ -629,11 +637,11 @@
       },
       back() {
         this.$emit('jugislist', true)
-        let queryParams = {
-          pageNum: 1,
-          pageSize: 10
-        }
-        this.$emit('refresh', queryParams)
+        // let queryParams = {
+        //   pageNum: 1,
+        //   pageSize: 10
+        // }
+        this.$emit('refresh')
       },
       // 子表增删行
       // handleSelectionChange(val) {

+ 1 - 1
src/views/material/label/label-add-dialog.vue

@@ -139,7 +139,7 @@ export default {
         ></el-input>
       </el-form-item>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button :disabled="loading" @click="dialogFormVisible = false"
         >取 消</el-button
       >

+ 1 - 1
src/views/material/label/label-auto-bind-dialog.vue

@@ -137,7 +137,7 @@ export default {
         </el-col>
       </el-row>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button type="primary" @click="onSubmit('form')">立即创建</el-button>
       <el-button @click="dialogFormVisible = false">取消</el-button>
     </div>

+ 1 - 1
src/views/material/label/label-bind-dialog.vue

@@ -194,7 +194,7 @@ export default {
         </template>
       </el-table-column>
     </el-table>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button :disabled="loading" @click="dialogFormVisible = false"
         >取 消</el-button
       >

+ 1 - 1
src/views/material/label/label-edit-dialog.vue

@@ -139,7 +139,7 @@ export default {
         ></el-input>
       </el-form-item>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button :disabled="loading" @click="dialogFormVisible = false"
         >取 消</el-button
       >

+ 1 - 1
src/views/material/label/label-hand-bind-dialog.vue

@@ -222,7 +222,7 @@ export default {
         </el-col>
       </el-row>
     </el-form>
-    <div slot="footer" class="dialog-footer">
+    <div slot="footer">
       <el-button type="primary" @click="onSubmit('form')">立即创建</el-button>
       <el-button @click="dialogFormVisible = false">取消</el-button>
     </div>

+ 47 - 25
src/views/material/requisition/add.vue

@@ -481,7 +481,7 @@
             </el-col>
             <el-col :span="8">
               <el-form-item label="剂型" prop="dosageFrom"
-                :rules="{ required: !isControl, message: '请选择剂型', trigger: 'change' }">
+                :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" />
@@ -610,7 +610,7 @@
           v-if="pageStu == 'add' || pageStu == 'edit' || pageStu ==='copy' ">保存</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 == 'edit'">提交</el-button>
+        <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>
@@ -1097,6 +1097,8 @@ export default {
       console.log('val1111111', val)
       if (val == '0') {
         this.isControl = false
+        this.basicForm2.dosageFrom = '0001A11000000000BX7Z'
+        this.getDoseDetails(this.basicForm2.dosageFrom)
       } else {
         this.basicForm2.isDrug = ''
         this.basicForm2.registrationNo = ''
@@ -1300,15 +1302,23 @@ export default {
           })
         })
         Promise.all([form1, form2]).then(() => {
-          editReq(sparams).then(res => {
-            if (res.code === 200) {
-              this.$message({
-                message: res.msg,
-                type: 'success'
-              });
-              this.back()
-            }
-          })
+          if(this.basicForm.isMedicine == '0' && this.sysMaterialMedcineItemApply.length == 0) {
+            this.$modal.notifyWarning("医药物料需要维护物料类别!");
+          } else {
+            this.$modal.loading("保存中...");
+            editReq(sparams).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: res.msg,
+                  type: 'success'
+                });
+                this.$modal.closeLoading();
+                this.back()
+              }
+            }).catch(err => {
+              this.$modal.closeLoading();
+            })
+          }
         })
       } else {
 
@@ -1334,15 +1344,23 @@ export default {
           })
         })
         Promise.all([form1, form2]).then(() => {
-          addReq(sparams).then(res => {
-            if (res.code === 200) {
-              this.$message({
-                message: res.msg,
-                type: 'success'
-              });
-              this.back()
-            }
-          })
+          if (this.basicForm.isMedicine == '0' && this.sysMaterialMedcineItemApply.length == 0) {
+            this.$modal.notifyWarning("医药物料需要维护物料类别!");
+          } else {
+            this.$modal.loading("保存中...");
+            addReq(sparams).then(res => {
+              if (res.code === 200) {
+                this.$message({
+                  message: res.msg,
+                  type: 'success'
+                });
+                this.$modal.closeLoading();
+                this.back()
+              }
+            }).catch(err => {
+              this.$modal.closeLoading();
+            })
+          }
         })
       }
     },
@@ -1368,14 +1386,18 @@ export default {
       Promise.all([form1, form2]).then(() => {
         // 提交时候要维护物料类别
         if (this.sysMaterialMedcineItemApply.length !== 0) {
+          this.$modal.loading("提交中...");
           editReq(sparams).then(res => {
             if (res.code === 200) {
               this.$message({
                 message: res.msg,
                 type: 'success'
               });
+              this.$modal.closeLoading();
               this.back()
             }
+          }).catch(err => {
+            this.$modal.closeLoading();
           })
         } else {
           this.$message({
@@ -1387,11 +1409,11 @@ export default {
     },
     back() {
       this.$emit('jugislist', true)
-      let queryParams = {
-        pageNum: 1,
-        pageSize: 10
-      }
-      this.$emit('refresh', queryParams)
+      // let queryParams = {
+      //   pageNum: 1,
+      //   pageSize: 10
+      // }
+      this.$emit('refresh')
     },
     // 子表增删行
     handleSelectionChange(val) {

+ 0 - 173
src/views/material/requisition/index copy.vue

@@ -1,173 +0,0 @@
-<!-- 物料申请单 -->
-<template>
-  <div class="material-requisition">
-    <!-- 操作栏 -->
-    <el-row :gutter="10" class="mb10">
-      <!-- 新增、修改、删除、复制 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" @click="handleInster">新增</el-button>
-          <el-button size="small" @click="handleEdit">修改</el-button>
-          <el-button size="small" @click="handleDel">删除</el-button>
-          <el-button size="small" @click="handleCopy">复制</el-button>
-        </el-button-group>
-      </el-col>
-
-      <!-- 查询、刷新 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" @click="handleQuery">查询</el-button>
-          <el-button size="small" @click="handleRefresh">刷新</el-button>
-        </el-button-group>
-      </el-col>
-
-      <!-- 提交、收回  审批、取消审批、查看审批意见 -->
-      <el-col :span="1.5">
-        <el-button-group>
-
-          <el-dropdown split-button size="small" @click="handleSubmit(true)" @command="handleSubmit">
-            提交
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="isSubmit(true)">提交</el-dropdown-item>
-              <el-dropdown-item :command="isSubmit(false)">收回</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-
-          <el-dropdown split-button size="small" @click="handleApproval('approval')" @command="handleApproval">
-            审批
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="approvalState('approval')">审批</el-dropdown-item>
-              <el-dropdown-item :command="approvalState('cancel')">取消审批</el-dropdown-item>
-              <el-dropdown-item :command="approvalState('view')">查看审批意见</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-        </el-button-group>
-      </el-col>
-
-      <!-- 附件管理 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" v-if="isComponent == 'requestDetails'">附件管理</el-button>
-          <!-- <el-button size="small">维护物料</el-button> -->
-
-        </el-button-group>
-      </el-col>
-    </el-row>
-
-    <component :is="isComponent" @actionBar="handleActionBar" :headerParams="headerParams"></component>
-  </div>
-</template>
-
-<script>
-import './style/index.scss';
-
-import requestList from './list.vue';
-import requestDetails from './details.vue';
-
-import Store from '@/store/index'
-export default {
-  name: "material-requisition",
-  components: {
-    requestList,
-    requestDetails,
-  },
-  data() {
-    return {
-      isComponent: 'requestList',
-      // 头部参数
-      headerParams: {
-        // 是否编辑
-        isEdit: false,
-      },
-      // 总条数
-      total: 1,
-      // 是否显示弹出层
-      open: false,
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        code: null,
-        name: null
-      },
-    };
-  },
-  created() {
-    this.getList();
-    console.log(Store.state.user, 'Store');
-  },
-  methods: {
-    // 新增
-    handleInster() {
-      console.log('新增');
-      this.isComponent = 'requestDetails';
-    },
-    // 修改
-    handleEdit() {
-      console.log('修改');
-    },
-    // 删除
-    handleDel() {
-      console.log('删除');
-    },
-    // 复制
-    handleCopy() {
-      console.log('复制');
-    },
-    // 查询
-    handleQuery() {
-      console.log('查询');
-    },
-    // 刷新
-    handleRefresh() {
-      console.log('刷新');
-    },
-    // 提交
-    handleSubmit(val) {
-      console.log(val, '提交');
-    },
-    isSubmit(type) {
-      return type
-    },
-    // 审批
-    handleApproval(val) {
-      console.log(val, '审批');
-    },
-    approvalState(type) {
-      return type
-    },
-    // 触发动态组件
-    handleActionBar(params) {
-      console.log(`需要更换至${params}~~~`);
-      this.isComponent = params;
-    },
-
-    handleClick() { },
-    /** 查询【请填写功能名称】列表 */
-    getList() {
-
-    },
-    // 取消按钮
-    cancel() {
-
-      this.reset();
-    },
-    // 表单重置
-    reset() {
-
-    },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-
-
-  }
-};
-</script>

+ 8 - 1
src/views/material/requisition/index.vue

@@ -60,6 +60,9 @@
       <el-col :span="1.5">
         <el-button size="small" :disabled="checkedList.length != 1" @click="handleCopy">复制</el-button>
       </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" size="small" plain @click="download('/system/apply/material/download',{},'申请单模板.xlsx')">模板下载</el-button>
+      </el-col>
       <!-- <el-col :span="1.5">
         <el-button type="primary" size="small" plain>导入</el-button>
       </el-col>
@@ -100,11 +103,12 @@
           fixed="right"
           label="操作"
           align="center"
-          width="150"
+          width="180"
           >
           <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 @click="commit(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>
@@ -243,6 +247,9 @@ export default {
       this.rowDetail = row
       this.disable = false
     },
+    commit(row) {
+      console.log('row', row)
+    },
     deleteRow(row) {
       this.$confirm('是否删除此条数据?', '提示', {
           confirmButtonText: '确定',

+ 0 - 217
src/views/material/requisition/index_bak.vue

@@ -1,217 +0,0 @@
-<!-- 物料申请单 -->
-<template>
-  <div class="material-requisition">
-    <!-- 操作栏 -->
-    <el-row :gutter="10" class="mb10">
-      <!-- 新增、修改、删除、复制 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" @click="handleInster">新增</el-button>
-          <el-button size="small" @click="handleEdit">修改</el-button>
-          <el-button size="small" @click="handleDel">删除</el-button>
-          <el-button size="small" @click="handleCopy">复制</el-button>
-        </el-button-group>
-      </el-col>
-
-      <!-- 查询、刷新 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" @click="handleQuery">查询</el-button>
-          <el-button size="small" @click="handleRefresh">刷新</el-button>
-        </el-button-group>
-      </el-col>
-
-      <!-- 提交、收回  审批、取消审批、查看审批意见 -->
-      <el-col :span="1.5">
-        <el-button-group>
-
-          <el-dropdown split-button size="small" @click="handleSubmit(true)" @command="handleSubmit">
-            提交
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="isSubmit(true)">提交</el-dropdown-item>
-              <el-dropdown-item :command="isSubmit(false)">收回</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-
-          <el-dropdown split-button size="small" @click="handleApproval('approval')" @command="handleApproval">
-            审批
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="approvalState('approval')">审批</el-dropdown-item>
-              <el-dropdown-item :command="approvalState('cancel')">取消审批</el-dropdown-item>
-              <el-dropdown-item :command="approvalState('view')">查看审批意见</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-        </el-button-group>
-      </el-col>
-
-      <!-- 附件管理 -->
-      <el-col :span="1.5">
-        <el-button-group>
-          <el-button size="small" v-if="isComponent == 'requestDetails'">附件管理</el-button>
-          <!-- <el-button size="small">维护物料</el-button> -->
-
-        </el-button-group>
-      </el-col>
-    </el-row>
-
-    <el-card class="request-list">
-      <!-- v-loading="loading" @selection-change="handleSelectionChange" -->
-      <el-table :data="taskList" @cell-dblclick="handledbClick" class="request-table">
-        <el-table-column type="index" label="序号" width="55" align="center" />
-        <el-table-column label="主键" align="center" prop="id" />
-        <el-table-column label="编码" align="center" prop="code" />
-        <el-table-column label="名称" align="center" prop="name" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-          <template slot-scope="scope">
-            <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-              v-hasPermi="['system:task:edit']">修改</el-button>
-            <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-              v-hasPermi="['system:task:remove']">删除</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-
-      <!-- v-show="total > 0" -->
-      <pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
-        @pagination="getList" />
-    </el-card>
-  </div>
-</template>
-
-<script>
-import './style/index.scss';
-
-import requestList from './list.vue';
-import requestDetails from './details.vue';
-
-import Store from '@/store/index'
-export default {
-  name: "material-requisition",
-  components: {
-    requestList,
-    requestDetails,
-  },
-  data() {
-    return {
-      isComponent: 'requestList',
-      // 头部参数
-      headerParams: {
-        // 是否编辑
-        isEdit: false,
-      },
-      // 总条数
-      total: 1,
-      // 是否显示弹出层
-      open: false,
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        code: null,
-        name: null
-      },
-      // 物料基本信息数据
-      taskList: [
-        {
-          id: 1,
-          code: '001',
-          name: '名称'
-        }
-      ],
-      // 总条数
-      total: 0,
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        code: null,
-        name: null
-      },
-    };
-  },
-  created() {
-    this.getList();
-    console.log(Store.state.user, 'Store');
-  },
-  methods: {
-    // 新增
-    handleInster() {
-      console.log('新增');
-      this.isComponent = 'requestDetails';
-    },
-    // 修改
-    handleEdit() {
-      console.log('修改');
-    },
-    // 删除
-    handleDel() {
-      console.log('删除');
-    },
-    // 复制
-    handleCopy() {
-      console.log('复制');
-    },
-    // 查询
-    handleQuery() {
-      console.log('查询');
-    },
-    // 刷新
-    handleRefresh() {
-      console.log('刷新');
-    },
-    // 提交
-    handleSubmit(val) {
-      console.log(val, '提交');
-    },
-    isSubmit(type) {
-      return type
-    },
-    // 审批
-    handleApproval(val) {
-      console.log(val, '审批');
-    },
-    approvalState(type) {
-      return type
-    },
-    // 触发动态组件
-    handleActionBar(params) {
-      console.log(`需要更换至${params}~~~`);
-      this.isComponent = params;
-    },
-
-    handleClick() { },
-    /** 查询【请填写功能名称】列表 */
-    getList() {
-
-    },
-    // 取消按钮
-    cancel() {
-
-      this.reset();
-    },
-    // 表单重置
-    reset() {
-
-    },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 双击行
-    handledbClick(e) {
-      console.log(e, '双击行');
-      // console.log(this.$tab.openPage('测试', '/material/requisition/detail'), 'this.$tab');
-      console.log(this.$router.push('/material/requisition/detail'), 'this.$tab');
-      // this.$emit("actionBar", "requestDetails")
-    },
-    handleSelectionChange() { },
-
-  }
-};
-</script>

+ 0 - 62
src/views/material/requisition/list.vue

@@ -1,62 +0,0 @@
-<!-- 物料申请单——列表 -->
-<template>
-  <el-card class="request-list">
-    <!-- v-loading="loading" @selection-change="handleSelectionChange" -->
-    <el-table :data="taskList" @cell-dblclick="handledbClick" class="request-table">
-      <el-table-column type="index" label="序号" width="55" align="center" />
-      <el-table-column label="主键1" align="center" prop="id" />
-      <el-table-column label="编码" align="center" prop="code" />
-      <el-table-column label="名称" align="center" prop="name" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-            v-hasPermi="['system:task:edit']">修改</el-button>
-          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-            v-hasPermi="['system:task:remove']">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <!-- v-show="total > 0" -->
-    <pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
-      @pagination="getList" />
-  </el-card>
-</template>
-
-<script>
-export default {
-  name: 'request-list',
-  data() {
-    return {
-      // 物料基本信息数据
-      taskList: [
-        {
-          id: 1,
-          code: '001',
-          name: '名称'
-        }
-      ],
-      // 总条数
-      total: 0,
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        code: null,
-        name: null
-      },
-    }
-  },
-  methods: {
-    // 双击行
-    handledbClick() {
-      this.$emit("actionBar", "requestDetails")
-    },
-    handleSelectionChange() { },
-
-    getList() {
-
-    },
-  }
-}
-</script>

+ 1 - 1
src/views/material/specialAttr/index.vue

@@ -164,7 +164,7 @@
         </el-row>
 
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submit('bindForm')">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 33 - 2
src/views/monitor/job/index.vue

@@ -29,6 +29,34 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="任务员工" prop="empno">
+        <el-input
+          v-model="queryParams.empno"
+          placeholder="请输入员工工号"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="任务大类" prop="jobType">
+        <el-select v-model="queryParams.status" placeholder="请选择任务大类" clearable>
+          <el-option
+            v-for="dict in dict.type.sys_job_type"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="任务小类" prop="jobTypeS">
+        <el-select v-model="queryParams.status" placeholder="请选择任务小类" clearable>
+          <el-option
+            v-for="dict in dict.type.sys_job_types"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </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>
@@ -106,6 +134,7 @@
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="任务编号" width="100" align="center" prop="jobId" />
       <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
+      <el-table-column label="员工工号" align="center" prop="empno" :show-overflow-tooltip="true" />
       <el-table-column label="任务组名" align="center" prop="jobGroup">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
@@ -307,7 +336,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>
@@ -360,7 +389,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button @click="openView = false">关 闭</el-button>
       </div>
     </el-dialog>
@@ -507,6 +536,7 @@ export default {
         this.total = response.total;
         this.loading = false;
       });
+      console.log(this.queryParams,'this.queryParams')
     },
     // 任务组名字典翻译
     jobGroupFormat(row, column) {
@@ -522,6 +552,7 @@ export default {
       this.form = {
         jobId: undefined,
         jobName: undefined,
+        empno:undefined,
         jobGroup: undefined,
         invokeTarget: undefined,
         cronExpression: undefined,

+ 1 - 1
src/views/monitor/job/log.vue

@@ -316,7 +316,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button @click="open = false">关 闭</el-button>
       </div>
     </el-dialog>

+ 1 - 1
src/views/monitor/operlog/index.vue

@@ -190,7 +190,7 @@
           </el-col>
         </el-row>
       </el-form>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
         <el-button @click="open = false">关 闭</el-button>
       </div>
     </el-dialog>

+ 22 - 4
src/views/purchase/DemandSummary/add.vue

@@ -63,11 +63,19 @@
               :disabled="scope.row.status !== '1' || lineDisable"
               active-value="Y"
               inactive-value="N"
+              @change="clean(scope.row, '选择补单供应商')"
               active-color="#13ce66"
               inactive-color="#a1a3a9">
             </el-switch>
           </template>
         </el-table-column>
+        <el-table-column show-overflow-tooltip label="补单供应商" align="center"  prop="additionalSupplierName" width="200px">
+          <template slot-scope="scope">
+              <el-input clearable :disabled="scope.row.isReplenishment == 'N' || lineDisable" size="mini" v-model="scope.row.additionalSupplierName" @clear="clean(scope.row, '选择补单供应商')" @focus="chooseMxHW(scope.$index, 'SUPPLIER_PARAM', true, '选择补单供应商')">
+                <el-button size="mini" :disabled="scope.row.isReplenishment == 'N' || lineDisable" slot="append" icon="el-icon-more" @click="chooseMxHW(scope.$index, 'SUPPLIER_PARAM', true, '选择补单供应商')"></el-button>
+              </el-input>
+          </template>
+        </el-table-column>
         <el-table-column show-overflow-tooltip label="需求单单号" align="center" prop="code" width="150"/>
         <el-table-column show-overflow-tooltip label="供应仓库" align="center" prop="lastWarehouseName" width="150"/>
         <el-table-column show-overflow-tooltip label="供应货位" align="center" prop="lastAllocationName" width="150"/>
@@ -75,7 +83,7 @@
         <el-table-column show-overflow-tooltip label="收货仓库" align="center" prop="deliveryWarehouseName" width="150"/>
         <el-table-column show-overflow-tooltip label="收货货位" align="center" prop="deliveryAllocationName" width="200">
           <template slot-scope="scope">
-            <el-input clearable :disabled="scope.row.status !== '1' || lineDisable" size="mini" v-model="scope.row.deliveryAllocationName" @clear="clean(scope.row)" @focus="chooseMxHW(scope.$index, 'ALLOCATION_PARAM', true, '收货货位', scope.row.deliveryWarehouse)">
+            <el-input clearable :disabled="scope.row.status !== '1' || lineDisable" size="mini" v-model="scope.row.deliveryAllocationName" @clear="clean(scope.row, '收货货位')" @focus="chooseMxHW(scope.$index, 'ALLOCATION_PARAM', true, '收货货位', scope.row.deliveryWarehouse)">
               <el-button size="mini" :disabled="scope.row.status !== '1' || lineDisable" slot="append" icon="el-icon-more" @click="chooseMxHW(scope.$index, 'ALLOCATION_PARAM', true, '收货货位', scope.row.deliveryWarehouse)"></el-button>
             </el-input>
           </template>
@@ -298,11 +306,21 @@ export default {
         this.tableList[this.tableIndex].deliveryAllocationName = selection[0].name
         this.tableList[this.tableIndex].deliveryAllocation = selection[0].id
       }
+      if (this.referCondition.title == '选择补单供应商') {
+        this.tableList[this.tableIndex].additionalSupplierName = selection[0].name
+        this.tableList[this.tableIndex].additionalSupplier = selection[0].id
+      }
     },
     // 清空选中的货位
-    clean(row) {
-      row.deliveryAllocation = ''
-      row.deliveryAllocationName = ''
+    clean(row, title) {
+      if (title == '收货货位') {
+        row.deliveryAllocation = ''
+        row.deliveryAllocationName = ''
+      }
+      if (title == '选择补单供应商') {
+        row.additionalSupplier = ''
+        row.additionalSupplierName = ''
+      }
     }
   }
 }

+ 33 - 66
src/views/purchase/DemandSummary/index.vue

@@ -33,6 +33,16 @@
               </el-form-item>
             </el-col>
             <el-col :span="1.5">
+              <el-form-item label="生产厂家">
+                <el-input
+                v-model.trim="queryParams.manufacturer"
+                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="search">搜索</el-button>
                 <el-button size="mini" icon="el-icon-refresh" plain @click="reset">重置</el-button>
@@ -44,16 +54,6 @@
           <div v-show="expanded">
             <el-row :gutter="10">
               <el-col :span="1.5">
-                <el-form-item label="生产厂家">
-                  <el-input
-                  v-model.trim="queryParams.manufacturer"
-                  size="mini"
-                  clearable
-                  style="width: 200px"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="1.5">
                 <el-form-item label="预测分类">
                   <el-select v-model="queryParams.forecastClassification" size="mini" style="width: 200px" clearable>
                     <el-option
@@ -69,39 +69,6 @@
                   </el-select>
                 </el-form-item>
               </el-col>
-              <!-- <el-col :span="1.5">
-                <el-form-item label="周期单位">
-                  <el-select v-model="queryParams.periodUnit" size="mini" style="width: 200px" clearable>
-                    <el-option
-                      v-for="dict in dict.type.sys_period_unit" :key="dict.value" :label="dict.label" :value="dict.value">
-                    </el-option>
-                  </el-select>
-                </el-form-item>
-              </el-col> -->
-            </el-row>
-
-            <el-row :gutter="10">
-              <!-- <el-col :span="1.5">
-                <el-form-item label="转请购单号">
-                  <el-input
-                  v-model="queryParams.zqgdh"
-                  size="mini"
-                  placeholder=""
-                  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.departmentName" @focus="chooseRefer('DEPT_PARAM', true, '业务部门')" style="width: 200px">
-                    <el-option v-for="item in deptOptions" :key="item.id" :label="item.name" :value="item.id" />
-                  </el-select>
-                </el-form-item>
-              </el-col> -->
-            </el-row>
-
-            <el-row :gutter="10">
               <el-col :span="1.5">
                 <el-form-item label="注册人">
                   <el-input
@@ -121,6 +88,9 @@
                   </el-select>
                 </el-form-item>
               </el-col>
+            </el-row>
+
+            <el-row :gutter="10">
               <el-col :span="1.5">
                 <el-form-item label="单据来源">
                   <el-select v-model="queryParams.billSource" size="mini" style="width: 200px" clearable>
@@ -130,9 +100,6 @@
                   </el-select>
                 </el-form-item>
               </el-col>
-            </el-row>
-
-            <el-row :gutter="10">
               <el-col :span="1.5">
                 <el-form-item label="需求客户">
                   <el-select clearable size="mini" v-model="queryParams.customer" @focus="chooseRefer('CUSTOMER_PARAM', true, '需求客户')" style="width: 200px">
@@ -142,14 +109,14 @@
               </el-col>
               <el-col :span="1.5">
                 <el-form-item label="供应仓库">
-                  <el-select clearable size="mini" v-model="queryParams.lastWarehouse" @focus="chooseRefer('WAREHOUSE_PARAM', true, '末级供应仓库')" style="width: 200px">
+                  <el-select clearable size="mini" v-model="queryParams.lastWarehouse" @focus="chooseRefer('WAREHOUSE_PARAM', true, '供应仓库')" style="width: 200px">
                     <el-option v-for="item in lastWarehouseOptions" :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="queryParams.lastAllocation" @focus="chooseRefer('ALLOCATION_PARAM', true, '末级供应库位', queryParams.lastWarehouse)" style="width: 200px">
+                  <el-select clearable size="mini" v-model="queryParams.lastAllocation" @focus="chooseRefer('ALLOCATION_PARAM', true, '供应库位', queryParams.lastWarehouse)" style="width: 200px">
                     <el-option v-for="item in lastAllocationOptions" :key="item.id" :label="item.name" :value="item.id" />
                   </el-select>
                 </el-form-item>
@@ -196,9 +163,6 @@
                   </el-date-picker>
                 </el-form-item>
               </el-col>
-            </el-row>
-
-            <el-row :gutter="10">
               <el-col :span="1.5">
                 <el-form-item label="采购需求单号">
                   <el-input
@@ -209,6 +173,9 @@
                   />
                 </el-form-item>
               </el-col>
+            </el-row>
+
+            <el-row :gutter="10">
               <el-col :span="1.5">
                 <el-form-item label="审批结束日期">
                   <el-date-picker
@@ -308,14 +275,14 @@
           <el-table-column show-overflow-tooltip label="采购员" align="center" prop="buyerName" width="150px">
             <template slot-scope="scope">
                 <el-input readonly :disabled="scope.row.status !== '1' || lineDisable" size="mini" v-model="scope.row.buyerName">
-                  <el-button size="mini" :disabled="scope.row.status !== '1' || lineDisable" slot="append" icon="el-icon-more" @click="chooseSon(scope.$index, 'CONTACTS_PARAM', true, '采购员')"></el-button>
+                  <el-button size="mini" :disabled="scope.row.status !== '1' || lineDisable" slot="append" icon="el-icon-more" @click="chooseSon(scope.$index, 'CONTACTS_PARAM', true, '明细采购员')"></el-button>
                 </el-input>
             </template>
           </el-table-column>
           <el-table-column show-overflow-tooltip label="默认采购组织" align="center" prop="purchaseOrgName" width="280px">
             <template slot-scope="scope">
                 <el-input readonly :disabled="scope.row.status !== '1' || lineDisable" size="mini" v-model="scope.row.purchaseOrgName">
-                  <el-button size="mini" :disabled="scope.row.status !== '1' || lineDisable" slot="append" icon="el-icon-more" @click="chooseSon(scope.$index, 'ORG_PARAM', true, '默认采购组织')"></el-button>
+                  <el-button size="mini" :disabled="scope.row.status !== '1' || lineDisable" slot="append" icon="el-icon-more" @click="chooseSon(scope.$index, 'ORG_PARAM', true, '明细默认采购组织')"></el-button>
                 </el-input>
             </template>
           </el-table-column>
@@ -493,11 +460,11 @@ export default {
       allSelection: [],
       // 子表index
       tableIndex: null,
-      referConditionMx: {
-        type: '',
-        isPage: true,
-        title: ''
-      }
+      // referConditionMx: {
+      //   type: '',
+      //   isPage: true,
+      //   title: ''
+      // }
     }
   },
   created() {
@@ -753,11 +720,11 @@ export default {
         this.customerOptions = selection
         this.queryParams.customer = selection[0].id
       }
-      if (this.referCondition.title == '末级供应仓库') {
+      if (this.referCondition.title == '供应仓库') {
         this.lastWarehouseOptions = selection
         this.queryParams.lastWarehouse = selection[0].id
       }
-      if (this.referCondition.title == '末级供应库位') {
+      if (this.referCondition.title == '供应库位') {
         this.lastAllocationOptions = selection
         this.queryParams.lastAllocation = selection[0].id
       }
@@ -765,12 +732,12 @@ export default {
         this.orgOptions = selection
         this.queryParams.purchaseOrg = selection[0].id
       }
-      if (this.referConditionMx.title == '采购员') {
+      if (this.referCondition.title == '明细采购员') {
         console.log('选择进了吗',this.tableList)
         this.tableList[this.tableIndex].buyer = selection[0].code
         this.tableList[this.tableIndex].buyerName = selection[0].name
       }
-      if (this.referConditionMx.title == '默认采购组织') {
+      if (this.referCondition.title == '明细默认采购组织') {
         console.log('选择进了吗',this.tableList)
         this.tableList[this.tableIndex].purchaseOrg = selection[0].id
         this.tableList[this.tableIndex].purchaseOrgName = selection[0].name
@@ -798,10 +765,10 @@ export default {
         // 明细行选择业务部门参照带出业务部门数据
     chooseSon(index, type, isPage, title) {
       this.tableIndex = index
-      this.referConditionMx.type = type
-      this.referConditionMx.isPage = isPage
-      this.referConditionMx.title = title
-      this.$refs.refer.init(this.referConditionMx)
+      this.referCondition.type = type
+      this.referCondition.isPage = isPage
+      this.referCondition.title = title
+      this.$refs.refer.init(this.referCondition)
     }
   }
 }

+ 26 - 5
src/views/purchase/MaterialClassDivision/add.vue

@@ -145,6 +145,7 @@
                   :disabled="disable"
                   v-model="basicForm.orderPersonal"
                   clearable
+                  @clear="clean('订单员')"
                   @focus="chooseRefer('CONTACTS_PARAM', true, '订单员')"
                 >
                   <el-option
@@ -177,6 +178,7 @@
                   :disabled="disable"
                   v-model="basicForm.buyer"
                   clearable
+                  @clear="clean('采购员')"
                   @focus="chooseRefer('CONTACTS_PARAM', true, '采购员')"
                 >
                   <el-option
@@ -335,27 +337,35 @@ export default {
   methods: {
     save() {
       if(this.pageStu == 'add') {
+        this.$modal.loading("保存中...");
         addDivision(this.basicForm).then(res => {
           if (res.code === 200) {
             this.$modal.msgSuccess("保存成功");
+            this.$modal.closeLoading();
             this.back()
           }
+        }).catch(err => {
+          this.$modal.closeLoading();
         })
       } else if(this.pageStu == 'edit') {
+        this.$modal.loading("保存中...");
         editDivision(this.basicForm).then(res => {
           this.$modal.msgSuccess("编辑成功");
+          this.$modal.closeLoading();
           this.back()
+        }).catch(err => {
+          this.$modal.closeLoading();
         })
       }
     },
     submit() {},
     back() {
       this.$emit('jugislist', true)
-      let queryParams = {
-        pageNum: 1,
-        pageSize: 10
-      }
-      this.$emit('refresh', queryParams)
+      // let queryParams = {
+      //   pageNum: 1,
+      //   pageSize: 10
+      // }
+      this.$emit('refresh')
     },
     // 如果需要回显则调用详情接口
     getDetails(row) {
@@ -443,6 +453,17 @@ export default {
         }
       })
     },
+    // 清空采购员,订单员
+    clean(title) {
+      if (title == '订单员') {
+        this.basicForm.orderPersonal = ''
+        this.basicForm.orderPersonalName = ''
+      }
+      if (title == '采购员') {
+        this.basicForm.buyer = ''
+        this.basicForm.buyerName = ''
+      }
+    }
   }
 }
 </script>

+ 190 - 31
src/views/purchase/PurchaseDemandList/add.vue

@@ -212,7 +212,7 @@
           <el-table-column show-overflow-tooltip label="物料编码" align="center" prop="materialCode" width="230px">
             <template slot-scope="scope">
               <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'materialCode'" :rules="{ required: true, message: '请选择物料编码', trigger: 'blur' }">
-                <el-input clearable :disabled="sonDisable" size="mini" v-model="scope.row.materialCode" @paste.native="pasteMe($event, scope)">
+                <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>
               </el-form-item>
@@ -246,7 +246,7 @@
             <el-table-column show-overflow-tooltip label="预留比例" align="center" prop="reservedProportion" width="150px">
               <template slot-scope="scope">
                 <el-form-item class="hang">
-                  <el-select clearable :disabled="sonDisable" size="mini" v-model="scope.row.reservedProportion" @change="getYLSL(scope)" @clear="scope.row.reservedQty = ''">
+                  <el-select clearable :disabled="sonDisable" size="mini" v-model="scope.row.reservedProportion" @change="getYLSL(scope)" @clear="cleanYLSL(scope)">
                     <el-option v-for=" dict in dict.type.sys_reserve_ratio" :key="dict.value" :label="dict.label" :value="dict.value">
                     </el-option>
                   </el-select>
@@ -256,7 +256,7 @@
             </el-table-column>
             <el-table-column show-overflow-tooltip label="预留周期" align="center" prop="reservedPeriod" width="150px">
               <template slot-scope="scope">
-                <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'reservedPeriod'" :rules="{ required: scope.row.reservedProportion !== '', message: '请填写预留周期', trigger: 'blur' }">
+                <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'reservedPeriod'" :rules="{ required: scope.row.reservedProportion && scope.row.reservedProportion !== '' , message: '请填写预留周期', trigger: 'blur' }">
                   <el-input type="number" min="0" clearable :readonly="sonDisable" size="mini" v-model="scope.row.reservedPeriod"></el-input>
                 </el-form-item>
               </template>
@@ -280,9 +280,10 @@
           <el-table-column show-overflow-tooltip label="集团预测分类" align="center"  prop="forecastClassify" width="120px"/>
           <el-table-column show-overflow-tooltip label="近一月需求" align="center"  prop="onemonthAvgVolume" width="120px"/>
           <el-table-column show-overflow-tooltip label="近三月需求" align="center"  prop="threemonthAvgVolume" width="120px"/>
+          <el-table-column show-overflow-tooltip label="采购在途" align="center"  prop="puFreight" width="120px"/>
           <el-table-column show-overflow-tooltip label="交货日期" align="center"  prop="deliveryDate" width="230px">
             <template slot-scope="scope">
-              <el-form-item class="hang" :prop="'puDemandItemList.' + scope.$index + '.' + 'deliveryDate'" :rules="{ required: true, message: '请填写交货日期', trigger: 'blur' }">
+              <el-form-item class="hang">
                 <el-date-picker
                   v-model="scope.row.deliveryDate"
                   :readonly="sonDisable"
@@ -333,7 +334,7 @@
           </el-table-column> 
           <el-table-column show-overflow-tooltip label="采购备注" align="center"  prop="puRemark" width="150px"/>
           <!-- <el-table-column show-overflow-tooltip label="末级供应仓库存量" align="center"  prop="lastWarehouseQty" /> -->
-          <el-table-column show-overflow-tooltip label="调拨占有量" align="center"  prop="superiorAllotQty" width="150px"/>
+          <el-table-column show-overflow-tooltip label="调拨占有量" align="center"  prop="allotQty" width="150px"/>
           <el-table-column show-overflow-tooltip label="最终净需求量" align="center"  prop="resDemandQty" width="150px">
             <template slot-scope="scope">
               <el-form-item class="hang">
@@ -562,7 +563,7 @@
           <el-input disabled clearable size="mini" v-model="adjust.address"/>
         </el-col>
       </el-row>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
       <el-button size="mini" type="primary" @click="confirmAdjust">确 认</el-button>
       <el-button size="mini" @click="adjust.open = false">取 消</el-button>
       </div>
@@ -649,13 +650,7 @@ export default {
       customerOptions: [],
       pickerOptionsEnd: {
         disabledDate: (time) => {
-          let beginDateVal = this.basicForm.demandDate;
-          if (beginDateVal) {
-            return (
-              time.getTime() <
-              new Date(beginDateVal).getTime() - 8.64e7
-            );
-          }
+          return time.getTime() < Date.now() - 1 * 24 * 60 * 60 * 1000
         }
       },
       isBDXQ: false,
@@ -738,11 +733,16 @@ export default {
         scope.row.reservedQty = Math.ceil(scope.row.reservedProportion.replace('%', '') / 100 * scope.row.qty)
       }
       // 如果选择预留比例,预留周期必填
-      if(scope.row.reservedQty && scope.row.reservedQty !== 0) {
-        this.isYl = true
-      } else {
-        this.isYl = false
-      }
+      // if(scope.row.reservedQty && scope.row.reservedQty !== 0) {
+      //   this.isYl = true
+      // } else {
+      //   this.isYl = false
+      // }
+    },
+    // 清空
+    cleanYLSL(scope) {
+      scope.row.reservedQty = ''
+      scope.row.reservedPeriod = ''
     },
     copy() {
       this.$modal.msgSuccess("复制成功");
@@ -765,6 +765,7 @@ export default {
         item.forecastClassify = ''
         item.onemonthAvgVolume = ''
         item.threemonthAvgVolume = ''
+        item.puFreight = ''
         item.superiorAllotQty = ''
         item.resDemandQty = ''
         item.executeQty = ''
@@ -778,6 +779,7 @@ export default {
         item.lastStockOrgName = ''
         item.centralWarehouseQty = ''
         item.allotCode = ''
+        item.allotQty = ''
         item.deliveryAddress = ''
         item.deliveryAddressName = ''
         item.contacts = ''
@@ -908,6 +910,7 @@ export default {
         forecastClassify: null,
         onemonthAvgVolume: null,
         threemonthAvgVolume: null,
+        puFreight: null,
         deliveryDate: null,
         isUrgency: this.basicForm.billType == 'JJXQ' ? 'Y' : 'N',
         isReplenishment: this.basicForm.billType == 'BDXQ'? 'Y': 'N',
@@ -1106,6 +1109,7 @@ export default {
             item.forecastClassify = ''
             item.onemonthAvgVolume = ''
             item.threemonthAvgVolume = ''
+            item.puFreight = ''
             item.superiorAllotQty = ''
             item.resDemandQty = ''
             item.executeQty = ''
@@ -1148,7 +1152,7 @@ export default {
       }
       if(this.referCondition.type == 'ADDRESS_PARAM' && this.referCondition.title == '收货地址') {
         this.adjust.deliveryAddressName = selection[0].name
-        this.adjust.deliveryAddress = selection[0].code
+        this.adjust.deliveryAddress = selection[0].id
         this.adjust.contacts = selection[0].contactsName
         this.adjust.contactsPhone = selection[0].contactsPhone
         this.adjust.address = selection[0].address
@@ -1177,33 +1181,183 @@ export default {
       }
       if(this.referCondition.title == '选择收货地址') {
         this.basicForm.puDemandItemList[this.tableIndex].deliveryAddressName = selection[0].name
-        this.basicForm.puDemandItemList[this.tableIndex].deliveryAddress = selection[0].code
+        this.basicForm.puDemandItemList[this.tableIndex].deliveryAddress = selection[0].id
         this.basicForm.puDemandItemList[this.tableIndex].contacts = selection[0].contactsName
         this.basicForm.puDemandItemList[this.tableIndex].contactsPhone = selection[0].contactsPhone
         this.basicForm.puDemandItemList[this.tableIndex].address = selection[0].address
       }
     },
     // 粘贴来的数据
-    pasteMe(e, scope) {
+    async pasteMe(e, scope, index) {
+      this.$modal.loading("正在处理数据...");
       e.preventDefault() //阻止默认粘贴事件
       let source = e.clipboardData.getData("Text");
       console.log('scope', scope.column.property)
       console.log('eee:', source)
       // 首先对源头进行解析
       let rows = source.split("\r\n"); // 拆成一个数组
-      // rows.pop()
+      // 数组去除空字符串
+      rows = rows.filter(item => {
+        return item && item.trim()
+      })
       console.log('复制的数组',rows);
       console.log('列表的数组',this.basicForm.puDemandItemList)
-      rows.forEach(item => {
-        console.log('items',item)
-        this.basicForm.puDemandItemList.push(this.basicForm.puDemandItemList[scope.$index])
-      })
+      if (rows.length < 1000) {
+        await getRefer({ type: 'MATERIAL_PARAM', materialCodeList: rows }).then(res => {
+          if (res.code === 200) {
+            let rowList = res.rows
+            for (let i = 0; i<rowList.length; i++) {
+            let line = {
+              contacts: null,
+              id: null,
+              demandId: null,
+              status: null,
+              businessDept: null,
+              businessDeptName: null,
+              materialCategory: null,
+              buyer: null,
+              buyerName: null,
+              mateiralClassifyOne: null,
+              materialClassifyOneName: null,
+              materialClassifyTwo: null,
+              materialClassifyTwoName: null,
+              materialClassifyThree: null,
+              materialClassifyThreeName: null,
+              materialClassifyFour: null,
+              materialClassifyFourName: null,
+              materialCode: null,
+              material: null,
+              materialName: null,
+              classifyId: null,
+              specification: null,
+              unit: null,
+              unitName: null,
+              manufacturerName: null,
+              registrant: null,
+              puPeriod: null,
+              expiryUnit: null,
+              expiry: null,
+              minPackage: null,
+              minOrderQty: null,
+              minBatch: null,
+              safeStock: null,
+              averageQtyMonth: null,
+              qty: null,
+              adjustmentPersonal: null,
+              adjustmentTime: null,
+              manualRegulation: null,
+              updateCause: null,
+              reservedProportion: null,
+              reservedPeriod: null,
+              reservedQty: null,
+              demandPeriod: null,
+              forecastClassify: null,
+              onemonthAvgVolume: null,
+              threemonthAvgVolume: null,
+              puFreight: null,
+              deliveryDate: null,
+              isUrgency: this.basicForm.billType == 'JJXQ' ? 'Y' : 'N',
+              isReplenishment: this.basicForm.billType == 'BDXQ' ? 'Y' : 'N',
+              isBatchLock: 'N',
+              remark: null,
+              puRemark: null,
+              lastWarehouseQty: null,
+              resDemandQty: null,
+              lastWarehouse: null,
+              lastWarehouseName: null,
+              deliveryWarehouse: null,
+              deliveryWarehouseName: null,
+              lastAllocation: null,
+              lastAllocationName: null,
+              deliveryAllocation: null,
+              deliveryAllocationName: null,
+              passageOn: null,
+              puOrg: null,
+              purOrgName: null,
+              lastStockQty: null,
+              superiorCenterQty: null,
+              superiorAllotQty: null,
+              availableQty: null,
+              statusAllot: 'N',
+              additionalSupplier: null,
+              additionalSupplierName: null,
+              periodUnit: null,
+              demandCustomer: this.basicForm.customer,
+              demandCustomerName: this.basicForm.customerName,
+              businessDept: this.basicForm.demandDept,
+              businessDeptName: null,
+              lastStockOrg: null,
+              lastStockOrgName: null,
+              superiorStockOrg: null,
+              superiorStockOrgName: null,
+              allotCode: null,
+              deliveryAddress: null,
+              deliveryAddressName: null,
+              contacts: null,
+              contactsPhone: null,
+              address: null,
+              source: null,
+              priceType: 'order',
+              puManagerApprover: null,
+              puManagerApproverName: null,
+              processTime: null,
+              affirmer: 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,
+            }
+              line.businessDept = rowList[i].businessDepartment
+              line.businessDeptName = rowList[i].businessDepartmentName
+              line.materialCode = rowList[i].code
+              line.material = rowList[i].id
+              line.materialName = rowList[i].name
+              line.classifyId = rowList[i].classifyId
+              line.materialClassifyOneName = rowList[i].oneClass
+              line.materialClassifyTwoName = rowList[i].twoClass
+              line.materialClassifyThreeName = rowList[i].threeClass
+              line.materialClassifyFourName = rowList[i].fourClass
+              line.specification = rowList[i].specification
+              line.model = rowList[i].model
+              line.unit = rowList[i].unitId
+              line.unitName = rowList[i].unitIdName
+              line.registrant = rowList[i].registrant
+              line.manufacturerName = rowList[i].manufacturerIdName
+              line.puPeriod = rowList[i].deliveryPeriod
+              line.expiry = rowList[i].usefulLife
+              line.expiryUnit = rowList[i].expiryUnitIdName
+              // line.minPackage = rowList[i].usefulLife
+              line.minPackage = rowList[i].minPackQty
+              line.minOrderQty = rowList[i].minOrderQty
+              line.minBatch = rowList[i].minBatchQty
+              line.safeStock = rowList[i].safeStock
+              line.purOrgName = rowList[i].purchasingOrganizationName
+              line.puOrg = rowList[i].purchasingOrganization
+              // 物料存储条件和运输条件
+              line.transportationCondition = rowList[i].transportationCondition
+              line.storageCondition = rowList[i].storageCondition
+              this.basicForm.puDemandItemList.push(line)
+              // console.log('临时数组', line)
+            }
+            this.$modal.msgSuccess("共粘贴" + rowList.length + '条数据');
+          }
+        }).catch(err => {
+          this.$modal.closeLoading();
+        })
+        this.$modal.closeLoading();
       console.log('列表', this.basicForm.puDemandItemList)
-      // this.basicForm.puDemandItemList.forEach(e => {
-      //   rows.forEach(d => {
-      //     e.materialCode = d
-      //   })
-      // })
+      } else {
+        this.$modal.msgWarning("复制长度不能超过1000!");
+      }
     },
     // 明细行选择物料编码带出数据
     chooseMaterial(index) {
@@ -1350,6 +1504,7 @@ export default {
           item.forecastClassify = ''
           item.onemonthAvgVolume = ''
           item.threemonthAvgVolume = ''
+          item.puFreight = ''
           item.superiorAllotQty = ''
           item.resDemandQty = ''
           item.executeQty = ''
@@ -1471,6 +1626,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 .success-row {
   background: #f11616;
 }

+ 37 - 26
src/views/purchase/PurchaseDemandList/index.vue

@@ -34,6 +34,13 @@
               </el-form-item>
             </el-col>
             <el-col :span="1.5">
+              <el-form-item label="需求人员">
+                <el-select clearable size="mini" v-model="queryParams.demandPersonal" @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="" 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>
@@ -44,13 +51,6 @@
           <div v-show="expanded">
           <el-row :gutter="10">
             <el-col :span="1.5">
-              <el-form-item label="需求人员">
-                <el-select clearable size="mini" v-model="queryParams.demandPersonal" @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.source" size="mini" style="width: 200px">
                   <el-option v-for="dict in dict.type.sys_bill_source" :key="dict.value" :label="dict.label" :value="dict.value">
@@ -66,12 +66,9 @@
                 </el-select>
               </el-form-item>
             </el-col>
-          </el-row>
-
-          <el-row :gutter="10">
             <el-col :span="1.5">
               <el-form-item label="需求部门">
-                <el-select clearable v-model="queryParams.demandDept" size="mini" :disabled="disable" @focus="chooseOrg('DEPT_PARAM', true, '需求部门')" style="width: 200px">
+                <el-select clearable v-model="queryParams.demandDept" size="mini" @focus="chooseOrg('DEPT_PARAM', true, '需求部门')" style="width: 200px">
                   <el-option
                     v-for="item in deptOptions"
                     :key="item.id"
@@ -94,18 +91,8 @@
                 </el-date-picker>
               </el-form-item>
             </el-col>
-            <el-col :span="1.5">
-              <el-form-item label="备注">
-                <el-input
-                  v-model.trim="queryParams.remark"
-                  size="mini"
-                  clearable
-                  style="width: 200px"
-                />
-                </el-form-item>
-              </el-col>
           </el-row>
-
+          
           <el-row :gutter="10">
             <el-col :span="1.5">
               <el-form-item label="物料编码">
@@ -125,6 +112,16 @@
                 </el-select>
               </el-form-item>
             </el-col>
+            <el-col :span="1.5">
+              <el-form-item label="备注">
+                <el-input
+                  v-model.trim="queryParams.remark"
+                  size="mini"
+                  clearable
+                  style="width: 200px"
+                />
+                </el-form-item>
+              </el-col>
           </el-row>
 
           </div>
@@ -186,11 +183,12 @@
           fixed="right"
           label="操作"
           align="center"
-          width="150"
+          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.status == '0' || scope.row.status == '3'" @click="edit(scope.row)">编辑</el-button>
+            <el-button type="text" size="mini" v-if="scope.row.status == '0' || scope.row.status == '3'" @click="commit(scope.row)">提交</el-button>
             <el-button type="text" size="mini" v-if="scope.row.status == '0' || scope.row.status == '3'" @click="deleteids(scope.row)">删除</el-button>
           </template>
         </el-table-column>
@@ -234,7 +232,7 @@
       </div> -->
       <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
       </el-upload>
-      <div slot="footer" class="dialog-footer">
+      <div slot="footer">
       <el-button size="mini" type="primary" @click="submitFileForm">确 定</el-button>
       <el-button size="mini" @click="upload.open = false">取 消</el-button>
       </div>
@@ -271,7 +269,7 @@
           <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">
+      <div slot="footer">
       <el-button size="mini" type="primary" @click="mbDownload">模板下载</el-button>
       <el-button size="mini" @click="download.open = false">取 消</el-button>
       </div>
@@ -292,7 +290,7 @@ 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 {getDemandList, delDemand, downLoadDemand, exportDemand } from '@/api/purchase/purchaseDemand.js'
+import {getDemandList, delDemand, downLoadDemand, exportDemand, submitDemand } from '@/api/purchase/purchaseDemand.js'
 export default {
   name: 'PurchaseDemandList',
   components: {
@@ -575,6 +573,19 @@ export default {
       this.rowDetail = row
       this.disable = false
     },
+    commit(row) {
+      console.log('row', row)
+      this.$modal.loading("提交中...");
+      submitDemand(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)

+ 0 - 312
src/views/purchase/apply/add/column.js

@@ -1,312 +0,0 @@
-export const FormColumns = [
-  {
-    item: { key: "priceName", title: "价格名称" },
-    attr: { is: "el-input", value: "价格申报单" },
-  },
-  {
-    item: { key: "priceCode", title: "价格编码" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "supplierName", title: "供应商", require: true },
-    attr: {
-      is: "el-popover-select-v2",
-      valueKey: "name",
-      referName: "SUPPLIER_PARAM",
-      dataMapping: {
-        supplier: "id",
-        supplierCode: "code",
-        supplierName: "name",
-      },
-    },
-  },
-  {
-    item: { key: "puOrgName", title: "采购组织", require: true },
-    attr: {
-      is: "el-popover-select-v2",
-      valueKey: "name",
-      referName: "ORG_PARAM",
-      dataMapping: { puOrg: "id", puOrgCode: "code", puOrgName: "name" },
-    },
-  },
-  {
-    item: { key: "currencyName", title: "币种", require: true },
-    attr: {
-      is: "el-popover-select-v2",
-      valueKey: "name",
-      referName: "CURRENCY_PARAM",
-      dataMapping: {
-        currency: "id",
-        currencyCode: "code",
-        currencyName: "name",
-      },
-    },
-  },
-  {
-    item: { key: "explainStr", title: "价格合理性说明", require: true },
-    attr: { is: "el-input" },
-  },
-  {
-    item: { key: "buyerName", title: "采购员", require: true },
-    attr: {
-      is: "el-popover-select-v2",
-      valueKey: "name",
-      referName: "CONTACTS_PARAM",
-      dataMapping: { buyer: "code", buyerName: "name" },
-    },
-  },
-  {
-    item: { key: "puDeptName", title: "采购部门", require: true },
-    attr: {
-      is: "el-popover-select-v2",
-      valueKey: "name",
-      referName: "DEPT_PARAM",
-      dataMapping: { puDept: "id", puDeptCode: "code", puDeptName: "name" },
-    },
-  },
-  {
-    item: { key: "createByName", title: "创建人" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "source", title: "来源单据号" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "id", title: "来源单据id" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "isEffective", title: "是否已推价格" },
-    attr: {
-      is: "el-select",
-      dictName: "is_effective",
-    },
-  },
-  {
-    item: { key: "effectiveDate", title: "生效日期" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "file", title: "附件", require: true, span: 24 },
-    attr: { is: "file-upload" },
-  },
-  {
-    item: { key: "sourceType", title: "来源单据类型" },
-    attr: { is: "el-input", disabled: true, readonly: true },
-  },
-  {
-    item: { key: "status", title: "单据状态" },
-    attr: {
-      is: "el-select",
-      dictName: "sys_status",
-      disabled: true,
-      readonly: true,
-      value: "0",
-    },
-  },
-];
-
-export const TabColumns = [
-  {
-    item: {
-      title: "物料信息表",
-      key: "priceApplyItems",
-    },
-    attr: {
-      value: [],
-    },
-    TableColumns: [
-      {
-        item: { key: "materialName", title: "物料名称", require: true },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "MATERIAL_PARAM",
-          dataMapping: {
-            model: "model",
-            material: "id",
-            materialCode: "code",
-            materialName: "name",
-            unitName: "unitIdName",
-            puUnitName: "unitIdName",
-            specification: "specification",
-            manufacturer: "manufacturerId",
-            manufacturerName: "manufacturerIdName",
-          },
-        },
-      },
-      { item: { key: "materialCode", title: "物料编码" }, attr: {} },
-      { item: { key: "manufacturerName", title: "生产厂家" }, attr: {} },
-      { item: { key: "specification", title: "规格" }, attr: {} },
-      { item: { key: "model", title: "型号" }, attr: {} },
-      {
-        item: { key: "unitName", title: "单位" },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "UNIT_PARAM",
-          dataMapping: { unit: "id", unitCode: "code", unitName: "name" },
-        },
-      },
-      {
-        item: { key: "puUnitName", title: "采购单位" },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "UNIT_PARAM",
-          dataMapping: { puUnit: "id", puUnitCode: "code", puUnitName: "name" },
-        },
-      },
-      {
-        item: { key: "conversionRate", title: "采购换算率", require: true },
-        attr: {
-          is: "el-input-number",
-          precision: 6,
-        },
-      },
-      {
-        item: { key: "tax", title: "税率%", require: true },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "ntaxrate",
-          referName: "TAX_RATE_PARAM",
-          dataMapping: { tax: "ntaxrate" },
-        },
-      },
-      {
-        item: { key: "taxPrice", title: "含税单价", require: true },
-        attr: {
-          is: "el-input-number",
-          precision: 6,
-          formatter: (prop) => (prop ? (prop * 1).toFixed(6) : null),
-        },
-      },
-      {
-        item: { key: "price", title: "无税单价", require: true },
-        attr: {
-          is: "el-computed-input",
-          formatter: (prop) => {
-            const { tax, taxPrice } = prop;
-            const newTax = Number(tax) / 100;
-            const price = (taxPrice / (1 + newTax)).toFixed(6);
-            return price === "NaN" ? null : price;
-          },
-        },
-      },
-      {
-        item: { key: "currencyName", title: "币种" },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "CURRENCY_PARAM",
-          dataMapping: {
-            currency: "id",
-            currencyCode: "code",
-            currencyName: "name",
-          },
-        },
-      },
-      {
-        item: { key: "periodBegin", title: "价格有效期(起)", require: true },
-        attr: {
-          is: "el-date-picker",
-          valueFormat: "yyyy-MM-dd",
-          value: new Date(),
-        },
-      },
-      {
-        item: { key: "periodEnd", title: "价格有效期(止)", require: true },
-        attr: {
-          is: "el-date-picker",
-          valueFormat: "yyyy-MM-dd",
-          pickerOptions: {
-            disabledDate(time) {
-              return time.getTime() < Date.now() + 3600 * 1000 * 24 * 365;
-            },
-          },
-
-          value: new Date(new Date().getTime() + 3600 * 1000 * 24 * 366),
-        },
-      },
-      {
-        item: { key: "customerName", title: "客户" },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "CUSTOMER_PARAM",
-          dataMapping: {
-            customer: "id",
-            customerCode: "code",
-            customerName: "name",
-          },
-        },
-      },
-      { item: { key: "recentlyPrice", title: "最近价格" }, attr: {} },
-      {
-        item: { key: "isApprovalFirst", title: "首次报批" },
-        attr: {
-          is: "el-select",
-          dictName: "is_effective",
-        },
-      },
-      {
-        item: { key: "isPriceAdjustment", title: "价格调整" },
-        attr: {
-          is: "el-select",
-          dictName: "is_effective",
-        },
-      },
-      {
-        item: { key: "priceType", title: "价格类型" },
-        attr: {
-          is: "el-select",
-          dictName: "sys_price_type",
-        },
-      },
-      {
-        item: { key: "isDistributionPrice", title: "配送价", require: true },
-        attr: {
-          is: "el-select",
-          dictName: "is_effective",
-        },
-      },
-      { item: { key: "createByName", title: "创建人名称" }, attr: {} },
-      { item: { key: "updateByName", title: "更新人名称" }, attr: {} },
-    ],
-  },
-  {
-    item: {
-      title: "合同执行组织范围",
-      key: "priceApplyOrgs",
-    },
-    attr: {
-      value: [],
-    },
-    TableColumns: [
-      {
-        item: { key: "orgName", title: "组织", require: true, width: "auto" },
-        attr: {
-          is: "el-popover-select-v2",
-          valueKey: "name",
-          referName: "ORG_PARAM",
-          dataMapping: {
-            org: "id",
-            orgCode: "code",
-            orgName: "name",
-          },
-        },
-      },
-      {
-        item: { key: "createByName", title: "创建人名称", width: "auto" },
-        attr: {},
-      },
-      {
-        item: { key: "updateByName", title: "更新人名称", width: "auto" },
-        attr: {},
-      },
-    ],
-  },
-];
-
-export default { FormColumns, TabColumns };

+ 322 - 0
src/views/purchase/apply/add/columns.js

@@ -0,0 +1,322 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    {
+      item: { key: "priceName", title: "价格名称" },
+      attr: { is: "el-input", value: "价格申报单" },
+    },
+    {
+      item: { key: "priceCode", title: "价格编码" },
+      attr: { is: "el-input", disabled: true, readonly: true },
+    },
+    {
+      item: { key: "supplierName", title: "供应商", require: true },
+      attr: {
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "SUPPLIER_PARAM",
+        dataMapping: {
+          supplier: "id",
+          supplierCode: "code",
+          supplierName: "name",
+        },
+      },
+    },
+    {
+      item: { key: "puOrgName", title: "采购组织", require: true },
+      attr: {
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "ORG_PARAM",
+        dataMapping: { puOrg: "id", puOrgCode: "code", puOrgName: "name" },
+      },
+    },
+    {
+      item: { key: "currencyName", title: "币种", require: true },
+      attr: {
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "CURRENCY_PARAM",
+        dataMapping: {
+          currency: "id",
+          currencyCode: "code",
+          currencyName: "name",
+        },
+      },
+    },
+    {
+      item: { key: "explainStr", title: "价格合理性说明", require: true },
+      attr: { is: "el-input" },
+    },
+    {
+      item: { key: "buyerName", title: "采购员", require: true },
+      attr: {
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "CONTACTS_PARAM",
+        dataMapping: { buyer: "code", buyerName: "name" },
+      },
+    },
+    {
+      item: { key: "puDeptName", title: "采购部门", require: true },
+      attr: {
+        is: "el-popover-select-v2",
+        valueKey: "name",
+        referName: "DEPT_PARAM",
+        dataMapping: { puDept: "id", puDeptCode: "code", puDeptName: "name" },
+      },
+    },
+    {
+      item: { key: "createByName", title: "创建人" },
+      attr: { is: "el-input", disabled: true, readonly: true },
+    },
+    {
+      item: { key: "source", title: "来源单据号" },
+      attr: { is: "el-input", disabled: true, readonly: true },
+    },
+    {
+      item: { key: "isEffective", title: "是否已推价格" },
+      attr: {
+        is: "el-select",
+        dictName: "is_effective",
+      },
+    },
+    {
+      item: { key: "effectiveDate", title: "生效日期" },
+      attr: { is: "el-input", disabled: true, readonly: true },
+    },
+    {
+      item: { key: "file", title: "附件", require: true, span: 24 },
+      attr: { is: "el-file-upload" },
+    },
+    {
+      item: { key: "sourceType", title: "来源单据类型" },
+      attr: { is: "el-input", disabled: true, readonly: true },
+    },
+    {
+      item: { key: "status", title: "单据状态" },
+      attr: {
+        is: "el-select",
+        dictName: "sys_status",
+        disabled: true,
+        readonly: true,
+        value: "0",
+      },
+    },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+
+  const TabColumns = [
+    {
+      item: {
+        title: "物料信息表",
+        key: "priceApplyItems",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "materialName", title: "物料名称", require: true },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "MATERIAL_PARAM",
+            dataMapping: {
+              model: "model",
+              material: "id",
+              materialCode: "code",
+              materialName: "name",
+              unitName: "unitIdName",
+              puUnitName: "unitIdName",
+              specification: "specification",
+              manufacturer: "manufacturerId",
+              manufacturerName: "manufacturerIdName",
+            },
+          },
+        },
+        { item: { key: "materialCode", title: "物料编码" }, attr: {} },
+        { item: { key: "manufacturerName", title: "生产厂家" }, attr: {} },
+        { item: { key: "specification", title: "规格" }, attr: {} },
+        { item: { key: "model", title: "型号" }, attr: {} },
+        {
+          item: { key: "unitName", title: "单位" },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "UNIT_PARAM",
+            dataMapping: { unit: "id", unitCode: "code", unitName: "name" },
+          },
+        },
+        {
+          item: { key: "puUnitName", title: "采购单位" },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "UNIT_PARAM",
+            dataMapping: {
+              puUnit: "id",
+              puUnitCode: "code",
+              puUnitName: "name",
+            },
+          },
+        },
+        {
+          item: { key: "conversionRate", title: "采购换算率", require: true },
+          attr: {
+            is: "el-input-number",
+            precision: CONFIG.precision,
+          },
+        },
+        {
+          item: { key: "tax", title: "税率%", require: true },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "ntaxrate",
+            referName: "TAX_RATE_PARAM",
+            dataMapping: { tax: "ntaxrate" },
+          },
+        },
+        {
+          item: { key: "taxPrice", title: "含税单价", require: true },
+          attr: {
+            is: "el-input-number",
+            precision: CONFIG.precision,
+          },
+        },
+        {
+          item: { key: "price", title: "无税单价", require: true },
+          attr: {
+            formatter: (prop) => {
+              const { tax = 0, taxPrice = 0 } = prop;
+              prop.price = ((taxPrice / (tax / 100 + 1)) * 1).toFixed(
+                CONFIG.precision
+              );
+              return prop.price;
+            },
+          },
+        },
+        {
+          item: { key: "currencyName", title: "币种" },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "CURRENCY_PARAM",
+            dataMapping: {
+              currency: "id",
+              currencyCode: "code",
+              currencyName: "name",
+            },
+          },
+        },
+        {
+          item: {
+            key: "periodBegin",
+            title: "价格有效期(起)",
+            require: true,
+          },
+          attr: {
+            is: "el-date-picker",
+            valueFormat: "yyyy-MM-dd",
+            value: new Date(),
+          },
+        },
+        {
+          item: { key: "periodEnd", title: "价格有效期(止)", require: true },
+          attr: {
+            is: "el-date-picker",
+            valueFormat: "yyyy-MM-dd",
+            pickerOptions: {
+              disabledDate(time) {
+                return time.getTime() < Date.now() + 3600 * 1000 * 24 * 365;
+              },
+            },
+
+            value: new Date(new Date().getTime() + 3600 * 1000 * 24 * 366),
+          },
+        },
+        {
+          item: { key: "customerName", title: "客户" },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "CUSTOMER_PARAM",
+            dataMapping: {
+              customer: "id",
+              customerCode: "code",
+              customerName: "name",
+            },
+          },
+        },
+        { item: { key: "recentlyPrice", title: "最近价格" }, attr: {} },
+        {
+          item: { key: "isApprovalFirst", title: "首次报批" },
+          attr: {
+            is: "el-select",
+            dictName: "is_effective",
+          },
+        },
+        {
+          item: { key: "isPriceAdjustment", title: "价格调整" },
+          attr: {
+            is: "el-select",
+            dictName: "is_effective",
+          },
+        },
+        {
+          item: { key: "priceType", title: "价格类型" },
+          attr: {
+            is: "el-select",
+            dictName: "sys_price_type",
+          },
+        },
+        {
+          item: { key: "isDistributionPrice", title: "配送价", require: true },
+          attr: {
+            is: "el-select",
+            dictName: "is_effective",
+          },
+        },
+        { item: { key: "createByName", title: "创建人名称" }, attr: {} },
+        { item: { key: "updateByName", title: "更新人名称" }, attr: {} },
+      ],
+    },
+    {
+      item: {
+        title: "合同执行组织范围",
+        key: "priceApplyOrgs",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "orgName", title: "组织", require: true, width: "auto" },
+          attr: {
+            is: "el-popover-select-v2",
+            valueKey: "name",
+            referName: "ORG_PARAM",
+            dataMapping: {
+              org: "id",
+              orgCode: "code",
+              orgName: "name",
+            },
+          },
+        },
+        {
+          item: { key: "createByName", title: "创建人名称", width: "auto" },
+          attr: {},
+        },
+        {
+          item: { key: "updateByName", title: "更新人名称", width: "auto" },
+          attr: {},
+        },
+      ],
+    },
+  ];
+
+  return { TableColumns, TabColumns };
+}

+ 385 - 213
src/views/purchase/apply/add/index.vue

@@ -1,68 +1,221 @@
 <script>
-import Column from "./column";
-import useData from "../hooks/data";
-import useWatch from "../hooks/watch";
-import useMethods from "../hooks/function";
+import useColumns from "./columns";
+import { REFER } from "@/components/popover-select/api";
+import { EXIST } from "@/api/business/purchase/catalogue";
 import { ITEM, SAVE } from "@/api/business/purchase/apply";
 
-const { watchPuOrgName: w1 } = useWatch();
-const { fetchTax, fetchUnit, fetchExist } = useMethods();
+const fetchTax = async (prop) => {
+  try {
+    // try
+    const { code, rows } = await REFER({
+      search: prop,
+      type: "TAX_RATE_PARAM",
+    });
+    if (code === 200) {
+      return rows[0] || {};
+    }
+  } catch (err) {
+    // catch
+    console.error(err);
+  } finally {
+    // finally
+  }
+};
+
+const fetchUnit = async (prop) => {
+  try {
+    // try
+    const { code, rows } = await REFER({
+      search: prop,
+      type: "UNIT_PARAM",
+    });
+    if (code === 200) {
+      return rows[0] || {};
+    }
+  } catch (err) {
+    // catch
+    console.error(err);
+  } finally {
+    // finally
+  }
+};
+
+const fetchExist = async (prop) => {
+  try {
+    // try
+    const { code, data } = await EXIST(prop);
+    if (code === 200) return data;
+  } catch (err) {
+    // catch
+    console.error(err);
+  } finally {
+    // finally
+  }
+};
 
 export default {
   name: "AddDrawer",
+  props: {
+    dict: {
+      type: Object,
+    },
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+    addType: {
+      type: String,
+      default: "add",
+    },
+  },
   components: {
-    ElComputedInput: () => import("@/components/computed-input/index.vue"),
+    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 {
-      title: "新 增",
-      ...useData(Column),
+      width: "100%",
+      visible: false,
+      loading: false,
+      rules: rules,
+      params: params,
+      tabName: tabName,
+      TabColumns: TabColumns,
+      TableColumns: TableColumns,
     };
   },
   computed: {
-    $dicts: {
-      get: function () {
-        return this.$parent.$parent.$dicts;
+    title: {
+      get() {
+        const { addType } = this;
+        if (addType === "add") {
+          return "新 增";
+        }
+        if (addType === "copy") {
+          return "复 制";
+        }
+        if (addType === "edit") {
+          return "编 辑";
+        }
       },
+      set() {},
+    },
+    disabled: {
+      get() {
+        const {
+          addType,
+          selectData,
+          selectData: [{ status } = {}],
+        } = this.$props;
+        if (addType === "add") {
+          return false;
+        }
+        if (addType === "copy") {
+          if (selectData.length !== 1) {
+            return true;
+          }
+        }
+        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() {},
+    },
+    priceApply: {
+      get() {
+        const {
+          params: { priceApplyOrgs, priceApplyItems },
+        } = this;
+        this.params.priceApplyOrgs = priceApplyOrgs.map((item, index) => ({
+          ...item,
+          $index: index,
+        }));
+        this.params.priceApplyItems = priceApplyItems.map((item, index) => ({
+          ...item,
+          $index: index,
+        }));
+        return {
+          priceApplyOrgs: this.params.priceApplyOrgs.filter(
+            ({ delFlag }) => delFlag !== "2"
+          ),
+          priceApplyItems: this.params.priceApplyItems.filter(
+            ({ delFlag }) => delFlag !== "2"
+          ),
+        };
+      },
+      set() {},
     },
   },
-  watch: {
-    "params.puOrgName": w1(),
-  },
+  watch: {},
   methods: {
     //
-    async fetchRefer(row, prop = {}) {
-      const { source, referName } = prop;
-      if (referName === "MATERIAL_PARAM") {
-        const { puOrg, customer, supplier } = this.params;
-        const { rateCode, unitIdName, code: materialCode } = row;
-        // task 1
-        fetchTax(rateCode).then((res) => {
-          const { ntaxrate } = res;
-          source.tax =
-            ntaxrate === "0E-8" ? "0.000000" : (ntaxrate * 1).toFixed(6);
-        });
-        // task 2
-        fetchUnit(unitIdName).then((res) => {
-          const { id, code, name } = res;
-          source.unit = id;
-          source.unitCode = code;
-          source.unitName = name;
-          source.puUnit = id;
-          source.puUnitCode = code;
-          source.puUnitName = name;
-        });
-        // task 3
-        fetchExist({ puOrg, customer, supplier, materialCode }).then((res) => {
-          const { recentlyPrice, isApprovalFirst, isPriceAdjustment } = res;
-          source.recentlyPrice = recentlyPrice;
-          source.isApprovalFirst = isApprovalFirst;
-          source.isPriceAdjustment = isPriceAdjustment;
+    changePuOrgName(prop) {
+      const {
+        select: { id: org, code: orgCode, name: orgName },
+      } = prop;
+      const index = this.params.priceApplyOrgs.findIndex(
+        (item) => item.org === org
+      );
+      if (index === -1) {
+        this.params.priceApplyOrgs.push({
+          org,
+          orgCode,
+          orgName,
+          createByName: undefined,
+          updateByName: undefined,
         });
       }
     },
     //
+    changeMaterialName(prop) {
+      const { row } = prop;
+      const { puOrg, customer, supplier } = this.params;
+      const { rateCode, unitIdName, code: materialCode } = row;
+      // task 1
+      fetchTax(rateCode).then((res) => {
+        const { ntaxrate } = res;
+        row.tax = ntaxrate === "0E-8" ? "0.000000" : (ntaxrate * 1).toFixed(6);
+      });
+      // task 2
+      fetchUnit(unitIdName).then((res) => {
+        const { id, code, name } = res;
+        row.unit = id;
+        row.unitCode = code;
+        row.unitName = name;
+        row.puUnit = id;
+        row.puUnitCode = code;
+        row.puUnitName = name;
+      });
+      // task 3
+      fetchExist({ puOrg, customer, supplier, materialCode }).then((res) => {
+        const { recentlyPrice, isApprovalFirst, isPriceAdjustment } = res;
+        row.recentlyPrice = recentlyPrice;
+        row.isApprovalFirst = isApprovalFirst;
+        row.isPriceAdjustment = isPriceAdjustment;
+      });
+    },
+
+    //
     async fetchItem(prop) {
       try {
         // try
@@ -70,29 +223,6 @@ export default {
         const { code, data } = await ITEM(prop);
         if (code === 200) {
           this.params = data;
-          this.params.id = null;
-          this.params.createBy = null;
-          this.params.priceCode = null;
-          this.params.createByName = null;
-          this.params.effectiveDate = null;
-          this.params.priceApplyItems = this.params.priceApplyItems.map(
-            (item) => ({
-              ...item,
-              id: null,
-              applyId: null,
-              createByName: null,
-              updateByName: null,
-            })
-          );
-          this.params.priceApplyOrgs = this.params.priceApplyOrgs.map(
-            (item) => ({
-              ...item,
-              id: null,
-              applyId: null,
-              createByName: null,
-              updateByName: null,
-            })
-          );
           return true;
         } else {
           return false;
@@ -106,23 +236,68 @@ export default {
       }
     },
     //
-    async open(prop) {
-      this.visible = prop ? await this.fetchItem(prop) : true;
+    async open() {
+      const { addType, selectData } = this.$props;
+      if (addType === "add") {
+        this.visible = true;
+      }
+      if (addType === "copy") {
+        const [{ id }] = selectData;
+        this.visible = await this.fetchItem(id);
+        this.params.id = null;
+        this.params.createBy = null;
+        this.params.priceCode = null;
+        this.params.createByName = null;
+        this.params.effectiveDate = null;
+        this.params.priceApplyItems = this.params.priceApplyItems.map(
+          (item) => ({
+            ...item,
+            id: null,
+            applyId: null,
+            createByName: null,
+            updateByName: null,
+          })
+        );
+        this.params.priceApplyOrgs = this.params.priceApplyOrgs.map((item) => ({
+          ...item,
+          id: null,
+          applyId: null,
+          createByName: null,
+          updateByName: null,
+        }));
+      }
+      if (addType === "edit") {
+        const [{ id }] = selectData;
+        this.visible = await this.fetchItem(id);
+        this.params.priceApplyItems = this.params.priceApplyItems.map(
+          (item) => ({
+            ...item,
+          })
+        );
+        this.params.priceApplyOrgs = this.params.priceApplyOrgs.map((item) => ({
+          ...item,
+        }));
+      }
     },
     //
     async hide() {
-      const { TabColumns, FormColumns, initParams } = this;
+      const {
+        TabColumns,
+        TableColumns,
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
       this.visible = false;
-      this.tabName = TabColumns[0].item.key;
-      this.params = initParams([...TabColumns, ...FormColumns]);
-      this.params.priceApplyOrgs = [];
-      this.params.priceApplyItems = [];
+      this.tabName = tabName;
+      this.params = this.$init.params([...TabColumns, ...TableColumns]);
     },
     //
     async useRowAdd(prop) {
       const {
         $notify,
-        initParams,
         TabColumns,
         params: { puOrgName, supplierName },
       } = this;
@@ -132,21 +307,53 @@ export default {
       if (!puOrgName) {
         return $notify.info("请选择采购组织");
       }
-      const { TableColumns } = TabColumns.find(({ item }) => item.key === prop);
-      this.params[prop].push(initParams(TableColumns));
+      const { TableColumns } = TabColumns.find(
+        ({ item: { key } }) => key === prop
+      );
+      this.params[prop].push({
+        delFlag: "0",
+        ...this.$init.params(TableColumns),
+      });
     },
     //
     async useRowRemove(prop, scope) {
-      const { $index } = scope;
-      this.params[prop].splice($index, 1);
+      const { addType } = this.$props;
+      const {
+        row: { $index },
+      } = scope;
+      if (addType === "add") {
+        this.params[prop].splice($index, 1);
+      }
+      if (addType === "copy") {
+        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].validate(async (valid) => {
+      this.$refs[prop].$refs[prop].validate(async (valid) => {
         if (valid) {
           try {
-            // try
-            const { msg, code } = await SAVE({ ...this.params });
+            this.loading = true;
+            const {
+              params,
+              params: { priceApplyOrgs, priceApplyItems },
+            } = this;
+            if (this.addType === "edit") {
+              params.priceApplyOrgs = priceApplyOrgs.filter(
+                (item) => item.orgName
+              );
+              params.priceApplyItems = priceApplyItems.filter(
+                (item) => item.materialName
+              );
+            }
+            const { msg, code } = await SAVE(params);
             if (code === 200) {
               this.hide();
               this.$emit("success");
@@ -171,144 +378,109 @@ export default {
 };
 </script>
 <template>
-  <el-drawer
-    :size="width"
-    :title="title"
-    :show-close="false"
-    :visible.sync="visible"
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
   >
-    <template slot="title">
-      <span>{{ title }}</span>
-      <span>
-        <el-button
-          :size="size"
-          circle
-          icon="el-icon-check"
-          @click="useSubmit('ruleForm')"
-        >
-        </el-button>
-        <el-button
-          :size="size"
-          circle
-          type="danger"
-          icon="el-icon-close"
-          @click="hide"
-        ></el-button>
-      </span>
-    </template>
-    <el-form
-      ref="ruleForm"
-      v-loading="loading"
-      :size="size"
-      :rules="rules"
-      :model="params"
-      label-width="auto"
-      label-position="right"
-      style="padding: 10px"
+    {{ title }}
+    <el-drawer
+      :size="width"
+      :title="title"
+      :visible.sync="visible"
+      append-to-body
+      destroy-on-close
+      @close="hide"
     >
-      <el-row :gutter="20" style="display: flex; flex-wrap: wrap">
-        <el-col
-          v-for="({ item, attr }, index) in FormColumns"
+      <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"
-          :span="item.span || 8"
+          :label="item.title"
+          :name="item.key"
+          lazy
         >
-          <el-form-item
-            :prop="item.key"
-            :label="item.title"
-            :require="item.require"
+          <el-super-table
+            v-model="priceApply[item.key]"
+            :dict="dict"
+            :ref="tabName"
+            :columns="columns"
+            :size="$attrs.size"
           >
-            <component
-              v-bind="attr"
-              v-model="params[item.key]"
-              :source.sync="params"
-              style="width: 100%"
-            >
-              <template v-if="attr.dictName">
-                <el-option
-                  v-for="item in $dicts[attr.dictName]"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
+            <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-option>
+                </el-button>
               </template>
-            </component>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label-width="0">
-            <el-tabs v-model="tabName">
-              <el-tab-pane
-                v-for="({ item, attr, TableColumns }, index) in TabColumns"
-                :key="index"
-                :label="item.title"
-                :name="item.key"
-                lazy
-              >
-                <el-table :size="size" :data="params[item.key]">
-                  <el-table-column label="序号">
-                    <template slot-scope="scope">
-                      {{ scope.$index + 1 }}
-                    </template>
-                  </el-table-column>
-                  <el-table-column
-                    v-for="(
-                      { item: cItem, attr: cAttr }, cIndex
-                    ) in TableColumns"
-                    :key="cIndex"
-                    :prop="cItem.key"
-                    :label="cItem.title"
-                    :width="cItem.width || 250"
-                    show-overflow-tooltip
-                  >
-                    <template slot-scope="scope">
-                      <component
-                        v-if="cAttr.is"
-                        v-bind="cAttr"
-                        v-model="scope.row[cItem.key]"
-                        :source.sync="scope.row"
-                        @change="fetchRefer"
-                        style="width: 100%"
-                      >
-                        <template v-if="cAttr.dictName">
-                          <el-option
-                            v-for="item in $dicts[cAttr.dictName]"
-                            :key="item.value"
-                            :label="item.label"
-                            :value="item.value"
-                          >
-                          </el-option>
-                        </template>
-                      </component>
-                      <span v-else> {{ scope.row[cItem.key] }}</span>
-                    </template>
-                  </el-table-column>
-                  <el-table-column fixed="right" label="操作" width="100">
-                    <template slot="header" slot-scope="scope">
-                      <el-button
-                        circle
-                        icon="el-icon-plus"
-                        :size="size"
-                        @click="useRowAdd(tabName)"
-                      >
-                      </el-button>
-                    </template>
-                    <template slot-scope="scope">
-                      <el-button
-                        circle
-                        icon="el-icon-minus"
-                        :size="size"
-                        @click.native.prevent="useRowRemove(tabName, scope)"
-                      >
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-tab-pane>
-            </el-tabs>
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-  </el-drawer>
+              <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>

+ 0 - 94
src/views/purchase/apply/column.js

@@ -1,94 +0,0 @@
-export const TableColumns = [
-  { item: { key: "priceName", title: "价格名称" }, attr: {} },
-  { item: { key: "priceCode", title: "价格编码" }, attr: {} },
-  {
-    item: { key: "status", title: "状态" },
-    attr: { dictName: "sys_status" },
-  },
-  { item: { key: "supplierName", title: "供应商" }, attr: {} },
-  { item: { key: "currencyName", title: "币种" }, attr: {} },
-  { item: { key: "explainStr", title: "价格合理性说明" }, attr: {} },
-  { item: { key: "buyerName", title: "采购员" }, attr: {} },
-  { item: { key: "puDeptName", title: "采购部门" }, attr: {} },
-  {
-    item: { key: "file", title: "附件" },
-    attr: { component: "dr-file-preview" },
-  },
-  { item: { key: "createByName", title: "创建人" }, attr: {} },
-  {
-    item: { key: "isEffective", title: "是否已推价格" },
-    attr: { dictName: "is_effective" },
-  },
-  { item: { key: "effectiveDate", title: "生效日期" }, attr: {} },
-  { item: { key: "id", title: "来源单据id" }, attr: {} },
-  { item: { key: "source", title: "来源单据号" }, attr: {} },
-  { item: { key: "sourceType", title: "来源单据类型" }, attr: {} },
-];
-
-export const SearchColumns = [
-  {
-    item: { key: "supplierName", title: "供应商" },
-    attr: {
-      is: "el-popover-select-v2",
-      referName: "SUPPLIER_PARAM",
-      valueKey: "name",
-      dataMapping: { supplier: "id", supplierName: "name" },
-    },
-  },
-  {
-    item: { key: "puOrgName", title: "采购组织" },
-    attr: {
-      is: "el-popover-select-v2",
-      referName: "ORG_PARAM",
-      valueKey: "name",
-      dataMapping: { puOrg: "id", puOrgName: "name" },
-    },
-    on: {
-      change: true,
-      "keyup.enter.native": true,
-    },
-  },
-  {
-    item: { key: "buyerName", title: "采购员" },
-    attr: {
-      is: "el-popover-select-v2",
-      referName: "CONTACTS_PARAM",
-      valueKey: "name",
-      dataMapping: { buyer: "code", buyerName: "name" },
-    },
-  },
-  {
-    item: { key: "currencyName", title: "币种" },
-    attr: {
-      is: "el-popover-select-v2",
-      referName: "CURRENCY_PARAM",
-      valueKey: "name",
-      dataMapping: { currency: "id", currencyName: "name" },
-    },
-  },
-  {
-    item: { key: "puDeptName", title: "采购部门" },
-    attr: {
-      is: "el-popover-select-v2",
-      referName: "DEPT_PARAM",
-      valueKey: "name",
-      dataMapping: { puDept: "id", puDeptName: "name" },
-    },
-  },
-  {
-    item: { key: "isEffective", title: "是否推价" },
-    attr: {
-      is: "el-select",
-      dictName: "is_effective",
-      clearable: true,
-    },
-  },
-  {
-    item: { key: "status", title: "状态" },
-    attr: {
-      is: "el-select",
-      dictName: "sys_status",
-      clearable: true,
-    },
-  },
-];

+ 109 - 0
src/views/purchase/apply/columns.js

@@ -0,0 +1,109 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    { item: { key: "priceName", title: "价格名称" }, attr: {} },
+    { item: { key: "priceCode", title: "价格编码" }, attr: {} },
+    {
+      item: { key: "status", title: "状态" },
+      attr: { is: "el-dict-tag", dictName: "sys_status" },
+    },
+    { item: { key: "supplierName", title: "供应商" }, attr: {} },
+    { item: { key: "currencyName", title: "币种" }, attr: {} },
+    {
+      item: { key: "explainStr", title: "价格合理性说明" },
+      attr: {},
+    },
+    { item: { key: "buyerName", title: "采购员" }, attr: {} },
+    { item: { key: "puDeptName", title: "采购部门" }, attr: {} },
+    {
+      item: { key: "file", title: "附件" },
+      attr: { is: "el-file-preview" },
+    },
+    { item: { key: "createByName", title: "创建人" }, attr: {} },
+    {
+      item: { key: "isEffective", title: "是否已推价格" },
+      attr: { is: "el-dict-tag", dictName: "is_effective" },
+    },
+    {
+      item: { key: "effectiveDate", title: "生效日期" },
+      attr: {},
+    },
+    { item: { key: "source", title: "来源单据号" }, attr: {} },
+    {
+      item: { key: "sourceType", title: "来源单据类型" },
+      attr: {},
+    },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, fixed: false },
+  }));
+  const SearchColumns = [
+    {
+      item: { key: "supplierName", title: "供应商" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "SUPPLIER_PARAM",
+        valueKey: "name",
+        dataMapping: { supplier: "id", supplierName: "name" },
+      },
+    },
+    {
+      item: { key: "puOrgName", title: "采购组织" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "ORG_PARAM",
+        valueKey: "name",
+        dataMapping: { puOrg: "id", puOrgName: "name" },
+      },
+    },
+    {
+      item: { key: "buyerName", title: "采购员" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "CONTACTS_PARAM",
+        valueKey: "name",
+        dataMapping: { buyer: "code", buyerName: "name" },
+      },
+    },
+    {
+      item: { key: "currencyName", title: "币种" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "CURRENCY_PARAM",
+        valueKey: "name",
+        dataMapping: { currency: "id", currencyName: "name" },
+      },
+    },
+    {
+      item: { key: "puDeptName", title: "采购部门" },
+      attr: {
+        is: "el-popover-select-v2",
+        referName: "DEPT_PARAM",
+        valueKey: "name",
+        dataMapping: { puDept: "id", puDeptName: "name" },
+      },
+    },
+    {
+      item: { key: "isEffective", title: "是否推价" },
+      attr: {
+        is: "el-select",
+        dictName: "is_effective",
+        clearable: true,
+      },
+    },
+    {
+      item: { key: "status", title: "状态" },
+      attr: {
+        is: "el-select",
+        dictName: "sys_status",
+        clearable: true,
+      },
+    },
+  ].map(({ item, attr }) => ({
+    attr,
+    item: { ...item, hidden: true, span: item.span || 6 },
+  }));
+
+  return { TableColumns, SearchColumns };
+}

+ 63 - 17
src/views/purchase/apply/delete/index.vue

@@ -3,40 +3,77 @@ import { REMOVE } from "@/api/business/purchase/apply";
 
 export default {
   name: "DeleteDialog",
+  props: {
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+  },
   data() {
-    return {};
+    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() {},
+    },
   },
-  computed: {},
   watch: {},
   methods: {
     //
-    open(prop) {
-      return new Promise((resolve, reject) => {
-        this.$confirm("是否删除数据项?", "提示", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "info",
-        })
-          .then(async () => {
+    open() {
+      this.$confirm(`是否删除数据项?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info",
+        beforeClose: async (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.confirmButtonText = "执行中...";
             try {
               // try
-              const ids = prop.map((item) => item.id).join(",");
+              const { selectData } = this.$props;
+              const ids = selectData.map((item) => item.id).join(",");
               const { msg, code } = await REMOVE(ids);
               if (code === 200) {
-                resolve(true);
+                done();
                 this.$emit("success");
                 this.$notify.success(msg);
               }
             } catch (err) {
               // catch
-              reject(false);
               console.error(err);
+              instance.confirmButtonText = "确认";
             } finally {
               // finally
+              instance.confirmButtonLoading = false;
             }
-          })
-          .catch(() => reject(false));
-      });
+          } else {
+            done();
+          }
+        },
+      })
+        .then(() => {})
+        .catch(() => {});
     },
   },
   created() {},
@@ -44,4 +81,13 @@ export default {
   destroyed() {},
 };
 </script>
-<template></template>
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
+  >
+    {{ title }}
+  </el-button>
+</template>

+ 14 - 0
src/views/purchase/apply/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);

+ 0 - 313
src/views/purchase/apply/edit/index.vue

@@ -1,313 +0,0 @@
-<script>
-import Column from "../add/column";
-import useData from "../hooks/data";
-import useWatch from "../hooks/watch";
-import useMethods from "../hooks/function";
-import { ITEM, SAVE } from "@/api/business/purchase/apply";
-
-const { watchPuOrgName: w1 } = useWatch();
-const { fetchTax, fetchUnit, fetchExist } = useMethods();
-
-export default {
-  name: "EditDrawer",
-  components: {
-    ElComputedInput: () => import("@/components/computed-input/index.vue"),
-    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
-  },
-  data() {
-    return {
-      title: "更 新",
-      ...useData(Column),
-    };
-  },
-  computed: {
-    $dicts: {
-      get: function () {
-        return this.$parent.$parent.$dicts;
-      },
-    },
-  },
-  watch: {
-    "params.puOrgName": w1(),
-  },
-  methods: {
-    //
-    async fetchRefer(row, prop = {}) {
-      const { source, referName } = prop;
-      if (referName === "MATERIAL_PARAM") {
-        const { puOrg, customer, supplier } = this.params;
-        const { rateCode, unitIdName, code: materialCode } = row;
-        // task 1
-        fetchTax(rateCode).then((res) => {
-          const { ntaxrate } = res;
-          source.tax =
-            ntaxrate === "0E-8" ? "0.000000" : (ntaxrate * 1).toFixed(6);
-        });
-        // task 2
-        fetchUnit(unitIdName).then((res) => {
-          const { id, code, name } = res;
-          source.unit = id;
-          source.unitCode = code;
-          source.unitName = name;
-          source.puUnit = id;
-          source.puUnitCode = code;
-          source.puUnitName = name;
-        });
-        // task 3
-        fetchExist({ puOrg, customer, supplier, materialCode }).then((res) => {
-          const { recentlyPrice, isApprovalFirst, isPriceAdjustment } = res;
-          source.recentlyPrice = recentlyPrice;
-          source.isApprovalFirst = isApprovalFirst;
-          source.isPriceAdjustment = isPriceAdjustment;
-        });
-      }
-    },
-    //
-    async fetchItem(prop) {
-      try {
-        // try
-        this.loading = true;
-        const { code, data } = await ITEM(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(prop) {
-      this.visible = await this.fetchItem(prop);
-    },
-    //
-    async hide() {
-      const { TabColumns, FormColumns, initParams } = this;
-      this.visible = false;
-      this.tabName = TabColumns[0].item.key;
-      this.params = initParams([...TabColumns, ...FormColumns]);
-    },
-    //
-    async useRowAdd(prop) {
-      const {
-        $notify,
-        TabColumns,
-        initParams,
-        params: { puOrgName, supplierName },
-      } = this;
-      if (!supplierName) {
-        return $notify.info("请选择供应商");
-      }
-      if (!puOrgName) {
-        return $notify.info("请选择采购组织");
-      }
-      const { TableColumns } = TabColumns.find(({ item }) => item.key === prop);
-      this.params[prop].push({ ...initParams(TableColumns), delFlag: "0" });
-    },
-    //
-    async useRowRemove(prop, scope) {
-      const {
-        row: { $index },
-      } = scope;
-      this.params[prop] = this.params[prop].map((item, index) => ({
-        ...item,
-        delFlag: index === $index ? "2" : item.delFlag,
-      }));
-    },
-    //
-    async useSubmit(prop) {
-      this.$refs[prop].validate(async (valid) => {
-        if (valid) {
-          try {
-            // try
-            this.loading = true;
-            const {
-              params,
-              params: { priceApplyOrgs, priceApplyItems },
-            } = this;
-            params.priceApplyOrgs = priceApplyOrgs.filter(
-              (item) => item.orgName
-            );
-            params.priceApplyItems = priceApplyItems.filter(
-              (item) => item.materialName
-            );
-            const { msg, code } = await SAVE(params);
-            if (code === 200) {
-              this.hide();
-              this.$emit("success");
-              this.$notify.success(msg);
-            }
-          } catch (err) {
-            // catch
-            console.error(err);
-          } finally {
-            // finally
-            this.loading = false;
-          }
-        } else {
-          return false;
-        }
-      });
-    },
-  },
-  created() {},
-  mounted() {},
-  destroyed() {},
-};
-</script>
-<template>
-  <el-drawer
-    :size="width"
-    :title="title"
-    :show-close="false"
-    :visible.sync="visible"
-  >
-    <template slot="title">
-      <span>{{ title }}</span>
-      <span>
-        <el-button
-          :size="size"
-          :loading="loading"
-          circle
-          icon="el-icon-check"
-          @click="useSubmit('ruleForm')"
-        >
-        </el-button>
-        <el-button
-          :size="size"
-          circle
-          type="danger"
-          icon="el-icon-close"
-          @click="hide"
-        ></el-button>
-      </span>
-    </template>
-    <el-form
-      ref="ruleForm"
-      v-loading="loading"
-      :size="size"
-      :rules="rules"
-      :model="params"
-      label-width="auto"
-      label-position="right"
-      style="padding: 10px"
-    >
-      <el-row :gutter="20" style="display: flex; flex-wrap: wrap">
-        <el-col
-          v-for="({ item, attr }, index) in FormColumns"
-          :key="index"
-          :span="item.span || 8"
-        >
-          <el-form-item
-            :prop="item.key"
-            :label="item.title"
-            :require="item.require"
-          >
-            <component
-              v-bind="attr"
-              v-model="params[item.key]"
-              :source.sync="params"
-              style="width: 100%"
-            >
-              <template v-if="attr.dictName">
-                <el-option
-                  v-for="item in $dicts[attr.dictName]"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                >
-                </el-option>
-              </template>
-            </component>
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label-width="0">
-            <el-tabs v-model="tabName">
-              <el-tab-pane
-                v-for="({ item, attr, TableColumns }, index) in TabColumns"
-                :key="index"
-                :label="item.title"
-                :name="item.key"
-                lazy
-              >
-                <el-table
-                  :size="size"
-                  :data="
-                    params[item.key]
-                      .map((item, index) => ({ ...item, $index: index }))
-                      .filter(({ delFlag }) => delFlag === '0')
-                  "
-                >
-                  <el-table-column label="序号">
-                    <template slot-scope="scope">
-                      {{ scope.$index + 1 }}
-                    </template>
-                  </el-table-column>
-                  <el-table-column
-                    v-for="(
-                      { item: cItem, attr: cAttr }, cIndex
-                    ) in TableColumns"
-                    :key="cIndex"
-                    :prop="cItem.key"
-                    :label="cItem.title"
-                    :width="cItem.width || 250"
-                    show-overflow-tooltip
-                  >
-                    <template slot-scope="scope">
-                      <component
-                        v-if="cAttr.is"
-                        v-bind="cAttr"
-                        v-model="scope.row[cItem.key]"
-                        :source.sync="scope.row"
-                        @change="fetchRefer"
-                        style="width: 100%"
-                      >
-                        <template v-if="cAttr.dictName">
-                          <el-option
-                            v-for="item in $dicts[cAttr.dictName]"
-                            :key="item.value"
-                            :label="item.label"
-                            :value="item.value"
-                          >
-                          </el-option>
-                        </template>
-                      </component>
-                      <span v-else> {{ scope.row[cItem.key] }}</span>
-                    </template>
-                  </el-table-column>
-                  <el-table-column fixed="right" label="操作" width="100">
-                    <template slot="header" slot-scope="scope">
-                      <el-button
-                        circle
-                        icon="el-icon-plus"
-                        :size="size"
-                        @click="useRowAdd(tabName)"
-                      >
-                      </el-button>
-                    </template>
-                    <template slot-scope="scope">
-                      <el-button
-                        circle
-                        icon="el-icon-minus"
-                        :size="size"
-                        @click.native.prevent="useRowRemove(tabName, scope)"
-                      >
-                      </el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </el-tab-pane>
-            </el-tabs>
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-  </el-drawer>
-</template>

+ 0 - 24
src/views/purchase/apply/hooks/data.js

@@ -1,24 +0,0 @@
-import { initRules, initParams } from "@/utils/init.js";
-
-export default function useData(prop) {
-  const { FormColumns, TabColumns } = prop;
-  const size = "mini";
-  const width = "100%";
-  const visible = false;
-  const loading = false;
-  const rules = initRules(FormColumns);
-  const params = initParams([...TabColumns, ...FormColumns]);
-  const tabName = "priceApplyItems";
-  return {
-    size,
-    width,
-    visible,
-    loading,
-    rules,
-    params,
-    tabName,
-    initParams,
-    TabColumns,
-    FormColumns,
-  };
-}

+ 0 - 55
src/views/purchase/apply/hooks/function.js

@@ -1,55 +0,0 @@
-import { REFER } from "@/components/popover-select/api";
-import { EXIST } from "@/api/business/purchase/catalogue";
-
-export default function useMethods() {
-  const fetchTax = async (prop) => {
-    try {
-      // try
-      const { code, rows } = await REFER({
-        search: prop,
-        type: "TAX_RATE_PARAM",
-      });
-      if (code === 200) {
-        return rows[0] || {};
-      }
-    } catch (err) {
-      // catch
-      console.error(err);
-    } finally {
-      // finally
-    }
-  };
-
-  const fetchUnit = async (prop) => {
-    try {
-      // try
-      const { code, rows } = await REFER({
-        search: prop,
-        type: "UNIT_PARAM",
-      });
-      if (code === 200) {
-        return rows[0] || {};
-      }
-    } catch (err) {
-      // catch
-      console.error(err);
-    } finally {
-      // finally
-    }
-  };
-
-  const fetchExist = async (prop) => {
-    try {
-      // try
-      const { code, data } = await EXIST(prop);
-      if (code === 200) return data;
-    } catch (err) {
-      // catch
-      console.error(err);
-    } finally {
-      // finally
-    }
-  };
-
-  return { fetchTax, fetchUnit, fetchExist };
-}

+ 0 - 46
src/views/purchase/apply/hooks/watch.js

@@ -1,46 +0,0 @@
-import { REFER } from "@/components/popover-select/api";
-
-const fetchOrg = async (prop) => {
-  try {
-    // try
-    const { code, rows } = await REFER({
-      search: prop,
-      type: "ORG_PARAM",
-    });
-    if (code === 200) {
-      return rows[0] || {};
-    }
-  } catch (err) {
-    // catch
-    console.error(err);
-  } finally {
-    // finally
-  }
-};
-
-export default function useWatch() {
-  const watchPuOrgName = () => ({
-    handler: async function (newProp) {
-      const index = this.params.priceApplyOrgs.findIndex(
-        (item) => item.orgName === newProp
-      );
-      if (index === -1 && newProp) {
-        const {
-          id: org,
-          code: orgCode,
-          name: orgName,
-        } = await fetchOrg(this.params.puOrgName);
-        await this.params.priceApplyOrgs.push({
-          org,
-          orgCode,
-          orgName,
-          createByName: undefined,
-          updateByName: undefined,
-        });
-      }
-    },
-    deep: true,
-  });
-
-  return { watchPuOrgName };
-}

+ 82 - 282
src/views/purchase/apply/index.vue

@@ -1,81 +1,39 @@
 <script>
+import { dicts } from "./dicts";
+import useColumns from "./columns";
 import { LIST } from "@/api/business/purchase/apply";
-import { TableColumns, SearchColumns } from "./column";
-import { initDicts, initParams } from "@/utils/init.js";
 
 export default {
   name: "PuchaseApply",
-  dicts: [...initDicts([...TableColumns, ...SearchColumns]), "sys_price_type"],
+  dicts: dicts,
   components: {
-    AddModel: () => import("./add/index.vue"),
-    SeeModel: () => import("./see/index.vue"),
-    EditModel: () => import("./edit/index.vue"),
-    SubmitModel: () => import("./submit/index.vue"),
-    DeleteModel: () => import("./delete/index.vue"),
-    ElPopoverSelectV2: () => import("@/components/popover-select-v2/index.vue"),
+    SeeButton: () => import("./see/index.vue"),
+    AddButton: () => import("./add/index.vue"),
+    DeleButton: () => import("./delete/index.vue"),
+    SubmButton: () => import("./submit/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,
-      batching: false,
-      searchColumns: SearchColumns,
-      params: initParams(SearchColumns),
+      params: params,
       tableData: [],
       selectData: [],
-      tableColumns: TableColumns,
+      SearchColumns: SearchColumns,
+      TableColumns: TableColumns,
       page: { pageNum: 1, pageSize: 10, total: 0 },
     };
   },
-  computed: {
-    $dicts: {
-      get: function () {
-        return this.dict.type;
-      },
-    },
-    $power: {
-      get() {
-        const {
-          batching,
-          selectData,
-          selectData: [{ status } = {}],
-        } = this;
-        const rule1 = selectData.length === 1;
-        const rule2 = selectData.length > 1;
-        const rule3 = status === "0" || status === "3";
-        const copy = rule1;
-        const edit = rule1 && rule3;
-        const delt = rule1 ? rule1 && rule3 : rule2;
-        const subm = rule1 ? rule1 && rule3 : rule2;
-        return {
-          // 复 制
-          copy: copy,
-          // 修 改
-          edit: edit,
-          // 删 除
-          delt: delt,
-          // 审 核
-          subm: subm,
-        };
-      },
-    },
-  },
+  computed: {},
   created() {
-    this.params.status = "0";
     this.useQuery(this.params, this.page);
   },
   methods: {
     //
-    setSelectable(row) {
-      const { status } = row;
-      // 审批中
-      if (status === "1") return false;
-      // 已完成
-      else if (status === "2") return false;
-      // other
-      else return true;
-    },
-    //
     async fetchList(prop, page) {
       try {
         this.loading = true;
@@ -90,9 +48,6 @@ export default {
             $index: (pageNum - 1) * pageSize + index + 1,
           }));
           this.page.total = total;
-          this.page.pageNum = pageNum;
-          this.page.pageSize = pageSize;
-          return this.tableData;
         }
       } catch (err) {
         // catch
@@ -111,77 +66,17 @@ export default {
     useReset() {
       this.page.pageNum = 1;
       this.page.pageSize = 10;
-      this.params = initParams(SearchColumns);
+      this.params = this.$init.params(this.SearchColumns);
       this.useQuery(this.params, this.page);
     },
     // 选 择
-    useRowClick(prop) {
-      if (!this.batching) this.selectData = prop;
-    },
-    // 选 择
     useSelect(prop) {
-      if (this.batching) this.selectData = prop;
-    },
-    // 批 量
-    useBatch() {
-      this.selectData = [];
-      this.batching = !this.batching;
-    },
-    // 新 增
-    async useAdd() {
-      const { open } = this.$refs.AddModel;
-      await open();
-    },
-    // 复 制
-    async useCopy(prop) {
-      const [{ id }] = prop;
-      const { open } = this.$refs.AddModel;
-      await open(id);
-    },
-    hasPowerCopy(prop) {
-      return prop.length === 1;
-    },
-    // 删 除
-    async useDelete(prop) {
-      const { open } = this.$refs.DeleteModel;
-      await open(prop);
-    },
-    hasPowerDelete(prop) {
-      if (prop.length === 1) {
-        const [{ status }] = prop;
-        if (status === "1") return false;
-        else if (status === "2") return false;
-        else return true;
-      } else {
-        return !!prop.length;
-      }
-    },
-    // 编 辑
-    async useEdit(prop) {
-      const [{ id }] = prop;
-      const { open } = this.$refs.EditModel;
-      await open(id);
+      this.selectData = prop;
     },
     // 明 细
     async useSee(prop) {
-      const { $index } = prop;
-      const { open } = this.$refs.SeeModel;
-      await open($index);
-    },
-    // 审 核
-    async useSubmit(prop, done) {
-      const { open } = this.$refs.SubmitModel;
-      await open(prop, done);
-    },
-    hasPowerSubmit(prop) {
-      if (prop.length === 1) {
-        const [{ status }] = prop;
-        if (status === "1") return false;
-        else if (status === "2") return false;
-        else return true;
-      } else {
-        return !!prop.length;
-      }
+      const { open } = this.$refs.SeeButton;
+      await open([prop]);
     },
   },
 };
@@ -189,163 +84,84 @@ export default {
 
 <template>
   <el-card v-loading="loading" :body-style="{ padding: 0 }">
-    <see-model ref="SeeModel" @success="useQuery(params, page)"></see-model>
-    <add-model ref="AddModel" @success="useReset"></add-model>
-    <edit-model ref="EditModel" @success="useQuery(params, page)"></edit-model>
-    <submit-model
-      ref="SubmitModel"
-      @success="useQuery(params, page)"
-    ></submit-model>
-    <delete-model
-      ref="DeleteModel"
-      @success="useQuery(params, page)"
-    ></delete-model>
-    <el-form
+    <el-super-search
+      v-model="params"
       :size="size"
-      :model="params"
-      label-width="auto"
-      label-position="right"
-      @submit.native.prevent
-    >
-      <el-row :gutter="20">
-        <el-col
-          v-for="column in searchColumns"
-          :key="column.item.title"
-          :span="column.item.span || 6"
-        >
-          <el-form-item :prop="column.item.key" :label="column.item.title">
-            <component
-              v-bind="column.attr"
-              v-model="params[column.item.key]"
-              :source.sync="params"
-              @change="useQuery(params, page)"
-              @keyup.enter.native="useQuery(params, page)"
-              style="width: 100%"
-            >
-              <template v-if="column.attr.dictName">
-                <el-option
-                  v-for="item in dict.type[column.attr.dictName]"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
-                >
-                </el-option>
-              </template>
-            </component>
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-    <div style="padding: 0 20px; display: flex; justify-content: space-between">
-      <div>
-        <el-button :size="size" @click="useQuery(params, page)">
-          查 询
-        </el-button>
-        <el-button :size="size" @click="useReset">重 置</el-button>
-        <el-button :size="size" @click="useAdd">新 增</el-button>
-        <el-button
-          v-show="$power.copy"
+      :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"
-          @click="useCopy(selectData)"
-        >
-          复 制
-        </el-button>
-        <el-button
-          v-show="$power.edit"
+          :select-data="[]"
+          :dict="dict"
+          add-type="add"
+          @success="useQuery(params, page)"
+        ></add-button>
+        <add-button
           :size="size"
-          @click="useEdit(selectData)"
-          >编 辑</el-button
+          :dict="dict"
+          :select-data="selectData"
+          add-type="copy"
+          @success="useQuery(params, page)"
         >
-        <!-- <el-button
-        v-show="$power.delt"
-        :size="size"
-        @click="useDelete(selectData)"
-      >
-        删 除
-      </el-button> -->
-        <el-button
-          v-show="$power.delt"
+        </add-button>
+      </el-button-group>
+      <el-button-group>
+        <see-button
+          v-show="false"
           :size="size"
-          @click="useDelete(selectData)"
-          >删 除</el-button
-        >
-        <el-button
-          v-show="$power.subm"
+          :dict="dict"
+          :model="params"
+          :select-data="selectData"
+          ref="SeeButton"
+          @success="useQuery(params, page)"
+        ></see-button>
+        <add-button
           :size="size"
-          @click="useSubmit(selectData)"
-          >审 核</el-button
-        >
-      </div>
-      <div>
-        <el-button
+          :dict="dict"
+          :select-data="selectData"
+          add-type="edit"
+          @success="useQuery(params, page)"
+        ></add-button>
+        <dele-button
           :size="size"
-          :icon="batching ? 'el-icon-close' : 'el-icon-check'"
-          @click="useBatch"
-        >
-          批 量
-        </el-button>
-      </div>
+          :select-data="selectData"
+          @success="useQuery(params, page)"
+        ></dele-button>
+      </el-button-group>
+      <el-button-group>
+        <subm-button
+          :size="size"
+          :select-data="selectData"
+          @success="useQuery(params, page)"
+        ></subm-button>
+      </el-button-group>
     </div>
-    <el-table
-      v-if="tableData.length"
+    <el-super-table
+      v-model="tableData"
       :size="size"
-      :data="tableData"
-      border
-      stripe
-      highlight-current-row
+      :dict="dict"
+      :columns="TableColumns"
+      stroage
+      hideOperationColumns
       @row-dblclick="useSee"
       @selection-change="useSelect"
-      @row-click="useRowClick([$event])"
     >
-      <el-table-column
-        v-if="batching"
-        fixed
-        width="55"
-        align="center"
-        type="selection"
-        :selectable="setSelectable"
-      >
-      </el-table-column>
-      <el-table-column width="55" align="center" type="index">
-        <template slot-scope="scope">
-          {{ scope.row.$index }}
-        </template>
+      <el-table-column fixed width="55" align="center" label="#" prop="$index">
       </el-table-column>
-      <el-table-column
-        v-for="(column, index) in tableColumns"
-        :key="index"
-        :prop="column.item.key"
-        :label="column.item.title"
-        :width="column.item.width || 200"
-        show-overflow-tooltip
-      >
-        <template slot-scope="scope">
-          <dict-tag
-            v-if="column.attr.dictName"
-            :size="size"
-            :value="scope.row[column.item.key]"
-            :options="dict.type[column.attr.dictName]"
-          />
-          <dr-file-preview
-            v-else-if="
-              column.attr.component === 'dr-file-preview' &&
-              scope.row[column.item.key]
-            "
-            v-model="scope.row[column.item.key]"
-          ></dr-file-preview>
-          <component is="span" v-else>{{
-            scope.row[column.item.key]
-          }}</component>
-        </template>
+      <el-table-column fixed width="55" align="center" type="selection">
       </el-table-column>
-    </el-table>
-    <el-empty v-else :image-size="200"></el-empty>
+    </el-super-table>
     <pagination
-      v-if="tableData.length"
       :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>
@@ -354,25 +170,9 @@ export default {
   width: calc(100% - 20px);
   height: 100%;
   margin: 10px;
-  padding: 0 0 20px 0;
-  .el-form {
-    padding: 20px 0 0;
-  }
-  .el-row {
-    display: flex;
-    flex-wrap: wrap;
-    padding: 0 20px;
-  }
-  ::v-deep .el-table--mini {
-    width: 100%;
-    margin: 20px 0 0 0;
-    .el-table__cell {
-      height: 50px;
-    }
-    td.el-table__cell {
-      border-right: 0;
-      // border-bottom: 0;
-    }
-  }
+  padding: 20px;
+}
+.el-button-group + .el-button-group {
+  margin: 0 0 0 10px;
 }
 </style>

+ 210 - 0
src/views/purchase/apply/see/columns.js

@@ -0,0 +1,210 @@
+import CONFIG from "@/config";
+
+export default function useColumns() {
+  const TableColumns = [
+    {
+      item: { key: "priceName", title: "价格名称" },
+      attr: {},
+    },
+    {
+      item: { key: "priceCode", title: "价格编码" },
+      attr: {},
+    },
+    {
+      item: { key: "supplierName", title: "供应商" },
+      attr: {},
+    },
+    {
+      item: { key: "puOrgName", title: "采购组织" },
+      attr: {},
+    },
+    {
+      item: { key: "currencyName", title: "币种" },
+      attr: {},
+    },
+    {
+      item: { key: "explainStr", title: "价格合理性说明" },
+      attr: {},
+    },
+    {
+      item: { key: "buyerName", title: "采购员" },
+      attr: {},
+    },
+    {
+      item: { key: "puDeptName", title: "采购部门" },
+      attr: {},
+    },
+    {
+      item: { key: "createByName", title: "创建人" },
+      attr: {},
+    },
+    {
+      item: { key: "source", title: "来源单据号" },
+      attr: {},
+    },
+    {
+      item: { key: "isEffective", title: "是否已推价格" },
+      attr: {
+        is: "el-dict-tag",
+        dictName: "is_effective",
+      },
+    },
+    {
+      item: { key: "effectiveDate", title: "生效日期" },
+      attr: {},
+    },
+    {
+      item: { key: "file", title: "附件" },
+      attr: { is: "el-file-preview" },
+    },
+    {
+      item: { key: "sourceType", title: "来源单据类型" },
+      attr: {},
+    },
+    {
+      item: { key: "status", title: "单据状态" },
+      attr: {
+        is: "el-dict-tag",
+        dictName: "sys_status",
+      },
+    },
+  ];
+
+  const TabColumns = [
+    {
+      item: {
+        title: "物料信息表",
+        key: "priceApplyItems",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "materialName", title: "物料名称" },
+          attr: {},
+        },
+        { item: { key: "materialCode", title: "物料编码" }, attr: {} },
+        { item: { key: "manufacturerName", title: "生产厂家" }, attr: {} },
+        { item: { key: "specification", title: "规格" }, attr: {} },
+        { item: { key: "model", title: "型号" }, attr: {} },
+        {
+          item: { key: "unitName", title: "单位" },
+          attr: {},
+        },
+        {
+          item: { key: "puUnitName", title: "采购单位" },
+          attr: {},
+        },
+        {
+          item: { key: "conversionRate", title: "采购换算率" },
+          attr: {
+            is: "el-computed-input-v2",
+            formatter: (prop) => {
+              return (prop * 1).toFixed(CONFIG.precision);
+            },
+          },
+        },
+        {
+          item: { key: "tax", title: "税率%" },
+          attr: {
+            is: "el-computed-input-v2",
+            formatter: (prop) => {
+              return (prop * 1).toFixed(CONFIG.precision);
+            },
+          },
+        },
+        {
+          item: { key: "taxPrice", title: "含税单价" },
+          attr: {
+            is: "el-computed-input-v2",
+            formatter: (prop) => {
+              return (prop * 1).toFixed(CONFIG.precision);
+            },
+          },
+        },
+        {
+          item: { key: "price", title: "无税单价" },
+          attr: {
+            is: "el-computed-input-v2",
+            formatter: (prop) => {
+              return (prop * 1).toFixed(CONFIG.precision);
+            },
+          },
+        },
+        {
+          item: { key: "currencyName", title: "币种" },
+          attr: {},
+        },
+        {
+          item: { key: "periodBegin", title: "价格有效期(起)" },
+          attr: {},
+        },
+        {
+          item: { key: "periodEnd", title: "价格有效期(止)" },
+          attr: {},
+        },
+        {
+          item: { key: "customerName", title: "客户" },
+          attr: {},
+        },
+        { item: { key: "recentlyPrice", title: "最近价格" }, attr: {} },
+        {
+          item: { key: "isApprovalFirst", title: "首次报批" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "is_effective",
+          },
+        },
+        {
+          item: { key: "isPriceAdjustment", title: "价格调整" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "is_effective",
+          },
+        },
+        {
+          item: { key: "priceType", title: "价格类型" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "sys_price_type",
+          },
+        },
+        {
+          item: { key: "isDistributionPrice", title: "配送价" },
+          attr: {
+            is: "el-dict-tag",
+            dictName: "is_effective",
+          },
+        },
+        { item: { key: "createByName", title: "创建人名称" }, attr: {} },
+        { item: { key: "updateByName", title: "更新人名称" }, attr: {} },
+      ],
+    },
+    {
+      item: {
+        title: "合同执行组织范围",
+        key: "priceApplyOrgs",
+      },
+      attr: {
+        value: [],
+      },
+      TableColumns: [
+        {
+          item: { key: "orgName", title: "组织", width: "auto" },
+          attr: {},
+        },
+        {
+          item: { key: "createByName", title: "创建人名称", width: "auto" },
+          attr: {},
+        },
+        {
+          item: { key: "updateByName", title: "更新人名称", width: "auto" },
+          attr: {},
+        },
+      ],
+    },
+  ];
+
+  return { TableColumns, TabColumns };
+}

+ 111 - 174
src/views/purchase/apply/see/index.vue

@@ -1,34 +1,57 @@
 <script>
-import Column from "../add/column";
-import useData from "../hooks/data";
+import useColumns from "./columns";
 import { ITEM, LIST } from "@/api/business/purchase/apply";
 
 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 {
-      column: 3,
+      width: "50%",
+      column: 2,
       title: "明 细",
-      ...useData(Column),
+      visible: false,
+      loading: false,
+      params: {},
+      tabName,
+      TabColumns: TabColumns,
+      TableColumns: TableColumns,
     };
   },
   props: {
-    // v-model
-    value: {
-      type: Boolean,
+    dict: {
+      type: Object,
+    },
+    model: {
+      type: Object,
+    },
+    selectData: {
+      type: [Array],
       require: true,
     },
   },
   computed: {
-    $father: {
-      get() {
-        return this.$parent.$parent;
-      },
-    },
-    $dicts: {
+    disabled: {
       get() {
-        return this.$father.$dicts;
+        const { selectData } = this;
+        if (selectData.length !== 1) {
+          return true;
+        }
       },
+      set() {},
     },
   },
   watch: {},
@@ -38,11 +61,11 @@ export default {
       try {
         // try
         this.loading = true;
-        const { params } = this.$father;
+        const { model } = this.$props;
         const {
           total,
           rows: [{ id }],
-        } = await LIST({ ...params }, { pageNum: prop, pageSize: 1 });
+        } = await LIST({ ...model }, { pageNum: prop, pageSize: 1 });
         const { code, data } = await ITEM(id);
         if (code === 200) {
           this.params = data;
@@ -62,33 +85,21 @@ export default {
     },
     //
     async open(prop) {
-      this.visible = await this.fetchItem(prop);
+      const [{ $index }] = prop;
+      this.visible = await this.fetchItem($index);
     },
     //
     async hide() {
-      const { TabColumns, FormColumns, initParams } = this;
+      const {
+        TabColumns: [
+          {
+            item: { key: tabName },
+          },
+        ],
+      } = useColumns();
       this.visible = false;
-      this.tabName = TabColumns[0].item.key;
-      this.params = initParams([...TabColumns, ...FormColumns]);
+      this.tabName = tabName;
     },
-    // //
-    // async useDelete(prop) {
-    //   await this.$father
-    //     .useDelete(prop)
-    //     .then(() => {
-    //       this.hide();
-    //     })
-    //     .catch(() => {});
-    // },
-    // //
-    // async useSubmit(prop) {
-    //   await this.$father
-    //     .useSubmit(prop)
-    //     .then(() => {
-    //       this.hide();
-    //     })
-    //     .catch(() => {});
-    // },
   },
   created() {},
   mounted() {},
@@ -96,147 +107,73 @@ export default {
 };
 </script>
 <template>
-  <el-drawer
-    :size="width"
-    :title="title"
-    :show-close="false"
-    :visible.sync="visible"
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
   >
-    <div
-      style="
-        z-index: 6666;
-        position: fixed;
-        right: 20px;
-        top: 50%;
-        transform: translateY(-50%);
-        display: flex;
-        flex-direction: column;
-      "
+    {{ title }}
+    <el-drawer
+      :size="width"
+      :title="title"
+      :visible.sync="visible"
+      append-to-body
+      @close="hide(selectData)"
     >
-      <el-button
-        :size="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="size"
-        :disabled="params.$index === params.$total"
-        circle
-        icon="el-icon-bottom"
-        @click="fetchItem(params.$index + 1)"
-        style="margin: 0"
-      ></el-button>
-    </div>
-    <template slot="title">
-      <span>{{ title }}</span>
-      <span>
-        <!-- <el-tooltip effect="dark" content="删 除" placement="bottom-end">
-          <el-button
-            :size="size"
-            circle
-            icon="el-icon-delete"
-            @click="useDelete([params])"
-          ></el-button>
-        </el-tooltip>
-        <el-tooltip effect="dark" content="复 制" placement="bottom-end">
-          <el-button
-            :size="size"
-            circle
-            icon="el-icon-document-copy"
-            @click="$father.useCopy([params])"
-          ></el-button>
-        </el-tooltip>
-        <el-tooltip
-          v-if="$father.hasPowerEdit([params])"
-          effect="dark"
-          content="编 辑"
-          placement="bottom-end"
-        >
-          <el-button
-            :size="size"
-            circle
-            icon="el-icon-edit"
-            @click="$father.useEdit([params])"
-          ></el-button>
-        </el-tooltip>
-        <el-tooltip
-          v-if="$father.hasPowerSubmit([params])"
-          effect="dark"
-          content="审 核"
-          placement="bottom-end"
-        >
-          <el-button
-            :size="size"
-            circle
-            icon="el-icon-check"
-            @click="useSubmit([params])"
-          ></el-button>
-        </el-tooltip> -->
+      <div
+        style="
+          z-index: 6666;
+          position: fixed;
+          right: 20px;
+          top: 50%;
+          transform: translateY(-50%);
+          display: flex;
+          flex-direction: column;
+        "
+      >
         <el-button
-          :size="size"
+          :size="$attrs.size"
+          :disabled="params.$index === 1"
           circle
-          type="danger"
-          icon="el-icon-close"
-          @click="hide"
+          icon="el-icon-top"
+          @click="fetchItem(params.$index - 1)"
+          style="margin: 0 0 10px 0"
         ></el-button>
-      </span>
-    </template>
-    <el-descriptions :size="size" :column="column" border style="margin: 10px">
-      <el-descriptions-item
-        v-if="params[item.key]"
-        v-for="({ item, attr }, index) in FormColumns"
-        :key="index"
-        :label="item.title"
-      >
-        <dict-tag
-          v-if="attr.is === 'el-select'"
-          :size="size"
-          :value="params[item.key]"
-          :options="$dicts[attr.dictName]"
-        />
-        <dr-file-preview
-          v-else-if="attr.is === 'file-upload'"
-          v-model="params[item.key]"
-        ></dr-file-preview>
-        <span v-else>{{ params[item.key] }}</span>
-      </el-descriptions-item>
-    </el-descriptions>
-    <el-tabs v-model="tabName" :size="size" style="margin: 10px">
-      <el-tab-pane
-        v-for="({ item, attr, TableColumns }, index) in TabColumns"
-        :key="index"
-        :name="item.key"
-        :label="item.title"
-        lazy
+        <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-table :size="size" :data="params[item.key]">
-          <el-table-column
-            v-for="({ item: cItem, attr: cAttr }, cIndex) in TableColumns"
-            :key="cIndex"
-            :prop="cItem.key"
-            :label="cItem.title"
-            :width="cItem.width || 250"
-            show-overflow-tooltip
+      </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"
           >
-            <template slot-scope="scope">
-              <dict-tag
-                v-if="cAttr.is === 'el-select'"
-                :size="size"
-                :value="scope.row[cItem.key]"
-                :options="$dicts[cAttr.dictName]"
-              />
-              <span v-else>{{
-                cAttr.formatter
-                  ? cAttr.formatter(scope.row[cItem.key])
-                  : scope.row[cItem.key]
-              }}</span>
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-tab-pane>
-    </el-tabs>
-  </el-drawer>
+          </el-super-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+  </el-button>
 </template>

+ 63 - 17
src/views/purchase/apply/submit/index.vue

@@ -3,40 +3,77 @@ import { SUBMIT } from "@/api/business/purchase/apply";
 
 export default {
   name: "SubmitDialog",
+  props: {
+    selectData: {
+      type: [Array],
+      require: true,
+    },
+  },
   data() {
-    return {};
+    return {
+      title: "提交OA",
+    };
+  },
+  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() {},
+    },
   },
-  computed: {},
   watch: {},
   methods: {
     //
-    open(prop) {
-      return new Promise((resolve, reject) => {
-        this.$confirm("是否提交审核数据项?", "提示", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "info",
-        })
-          .then(async () => {
+    open() {
+      this.$confirm(`是否提交数据项至OA系统?`, "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info",
+        beforeClose: async (action, instance, done) => {
+          if (action === "confirm") {
+            instance.confirmButtonLoading = true;
+            instance.confirmButtonText = "执行中...";
             try {
               // try
-              const ids = prop.map((item) => item.id).join(",");
+              const { selectData } = this.$props;
+              const ids = selectData.map((item) => item.id).join(",");
               const { msg, code } = await SUBMIT(ids);
               if (code === 200) {
-                resolve(true);
+                done();
                 this.$emit("success");
                 this.$notify.success(msg);
               }
             } catch (err) {
               // catch
-              reject(false);
               console.error(err);
+              instance.confirmButtonText = "确认";
             } finally {
               // finally
+              instance.confirmButtonLoading = false;
             }
-          })
-          .catch(() => reject(false));
-      });
+          } else {
+            done();
+          }
+        },
+      })
+        .then(() => {})
+        .catch(() => {});
     },
   },
   created() {},
@@ -44,4 +81,13 @@ export default {
   destroyed() {},
 };
 </script>
-<template></template>
+<template>
+  <el-button
+    v-bind="$attrs"
+    v-on="$listeners"
+    :disabled="disabled"
+    @click="open"
+  >
+    {{ title }}
+  </el-button>
+</template>

+ 0 - 131
src/views/purchase/catalogue/column.js

@@ -1,131 +0,0 @@
-export const FormColumns = [
-  {
-    key: "puOrgName",
-    title: "采购组织",
-  },
-  // {
-  //   key: "puOrg",
-  //   title: "采购组织编码",
-  // },
-  { key: "materialName", title: "物料" },
-  { key: "materialCode", title: "物料编码" },
-  { key: "materialClassifyName", title: "物料一级分类" },
-  { key: "manufacturerName", title: "生产厂家名称" },
-  // { key: "manufacturer", title: "生产厂家" },
-  { key: "model", title: "物料型号" },
-  { key: "specification", title: "物料规格" },
-  // { key: "supplier", title: "供应商" },
-  {
-    key: "supplierName",
-    title: "供应商名称",
-  },
-  // { key: "customer", title: "客户" },
-  { key: "customerName", title: "客户" },
-  {
-    key: "taxPrice",
-    title: "主含税单价",
-    formatter: (prop) => (prop ? prop.toFixed(6) : null),
-  },
-  // { key: "unit", title: "主单位" },
-  { key: "unitName", title: "主单位" },
-  { key: "effectiveDate", title: "价格生效日期" },
-  { key: "endDate", title: "价格失效日期" },
-  // { key: "buyer", title: "采购员" },
-  { key: "buyerName", title: "采购员" },
-  { key: "source", title: "来源单据编号" },
-  {
-    key: "convertRate",
-    title: "换算率",
-    formatter: (prop) => (prop ? prop.toFixed(6) : null),
-  },
-  {
-    key: "status",
-    title: "有效状态",
-    inputType: "Select",
-    referName: "is_effective",
-    width: 100,
-  },
-  {
-    key: "enableStatus",
-    title: "启用状态",
-    inputType: "Select",
-    referName: "is_effective",
-    width: 100,
-  },
-  {
-    key: "materialStatus",
-    title: "物料启用状态",
-    inputType: "Select",
-    referName: "is_effective",
-  },
-  {
-    key: "isDistribution",
-    title: "配送价",
-    inputType: "Select",
-    referName: "is_effective",
-  },
-  {
-    key: "priceType",
-    title: "价格类型",
-    inputType: "Select",
-    referName: "sys_price_type",
-  },
-  { key: "demandCode", title: "采购需求单号" },
-  { key: "expiryEarly", title: "效期预警" },
-  { key: "priority", title: "含税/无税优先" },
-  { key: "createByName", title: "创建人" },
-  { key: "updateByName", title: "更新人名称" },
-];
-
-export const SearchColumns = [
-  {
-    key: "puOrgName",
-    title: "采购组织",
-    inputType: "PopoverSelect",
-    referName: "ORG_PARAM",
-    dataMapping: {
-      puOrg: "id",
-      puOrgName: "name",
-    },
-  },
-  {
-    key: "manufacturer",
-    title: "生产厂家",
-    inputType: "Input",
-  },
-  {
-    key: "supplierName",
-    title: "供应商",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    dataMapping: {
-      supplier: "id",
-      supplierName: "name",
-    },
-  },
-  { key: "source", title: "来源单据编号", inputType: "Input" },
-  {
-    key: "materialCode",
-    title: "物料编码",
-    inputType: "PopoverSelect",
-    referName: "MATERIAL_PARAM",
-    dataMapping: {
-      material: "id",
-      materialCode: "code",
-    },
-  },
-  {
-    key: "status",
-    title: "有效状态",
-    inputType: "Select",
-    referName: "is_effective",
-  },
-  {
-    key: "enableStatus",
-    title: "启用状态",
-    inputType: "Select",
-    referName: "is_effective",
-  },
-];
-
-export default { FormColumns, SearchColumns };

Some files were not shown because too many files changed in this diff