Sfoglia il codice sorgente

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

黄梓星 2 anni fa
parent
commit
1f5b6caad1
43 ha cambiato i file con 2836 aggiunte e 2034 eliminazioni
  1. 7 20
      src/api/business/purchase/apply.js
  2. 37 30
      src/api/business/purchase/contract.js
  3. 0 8
      src/components/FileUpload/index.vue
  4. 115 0
      src/components/file-preview/index.vue
  5. 0 66
      src/components/file-tag/index.vue
  6. 9 9
      src/components/popover-select/index.vue
  7. 2 2
      src/main.js
  8. 366 0
      src/views/purchase/apply/add/column.js
  9. 183 57
      src/views/purchase/apply/add/index.vue
  10. 18 103
      src/views/purchase/apply/column.js
  11. 4 13
      src/views/purchase/apply/delete/index.vue
  12. 364 0
      src/views/purchase/apply/edit/column.js
  13. 293 0
      src/views/purchase/apply/edit/index.vue
  14. 29 0
      src/views/purchase/apply/hooks/use-data.js
  15. 16 0
      src/views/purchase/apply/hooks/use-dicts.js
  16. 160 0
      src/views/purchase/apply/hooks/use-methods.js
  17. 25 0
      src/views/purchase/apply/hooks/use-table.js
  18. 88 43
      src/views/purchase/apply/index.vue
  19. 134 36
      src/views/purchase/apply/see/index.vue
  20. 33 0
      src/views/purchase/apply/submit/index.vue
  21. 6 5
      src/views/purchase/contract/add/column.js
  22. 182 237
      src/views/purchase/contract/add/index.vue
  23. 14 352
      src/views/purchase/contract/column.js
  24. 4 11
      src/views/purchase/contract/delete/index.vue
  25. 181 280
      src/views/purchase/contract/edit/index.vue
  26. 32 0
      src/views/purchase/contract/hooks/use-data.js
  27. 16 0
      src/views/purchase/contract/hooks/use-dicts.js
  28. 148 0
      src/views/purchase/contract/hooks/use-methods.js
  29. 61 0
      src/views/purchase/contract/hooks/use-table.js
  30. 20 0
      src/views/purchase/contract/hooks/use-watch.js
  31. 1 2
      src/views/purchase/contract/import/index.vue
  32. 86 16
      src/views/purchase/contract/index.vue
  33. 0 531
      src/views/purchase/contract/record/column.js
  34. 76 134
      src/views/purchase/contract/record/index.vue
  35. 37 64
      src/views/purchase/contract/see/index.vue
  36. 33 0
      src/views/purchase/contract/termination/index.vue
  37. 7 1
      src/views/purchase/purchase-order/add/column.js
  38. 6 1
      src/views/purchase/purchase-order/add/index.vue
  39. 27 6
      src/views/purchase/purchase-order/edit/index.vue
  40. 7 4
      src/views/purchase/purchase-order/index.vue
  41. 6 1
      src/views/purchase/task/first-direct/column.js
  42. 1 0
      src/views/purchase/task/first-direct/index.vue
  43. 2 2
      vue.config.js

+ 7 - 20
src/api/business/purchase/apply.js

@@ -1,10 +1,11 @@
 import request from "@/utils/request";
 
-export function LIST(params) {
+export function LIST(data, params) {
   return request({
     url: "/pu/priceApply/list",
-    method: "GET",
+    method: "POST",
     params: params,
+    data: data,
   });
 }
 
@@ -15,17 +16,17 @@ export function ITEM(data) {
   });
 }
 
-export function ADD(data) {
+export function SAVE(data) {
   return request({
-    url: "/pu/priceApply/add",
+    url: "/pu/priceApply/save",
     method: "POST",
     data: data,
   });
 }
 
-export function EDIT(data) {
+export function SUBMIT(data) {
   return request({
-    url: "/pu/priceApply/edit",
+    url: `/pu/priceApply/submit/${data}`,
     method: "POST",
     data: data,
   });
@@ -37,17 +38,3 @@ export function REMOVE(data) {
     method: "delete",
   });
 }
-
-export function itemTableList(params, name) {
-  let url = "";
-  if (name === "priceApplyItemList") url = "/pu/priceApply/item/list";
-  if (name === "priceApplyClauseList") url = "/pu/priceApply/clause/list";
-  if (name === "priceApplyExpenseList") url = "/pu/priceApply/expense/list";
-  if (name === "priceApplyAgreementList") url = "/pu/priceApply/agreement/list";
-  if (name === "priceApplyApplyOrgList") url = "/pu/priceApply/org/list";
-  return request({
-    url: url,
-    method: "GET",
-    params: params,
-  });
-}

+ 37 - 30
src/api/business/purchase/contract.js

@@ -47,6 +47,14 @@ export function REMOVE(data) {
   });
 }
 
+export function TERMINATION(params) {
+  return request({
+    url: `/pu/contract/termination`,
+    method: "PUT",
+    params: params,
+  });
+}
+
 export function ITEM(data) {
   return request({
     url: `/pu/contract/${data}`,
@@ -69,33 +77,32 @@ const switchUrl = (prop) => {
   if (prop === "contractApplyOrgList") return "/pu/contract/org";
 };
 
-export function TABLELIST(params, name) {
-  return request({
-    url: `${switchUrl(name)}/list`,
-    method: "GET",
-    params: params,
-  });
-}
-
-export function TABLEADD(data, name) {
-  return request({
-    url: `${switchUrl(name)}/add`,
-    method: "POST",
-    data: data,
-  });
-}
-
-export function TABLEEDIT(data, name) {
-  return request({
-    url: `${switchUrl(name)}`,
-    method: "PUT",
-    data: data,
-  });
-}
-
-export function TABLEROMOVE(data, name) {
-  return request({
-    url: `${switchUrl(name)}/${data}`,
-    method: "DELETE",
-  });
-}
+export const TABLE = {
+  LIST: function (params, name) {
+    return request({
+      url: `${switchUrl(name)}/list`,
+      method: "GET",
+      params: params,
+    });
+  },
+  ADD: function (data, name) {
+    return request({
+      url: `${switchUrl(name)}/add`,
+      method: "POST",
+      data: data,
+    });
+  },
+  EDIT: function (data, name) {
+    return request({
+      url: `${switchUrl(name)}`,
+      method: "PUT",
+      data: data,
+    });
+  },
+  REMOVE: function (data, name) {
+    return request({
+      url: `${switchUrl(name)}/${data}`,
+      method: "DELETE",
+    });
+  },
+};

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

@@ -118,14 +118,6 @@ export default {
           const list = Array.isArray(val)
             ? val
             : this.value.split(this.separator);
-          // 然后将数组转为对象数组
-          // this.fileList = list.map((item) => {
-          //   if (typeof item === "string") {
-          //     item = { name: item, url: item };
-          //   }
-          //   item.uid = item.uid || new Date().getTime() + temp++;
-          //   return item;
-          // });
           this.fileList = list.map((item) => {
             item = JSON.parse(item);
             return {

+ 115 - 0
src/components/file-preview/index.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="file-preview">
+    <el-button
+      :size="size"
+      type="text"
+      @click="visible = true"
+      style="font-size: 12px"
+    >
+      附 件
+    </el-button>
+    <i class="el-icon-link el-icon--right"></i>
+    <el-dialog :visible.sync="visible" title="查看" append-to-body>
+      <div class="file-preview_content">
+        <div
+          v-for="item in fileList"
+          :key="item.url"
+          style="
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 10px 10px;
+            border: 1px dashed rgba(88, 140, 233, 0.3);
+          "
+        >
+          <span> {{ item.name }}</span>
+          <span>
+            <el-button
+              :size="size"
+              type="text"
+              icon="el-icon-view"
+              @click="useView(item)"
+            ></el-button>
+            <el-button
+              :size="size"
+              type="text"
+              icon="el-icon-download"
+              @click="useDownload(item)"
+            ></el-button>
+          </span>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "FilePreview",
+  props: {
+    // 值
+    value: [String, Object, Array],
+    // 组件大小
+    size: {
+      type: String,
+      dafault: () => {
+        return "mini";
+      },
+    },
+  },
+  data() {
+    return {
+      visible: false,
+      fileList: [],
+    };
+  },
+  computed: {},
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          let temp = 1;
+          // 首先将值转为数组
+          const list = Array.isArray(val)
+            ? val
+            : this.value.split(this.separator);
+          this.fileList = list.map((item) => {
+            item = JSON.parse(item);
+            return {
+              ...item,
+              uid: item.uid || new Date().getTime() + temp++,
+            };
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  methods: {
+    //
+    useDownload(prop) {
+      const { url, name } = prop;
+      this.download("/pu/contract/download/resource", { resource: url }, name);
+    },
+    //
+    useView(prop) {
+      this.$notify.info({ title: "暂不支持查看" });
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<style scoped>
+.file-preview_content > div {
+  margin-bottom: 10px;
+}
+.file-preview_content > div:last-of-type {
+  margin-bottom: 0;
+}
+</style>

+ 0 - 66
src/components/file-tag/index.vue

@@ -1,66 +0,0 @@
-<template>
-  <div class="file-tag">
-    <el-popconfirm
-      v-for="item in newValue"
-      :key="item.url"
-      confirm-button-text="好的"
-      cancel-button-text="不用了"
-      :title="`下载${item.name}`"
-      style="display: block"
-      @confirm="
-        download(
-          '/pu/contract/download/resource',
-          { resource: item.url },
-          item.name
-        )
-      "
-    >
-      <el-button :size="size" type="text" slot="reference">
-        {{ item.name }}
-      </el-button>
-    </el-popconfirm>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "FileTag",
-  props: {
-    // v-model
-    value: {
-      type: String,
-      require: true,
-    },
-    // 组件大小
-    size: {
-      type: String,
-      dafault: () => {
-        return "mini";
-      },
-    },
-  },
-  data() {
-    return {};
-  },
-  computed: {
-    newValue() {
-      const { value } = this.$props;
-      return this.setFileList(value);
-    },
-  },
-  watch: {},
-  methods: {
-    //
-    setFileList(prop) {
-      return prop.split(";").map((file) => {
-        const { url, name } = JSON.parse(file);
-        return { url: url, name: name };
-      });
-    },
-  },
-  created() {},
-  mounted() {},
-  destroyed() {},
-};
-</script>
-<style scoped></style>

+ 9 - 9
src/components/popover-select/index.vue

@@ -101,14 +101,14 @@ export default {
     //   const { value, multiple } = this.$props;
     //   return multiple ? "" : value;
     // },
-    innerValue:{
-      get(){
+    innerValue: {
+      get() {
         const { value, multiple } = this.$props;
         return multiple ? "" : value;
       },
-      set(val){
+      set(val) {
         this.$emit("input", val);
-      }
+      },
     },
     TableColumnTemp() {
       const { type } = this.$props;
@@ -128,7 +128,7 @@ export default {
     //
     emitChange(prop) {
       const { type, source, multiple } = this.$props;
-      this.$emit("change", multiple ? prop : prop[0], source, type);
+      this.$emit("change", multiple ? prop : prop[0], type, source);
     },
     // open dialog
     async open() {
@@ -231,11 +231,11 @@ export default {
         this.selectData = prop;
       }
     },
-    handleClear(){
-      if(!this.$props.multiple){
-        this.innerValue = '';
+    handleClear() {
+      if (!this.$props.multiple) {
+        this.innerValue = "";
       }
-    }
+    },
   },
   created() {
 

+ 2 - 2
src/main.js

@@ -54,7 +54,7 @@ import PopoverTreeSelect from "@/components/popover-tree-select";
 //
 import ComputedInput from "@/components/computed-input";
 // 附件标签组件
-import FileTag from "@/components/file-tag";
+import FilePreview from "@/components/file-preview";
 
 // 全局方法挂载
 Vue.prototype.getDicts = getDicts;
@@ -78,7 +78,7 @@ Vue.component("ImagePreview", ImagePreview);
 Vue.component("DrPopoverSelect", PopoverSelect);
 Vue.component("DrPopoverTreeSelect", PopoverTreeSelect);
 Vue.component("DrComputedInput", ComputedInput);
-Vue.component("DrFileTag", FileTag);
+Vue.component("DrFilePreview", FilePreview);
 
 Vue.use(directive);
 Vue.use(plugins);

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

@@ -0,0 +1,366 @@
+export const FormColumns = [
+  {
+    key: "priceName",
+    title: "价格名称",
+    inputType: "Input",
+    value: "价格申报单",
+  },
+  {
+    key: "supplierName",
+    title: "供应商",
+    inputType: "PopoverSelect",
+    referName: "SUPPLIER_PARAM",
+    valueKey: "name",
+    dataMapping: {
+      supplier: "code",
+      supplierName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "supplier",
+    title: "供应商编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "puOrgName",
+    title: "采购组织",
+    inputType: "PopoverSelect",
+    referName: "ORG_PARAM",
+    valueKey: "name",
+    dataMapping: {
+      puOrg: "code",
+      puOrgName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "puOrg",
+    title: "采购组织编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "currencyName",
+    title: "币种",
+    inputType: "PopoverSelect",
+    referName: "CURRENCY_PARAM",
+    dataMapping: {
+      currency: "code",
+      currencyName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "currency",
+    title: "币种编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "explainStr",
+    title: "价格合理性说明",
+    inputType: "Input",
+    require: true,
+  },
+  {
+    key: "buyerName",
+    title: "采购员",
+    inputType: "PopoverSelect",
+    referName: "CONTACTS_PARAM",
+    dataMapping: {
+      buyer: "code",
+      buyerName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "buyer",
+    title: "采购员编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "puDeptName",
+    title: "采购部门",
+    inputType: "PopoverSelect",
+    referName: "DEPT_PARAM",
+    dataMapping: {
+      puDept: "code",
+      puDeptName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "puDept",
+    title: "采购部门编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "createByName",
+    title: "创建人",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "source",
+    title: "来源单据号",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "id",
+    title: "来源单据id",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "isEffective",
+    title: "是否已推价格",
+    inputType: "Select",
+    referName: "sys_yes_no",
+  },
+  {
+    key: "effectiveDate",
+    title: "生效日期",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "file",
+    title: "附件",
+    inputType: "Upload",
+    span: 24,
+    disabled: true,
+    readonly: true,
+    value: [],
+  },
+  {
+    key: "sourceType",
+    title: "来源单据类型",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "status",
+    title: "单据状态",
+    inputType: "Select",
+    referName: "sys_status",
+    disabled: true,
+    readonly: true,
+    value: "0",
+  },
+];
+
+export const TabColumns = [
+  {
+    title: "物料信息表",
+    key: "priceApplyItems",
+    tableColumns: [
+      {
+        title: "物料名称",
+        key: "materialName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "MATERIAL_PARAM",
+        dataMapping: {
+          material: "code",
+          materialName: "name",
+          puUnit: "unitIdName",
+          specification: "specification",
+          manufacturer: "manufacturerIdName",
+        },
+      },
+      { title: "物料编码", key: "material" },
+      {
+        title: "生产厂家",
+        key: "manufacturer",
+      },
+      {
+        title: "规格",
+        key: "specification",
+      },
+      {
+        title: "型号",
+        key: "model",
+      },
+      {
+        title: "单位名称",
+        key: "unitName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "UNIT_PARAM",
+        dataMapping: {
+          puUnit: "name",
+        },
+      },
+      {
+        title: "单位",
+        key: "unit",
+      },
+      {
+        title: "采购单位名称",
+        key: "puUnitName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "UNIT_PARAM",
+        dataMapping: {
+          puUnit: "name",
+        },
+      },
+      {
+        title: "采购单位",
+        key: "puUnit",
+      },
+      {
+        title: "采购换算率",
+        key: "conversionRate",
+        inputType: "InputNumber",
+        width: 200,
+      },
+      {
+        title: "税率%",
+        key: "tax",
+        inputType: "PopoverSelect",
+        referName: "TAX_RATE_PARAM",
+        dataMapping: {
+          tax: "ntaxrate",
+        },
+        width: 200,
+      },
+      {
+        title: "含税单价",
+        key: "taxPrice",
+        inputType: "InputNumber",
+        width: 200,
+      },
+      {
+        title: "无税单价",
+        key: "taxFreePrice",
+        inputType: "ComputedInput",
+        width: 200,
+        computed: (prop) => {
+          const { tax, taxPrice } = prop;
+          const newTax = Number(tax) / 100;
+          const taxFreePrice = (taxPrice / (1 + newTax)).toFixed(8);
+          return taxFreePrice === "NaN" ? null : taxFreePrice;
+        },
+      },
+      {
+        key: "currencyName",
+        title: "币种名称",
+        inputType: "PopoverSelect",
+        referName: "CURRENCY_PARAM",
+        dataMapping: {
+          currency: "code",
+          currencyName: "name",
+        },
+      },
+      {
+        title: "币种",
+        key: "currency",
+      },
+      {
+        key: "periodBegin",
+        title: "价格有效期(起)",
+        inputType: "DatePicker",
+        valueFormat: "yyyy-MM-dd",
+      },
+      {
+        key: "periodEnd",
+        title: "价格有效期(止)",
+        inputType: "DatePicker",
+        valueFormat: "yyyy-MM-dd",
+      },
+      {
+        title: "客户名称",
+        key: "customerName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "CUSTOMER_PARAM",
+        dataMapping: {
+          customer: "code",
+          customerName: "name",
+        },
+      },
+      {
+        title: "客户",
+        key: "customer",
+      },
+      {
+        title: "首次报批",
+        key: "isApprovalFirst",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        title: "价格调整",
+        key: "isPriceAdjustment",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        key: "priceType",
+        title: "价格类型",
+        inputType: "Select",
+        referName: "sys_price_type",
+      },
+      {
+        title: "配送价",
+        key: "isDistributionPrice",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        title: "创建人名称",
+        key: "createByName",
+      },
+      {
+        title: "更新人名称",
+        key: "updateByName",
+      },
+    ],
+  },
+  {
+    title: "合同执行组织范围",
+    key: "priceApplyOrgs",
+    tableColumns: [
+      {
+        title: "组织名称",
+        key: "orgName",
+        inputType: "PopoverSelect",
+        referName: "ORG_PARAM",
+        dataMapping: {
+          org: "code",
+          orgName: "name",
+        },
+      },
+      { title: "组织编码", key: "org" },
+      {
+        title: "创建人名称",
+        key: "createByName",
+      },
+      {
+        title: "更新人名称",
+        key: "updateByName",
+      },
+    ],
+  },
+];
+
+export default { FormColumns, TabColumns };

+ 183 - 57
src/views/purchase/apply/add/index.vue

@@ -1,71 +1,53 @@
 <script>
-import { TableColumns } from "../column";
-import { ADD } from "@/api/business/purchase/apply";
-import { initDicts, initRules, initParams } from "@/utils/init";
+import Column from "./column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useTable from "../hooks/use-table";
+import useMethods from "../hooks/use-methods";
 
 export default {
-  name: "AddDialog",
-  dicts: initDicts(TableColumns),
+  name: "AddDrawer",
+  dicts: useDicts(Column),
   components: {},
   data() {
     return {
-      size: "mini",
-      visible: false,
-      loading: false,
-      columns: TableColumns,
-      rules: initRules(TableColumns),
-      params: initParams(TableColumns),
+      title: "新 增",
+      ...useData(Column),
     };
   },
   computed: {},
   watch: {},
   methods: {
     //
-    open(prop) {
-      this.visible = true;
-      this.fetchItem(prop);
+    async fetchRefer(prop, type, source) {
+      const { fetchRefer } = useMethods();
+      await fetchRefer({ _this: this, prop, type, source });
     },
     //
-    hide() {
-      this.visible = false;
-      this.params = initParams(this.columns);
+    async open(prop) {
+      const { open, fetchItem } = useMethods();
+      await open({ _this: this });
+      if (prop) await fetchItem({ _this: this, prop });
     },
     //
-    async fetchItem(prop) {
-      try {
-        this.loading = true;
-        this.params = prop;
-      } catch (err) {
-        //
-      } finally {
-        this.loading = false;
-      }
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
     //
-    submit(prop) {
-      this.$refs[prop].validate(async (valid) => {
-        if (valid) {
-          try {
-            this.params.id = undefined;
-            const { code, msg } = await ADD({
-              ...this.params,
-            });
-            if (code === 200) {
-              this.hide();
-              this.$emit("success");
-              
-            } else {
-              this.$notify.warning({ title: msg });
-            }
-          } catch (err) {
-            //
-          } finally {
-            //
-          }
-        } else {
-          return false;
-        }
-      });
+    async useRowAdd(prop) {
+      const { add } = useTable();
+      await add({ _this: this, prop });
+    },
+    //
+    async useRowRemove(prop, scope) {
+      const { remove } = useTable();
+      await remove({ _this: this, prop, scope, type: "ADD" });
+    },
+    //
+    async useSubmit(prop) {
+      const { add } = useMethods();
+      await add({ _this: this, prop });
     },
   },
   created() {},
@@ -74,7 +56,30 @@ export default {
 };
 </script>
 <template>
-  <el-dialog :visible.sync="visible" title="新增" fullscreen @close="hide">
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-check"
+          @click="useSubmit('ruleForm')"
+        >
+        </el-button>
+      </span>
+    </template>
     <el-form
       ref="ruleForm"
       v-loading="loading"
@@ -83,10 +88,11 @@ export default {
       :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="(column, index) in columns"
+          v-for="(column, index) in formColumns"
           :key="index"
           :span="column.span || 8"
         >
@@ -137,11 +143,131 @@ export default {
             ></file-upload>
           </el-form-item>
         </el-col>
+        <el-divider></el-divider>
+        <el-col :span="24">
+          <el-form-item label-width="0">
+            <el-tabs v-model="tabName">
+              <el-tab-pane
+                v-for="(column, index) in tabColumns"
+                :key="index"
+                :label="column.title"
+                :name="column.key"
+                lazy
+              >
+                <el-table :size="size" :data="params[column.key]">
+                  <el-table-column label="序号">
+                    <template slot-scope="scope">
+                      {{ scope.$index + 1 }}
+                    </template>
+                  </el-table-column>
+                  <el-table-column
+                    v-for="(cColumn, cIndex) in column.tableColumns"
+                    :key="cIndex"
+                    :prop="cColumn.key"
+                    :label="cColumn.title"
+                    :width="cColumn.width || 200"
+                    show-overflow-tooltip
+                  >
+                    <template slot-scope="scope">
+                      <el-input
+                        v-if="cColumn.inputType === 'Input'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></el-input>
+                      <dr-computed-input
+                        v-else-if="cColumn.inputType === 'ComputedInput'"
+                        v-model="scope.row[cColumn.key]"
+                        :source="scope.row"
+                        :computed="cColumn.computed"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></dr-computed-input>
+                      <dr-popover-select
+                        v-else-if="cColumn.inputType === 'PopoverSelect'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :title="cColumn.title"
+                        :source.sync="scope.row"
+                        :type="cColumn.referName"
+                        :disabled="cColumn.disabled"
+                        :readonly="cColumn.readonly"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :data-mapping="cColumn.dataMapping"
+                        @change="fetchRefer"
+                      >
+                      </dr-popover-select>
+                      <el-input-number
+                        v-else-if="cColumn.inputType === 'InputNumber'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :controls-position="cColumn.controlsPosition"
+                        style="width: 100%"
+                      ></el-input-number>
+                      <el-select
+                        v-else-if="cColumn.inputType === 'Select'"
+                        v-model="scope.row[cColumn.key]"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      >
+                        <el-option
+                          v-for="item in dict.type[cColumn.referName]"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                      <el-date-picker
+                        v-else-if="cColumn.inputType === 'DatePicker'"
+                        v-model="scope.row[cColumn.key]"
+                        :type="cColumn.type"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :value-format="cColumn.valueFormat"
+                        :picker-options="cColumn.pickerOptions"
+                        style="width: 100%"
+                      >
+                      </el-date-picker>
+                      <span v-else> {{ scope.row[cColumn.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>
-    <div style="text-align: right">
-      <el-button :size="size" @click="hide">取 消</el-button>
-      <el-button :size="size" @click="submit('ruleForm')">新 增</el-button>
-    </div>
-  </el-dialog>
+  </el-drawer>
 </template>

+ 18 - 103
src/views/purchase/apply/column.js

@@ -1,132 +1,54 @@
-export const TableColumns = [
-  { key: "priceName", title: "价格名称", inputType: "Input" },
+export const FormColumns = [
   {
-    key: "supplierName",
-    title: "供应商",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    valueKey: "name",
-    dataMapping: {
-      supplier: "code",
-      supplierName: "name",
-    },
-    require: true,
+    key: "priceName",
+    title: "价格名称",
   },
   {
-    key: "supplier",
-    title: "供应商编码",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
+    key: "status",
+    title: "状态",
+    inputType: "Select",
+    referName: "sys_status",
   },
   {
-    key: "puOrgName",
-    title: "采购组织",
-    inputType: "PopoverSelect",
-    referName: "ORG_PARAM",
-    valueKey: "name",
-    dataMapping: {
-      puOrg: "code",
-      puOrgName: "name",
-    },
-    require: true,
+    key: "supplierName",
+    title: "供应商",
   },
   {
-    key: "puOrg",
-    title: "采购组织编码",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
+    key: "puOrgName",
+    title: "采购组织",
   },
   {
     key: "currencyName",
     title: "币种",
-    inputType: "PopoverSelect",
-    referName: "CURRENCY_PARAM",
-    dataMapping: {
-      currency: "code",
-      currencyName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "currency",
-    title: "币种编码",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "explainStr",
     title: "价格合理性说明",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "buyerName",
     title: "采购员",
-    inputType: "PopoverSelect",
-    referName: "CONTACTS_PARAM",
-    dataMapping: {
-      buyer: "code",
-      buyerName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "buyer",
-    title: "采购员编码",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "puDeptName",
     title: "采购部门",
-    inputType: "PopoverSelect",
-    referName: "DEPT_PARAM",
-    dataMapping: {
-      puDept: "code",
-      puDeptName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "puDept",
-    title: "采购部门编码",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "file",
     title: "附件",
     inputType: "Upload",
-    span: "24",
-    disabled: true,
-    readonly: true,
-    value: [],
   },
   {
     key: "createByName",
     title: "创建人",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "source",
     title: "来源单据号",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "id",
     title: "来源单据id",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "isEffective",
@@ -137,28 +59,15 @@ export const TableColumns = [
   {
     key: "effectiveDate",
     title: "生效日期",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "sourceType",
     title: "来源单据类型",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
   },
   {
     key: "status",
     title: "单据状态",
-    inputType: "Input",
-    disabled: true,
-    readonly: true,
-  },
-  // { key: "tenantId", title: "租户号" },
-  // { key: "revision", title: "乐观锁" },
-  // { key: "updateByName", title: "更新人" },
-  // { key: "delFlag", title: "删除标记" },
+  },
 ];
 
 export const SearchColumns = [
@@ -218,4 +127,10 @@ export const SearchColumns = [
     inputType: "Select",
     referName: "sys_yes_no",
   },
+  {
+    key: "status",
+    title: "状态",
+    inputType: "Select",
+    referName: "sys_status",
+  },
 ];

+ 4 - 13
src/views/purchase/apply/delete/index.vue

@@ -1,5 +1,6 @@
 <script>
-import { REMOVE } from "@/api/business/purchase/apply";
+import useMethods from "../hooks/use-methods";
+
 export default {
   name: "DeleteDialog",
   data() {
@@ -16,18 +17,8 @@ export default {
         type: "info",
       })
         .then(async () => {
-          try {
-            this.loading = true;
-            const { id } = prop;
-            const { code } = await REMOVE(id);
-            if (code === 200) {
-              this.$emit("success");
-            }
-          } catch (err) {
-            // catch
-          } finally {
-            // finally
-          }
+          const { remove } = useMethods();
+          await remove({ _this: this, prop });
         })
         .catch((err) => {
           console.error(err);

+ 364 - 0
src/views/purchase/apply/edit/column.js

@@ -0,0 +1,364 @@
+export const FormColumns = [
+  {
+    key: "priceName",
+    title: "价格名称",
+    inputType: "Input",
+    value: "价格申报单",
+  },
+  {
+    key: "supplierName",
+    title: "供应商",
+    inputType: "PopoverSelect",
+    referName: "SUPPLIER_PARAM",
+    valueKey: "name",
+    dataMapping: {
+      supplier: "code",
+      supplierName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "supplier",
+    title: "供应商编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "puOrgName",
+    title: "采购组织",
+    inputType: "PopoverSelect",
+    referName: "ORG_PARAM",
+    valueKey: "name",
+    dataMapping: {
+      puOrg: "code",
+      puOrgName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "puOrg",
+    title: "采购组织编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "currencyName",
+    title: "币种",
+    inputType: "PopoverSelect",
+    referName: "CURRENCY_PARAM",
+    dataMapping: {
+      currency: "code",
+      currencyName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "currency",
+    title: "币种编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "explainStr",
+    title: "价格合理性说明",
+    inputType: "Input",
+    require: true,
+  },
+  {
+    key: "buyerName",
+    title: "采购员",
+    inputType: "PopoverSelect",
+    referName: "CONTACTS_PARAM",
+    dataMapping: {
+      buyer: "code",
+      buyerName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "buyer",
+    title: "采购员编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "puDeptName",
+    title: "采购部门",
+    inputType: "PopoverSelect",
+    referName: "DEPT_PARAM",
+    dataMapping: {
+      puDept: "code",
+      puDeptName: "name",
+    },
+    require: true,
+  },
+  {
+    key: "puDept",
+    title: "采购部门编码",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "createByName",
+    title: "创建人",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "source",
+    title: "来源单据号",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "id",
+    title: "来源单据id",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "isEffective",
+    title: "是否已推价格",
+    inputType: "Select",
+    referName: "sys_yes_no",
+  },
+  {
+    key: "effectiveDate",
+    title: "生效日期",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "file",
+    title: "附件",
+    inputType: "Upload",
+    span: 24,
+    disabled: true,
+    readonly: true,
+    value: [],
+  },
+  {
+    key: "sourceType",
+    title: "来源单据类型",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+  {
+    key: "status",
+    title: "单据状态",
+    inputType: "Input",
+    disabled: true,
+    readonly: true,
+  },
+];
+
+export const TabColumns = [
+  {
+    title: "物料信息表",
+    key: "priceApplyItems",
+    tableColumns: [
+      {
+        title: "物料名称",
+        key: "materialName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "MATERIAL_PARAM",
+        dataMapping: {
+          material: "code",
+          materialName: "name",
+          puUnit: "unitIdName",
+          specification: "specification",
+          manufacturer: "manufacturerIdName",
+        },
+      },
+      { title: "物料编码", key: "material" },
+      {
+        title: "生产厂家",
+        key: "manufacturer",
+      },
+      {
+        title: "规格",
+        key: "specification",
+      },
+      {
+        title: "型号",
+        key: "model",
+      },
+      {
+        title: "单位名称",
+        key: "unitName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "UNIT_PARAM",
+        dataMapping: {
+          puUnit: "name",
+        },
+      },
+      {
+        title: "单位",
+        key: "unit",
+      },
+      {
+        title: "采购单位名称",
+        key: "puUnitName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "UNIT_PARAM",
+        dataMapping: {
+          puUnit: "name",
+        },
+      },
+      {
+        title: "采购单位",
+        key: "puUnit",
+      },
+      {
+        title: "采购换算率",
+        key: "conversionRate",
+        inputType: "InputNumber",
+        width: 200,
+      },
+      {
+        title: "税率%",
+        key: "tax",
+        inputType: "PopoverSelect",
+        referName: "TAX_RATE_PARAM",
+        dataMapping: {
+          tax: "ntaxrate",
+        },
+        width: 200,
+      },
+      {
+        title: "含税单价",
+        key: "taxPrice",
+        inputType: "InputNumber",
+        width: 200,
+      },
+      {
+        title: "无税单价",
+        key: "taxFreePrice",
+        inputType: "ComputedInput",
+        width: 200,
+        computed: (prop) => {
+          const { tax, taxPrice } = prop;
+          const newTax = Number(tax) / 100;
+          const taxFreePrice = (taxPrice / (1 + newTax)).toFixed(8);
+          return taxFreePrice === "NaN" ? null : taxFreePrice;
+        },
+      },
+      {
+        key: "currencyName",
+        title: "币种名称",
+        inputType: "PopoverSelect",
+        referName: "CURRENCY_PARAM",
+        dataMapping: {
+          currency: "code",
+          currencyName: "name",
+        },
+      },
+      {
+        title: "币种",
+        key: "currency",
+      },
+      {
+        key: "periodBegin",
+        title: "价格有效期(起)",
+        inputType: "DatePicker",
+        valueFormat: "yyyy-MM-dd",
+      },
+      {
+        key: "periodEnd",
+        title: "价格有效期(止)",
+        inputType: "DatePicker",
+        valueFormat: "yyyy-MM-dd",
+      },
+      {
+        title: "客户名称",
+        key: "customerName",
+        inputType: "PopoverSelect",
+        width: 200,
+        referName: "CUSTOMER_PARAM",
+        dataMapping: {
+          customer: "code",
+          customerName: "name",
+        },
+      },
+      {
+        title: "客户",
+        key: "customer",
+      },
+      {
+        title: "首次报批",
+        key: "isApprovalFirst",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        title: "价格调整",
+        key: "isPriceAdjustment",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        key: "priceType",
+        title: "价格类型",
+        inputType: "Select",
+        referName: "sys_price_type",
+      },
+      {
+        title: "配送价",
+        key: "isDistributionPrice",
+        width: 200,
+        inputType: "Select",
+        referName: "sys_yes_no",
+      },
+      {
+        title: "创建人名称",
+        key: "createByName",
+      },
+      {
+        title: "更新人名称",
+        key: "updateByName",
+      },
+    ],
+  },
+  {
+    title: "合同执行组织范围",
+    key: "priceApplyOrgs",
+    tableColumns: [
+      {
+        title: "组织名称",
+        key: "orgName",
+        inputType: "PopoverSelect",
+        referName: "ORG_PARAM",
+        dataMapping: {
+          org: "code",
+          orgName: "name",
+        },
+      },
+      { title: "组织编码", key: "org" },
+      {
+        title: "创建人名称",
+        key: "createByName",
+      },
+      {
+        title: "更新人名称",
+        key: "updateByName",
+      },
+    ],
+  },
+];
+
+export default { FormColumns, TabColumns };

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

@@ -0,0 +1,293 @@
+<script>
+import Column from "./column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useTable from "../hooks/use-table";
+import useMethods from "../hooks/use-methods";
+
+export default {
+  name: "EditDrawer",
+  dicts: useDicts(Column),
+  components: {},
+  data() {
+    return {
+      title: "更 新",
+      newParams: {
+        priceApplyOrgs: [],
+        priceApplyItems: [],
+      },
+      ...useData(Column),
+    };
+  },
+  computed: {},
+  watch: {
+    "params.priceApplyOrgs": {
+      handler: function (newValue) {
+        this.newParams.priceApplyOrgs = newValue.filter(
+          (item) => item.delFlag === "0"
+        );
+      },
+      deep: true,
+    },
+    "params.priceApplyItems": {
+      handler: function (newValue) {
+        this.newParams.priceApplyItems = newValue.filter(
+          (item) => item.delFlag === "0"
+        );
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    //
+    async fetchRefer(prop, type, source) {
+      const { fetchRefer } = useMethods();
+      await fetchRefer({ _this: this, prop, type, source });
+    },
+    //
+    async open(prop) {
+      const { open, fetchItem } = useMethods();
+      await open({ _this: this });
+      if (prop) await fetchItem({ _this: this, prop });
+    },
+    //
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
+    },
+    //
+    async useRowAdd(prop) {
+      const { add } = useTable();
+      await add({ _this: this, prop });
+    },
+    //
+    async useRowRemove(prop, scope) {
+      const { remove } = useTable();
+      await remove({ _this: this, prop, scope, type: "EDIT" });
+    },
+    //
+    async useSubmit(prop) {
+      const { edit } = useMethods();
+      await edit({ _this: this, prop });
+    },
+  },
+  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"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-check"
+          @click="useSubmit('ruleForm')"
+        ></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="(column, index) in formColumns"
+          :key="index"
+          :span="column.span || 8"
+        >
+          <el-form-item :prop="column.key" :label="column.title">
+            <el-input
+              v-if="column.inputType === 'Input'"
+              v-model="params[column.key]"
+              :disabled="column.disabled"
+              :readonly="column.readonly"
+              :clearable="column.clearable"
+              :placeholder="column.placeholder"
+              style="width: 100%"
+            ></el-input>
+            <dr-popover-select
+              v-if="column.inputType === 'PopoverSelect'"
+              v-model="params[column.key]"
+              :source.sync="params"
+              :title="column.title"
+              :type="column.referName"
+              :disabled="column.disabled"
+              :readonly="column.readonly"
+              :clearable="column.clearable"
+              :placeholder="column.placeholder"
+              :data-mapping="column.dataMapping"
+              style="width: 100%"
+            >
+            </dr-popover-select>
+            <el-select
+              v-if="column.inputType === 'Select'"
+              v-model="params[column.key]"
+              :disabled="column.disabled"
+              :clearable="column.clearable"
+              :placeholder="column.placeholder"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in dict.type[column.referName]"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+            <file-upload
+              v-if="column.inputType === 'Upload'"
+              v-model="params[column.key]"
+              :file-type="column.fileType"
+            ></file-upload>
+          </el-form-item>
+        </el-col>
+        <el-divider></el-divider>
+        <el-col :span="24">
+          <el-form-item label-width="0">
+            <el-tabs v-model="tabName">
+              <el-tab-pane
+                v-for="(column, index) in tabColumns"
+                :key="index"
+                :label="column.title"
+                :name="column.key"
+                lazy
+              >
+                <el-table :size="size" :data="newParams[column.key]">
+                  <el-table-column label="序号">
+                    <template slot-scope="scope">
+                      {{ scope.$index + 1 }}
+                    </template>
+                  </el-table-column>
+                  <el-table-column
+                    v-for="(cColumn, cIndex) in column.tableColumns"
+                    :key="cIndex"
+                    :prop="cColumn.key"
+                    :label="cColumn.title"
+                    :width="cColumn.width || 200"
+                    show-overflow-tooltip
+                  >
+                    <template slot-scope="scope">
+                      <el-input
+                        v-if="cColumn.inputType === 'Input'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></el-input>
+                      <dr-computed-input
+                        v-else-if="cColumn.inputType === 'ComputedInput'"
+                        v-model="scope.row[cColumn.key]"
+                        :source="scope.row"
+                        :computed="cColumn.computed"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></dr-computed-input>
+                      <dr-popover-select
+                        v-else-if="cColumn.inputType === 'PopoverSelect'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :title="cColumn.title"
+                        :source.sync="scope.row"
+                        :type="cColumn.referName"
+                        :disabled="cColumn.disabled"
+                        :readonly="cColumn.readonly"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :data-mapping="cColumn.dataMapping"
+                        @change="fetchRefer"
+                      >
+                      </dr-popover-select>
+                      <el-input-number
+                        v-else-if="cColumn.inputType === 'InputNumber'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :controls-position="cColumn.controlsPosition"
+                        style="width: 100%"
+                      ></el-input-number>
+                      <el-select
+                        v-else-if="cColumn.inputType === 'Select'"
+                        v-model="scope.row[cColumn.key]"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      >
+                        <el-option
+                          v-for="item in dict.type[cColumn.referName]"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                      <el-date-picker
+                        v-else-if="cColumn.inputType === 'DatePicker'"
+                        v-model="scope.row[cColumn.key]"
+                        :type="cColumn.type"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :value-format="cColumn.valueFormat"
+                        :picker-options="cColumn.pickerOptions"
+                        style="width: 100%"
+                      >
+                      </el-date-picker>
+                      <span v-else> {{ scope.row[cColumn.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>

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

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

+ 16 - 0
src/views/purchase/apply/hooks/use-dicts.js

@@ -0,0 +1,16 @@
+import { initDicts } from "@/utils/init";
+
+export default function useDicts(prop) {
+  const { FormColumns = [], TabColumns = [] } = prop;
+  const dicts = Array.from(
+    new Set([
+      ...initDicts(FormColumns),
+      ...initDicts(
+        TabColumns.map((item) => item.tableColumns)
+          .flat()
+          .filter((item) => item.inputType === "Select")
+      ),
+    ])
+  );
+  return dicts;
+}

+ 160 - 0
src/views/purchase/apply/hooks/use-methods.js

@@ -0,0 +1,160 @@
+import { REFER } from "@/components/popover-select/api";
+import { SAVE, ITEM, REMOVE, SUBMIT } from "@/api/business/purchase/apply";
+
+export default function useMethods() {
+  const fetchItem = async ({ _this, prop }) => {
+    try {
+      // try
+      _this.loading = true;
+      const { code, data } = await ITEM(prop);
+      if (code === 200) {
+        _this.params = data;
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+      _this.loading = false;
+    }
+  };
+  const fetchRefer = async ({ _this, prop, type, source }) => {
+    const { rateCode } = prop;
+    if (type === "MATERIAL_PARAM") {
+      try {
+        // try
+        _this.loading = true;
+        const { code, rows } = await REFER({
+          search: rateCode,
+          type: "TAX_RATE_PARAM",
+        });
+        if (code === 200) {
+          const [{ ntaxrate }] = rows;
+          source.tax = ntaxrate === "0E-8" ? "0.00000000" : ntaxrate;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        _this.loading = false;
+      }
+    }
+  };
+  const open = ({ _this }) => {
+    _this.visible = true;
+    _this.tabName = _this.tabColumns[0].key;
+  };
+  const hide = ({ _this }) => {
+    _this.visible = false;
+  };
+  const add = ({ _this, prop }) => {
+    _this.$refs[prop].validate(async (valid) => {
+      if (valid) {
+        try {
+          // try
+          const {
+            priceApplyOrgs: _priceApplyOrgs,
+            priceApplyItems: _priceApplyItems,
+          } = _this.params;
+          const id = undefined;
+          const priceApplyOrgs = _priceApplyOrgs.map((item) => ({
+            ...item,
+            id: undefined,
+            applyId: undefined,
+          }));
+          const priceApplyItems = _priceApplyItems.map((item) => ({
+            ...item,
+            id: undefined,
+            applyId: undefined,
+          }));
+          const { msg, code } = await SAVE({
+            ..._this.params,
+            id,
+            priceApplyOrgs,
+            priceApplyItems,
+          });
+          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;
+      }
+    });
+  };
+  const edit = ({ _this, prop }) => {
+    _this.$refs[prop].validate(async (valid) => {
+      if (valid) {
+        try {
+          // try
+          const { msg, code } = await SAVE({
+            ..._this.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;
+      }
+    });
+  };
+  const remove = async ({ _this, prop }) => {
+    try {
+      // try
+      const { msg, code } = await REMOVE(prop);
+      if (code === 200) {
+        _this.$emit("success");
+        _this.$notify.success(msg);
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+    }
+  };
+  const submit = async ({ _this, prop }) => {
+    try {
+      // try
+      const ids = prop.map((item) => item.id).join(",");
+      const { msg, code } = await SUBMIT(ids);
+      if (code === 200) {
+        _this.$emit("success");
+        _this.$notify.success(msg);
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+    }
+  };
+  return {
+    open,
+    hide,
+    add,
+    edit,
+    remove,
+    submit,
+    fetchItem,
+    fetchRefer,
+  };
+}

+ 25 - 0
src/views/purchase/apply/hooks/use-table.js

@@ -0,0 +1,25 @@
+import { initParams } from "@/utils/init";
+
+export default function useTable() {
+  // 新 增
+  const add = ({ _this, prop }) => {
+    const { tableColumns } = _this.tabColumns.find(
+      (element) => element.key === prop
+    );
+    _this.params[prop].push(initParams(tableColumns));
+  };
+  // 删 除
+  const remove = ({ _this, prop, scope, type }) => {
+    const { $index } = scope;
+    if (type === "ADD") {
+      _this.params[prop].splice($index, 1);
+    } else {
+      _this.params[prop] = _this.params[prop].map((item, index) => ({
+        ...item,
+        delFlag: index === $index ? "2" : item.delFlag,
+      }));
+    }
+  };
+
+  return { add, remove };
+}

+ 88 - 43
src/views/purchase/apply/index.vue

@@ -1,13 +1,15 @@
 <script>
-import { TableColumns, SearchColumns } from "./column";
 import { LIST } from "@/api/business/purchase/apply";
+import { FormColumns, SearchColumns } from "./column";
 import { initPage, initDicts, initParams } from "@/utils/init";
 export default {
   name: "PuchaseApply",
-  dicts: [...initDicts(SearchColumns), ...initDicts(TableColumns)],
+  dicts: [...initDicts(SearchColumns), ...initDicts(FormColumns)],
   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"),
   },
   data() {
@@ -17,7 +19,8 @@ export default {
       searchColumns: SearchColumns,
       params: initParams(SearchColumns),
       tableData: [],
-      tableColumns: TableColumns,
+      currentData: [],
+      tableColumns: FormColumns,
       page: { pageNum: 1, pageSize: 10, total: 0 },
     };
   },
@@ -31,17 +34,19 @@ export default {
       try {
         this.loading = true;
         const { pageNum, pageSize } = page;
-        const { code, rows, total } = await LIST({
-          pageNum,
-          pageSize,
-          ...prop,
-        });
+        const { code, rows, total } = await LIST(
+          {
+            ...prop,
+          },
+          { pageNum, pageSize }
+        );
         if (code === 200) {
           this.tableData = rows;
           this.page.total = total;
         }
       } catch (err) {
         // catch
+        console.error(err);
       } finally {
         // finally
         this.loading = false;
@@ -57,22 +62,42 @@ export default {
       this.params = initParams(SearchColumns);
       this.useQuery(this.params, this.page);
     },
-    // 删 除
-    async useDelete(prop) {
-      const { id } = prop;
-      const { open } = this.$refs.DeleteModel;
+    // 选 择
+    useSelect(prop) {
+      this.currentData = [prop];
+    },
+    // 新 增
+    async useAdd() {
+      const { open } = this.$refs.AddModel;
+      await open();
+    },
+    // 复 制
+    async useCopy(prop) {
+      const [{ id }] = prop;
+      const { open } = this.$refs.AddModel;
       await open(id);
     },
     // 删 除
     async useDelete(prop) {
-      const { id } = prop;
+      const [{ id }] = prop;
       const { open } = this.$refs.DeleteModel;
       await open(id);
     },
-    // 新 增
-    async useAdd() {
-      const { open } = this.$refs.AddModel;
-      await open();
+    hasPowerDelete(prop) {
+      if (!prop.length) return true;
+      const [{ status = undefined }] = prop;
+      return status === "1" || status === "2";
+    },
+    // 编 辑
+    async useEdit(prop) {
+      const [{ id }] = prop;
+      const { open } = this.$refs.EditModel;
+      await open(id);
+    },
+    hasPowerEdit(prop) {
+      if (!prop.length) return true;
+      const [{ status = undefined }] = prop;
+      return status === "1" || status === "2";
     },
     // 明 细
     async useSee(prop) {
@@ -80,6 +105,16 @@ export default {
       const { open } = this.$refs.SeeModel;
       await open(id);
     },
+    // 审 核
+    async useSubmit(prop, done) {
+      const { open } = this.$refs.SubmitModel;
+      await open(prop, done);
+    },
+    hasPowerSubmit(prop) {
+      if (!prop.length) return true;
+      const [{ status = undefined }] = prop;
+      return status === "1" || status === "2";
+    },
   },
 };
 </script>
@@ -97,6 +132,11 @@ export default {
   >
     <see-model ref="SeeModel"></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)"
@@ -163,11 +203,28 @@ export default {
         查 询
       </el-button>
       <el-button :size="size" @click="useReset"> 重 置 </el-button>
+      <el-button :size="size" @click="useAdd"> 新 增 </el-button>
+      <el-button
+        :size="size"
+        :disabled="!currentData.length"
+        @click="useCopy(currentData)"
+      >
+        复 制
+      </el-button>
+      <el-button
+        v-if="!hasPowerDelete(currentData)"
+        :size="size"
+        @click="useDelete(currentData)"
+      >
+        删 除
+      </el-button>
     </el-row>
     <el-table
       :size="size"
       :data="tableData"
-      @row-dblclick="openSeeModel"
+      highlight-current-row
+      @row-click="useSelect"
+      @row-dblclick="useSee"
       style="width: 100%; margin: 20px 0 0 0"
     >
       <el-table-column
@@ -175,33 +232,21 @@ export default {
         :key="index"
         :prop="column.key"
         :label="column.title"
-        :width="column.width || 180"
-        :show-overflow-tooltip="column.showOverflowTooltip || true"
+        :width="column.width || 200"
+        show-overflow-tooltip
       >
-      </el-table-column>
-      <el-table-column fixed="right" label="操作" width="200">
         <template slot-scope="scope">
-          <el-button
-            @click.native.prevent="useAdd(scope.row)"
-            type="text"
-            size="small"
-          >
-            复 制
-          </el-button>
-          <!-- <el-button
-            @click.native.prevent="editItem(scope.row)"
-            type="text"
-            size="small"
-          >
-            编 辑
-          </el-button> -->
-          <el-button
-            @click.native.prevent="useDelete(scope.row)"
-            type="text"
-            size="small"
-          >
-            删 除
-          </el-button>
+          <dict-tag
+            v-if="column.inputType === 'Select'"
+            :size="size"
+            :value="scope.row[column.key]"
+            :options="dict.type[column.referName]"
+          />
+          <dr-file-preview
+            v-else-if="column.inputType === 'Upload'"
+            v-model="scope.row[column.key]"
+          ></dr-file-preview>
+          <span v-else>{{ scope.row[column.key] }}</span>
         </template>
       </el-table-column>
     </el-table>

+ 134 - 36
src/views/purchase/apply/see/index.vue

@@ -1,49 +1,59 @@
 <script>
-import { TableColumns } from "../column";
-import { initDicts, initParams } from "@/utils/init";
-import { ITEM } from "@/api/business/purchase/apply";
+import Column from "../add/column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useMethods from "../hooks/use-methods";
 
 export default {
-  name: "SeeDialog",
-  dicts: initDicts(TableColumns),
+  name: "SeeDrawer",
+  dicts: useDicts(Column),
   data() {
     return {
-      size: "mini",
-      visible: false,
-      loading: false,
-      columns: TableColumns,
-      params: initParams(TableColumns),
+      column: 3,
+      title: "明 细",
+      ...useData(Column),
     };
   },
-  computed: {},
+  computed: {
+    hasPowerEdit: function () {
+      return this.$parent.$parent.hasPowerEdit;
+    },
+    hasPowerSubmit: function () {
+      return this.$parent.$parent.hasPowerSubmit;
+    },
+  },
   watch: {},
   methods: {
     //
-    open(prop) {
-      this.visible = true;
-      this.fetchItem(prop);
+    async open(prop) {
+      const { open, fetchItem } = useMethods();
+      await open({ _this: this });
+      await fetchItem({ _this: this, prop });
     },
     //
-    hide() {
-      this.visible = false;
-      this.params = initParams(Columns);
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
     //
-    async fetchItem(prop) {
-      try {
-        this.loading = true;
-        const { code,data } = await ITEM(prop);
-        if (code === 200) {
-          this.params = data;
-          
-        } else {
-          this.$notify.warning({ title: msg });
-        }
-      } catch (err) {
-        //
-      } finally {
-        this.loading = false;
-      }
+    async useCopy(prop) {
+      const { useCopy } = this.$parent.$parent;
+      await this.hide();
+      await useCopy(prop);
+    },
+    //
+    async useEdit(prop) {
+      const { useEdit } = this.$parent.$parent;
+      await useEdit(prop);
+    },
+    //
+    async useSubmit(prop) {
+      const { useSubmit } = this.$parent.$parent;
+      await useSubmit(prop).then(() => {
+        const { id } = this.params;
+        const { fetchItem } = useMethods();
+        fetchItem({ _this: this, prop: id });
+      });
     },
   },
   created() {},
@@ -52,11 +62,67 @@ export default {
 };
 </script>
 <template>
-  <el-dialog :visible.sync="visible" title="明细" @close="hide">
-    <el-descriptions :column="2" border>
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="复 制"
+          placement="bottom-end"
+        >
+          <el-button
+            :size="size"
+            circle
+            icon="el-icon-document-copy"
+            @click="useCopy([params])"
+          ></el-button>
+        </el-tooltip>
+        <el-tooltip
+          v-if="!hasPowerEdit([params])"
+          class="item"
+          effect="dark"
+          content="编 辑"
+          placement="bottom-end"
+        >
+          <el-button
+            :size="size"
+            circle
+            icon="el-icon-edit"
+            @click="useEdit([params])"
+          ></el-button>
+        </el-tooltip>
+        <el-tooltip
+          class="item"
+          effect="dark"
+          content="审 核"
+          placement="bottom-end"
+        >
+          <el-button
+            :size="size"
+            circle
+            icon="el-icon-check"
+            @click="useSubmit([params])"
+          ></el-button>
+        </el-tooltip>
+      </span>
+    </template>
+    <el-descriptions :size="size" :column="column" border style="margin: 10px">
       <el-descriptions-item
         v-if="params[column.key]"
-        v-for="(column, index) in columns"
+        v-for="(column, index) in formColumns"
         :key="index"
         :label="column.title"
       >
@@ -66,8 +132,40 @@ export default {
           :value="params[column.key]"
           :options="dict.type[column.referName]"
         />
+        <span v-else-if="column.inputType === 'Upload'">
+          <dr-file-preview v-model="params[column.key]"></dr-file-preview>
+        </span>
         <span v-else>{{ params[column.key] }}</span>
       </el-descriptions-item>
     </el-descriptions>
-  </el-dialog>
+    <el-tabs v-model="tabName" :size="size" style="margin: 10px">
+      <el-tab-pane
+        v-for="(column, index) in tabColumns"
+        :key="index"
+        :name="column.key"
+        :label="column.title"
+        lazy
+      >
+        <el-table :size="size" :data="params[column.key]">
+          <el-table-column
+            v-for="(cColumn, cIndex) in column.tableColumns"
+            :key="cIndex"
+            :prop="cColumn.key"
+            :label="cColumn.title"
+            :width="cColumn.width || 200"
+          >
+            <template slot-scope="scope">
+              <dict-tag
+                v-if="cColumn.inputType === 'Select'"
+                :size="size"
+                :value="scope.row[cColumn.key]"
+                :options="dict.type[cColumn.referName]"
+              />
+              <span v-else>{{ scope.row[cColumn.key] }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-tab-pane>
+    </el-tabs>
+  </el-drawer>
 </template>

+ 33 - 0
src/views/purchase/apply/submit/index.vue

@@ -0,0 +1,33 @@
+<script>
+import useMethods from "../hooks/use-methods";
+
+export default {
+  name: "SubmitDialog",
+  data() {
+    return {};
+  },
+  computed: {},
+  watch: {},
+  methods: {
+    //
+    open(prop) {
+      return this.$confirm("是否提交审核数据项?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info",
+      })
+        .then(async () => {
+          const { submit } = useMethods();
+          await submit({ _this: this, prop });
+        })
+        .catch((err) => {
+          console.error(err);
+        });
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template></template>

+ 6 - 5
src/views/purchase/contract/add/column.js

@@ -1,4 +1,4 @@
-export const Columns = [
+export const FormColumns = [
   {
     key: "puOrgName",
     title: "采购组织",
@@ -98,6 +98,7 @@ export const Columns = [
     title: "合同生效日期",
     inputType: "DatePicker",
     require: true,
+    valueFormat: "yyyy-MM-dd",
   },
   {
     key: "brandGrossRate",
@@ -123,6 +124,7 @@ export const Columns = [
     title: "合同终止日期",
     inputType: "DatePicker",
     require: true,
+    valueFormat: "yyyy-MM-dd",
   },
   {
     key: "invoiceTax",
@@ -147,6 +149,7 @@ export const Columns = [
     title: "合同签订日期",
     inputType: "DatePicker",
     require: true,
+    valueFormat: "yyyy-MM-dd",
   },
   {
     key: "deliveryType",
@@ -297,10 +300,6 @@ export const Columns = [
   { key: "guaranteePeriod", title: "质保期", inputType: "Input" },
 ];
 
-export const SearchColumns = [
-  { key: "contractName", title: "合同名称", search: true, inputType: "Input" },
-];
-
 export const TabColumns = [
   {
     title: "物料基本信息",
@@ -529,3 +528,5 @@ export const TabColumns = [
     ],
   },
 ];
+
+export default { FormColumns, TabColumns };

+ 182 - 237
src/views/purchase/contract/add/index.vue

@@ -1,162 +1,105 @@
 <script>
-import { Columns, TabColumns } from "./column";
-import { REFER } from "@/components/popover-select/api";
-import { ADD, CODE } from "@/api/business/purchase/contract";
-import { initDicts, initRules, initParams } from "@/utils/init";
+import Column from "./column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useTable from "../hooks/use-table";
+import useWatch from "../hooks/use-watch";
+import useMethods from "../hooks/use-methods";
+const { watchContractType } = useWatch();
 
 export default {
-  name: "AddDialog",
-  dicts: Array.from(
-    new Set([
-      ...initDicts(Columns),
-      ...initDicts(
-        TabColumns.map((item) => item.tableColumns)
-          .flat()
-          .filter((item) => item.inputType === "Select")
-      ),
-    ])
-  ),
+  name: "AddDrawer",
+  dicts: useDicts(Column),
   components: {},
   data() {
     return {
-      size: "mini",
-      visible: false,
-      loading: false,
-      columns: Columns,
-      rules: initRules(Columns),
-      params: {
-        ...initParams(Columns),
-        contractItemList: [],
-        contractClauseList: [],
-        contractExpenseList: [],
-        contractAgreementList: [],
-        contractApplyOrgList: [],
-      },
-      tabColumns: TabColumns,
-      tabName: "contractItemList",
+      title: "新 增",
+      ...useData(Column),
     };
   },
   computed: {},
   watch: {
-    "params.contractType": function (newProp) {
-      this.tabColumns = TabColumns.filter((element) =>
-        newProp === "1" ? element.key !== "contractItemList" : element
-      );
-      this.tabName = this.tabColumns[0].key;
-    },
+    "params.contractType": watchContractType(),
   },
   methods: {
     //
-    open() {
+    async fetchRefer(prop, type, source) {
+      const { fetchRefer } = useMethods();
+      await fetchRefer({ _this: this, prop, type, source });
+    },
+    //
+    async open() {
+      const { open, fetchCode } = useMethods();
+      await open({ _this: this });
+      await fetchCode({ _this: this });
       const {
-        deptId: puDept,
-        deptName: puDeptName,
-        name: buyer,
-        nickName: buyerName,
-        orgId: puOrg,
-        orgName: puOrgName,
-      } = this.$store.state.user;
+        user: {
+          deptId: puDept,
+          deptName: puDeptName,
+          name: buyer,
+          nickName: buyerName,
+          orgId: puOrg,
+          orgName: puOrgName,
+        },
+      } = this.$store.state;
       this.params.puOrg = puOrg;
       this.params.puOrgName = puOrgName;
       this.params.buyer = buyer;
       this.params.buyerName = buyerName;
       this.params.puDept = puDept;
       this.params.puDeptName = puDeptName;
-      this.fetchCode();
-      this.visible = true;
     },
     //
-    hide() {
-      this.visible = false;
-      this.params = initParams(this.columns);
-      this.tabName = this.tabColumns[0].key;
-    },
-    //
-    async fetchCode() {
-      try {
-        this.loading = true;
-        const code = await CODE();
-        this.params.code = code;
-      } catch (err) {
-        // catch
-      } finally {
-        // finally
-        this.loading = false;
-      }
-    },
-    //
-    async fetchRefer(prop, type, source) {
-      const { rateCode } = prop;
-      if (type === "MATERIAL_PARAM") {
-        try {
-          this.loading = true;
-          const { code, rows } = await REFER({
-            search: rateCode,
-            type: "TAX_RATE_PARAM",
-          });
-          if (code === 200) {
-            const [{ ntaxrate }] = rows;
-            source.tax = ntaxrate === "0E-8" ? "0.00000000" : ntaxrate;
-          }
-        } catch (err) {
-          // catch
-        } finally {
-          // finally
-          this.loading = false;
-        }
-      }
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
     //
-    rowAdd(prop) {
-      const tab = this.tabColumns.find((element) => element.key === prop);
-      this.params[prop].push(initParams(tab.tableColumns));
+    async useRowAdd(prop) {
+      const { add } = useTable();
+      await add({ _this: this, prop });
     },
     //
-    async rowDelete(prop, { $index }) {
-      this.params[prop].splice($index, 1);
+    async useRowRemove(prop, scope) {
+      const { remove } = useTable();
+      await remove({ _this: this, prop, scope });
     },
     //
-    submit(prop) {
-      this.$refs[prop].validate(async (valid) => {
-        if (valid) {
-          try {
-            const createById = this.params.buyer;
-            const createByName = this.params.buyerName;
-            const updateById = this.$store.state.user.id;
-            const updateByName = this.$store.state.user.name;
-            const { code, msg } = await ADD({
-              createById,
-              createByName,
-              updateById,
-              updateByName,
-              ...this.params,
-            });
-            if (code === 200) {
-              this.hide();
-              this.$emit("success");
-            } else {
-              this.$notify.warning({ title: msg });
-            }
-          } catch (err) {
-            //
-          } finally {
-            //
-          }
-        } else {
-          return false;
-        }
-      });
+    async useSubmit(prop) {
+      const { submit } = useMethods();
+      await submit({ _this: this, prop, type: "ADD" });
     },
   },
-  created() {
-    console.log(this);
-  },
+  created() {},
   mounted() {},
   destroyed() {},
 };
 </script>
 <template>
-  <el-dialog :visible.sync="visible" title="新增" fullscreen @close="hide">
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-check"
+          @click="useSubmit('ruleForm')"
+        >
+        </el-button>
+      </span>
+    </template>
     <el-form
       ref="ruleForm"
       v-loading="loading"
@@ -165,10 +108,11 @@ export default {
       :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="(column, index) in columns"
+          v-for="(column, index) in formColumns"
           :key="index"
           :span="column.span || 6"
         >
@@ -235,6 +179,7 @@ export default {
               :disabled="column.disabled"
               :clearable="column.clearable"
               :placeholder="column.placeholder"
+              :value-format="column.valueFormat"
               :picker-options="column.pickerOptions"
               style="width: 100%"
             >
@@ -246,119 +191,119 @@ export default {
             ></file-upload>
           </el-form-item>
         </el-col>
-      </el-row>
-      <el-form-item label-width="0">
-        <el-tabs v-model="tabName" tab-position="left" style="width: 100%">
-          <el-tab-pane
-            v-for="(column, index) in tabColumns"
-            :key="index"
-            :label="column.title"
-            :name="column.key"
-          >
-            <el-table :data="params[column.key]" style="width: 100%">
-              <el-table-column label="序号">
-                <template slot-scope="scope">
-                  {{ scope.$index + 1 }}
-                </template>
-              </el-table-column>
-              <el-table-column
-                v-for="(cColumn, cIndex) in column.tableColumns"
-                :key="cIndex"
-                :prop="cColumn.key"
-                :label="cColumn.title"
-                :width="cColumn.width"
-                show-overflow-tooltip
+        <el-divider></el-divider>
+        <el-col :span="24">
+          <el-form-item label-width="0">
+            <el-tabs v-model="tabName">
+              <el-tab-pane
+                v-for="(column, index) in tabColumns"
+                :key="index"
+                :label="column.title"
+                :name="column.key"
+                lazy
               >
-                <template slot-scope="scope">
-                  <el-input
-                    v-if="cColumn.inputType === 'Input'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                  ></el-input>
-                  <dr-computed-input
-                    v-else-if="cColumn.inputType === 'ComputedInput'"
-                    v-model="scope.row[cColumn.key]"
-                    :source="scope.row"
-                    :computed="cColumn.computed"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                  ></dr-computed-input>
-                  <dr-popover-select
-                    v-else-if="cColumn.inputType === 'PopoverSelect'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :title="cColumn.title"
-                    :source.sync="scope.row"
-                    :type="cColumn.referName"
-                    :disabled="cColumn.disabled"
-                    :readonly="cColumn.readonly"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    :data-mapping="cColumn.dataMapping"
-                    @change="fetchRefer"
-                  >
-                  </dr-popover-select>
-                  <el-input-number
-                    v-else-if="cColumn.inputType === 'InputNumber'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    :controls-position="cColumn.controlsPosition"
-                    style="width: 100%"
-                  ></el-input-number>
-                  <el-select
-                    v-else-if="cColumn.inputType === 'Select'"
-                    v-model="scope.row[cColumn.key]"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                  >
-                    <el-option
-                      v-for="item in dict.type[cColumn.referName]"
-                      :key="item.value"
-                      :label="item.label"
-                      :value="item.value"
-                    >
-                    </el-option>
-                  </el-select>
-                  <span v-else> {{ scope.row[cColumn.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="rowAdd(tabName)"
+                <el-table :size="size" :data="params[column.key]">
+                  <el-table-column label="序号">
+                    <template slot-scope="scope">
+                      {{ scope.$index + 1 }}
+                    </template>
+                  </el-table-column>
+                  <el-table-column
+                    v-for="(cColumn, cIndex) in column.tableColumns"
+                    :key="cIndex"
+                    :prop="cColumn.key"
+                    :label="cColumn.title"
+                    :width="cColumn.width"
+                    show-overflow-tooltip
                   >
-                  </el-button>
-                </template>
-                <template slot-scope="scope">
-                  <el-button
-                    circle
-                    icon="el-icon-minus"
-                    :size="size"
-                    @click.native.prevent="rowDelete(tabName, scope)"
-                  >
-                  </el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-tab-pane>
-        </el-tabs>
-      </el-form-item>
-      <el-form-item label-width="0" style="text-align: right">
-        <el-button :size="size" @click="hide">取 消</el-button>
-        <el-button :size="size" @click="submit('ruleForm')"> 新 增 </el-button>
-      </el-form-item>
+                    <template slot-scope="scope">
+                      <el-input
+                        v-if="cColumn.inputType === 'Input'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></el-input>
+                      <dr-computed-input
+                        v-else-if="cColumn.inputType === 'ComputedInput'"
+                        v-model="scope.row[cColumn.key]"
+                        :source="scope.row"
+                        :computed="cColumn.computed"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></dr-computed-input>
+                      <dr-popover-select
+                        v-else-if="cColumn.inputType === 'PopoverSelect'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :title="cColumn.title"
+                        :source.sync="scope.row"
+                        :type="cColumn.referName"
+                        :disabled="cColumn.disabled"
+                        :readonly="cColumn.readonly"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :data-mapping="cColumn.dataMapping"
+                        @change="fetchRefer"
+                      >
+                      </dr-popover-select>
+                      <el-input-number
+                        v-else-if="cColumn.inputType === 'InputNumber'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :controls-position="cColumn.controlsPosition"
+                        style="width: 100%"
+                      ></el-input-number>
+                      <el-select
+                        v-else-if="cColumn.inputType === 'Select'"
+                        v-model="scope.row[cColumn.key]"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      >
+                        <el-option
+                          v-for="item in dict.type[cColumn.referName]"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                      <span v-else> {{ scope.row[cColumn.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-dialog>
+  </el-drawer>
 </template>

+ 14 - 352
src/views/purchase/contract/column.js

@@ -1,152 +1,94 @@
-export const Columns = [
+export const FormColumns = [
   {
     key: "puOrgName",
     title: "采购组织",
-    inputType: "PopoverSelect",
-    referName: "ORG_PARAM",
-    dataMapping: {
-      puOrg: "code",
-      puOrgName: "name",
-    },
-    require: true,
   },
-  { key: "code", title: "合同编码", inputType: "Input" },
+  { key: "code", title: "合同编码" },
   {
     key: "lastPuMoney",
     title: "上年度采购额",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "buyerName",
     title: "采购员",
-    inputType: "PopoverSelect",
-    referName: "CONTACTS_PARAM",
-    dataMapping: {
-      buyer: "code",
-      buyerName: "name",
-      puDept: "deptId",
-      puDeptName: "deptName",
-    },
-    require: true,
   },
   {
     key: "supplierName",
     title: "供应商",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    dataMapping: {
-      supplier: "code",
-      supplierName: "name",
-    },
-    require: true,
   },
   {
     key: "contractType",
     title: "合同类型",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_contract_type",
   },
   {
     key: "puMoneyYear",
     title: "本年度采购额",
-    inputType: "InputNumber",
-    require: true,
   },
   {
     key: "puDeptName",
     title: "采购部门",
-    inputType: "PopoverSelect",
-    referName: "DEPT_PARAM",
-    dataMapping: {
-      puDept: "code",
-      puDeptName: "name",
-    },
-    require: true,
   },
   {
     key: "supplierTier",
     title: "供应商层级",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_supplier_tier",
   },
-  { key: "contractName", title: "合同名称", inputType: "Input", require: true },
+  { key: "contractName", title: "合同名称" },
   {
     key: "grossRateAverage",
     title: "平均毛利率",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "approveFlow",
     title: "审批流程",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_approve_flow",
   },
   {
     key: "consumableClass",
     title: "耗材类别",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_consumable_class",
   },
   {
     key: "effectiveDate",
     title: "合同生效日期",
-    inputType: "DatePicker",
-    require: true,
   },
   {
     key: "brandGrossRate",
     title: "同类品牌及毛利率",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "contractFormat",
     title: "合同格式",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_contract_format",
   },
   {
     key: "productName",
     title: "产品类别&名称",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "endDate",
     title: "合同终止日期",
-    inputType: "DatePicker",
-    require: true,
   },
   {
     key: "invoiceTax",
     title: "发票税率",
-    inputType: "PopoverSelect",
-    referName: "TAX_RATE_PARAM",
-    dataMapping: {
-      invoiceTax: "ntaxrate",
-    },
-    require: true,
   },
   {
     key: "emergencyDegree",
     title: "紧急程度",
     inputType: "Select",
-    require: true,
     referName: "puarchase_contract_emergency_degree",
   },
-  { key: "project", title: "项目医院", inputType: "Input", require: true },
+  { key: "project", title: "项目医院" },
   {
     key: "signDate",
     title: "合同签订日期",
-    inputType: "DatePicker",
-    require: true,
   },
   {
     key: "deliveryType",
@@ -157,25 +99,14 @@ export const Columns = [
   {
     key: "source",
     title: "合同来源",
-    inputType: "Input",
-    value: "自制",
-    disabled: true,
   },
   {
     key: "contractPartycName",
     title: "合同丙方",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    dataMapping: {
-      contractPartyc: "code",
-      contractPartycName: "name",
-    },
   },
   {
     key: "guaranteePeriodEnd",
     title: "质保期限",
-    inputType: "Input",
-    require: true,
   },
   {
     key: "freightMethods",
@@ -186,346 +117,77 @@ export const Columns = [
   {
     key: "signDate",
     title: "合同创建时间",
-    inputType: "DatePicker",
-    disabled: true,
   },
   {
     key: "isTarget",
     title: "是否有指标",
     inputType: "Select",
-    require: true,
     referName: "sys_yes_no",
   },
   {
     key: "contractTarget",
     title: "合同指标",
-    inputType: "Input",
-    require: true,
-    placeholder: '当【是否有指标】="有"时,必填',
   },
   {
     key: "exemptionPostageCondtion",
     title: "包邮条件",
-    inputType: "Input",
-    placeholder:
-      "当运费承担方式为供应商有条件承担时,该字段必填,填写要求,写明什么条件下供应商承担全部,什么条件下我方承担,什么条件下分别承担",
-    span: 12,
   },
   {
     key: "isRebate",
     title: "是否有返利",
     inputType: "Select",
-    require: true,
     referName: "sys_yes_no",
   },
   {
     key: "rebatePolicy",
     title: "返利政策",
-    inputType: "Input",
-    placeholder: '当【是否有返利】="有"时,必填',
-    span: 18,
   },
-  { key: "externalContract", title: "外部合同号", inputType: "Input" },
+  { key: "externalContract", title: "外部合同号" },
   {
     key: "rollbackPolicy",
     title: "退换货政策",
-    inputType: "Input",
-    require: true,
   },
-  { key: "enquiryCode", title: "询价单号", inputType: "Input" },
+  { key: "enquiryCode", title: "询价单号" },
   {
     key: "contractContent",
     title: "合同主要内容",
-    inputType: "Textarea",
-    require: true,
-    span: 24,
   },
-  { key: "refusalReasons", title: "拒绝理由", inputType: "Input", span: 24 },
+  { key: "refusalReasons", title: "拒绝理由" },
 
   {
     key: "externalFile",
     title: "对外附件",
     inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
   },
   {
     key: "puFile",
     title: "采购商盖章合同附件",
     inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
   },
   {
     key: "supplierFile",
     title: "供应商盖章合同附件",
     inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
   },
-  { key: "projectCode", title: "项目编号", inputType: "Input" },
-  { key: "projectName", title: "项目名称", inputType: "Input" },
-  { key: "area", title: "区域", inputType: "Input" },
-  { key: "consigneePhone", title: "收货人联系方式", inputType: "Input" },
+  { key: "projectCode", title: "项目编号" },
+  { key: "projectName", title: "项目名称" },
+  { key: "area", title: "区域" },
+  { key: "consigneePhone", title: "收货人联系方式" },
   {
     key: "paymentAgreement",
     title: "付款协议",
-    inputType: "PopoverSelect",
-    referName: "PAYAGREEMENT_PARAM",
-    dataMapping: {
-      paymentAgreement: "code",
-      paymentAgreementName: "name",
-    },
-    require: true,
   },
   {
     key: "taxPrice",
     title: "价税合计",
-    inputType: "InputNumber",
   },
   {
     key: "currencyName",
     title: "币种",
-    inputType: "PopoverSelect",
-    referName: "CURRENCY_PARAM",
-    dataMapping: {
-      currency: "code",
-      currencyName: "name",
-    },
-    require: true,
-  },
-  { key: "guaranteePeriod", title: "质保期", inputType: "Input" },
+  },
+  { key: "guaranteePeriod", title: "质保期" },
 ];
 
 export const SearchColumns = [
-  { key: "contractName", title: "合同名称", search: true, inputType: "Input" },
-];
-
-export const TabColumns = [
-  {
-    title: "物料基本信息",
-    key: "contractItemList",
-    tableColumns: [
-      {
-        title: "物料名称",
-        key: "materialName",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "MATERIAL_PARAM",
-        dataMapping: {
-          material: "code",
-          materialName: "name",
-          puUnit: "unitIdName",
-          registration: "registrationNo",
-          specification: "specification",
-          manufacturer: "manufacturerIdName",
-        },
-      },
-      { title: "物料编码", key: "material", width: 200 },
-      {
-        title: "规格",
-        key: "specification",
-        width: 200,
-      },
-      // {
-      //   title: "品牌",
-      //   key: "brand",
-      //   inputType: "PopoverSelect",
-      //   width: 200,
-      //   referName: "MATERIAL_PARAM",
-      //   dataMapping: {
-      //     material: "code",
-      //     materialName: "name",
-      //   },
-      // },
-      {
-        title: "生产厂家",
-        key: "manufacturer",
-        inputType: "Input",
-        width: 200,
-      },
-      {
-        title: "采购单位",
-        key: "puUnit",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "UNIT_PARAM",
-        dataMapping: {
-          puUnit: "name",
-        },
-      },
-      {
-        title: "税率%",
-        key: "tax",
-        inputType: "PopoverSelect",
-        referName: "TAX_RATE_PARAM",
-        dataMapping: {
-          tax: "ntaxrate",
-        },
-        width: 200,
-      },
-      {
-        title: "采购数量",
-        key: "qty",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "含税单价",
-        key: "taxPrice",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "含税金额合计",
-        key: "taxMoney",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { qty, taxPrice } = prop;
-          const taxMoney = (qty * taxPrice).toFixed(8);
-          return taxMoney === "NaN" ? null : taxMoney;
-        },
-      },
-      {
-        title: "无税单价",
-        key: "taxFreePrice",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { tax, taxPrice } = prop;
-          const newTax = Number(tax) / 100;
-          const taxFreePrice = (taxPrice / (1 + newTax)).toFixed(8);
-          return taxFreePrice === "NaN" ? null : taxFreePrice;
-        },
-      },
-      {
-        title: "无税金额合计",
-        key: "taxFreeMoney",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { qty, taxFreePrice } = prop;
-          const taxFreeMoney = (qty * taxFreePrice).toFixed(8);
-          return taxFreeMoney === "NaN" ? null : taxFreeMoney;
-        },
-      },
-      {
-        title: "注册证号及备案凭证号",
-        key: "registration",
-        inputType: "Input",
-        width: 200,
-      },
-      {
-        title: "收货客户",
-        key: "customerName",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "CUSTOMER_PARAM",
-        dataMapping: {
-          customer: "code",
-          customerName: "name",
-        },
-      },
-      { title: "备注", key: "remark", inputType: "Input", width: 200 },
-    ],
-  },
-  {
-    title: "合同条款",
-    key: "contractClauseList",
-    tableColumns: [
-      { title: "条款编码", key: "code", inputType: "Input" },
-      { title: "条款名称", key: "name", inputType: "Input" },
-      { title: "条款内容", key: "content", inputType: "Input" },
-      { title: "变量序号", key: "variableRowno" },
-      { title: "变量内容", key: "variableContent", inputType: "Input" },
-      { title: "备注", key: "remark", inputType: "Input" },
-    ],
-  },
-  {
-    title: "合同费用",
-    key: "contractExpenseList",
-    tableColumns: [
-      { title: "费用编码", key: "code", inputType: "Input" },
-      { title: "费用名称", key: "name", inputType: "Input" },
-      {
-        title: "费用金额",
-        key: "money",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      { title: "备注", key: "remark", inputType: "Input" },
-    ],
-  },
-  {
-    title: "付款协议信息",
-    key: "contractAgreementList",
-    tableColumns: [
-      {
-        title: "付款阶段",
-        key: "satge",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "付款起点",
-        key: "origin",
-        width: 200,
-        inputType: "Select",
-        referName: "puarchase_contract_origin",
-      },
-      { title: "账期天数", key: "paymetDays", inputType: "Input", width: 200 },
-      { title: "付款比例%", key: "ratio", inputType: "Input", width: 200 },
-      { title: "付款金额", key: "money", inputType: "Input", width: 200 },
-      {
-        title: "是否预付款",
-        key: "isAdvance",
-        width: 200,
-        inputType: "Select",
-        referName: "sys_yes_no",
-      },
-      {
-        title: "是否质保金",
-        key: "isQuality",
-        width: 200,
-        inputType: "Select",
-        referName: "sys_yes_no",
-      },
-      {
-        title: "结算方式",
-        key: "paymentMeans",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "BALATYPE_PARAM",
-        dataMapping: {
-          paymentMeans: "name",
-        },
-      },
-      { title: "备注", key: "remark", inputType: "Input", width: 200 },
-      {
-        title: "需进度确认",
-        key: "schedule",
-        inputType: "Select",
-        referName: "sys_yes_no",
-        width: 200,
-      },
-    ],
-  },
-  {
-    title: "合同执行组织范围",
-    key: "contractApplyOrgList",
-    tableColumns: [
-      {
-        title: "组织名称",
-        key: "orgName",
-        inputType: "PopoverSelect",
-        referName: "ORG_PARAM",
-        dataMapping: {
-          org: "code",
-          orgName: "name",
-        },
-      },
-      { title: "组织编码", key: "org" },
-    ],
-  },
+  { key: "contractName", title: "合同名称", inputType: "Input" },
 ];

+ 4 - 11
src/views/purchase/contract/delete/index.vue

@@ -1,5 +1,6 @@
 <script>
-import { REMOVE } from "@/api/business/purchase/contract";
+import useMethods from "../hooks/use-methods";
+
 export default {
   name: "DeleteDialog",
   data() {
@@ -16,16 +17,8 @@ export default {
         type: "info",
       })
         .then(async () => {
-          try {
-            const { code } = await REMOVE(prop);
-            if (code === 200) {
-              this.$emit("success");
-            }
-          } catch (err) {
-            // catch
-          } finally {
-            // finally
-          }
+          const { remove } = useMethods();
+          await remove({ _this: this, prop });
         })
         .catch((err) => {
           console.error(err);

+ 181 - 280
src/views/purchase/contract/edit/index.vue

@@ -1,184 +1,62 @@
 <script>
-import { Columns, TabColumns } from "../column";
-import {
-  EDIT,
-  ITEM,
-  TABLELIST,
-  TABLEADD,
-  TABLEEDIT,
-  TABLEROMOVE,
-} from "@/api/business/purchase/contract";
-import { REFER } from "@/components/popover-select/api";
-import { initDicts, initRules, initParams } from "@/utils/init";
+import Column from "../add/column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useTable from "../hooks/use-table";
+import useWatch from "../hooks/use-watch";
+import useMethods from "../hooks/use-methods";
+const { watchContractType } = useWatch();
 
 export default {
-  name: "EditDialog",
-  dicts: Array.from(
-    new Set([
-      ...initDicts(Columns),
-      ...initDicts(TabColumns.map((item) => item.tableColumns))
-        .flat()
-        .filter((cItem) => cItem.inputType === "Select"),
-    ])
-  ),
+  name: "EditDrawer",
+  dicts: useDicts(Column),
   data() {
     return {
-      size: "mini",
-      visible: false,
-      loading: false,
-      columns: Columns,
-      rules: initRules(Columns),
-      params: {
-        ...initParams(Columns),
-        contractItemList: [],
-        contractClauseList: [],
-        contractExpenseList: [],
-        contractApplyOrgList: [],
-        contractAgreementList: [],
-      },
-      tabColumns: TabColumns,
-      tabName: "contractItemList",
+      title: "更 新",
+      ...useData(Column),
     };
   },
   computed: {},
   watch: {
-    "params.contractType": {
-      handler: function (newProp) {
-        if (newProp === "1") {
-          this.params.contractItemList = [];
-          this.tabColumns = TabColumns.filter(
-            (element) => element.key !== "contractItemList"
-          );
-        } else {
-          this.tabColumns = TabColumns;
-        }
-        this.tabName = this.tabColumns[0].key;
-      },
-      immediate: true,
-    },
+    "params.contractType": watchContractType(),
   },
   methods: {
     //
-    open(prop) {
-      this.visible = true;
-      this.fetchItem(prop);
-    },
-    //
-    hide() {
-      this.visible = false;
-      this.params = initParams(Columns);
-      this.tabName = this.tabColumns[0].key;
+    async fetchRefer(prop, type, source) {
+      const { fetchRefer } = useMethods();
+      await fetchRefer({ _this: this, prop, type, source });
     },
     //
-    async fetchItem(prop) {
-      try {
-        this.loading = true;
-        const { code, data } = await ITEM(prop);
-        if (code === 200) {
-          this.params = data;
-        }
-      } catch (err) {
-        // catch
-      } finally {
-        // finally
-        this.loading = false;
-      }
+    async open(prop) {
+      const { open, fetchItem } = useMethods();
+      await open({ _this: this });
+      await fetchItem({ _this: this, prop });
     },
     //
-    async fetchRefer(prop, type, source) {
-      console.log("prop", prop);
-      const { rateCode } = prop;
-      if (type === "MATERIAL_PARAM") {
-        try {
-          this.loading = true;
-          const { code, rows } = await REFER({
-            search: rateCode,
-            type: "TAX_RATE_PARAM",
-          });
-          if (code === 200) {
-            const [{ ntaxrate }] = rows;
-            source.tax = ntaxrate === "0E-8" ? "0.00000000" : ntaxrate;
-          }
-        } catch (err) {
-          // catch
-        } finally {
-          // finally
-          this.loading = false;
-        }
-      }
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
     //
-    rowAdd(prop) {
-      const tab = this.tabColumns.find((element) => element.key === prop);
-      this.params[prop].push(initParams(tab.tableColumns));
+    async useRowAdd(prop) {
+      const { add } = useTable();
+
+      await add({ _this: this, prop });
     },
     //
-    async rowDelete(prop, { row: { id }, $index }) {
-      if (id) {
-        try {
-          this.loading = true;
-          const { code } = await TABLEROMOVE(id, prop);
-          if (code === 200) {
-            this.fetchItem(this.params.id);
-          }
-        } catch (err) {
-          // catch
-        } finally {
-          // finally
-          this.loading = false;
-        }
-      } else {
-        this.params[prop].splice($index, 1);
-      }
+    async useRowRemove(prop, scope) {
+      const { remove } = useTable();
+      await remove({ _this: this, prop, scope });
     },
     //
-    async rowSubmit(prop, { row }) {
-      try {
-        this.loading = true;
-        const { id } = this.params;
-        const { contractId } = row;
-        if (contractId) {
-          await TABLEEDIT(row, prop);
-        } else {
-          await TABLEADD({ ...row, contractId: id }, prop);
-        }
-        await this.fetchItem(id);
-      } catch (err) {
-        // catch
-      } finally {
-        // finally
-        this.loading = false;
-      }
+    async useRowSubmit(prop, scope) {
+      const { submit } = useTable();
+      await submit({ _this: this, prop, scope });
     },
     //
-    submit(prop) {
-      this.$refs[prop].validate(async (valid) => {
-        if (valid) {
-          try {
-            const createById = this.params.buyer;
-            const createByName = this.params.buyerName;
-            const updateById = this.$store.state.user.id;
-            const updateByName = this.$store.state.user.name;
-            const { code } = await EDIT({
-              createById,
-              createByName,
-              updateById,
-              updateByName,
-              ...this.params,
-            });
-            if (code === 200) {
-              this.hide();
-              this.$emit("success");
-            }
-          } catch (err) {
-            // catch
-          } finally {
-            // finally
-          }
-        } else {
-          return false;
-        }
-      });
+    async useSubmit(prop) {
+      const { submit } = useMethods();
+      await submit({ _this: this, prop, type: "EDIT" });
     },
   },
   created() {},
@@ -187,7 +65,30 @@ export default {
 };
 </script>
 <template>
-  <el-dialog :visible.sync="visible" title="编辑" fullscreen @close="hide">
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-check"
+          @click="useSubmit('ruleForm')"
+        >
+        </el-button>
+      </span>
+    </template>
     <el-form
       ref="ruleForm"
       v-loading="loading"
@@ -196,10 +97,11 @@ export default {
       :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="(column, index) in columns"
+          v-for="(column, index) in formColumns"
           :key="index"
           :span="column.span || 6"
         >
@@ -266,6 +168,7 @@ export default {
               :disabled="column.disabled"
               :clearable="column.clearable"
               :placeholder="column.placeholder"
+              :value-format="column.valueFormat"
               :picker-options="column.pickerOptions"
               style="width: 100%"
             >
@@ -277,128 +180,126 @@ export default {
             ></file-upload>
           </el-form-item>
         </el-col>
-      </el-row>
-      <el-form-item label-width="0">
-        <el-tabs v-model="tabName" tab-position="left" style="width: 100%">
-          <el-tab-pane
-            v-for="(column, index) in tabColumns"
-            :key="index"
-            :label="column.title"
-            :name="column.key"
-          >
-            <el-table :data="params[column.key]" style="width: 100%">
-              <el-table-column label="序号">
-                <template slot-scope="scope">
-                  {{ scope.$index + 1 }}
-                </template>
-              </el-table-column>
-              <el-table-column
-                v-for="(cColumn, cIndex) in column.tableColumns"
-                show-overflow-tooltip
-                :key="cIndex"
-                :prop="cColumn.key"
-                :label="cColumn.title"
-                :width="cColumn.width"
+        <el-col :span="24">
+          <el-form-item label-width="0">
+            <el-tabs v-model="tabName">
+              <el-tab-pane
+                v-for="(column, index) in tabColumns"
+                :key="index"
+                :label="column.title"
+                :name="column.key"
+                lazy
               >
-                <template slot-scope="scope">
-                  <el-input
-                    v-if="cColumn.inputType === 'Input'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                    @change="fetchRefer"
-                  ></el-input>
-                  <dr-computed-input
-                    v-else-if="cColumn.inputType === 'ComputedInput'"
-                    v-model="scope.row[cColumn.key]"
-                    :source="scope.row"
-                    :computed="cColumn.computed"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                  ></dr-computed-input>
-                  <dr-popover-select
-                    v-else-if="cColumn.inputType === 'PopoverSelect'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :title="cColumn.title"
-                    :source.sync="scope.row"
-                    :type="cColumn.referName"
-                    :disabled="cColumn.disabled"
-                    :readonly="cColumn.readonly"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    :data-mapping="cColumn.dataMapping"
-                    @change="fetchRefer"
+                <el-divider></el-divider>
+                <el-table :size="size" :data="params[column.key]">
+                  <el-table-column label="序号">
+                    <template slot-scope="scope">
+                      {{ scope.$index + 1 }}
+                    </template>
+                  </el-table-column>
+                  <el-table-column
+                    v-for="(cColumn, cIndex) in column.tableColumns"
+                    :key="cIndex"
+                    :prop="cColumn.key"
+                    :label="cColumn.title"
+                    :width="cColumn.width"
+                    show-overflow-tooltip
                   >
-                  </dr-popover-select>
-                  <el-input-number
-                    v-else-if="cColumn.inputType === 'InputNumber'"
-                    v-model="scope.row[cColumn.key]"
-                    :size="size"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    :controls-position="cColumn.controlsPosition"
-                    style="width: 100%"
-                  ></el-input-number>
-                  <el-select
-                    v-else-if="cColumn.inputType === 'Select'"
-                    v-model="scope.row[cColumn.key]"
-                    :disabled="cColumn.disabled"
-                    :clearable="cColumn.clearable"
-                    :placeholder="cColumn.placeholder"
-                    style="width: 100%"
-                  >
-                    <el-option
-                      v-for="item in dict.type[cColumn.referName]"
-                      :key="item.value"
-                      :label="item.label"
-                      :value="item.value"
-                    >
-                    </el-option>
-                  </el-select>
-                  <span v-else> {{ scope.row[cColumn.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="rowAdd(tabName)"
-                  >
-                  </el-button>
-                </template>
-                <template slot-scope="scope">
-                  <!-- v-if="scope.row.status !== 'success'" -->
-                  <el-button
-                    circle
-                    icon="el-icon-check"
-                    :size="size"
-                    @click.native.prevent="rowSubmit(tabName, scope)"
-                  >
-                  </el-button>
-                  <el-button
-                    circle
-                    icon="el-icon-minus"
-                    :size="size"
-                    @click.native.prevent="rowDelete(tabName, scope)"
-                  >
-                  </el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-tab-pane>
-        </el-tabs>
-      </el-form-item>
-      <el-form-item label-width="0" style="text-align: right">
-        <el-button :size="size" @click="hide">取 消</el-button>
-        <el-button :size="size" @click="submit('ruleForm')"> 更 新 </el-button>
-      </el-form-item>
+                    <template slot-scope="scope">
+                      <el-input
+                        v-if="cColumn.inputType === 'Input'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></el-input>
+                      <dr-computed-input
+                        v-else-if="cColumn.inputType === 'ComputedInput'"
+                        v-model="scope.row[cColumn.key]"
+                        :source="scope.row"
+                        :computed="cColumn.computed"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      ></dr-computed-input>
+                      <dr-popover-select
+                        v-else-if="cColumn.inputType === 'PopoverSelect'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :title="cColumn.title"
+                        :source.sync="scope.row"
+                        :type="cColumn.referName"
+                        :disabled="cColumn.disabled"
+                        :readonly="cColumn.readonly"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :data-mapping="cColumn.dataMapping"
+                        @change="fetchRefer"
+                      >
+                      </dr-popover-select>
+                      <el-input-number
+                        v-else-if="cColumn.inputType === 'InputNumber'"
+                        v-model="scope.row[cColumn.key]"
+                        :size="size"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        :controls-position="cColumn.controlsPosition"
+                        style="width: 100%"
+                      ></el-input-number>
+                      <el-select
+                        v-else-if="cColumn.inputType === 'Select'"
+                        v-model="scope.row[cColumn.key]"
+                        :disabled="cColumn.disabled"
+                        :clearable="cColumn.clearable"
+                        :placeholder="cColumn.placeholder"
+                        style="width: 100%"
+                      >
+                        <el-option
+                          v-for="item in dict.type[cColumn.referName]"
+                          :key="item.value"
+                          :label="item.label"
+                          :value="item.value"
+                        >
+                        </el-option>
+                      </el-select>
+                      <span v-else> {{ scope.row[cColumn.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-check"
+                        :size="size"
+                        @click.native.prevent="useRowSubmit(tabName, scope)"
+                      >
+                      </el-button>
+                      <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-dialog>
+  </el-drawer>
 </template>

+ 32 - 0
src/views/purchase/contract/hooks/use-data.js

@@ -0,0 +1,32 @@
+import { initRules, initParams } from "@/utils/init";
+
+export default function useData(prop) {
+  const { FormColumns, TabColumns } = prop;
+  const size = "mini";
+  const width = "100%";
+  const visible = false;
+  const loading = false;
+  const formColumns = FormColumns;
+  const rules = initRules(FormColumns);
+  const params = {
+    ...initParams(FormColumns),
+    contractItemList: [],
+    contractClauseList: [],
+    contractExpenseList: [],
+    contractAgreementList: [],
+    contractApplyOrgList: [],
+  };
+  const tabColumns = TabColumns;
+  const tabName = "contractItemList";
+  return {
+    size,
+    width,
+    visible,
+    loading,
+    formColumns,
+    rules,
+    params,
+    tabColumns,
+    tabName,
+  };
+}

+ 16 - 0
src/views/purchase/contract/hooks/use-dicts.js

@@ -0,0 +1,16 @@
+import { initDicts } from "@/utils/init";
+
+export default function useDicts(prop) {
+  const { FormColumns = [], TabColumns = [] } = prop;
+  const dicts = Array.from(
+    new Set([
+      ...initDicts(FormColumns),
+      ...initDicts(
+        TabColumns.map((item) => item.tableColumns)
+          .flat()
+          .filter((item) => item.inputType === "Select")
+      ),
+    ])
+  );
+  return dicts;
+}

+ 148 - 0
src/views/purchase/contract/hooks/use-methods.js

@@ -0,0 +1,148 @@
+import { REFER } from "@/components/popover-select/api";
+import {
+  ADD,
+  EDIT,
+  ITEM,
+  CODE,
+  REMOVE,
+  TERMINATION,
+} from "@/api/business/purchase/contract";
+
+export default function useMethods() {
+  const fetchCode = async ({ _this }) => {
+    try {
+      // try
+      _this.loading = true;
+      const code = await CODE();
+      _this.params.code = code;
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+      _this.loading = false;
+    }
+  };
+  const fetchItem = async ({ _this, prop }) => {
+    try {
+      // try
+      _this.loading = true;
+      const { code, data } = await ITEM(prop);
+      if (code === 200) {
+        _this.params = data;
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+      _this.loading = false;
+    }
+  };
+  const fetchRefer = async ({ _this, prop, type, source }) => {
+    const { rateCode } = prop;
+    if (type === "MATERIAL_PARAM") {
+      try {
+        // try
+        _this.loading = true;
+        const { code, rows } = await REFER({
+          search: rateCode,
+          type: "TAX_RATE_PARAM",
+        });
+        if (code === 200) {
+          const [{ ntaxrate }] = rows;
+          source.tax = ntaxrate === "0E-8" ? "0.00000000" : ntaxrate;
+        }
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        _this.loading = false;
+      }
+    }
+  };
+  const open = ({ _this }) => {
+    _this.visible = true;
+    _this.tabName = _this.tabColumns[0].key;
+  };
+  const hide = ({ _this }) => {
+    _this.visible = false;
+  };
+  const submit = ({ _this, prop, type }) => {
+    _this.$refs[prop].validate(async (valid) => {
+      if (valid) {
+        try {
+          // try
+          _this.loading = true;
+          const { buyer: createById, buyerName: createByName } = _this.params;
+          const {
+            user: { id: updateById, name: updateByName },
+          } = _this.$store.state;
+          const params = {
+            createById,
+            createByName,
+            updateById,
+            updateByName,
+            ..._this.params,
+          };
+          const { msg, code } =
+            type === "ADD" ? await ADD(params) : await EDIT(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;
+      }
+    });
+  };
+  const remove = async ({ _this, prop }) => {
+    try {
+      // try
+      const { msg, code } = await REMOVE(prop);
+      if (code === 200) {
+        _this.$emit("success");
+        _this.$notify.success(msg);
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+    }
+  };
+  const termination = async ({ _this, prop }) => {
+    try {
+      // try
+      const { code } = await TERMINATION({ id: prop });
+      if (code === 200) {
+        _this.$emit("success");
+        _this.$notify.success(msg);
+      }
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+    }
+  };
+  return {
+    open,
+    hide,
+    submit,
+    remove,
+    termination,
+    fetchRefer,
+    fetchCode,
+    fetchItem,
+  };
+}

+ 61 - 0
src/views/purchase/contract/hooks/use-table.js

@@ -0,0 +1,61 @@
+import { initParams } from "@/utils/init";
+import { TABLE } from "@/api/business/purchase/contract";
+
+export default function useTable() {
+  // 新 增
+  const add = ({ _this, prop }) => {
+    const { tableColumns } = _this.tabColumns.find(
+      (element) => element.key === prop
+    );
+    _this.params[prop].push(initParams(tableColumns));
+  };
+  // 提 交
+  const submit = async ({ _this, prop, scope }, done = () => {}) => {
+    const { row } = scope;
+    const { ADD, EDIT } = TABLE;
+    try {
+      // try
+      _this.loading = true;
+      const { contractId } = row;
+      const { id } = _this.params;
+      if (contractId) {
+        await EDIT(row, prop);
+      } else {
+        await ADD({ ...row, contractId: id }, prop);
+      }
+      await done();
+    } catch (err) {
+      // catch
+      console.error(err);
+    } finally {
+      // finally
+      _this.loading = false;
+    }
+  };
+  // 删 除
+  const remove = ({ _this, prop, scope }, done = () => {}) => {
+    const {
+      row: { id },
+      $index,
+    } = scope;
+    const { ROMVE } = TABLE;
+    if (id) {
+      try {
+        // try
+        _this.loading = true;
+        const { code } = ROMVE(id, prop);
+        if (code === 200) done();
+      } catch (err) {
+        // catch
+        console.error(err);
+      } finally {
+        // finally
+        _this.loading = false;
+      }
+    } else {
+      _this.params[prop].splice($index, 1);
+    }
+  };
+
+  return { add, submit, remove };
+}

+ 20 - 0
src/views/purchase/contract/hooks/use-watch.js

@@ -0,0 +1,20 @@
+import Column from "../add/column";
+
+export default function useWatch() {
+  const { TabColumns } = Column;
+  const watchContractType = () => ({
+    handler: function (newProp) {
+      if (newProp === "1") {
+        this.params.contractItemList = [];
+        this.tabColumns = TabColumns.filter(
+          (element) => element.key !== "contractItemList"
+        );
+      } else {
+        this.tabColumns = TabColumns;
+      }
+      this.tabName = this.tabColumns[0].key;
+    },
+    immediate: true,
+  });
+  return { watchContractType };
+}

+ 1 - 2
src/views/purchase/contract/import/index.vue

@@ -37,11 +37,10 @@ export default {
         const { msg, code } = await IMPORTTEMPLATE();
         if (code === 200) {
           this.download(msg, {});
-        } else {
-          this.$notify.warning({ title: msg });
         }
       } catch (err) {
         // catch
+        console.error(err);
       } finally {
         // finally
       }

+ 86 - 16
src/views/purchase/contract/index.vue

@@ -1,10 +1,10 @@
 <script>
+import { FormColumns, SearchColumns } from "./column";
 import { LIST } from "@/api/business/purchase/contract";
 import { initPage, initDicts, initParams } from "@/utils/init";
-import { Columns as TableColumns, SearchColumns } from "./column";
 export default {
   name: "PuchaseContract",
-  dicts: initDicts(TableColumns),
+  dicts: [...initDicts(SearchColumns), ...initDicts(FormColumns)],
   components: {
     AddModel: () => import("./add/index.vue"),
     SeeModel: () => import("./see/index.vue"),
@@ -13,6 +13,7 @@ export default {
     ImportModel: () => import("./import/index.vue"),
     RecordModel: () => import("./record/index.vue"),
     DeleteModel: () => import("./delete/index.vue"),
+    TerminationModel: () => import("./termination/index.vue"),
   },
   data() {
     return {
@@ -21,7 +22,8 @@ export default {
       searchColumns: SearchColumns,
       params: initParams(SearchColumns),
       tableData: [],
-      tableColumns: TableColumns,
+      currentData: [],
+      tableColumns: FormColumns,
       page: { pageNum: 1, pageSize: 10, total: 0 },
     };
   },
@@ -33,6 +35,7 @@ export default {
     //
     async fetchList(prop, page) {
       try {
+        // try
         this.loading = true;
         const { pageNum, pageSize } = page;
         const { code, rows, total } = await LIST({
@@ -46,6 +49,7 @@ export default {
         }
       } catch (err) {
         // catch
+        console.error(err);
       } finally {
         // finally
         this.loading = false;
@@ -61,6 +65,10 @@ export default {
       this.params = initParams(SearchColumns);
       this.useQuery(this.params, this.page);
     },
+    // 选 择
+    useSelect(prop) {
+      this.currentData = [prop];
+    },
     // 新 增
     async useAdd() {
       const { open } = this.$refs.AddModel;
@@ -68,22 +76,28 @@ export default {
     },
     // 删 除
     async useDelete(prop) {
-      const { id } = prop;
+      const [{ id }] = prop;
       const { open } = this.$refs.DeleteModel;
       await open(id);
     },
     // 编 辑
     async useEdit(prop) {
-      const { id } = prop;
+      const [{ id }] = prop;
       const { open } = this.$refs.EditModel;
       await open(id);
     },
     // 明 细
     async useSee(prop) {
-      const { id } = prop;
+      const [{ id }] = prop;
       const { open } = this.$refs.SeeModel;
       await open(id);
     },
+    // 终 止
+    async useTermination(prop) {
+      const [{ id }] = prop;
+      const { open } = this.$refs.TerminationModel;
+      await open(id);
+    },
     // 导 出
     async useExport(prop) {
       const { pageNum, pageSize } = this.page;
@@ -125,6 +139,10 @@ export default {
       ref="DeleteModel"
       @success="useQuery(params, page)"
     ></delete-model>
+    <termination-model
+      ref="TerminationModel"
+      @success="useQuery(params, page)"
+    ></termination-model>
     <el-form
       :size="size"
       :model="params"
@@ -155,13 +173,48 @@ export default {
       </el-button>
       <el-button :size="size" @click="useReset"> 重 置 </el-button>
       <el-button :size="size" @click="useAdd"> 新 增 </el-button>
-      <el-button :size="size" @click="useExport(params)"> 导 出 </el-button>
       <el-button :size="size" @click="useRecord"> 期初补录 </el-button>
+      <el-button
+        :size="size"
+        :disabled="!currentData.length"
+        @click="useEdit(currentData)"
+      >
+        编 辑
+      </el-button>
+      <el-button
+        :size="size"
+        :disabled="!currentData.length"
+        @click="useDelete(currentData)"
+      >
+        删 除
+      </el-button>
+      <el-button
+        :size="size"
+        :disabled="!currentData.length"
+        @click="useTermination(currentData)"
+      >
+        终 止
+      </el-button>
+      <el-button :size="size" :disabled="!currentData.length">
+        变 更
+      </el-button>
+      <el-button :size="size" :disabled="!currentData.length">
+        归 档
+      </el-button>
+      <el-button
+        :size="size"
+        :disabled="!currentData.length"
+        @click="useExport(params)"
+      >
+        导 出
+      </el-button>
       <!-- <el-button :size="size" @click="useImport"> 导 入 </el-button> -->
     </el-row>
     <el-table
       :size="size"
       :data="tableData"
+      highlight-current-row
+      @row-click="useSelect"
       @row-dblclick="useSee"
       style="width: 100%; margin: 20px 0 0 0"
     >
@@ -180,18 +233,14 @@ export default {
             :value="scope.row[column.key]"
             :options="dict.type[column.referName]"
           />
-          <el-button
+          <dr-file-preview
             v-else-if="column.inputType === 'Upload'"
-            type="text"
-            size="small"
-            @click.native.prevent="useEdit(scope.row)"
-          >
-            点击查看
-          </el-button>
+            v-model="scope.row[column.key]"
+          ></dr-file-preview>
           <span v-else>{{ scope.row[column.key] }}</span>
         </template>
       </el-table-column>
-      <el-table-column fixed="right" label="操作" width="120">
+      <!-- <el-table-column fixed="right" label="操作" width="150">
         <template slot-scope="scope">
           <el-button
             type="text"
@@ -203,12 +252,33 @@ export default {
           <el-button
             type="text"
             size="small"
+            @click.native.prevent="useEdit(scope.row)"
+          >
+            变 更
+          </el-button>
+          <el-button
+            type="text"
+            size="small"
+            @click.native.prevent="useEdit(scope.row)"
+          >
+            归 档
+          </el-button>
+          <el-button
+            type="text"
+            size="small"
+            @click.native.prevent="useTermination(scope.row)"
+          >
+            终 止
+          </el-button>
+          <el-button
+            type="text"
+            size="small"
             @click.native.prevent="useDelete(scope.row)"
           >
             删 除
           </el-button>
         </template>
-      </el-table-column>
+      </el-table-column> -->
     </el-table>
     <pagination
       :total="page.total"

+ 0 - 531
src/views/purchase/contract/record/column.js

@@ -1,531 +0,0 @@
-export const Columns = [
-  {
-    key: "puOrgName",
-    title: "采购组织",
-    inputType: "PopoverSelect",
-    referName: "ORG_PARAM",
-    dataMapping: {
-      puOrg: "code",
-      puOrgName: "name",
-    },
-    require: true,
-  },
-  { key: "code", title: "合同编码", inputType: "Input" },
-  {
-    key: "lastPuMoney",
-    title: "上年度采购额",
-    inputType: "Input",
-    require: true,
-  },
-  {
-    key: "buyerName",
-    title: "采购员",
-    inputType: "PopoverSelect",
-    referName: "CONTACTS_PARAM",
-    dataMapping: {
-      buyer: "code",
-      buyerName: "name",
-      puDept: "deptId",
-      puDeptName: "deptName",
-    },
-    require: true,
-  },
-  {
-    key: "supplierName",
-    title: "供应商",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    dataMapping: {
-      supplier: "code",
-      supplierName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "contractType",
-    title: "合同类型",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_contract_type",
-  },
-  {
-    key: "puMoneyYear",
-    title: "本年度采购额",
-    inputType: "InputNumber",
-    require: true,
-  },
-  {
-    key: "puDeptName",
-    title: "采购部门",
-    inputType: "PopoverSelect",
-    referName: "DEPT_PARAM",
-    dataMapping: {
-      puDept: "code",
-      puDeptName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "supplierTier",
-    title: "供应商层级",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_supplier_tier",
-  },
-  { key: "contractName", title: "合同名称", inputType: "Input", require: true },
-  {
-    key: "grossRateAverage",
-    title: "平均毛利率",
-    inputType: "Input",
-    require: true,
-  },
-  {
-    key: "approveFlow",
-    title: "审批流程",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_approve_flow",
-  },
-  {
-    key: "consumableClass",
-    title: "耗材类别",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_consumable_class",
-  },
-  {
-    key: "effectiveDate",
-    title: "合同生效日期",
-    inputType: "DatePicker",
-    require: true,
-  },
-  {
-    key: "brandGrossRate",
-    title: "同类品牌及毛利率",
-    inputType: "Input",
-    require: true,
-  },
-  {
-    key: "contractFormat",
-    title: "合同格式",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_contract_format",
-  },
-  {
-    key: "productName",
-    title: "产品类别&名称",
-    inputType: "Input",
-    require: true,
-  },
-  {
-    key: "endDate",
-    title: "合同终止日期",
-    inputType: "DatePicker",
-    require: true,
-  },
-  {
-    key: "invoiceTax",
-    title: "发票税率",
-    inputType: "PopoverSelect",
-    referName: "TAX_RATE_PARAM",
-    dataMapping: {
-      invoiceTax: "ntaxrate",
-    },
-    require: true,
-  },
-  {
-    key: "emergencyDegree",
-    title: "紧急程度",
-    inputType: "Select",
-    require: true,
-    referName: "puarchase_contract_emergency_degree",
-  },
-  { key: "project", title: "项目医院", inputType: "Input", require: true },
-  {
-    key: "signDate",
-    title: "合同签订日期",
-    inputType: "DatePicker",
-    require: true,
-  },
-  {
-    key: "deliveryType",
-    title: "交货方式",
-    inputType: "Select",
-    referName: "puarchase_contract_delivery_type",
-  },
-  {
-    key: "source",
-    title: "合同来源",
-    inputType: "Input",
-    value: "期初补录",
-    disabled: true,
-  },
-  {
-    key: "contractPartycName",
-    title: "合同丙方",
-    inputType: "PopoverSelect",
-    referName: "SUPPLIER_PARAM",
-    dataMapping: {
-      contractPartyc: "code",
-      contractPartycName: "name",
-    },
-  },
-  {
-    key: "guaranteePeriodEnd",
-    title: "质保期限",
-    inputType: "Input",
-    require: true,
-  },
-  {
-    key: "freightMethods",
-    title: "运费承担方式",
-    inputType: "Select",
-    referName: "puarchase_contract_freight_methods",
-  },
-  {
-    key: "signDate",
-    title: "合同创建时间",
-    inputType: "DatePicker",
-    disabled: true,
-  },
-  {
-    key: "isTarget",
-    title: "是否有指标",
-    inputType: "Select",
-    require: true,
-    referName: "sys_yes_no",
-  },
-  {
-    key: "contractTarget",
-    title: "合同指标",
-    inputType: "Input",
-    require: true,
-    placeholder: '当【是否有指标】="有"时,必填',
-  },
-  {
-    key: "exemptionPostageCondtion",
-    title: "包邮条件",
-    inputType: "Input",
-    placeholder:
-      "当运费承担方式为供应商有条件承担时,该字段必填,填写要求,写明什么条件下供应商承担全部,什么条件下我方承担,什么条件下分别承担",
-    span: 12,
-  },
-  {
-    key: "isRebate",
-    title: "是否有返利",
-    inputType: "Select",
-    require: true,
-    referName: "sys_yes_no",
-  },
-  {
-    key: "rebatePolicy",
-    title: "返利政策",
-    inputType: "Input",
-    placeholder: '当【是否有返利】="有"时,必填',
-    span: 18,
-  },
-  { key: "externalContract", title: "外部合同号", inputType: "Input" },
-  {
-    key: "rollbackPolicy",
-    title: "退换货政策",
-    inputType: "Input",
-    require: true,
-  },
-  { key: "enquiryCode", title: "询价单号", inputType: "Input" },
-  {
-    key: "contractContent",
-    title: "合同主要内容",
-    inputType: "Textarea",
-    require: true,
-    span: 24,
-  },
-  { key: "refusalReasons", title: "拒绝理由", inputType: "Input", span: 24 },
-
-  {
-    key: "externalFile",
-    title: "对外附件",
-    inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
-  },
-  {
-    key: "puFile",
-    title: "采购商盖章合同附件",
-    inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
-  },
-  {
-    key: "supplierFile",
-    title: "供应商盖章合同附件",
-    inputType: "Upload",
-    span: 24,
-    fileType: ["pdf"],
-  },
-  { key: "projectCode", title: "项目编号", inputType: "Input" },
-  { key: "projectName", title: "项目名称", inputType: "Input" },
-  { key: "area", title: "区域", inputType: "Input" },
-  { key: "consigneePhone", title: "收货人联系方式", inputType: "Input" },
-  {
-    key: "paymentAgreement",
-    title: "付款协议",
-    inputType: "PopoverSelect",
-    referName: "PAYAGREEMENT_PARAM",
-    dataMapping: {
-      paymentAgreement: "code",
-      paymentAgreementName: "name",
-    },
-    require: true,
-  },
-  {
-    key: "taxPrice",
-    title: "价税合计",
-    inputType: "InputNumber",
-  },
-  {
-    key: "currencyName",
-    title: "币种",
-    inputType: "PopoverSelect",
-    referName: "CURRENCY_PARAM",
-    dataMapping: {
-      currency: "code",
-      currencyName: "name",
-    },
-    require: true,
-  },
-  { key: "guaranteePeriod", title: "质保期", inputType: "Input" },
-];
-
-export const SearchColumns = [
-  { key: "contractName", title: "合同名称", search: true, inputType: "Input" },
-];
-
-export const TabColumns = [
-  {
-    title: "物料基本信息",
-    key: "contractItemList",
-    tableColumns: [
-      {
-        title: "物料名称",
-        key: "materialName",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "MATERIAL_PARAM",
-        dataMapping: {
-          material: "code",
-          materialName: "name",
-          puUnit: "unitIdName",
-          registration: "registrationNo",
-          specification: "specification",
-          manufacturer: "manufacturerIdName",
-        },
-      },
-      { title: "物料编码", key: "material", width: 200 },
-      {
-        title: "规格",
-        key: "specification",
-        width: 200,
-      },
-      // {
-      //   title: "品牌",
-      //   key: "brand",
-      //   inputType: "PopoverSelect",
-      //   width: 200,
-      //   referName: "MATERIAL_PARAM",
-      //   dataMapping: {
-      //     material: "code",
-      //     materialName: "name",
-      //   },
-      // },
-      {
-        title: "生产厂家",
-        key: "manufacturer",
-        inputType: "Input",
-        width: 200,
-      },
-      {
-        title: "采购单位",
-        key: "puUnit",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "UNIT_PARAM",
-        dataMapping: {
-          puUnit: "name",
-        },
-      },
-      {
-        title: "税率%",
-        key: "tax",
-        inputType: "PopoverSelect",
-        referName: "TAX_RATE_PARAM",
-        dataMapping: {
-          tax: "ntaxrate",
-        },
-        width: 200,
-      },
-      {
-        title: "采购数量",
-        key: "qty",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "含税单价",
-        key: "taxPrice",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "含税金额合计",
-        key: "taxMoney",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { qty, taxPrice } = prop;
-          const taxMoney = (qty * taxPrice).toFixed(8);
-          return taxMoney === "NaN" ? null : taxMoney;
-        },
-      },
-      {
-        title: "无税单价",
-        key: "taxFreePrice",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { tax, taxPrice } = prop;
-          const newTax = Number(tax) / 100;
-          const taxFreePrice = (taxPrice / (1 + newTax)).toFixed(8);
-          return taxFreePrice === "NaN" ? null : taxFreePrice;
-        },
-      },
-      {
-        title: "无税金额合计",
-        key: "taxFreeMoney",
-        inputType: "ComputedInput",
-        width: 200,
-        computed: (prop) => {
-          const { qty, taxFreePrice } = prop;
-          const taxFreeMoney = (qty * taxFreePrice).toFixed(8);
-          return taxFreeMoney === "NaN" ? null : taxFreeMoney;
-        },
-      },
-      {
-        title: "注册证号及备案凭证号",
-        key: "registration",
-        inputType: "Input",
-        width: 200,
-      },
-      {
-        title: "收货客户",
-        key: "customerName",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "CUSTOMER_PARAM",
-        dataMapping: {
-          customer: "code",
-          customerName: "name",
-        },
-      },
-      { title: "备注", key: "remark", inputType: "Input", width: 200 },
-    ],
-  },
-  {
-    title: "合同条款",
-    key: "contractClauseList",
-    tableColumns: [
-      { title: "条款编码", key: "code", inputType: "Input" },
-      { title: "条款名称", key: "name", inputType: "Input" },
-      { title: "条款内容", key: "content", inputType: "Input" },
-      { title: "变量序号", key: "variableRowno" },
-      { title: "变量内容", key: "variableContent", inputType: "Input" },
-      { title: "备注", key: "remark", inputType: "Input" },
-    ],
-  },
-  {
-    title: "合同费用",
-    key: "contractExpenseList",
-    tableColumns: [
-      { title: "费用编码", key: "code", inputType: "Input" },
-      { title: "费用名称", key: "name", inputType: "Input" },
-      {
-        title: "费用金额",
-        key: "money",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      { title: "备注", key: "remark", inputType: "Input" },
-    ],
-  },
-  {
-    title: "付款协议信息",
-    key: "contractAgreementList",
-    tableColumns: [
-      {
-        title: "付款阶段",
-        key: "satge",
-        inputType: "InputNumber",
-        width: 200,
-      },
-      {
-        title: "付款起点",
-        key: "origin",
-        width: 200,
-        inputType: "Select",
-        referName: "puarchase_contract_origin",
-      },
-      { title: "账期天数", key: "paymetDays", inputType: "Input", width: 200 },
-      { title: "付款比例%", key: "ratio", inputType: "Input", width: 200 },
-      { title: "付款金额", key: "money", inputType: "Input", width: 200 },
-      {
-        title: "是否预付款",
-        key: "isAdvance",
-        width: 200,
-        inputType: "Select",
-        referName: "sys_yes_no",
-      },
-      {
-        title: "是否质保金",
-        key: "isQuality",
-        width: 200,
-        inputType: "Select",
-        referName: "sys_yes_no",
-      },
-      {
-        title: "结算方式",
-        key: "paymentMeans",
-        inputType: "PopoverSelect",
-        width: 200,
-        referName: "BALATYPE_PARAM",
-        dataMapping: {
-          paymentMeans: "name",
-        },
-      },
-      { title: "备注", key: "remark", inputType: "Input", width: 200 },
-      {
-        title: "需进度确认",
-        key: "schedule",
-        inputType: "Select",
-        referName: "sys_yes_no",
-        width: 200,
-      },
-    ],
-  },
-  {
-    title: "合同执行组织范围",
-    key: "contractApplyOrgList",
-    tableColumns: [
-      {
-        title: "组织名称",
-        key: "orgName",
-        inputType: "PopoverSelect",
-        referName: "ORG_PARAM",
-        dataMapping: {
-          org: "code",
-          orgName: "name",
-        },
-      },
-      { title: "组织编码", key: "org" },
-    ],
-  },
-];

+ 76 - 134
src/views/purchase/contract/record/index.vue

@@ -1,162 +1,106 @@
 <script>
-import { Columns, TabColumns } from "./column";
-import { REFER } from "@/components/popover-select/api";
-import { ADD, CODE } from "@/api/business/purchase/contract";
-import { initDicts, initRules, initParams } from "@/utils/init";
+import Column from "../add/column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useTable from "../hooks/use-table";
+import useWatch from "../hooks/use-watch";
+import useMethods from "../hooks/use-methods";
+const { watchContractType } = useWatch();
 
 export default {
-  name: "RecordDialog",
-  dicts: Array.from(
-    new Set([
-      ...initDicts(Columns),
-      ...initDicts(
-        TabColumns.map((item) => item.tableColumns)
-          .flat()
-          .filter((item) => item.inputType === "Select")
-      ),
-    ])
-  ),
+  name: "RecordDrawer",
+  dicts: useDicts(Column),
   components: {},
   data() {
     return {
-      size: "mini",
-      visible: false,
-      loading: false,
-      columns: Columns,
-      rules: initRules(Columns),
-      params: {
-        ...initParams(Columns),
-        contractItemList: [],
-        contractClauseList: [],
-        contractExpenseList: [],
-        contractAgreementList: [],
-        contractApplyOrgList: [],
-      },
-      tabColumns: TabColumns,
-      tabName: "contractItemList",
+      title: "期 初 补 录",
+      ...useData(Column),
     };
   },
   computed: {},
   watch: {
-    "params.contractType": function (newProp) {
-      this.tabColumns = TabColumns.filter((element) =>
-        newProp === "1" ? element.key !== "contractItemList" : element
-      );
-      this.tabName = this.tabColumns[0].key;
-    },
+    "params.contractType": watchContractType(),
   },
   methods: {
     //
-    open() {
+    async fetchRefer(prop, type, source) {
+      const { fetchRefer } = useMethods();
+      await fetchRefer({ _this: this, prop, type, source });
+    },
+    //
+    async open() {
+      const { open, fetchCode } = useMethods();
+      await open({ _this: this });
+      await fetchCode({ _this: this });
       const {
-        deptId: puDept,
-        deptName: puDeptName,
-        name: buyer,
-        nickName: buyerName,
-        orgId: puOrg,
-        orgName: puOrgName,
-      } = this.$store.state.user;
+        user: {
+          deptId: puDept,
+          deptName: puDeptName,
+          name: buyer,
+          nickName: buyerName,
+          orgId: puOrg,
+          orgName: puOrgName,
+        },
+      } = this.$store.state;
       this.params.puOrg = puOrg;
       this.params.puOrgName = puOrgName;
       this.params.buyer = buyer;
       this.params.buyerName = buyerName;
       this.params.puDept = puDept;
       this.params.puDeptName = puDeptName;
-      this.fetchCode();
-      this.visible = true;
-    },
-    //
-    hide() {
-      this.visible = false;
-      this.params = initParams(this.columns);
-      this.tabName = this.tabColumns[0].key;
+      this.params.source = "期初补录";
     },
     //
-    async fetchCode() {
-      try {
-        this.loading = true;
-        const code = await CODE();
-        this.params.code = code;
-      } catch (err) {
-        // catch
-      } finally {
-        // finally
-        this.loading = false;
-      }
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
     //
-    async fetchRefer(prop, type, source) {
-      const { rateCode } = prop;
-      if (type === "MATERIAL_PARAM") {
-        try {
-          this.loading = true;
-          const { code, rows } = await REFER({
-            search: rateCode,
-            type: "TAX_RATE_PARAM",
-          });
-          if (code === 200) {
-            const [{ ntaxrate }] = rows;
-            source.tax = ntaxrate === "0E-8" ? "0.00000000" : ntaxrate;
-          }
-        } catch (err) {
-          // catch
-        } finally {
-          // finally
-          this.loading = false;
-        }
-      }
-    },
-    //
-    rowAdd(prop) {
-      const tab = this.tabColumns.find((element) => element.key === prop);
-      this.params[prop].push(initParams(tab.tableColumns));
+    async useRowAdd(prop) {
+      const { add } = useTable();
+      await add({ _this: this, prop });
     },
     //
-    async rowDelete(prop, { $index }) {
-      this.params[prop].splice($index, 1);
+    async useRowRemove(prop, scope) {
+      const { remove } = useTable();
+      await remove({ _this: this, prop, scope });
     },
     //
-    submit(prop) {
-      this.$refs[prop].validate(async (valid) => {
-        if (valid) {
-          try {
-            const createById = this.params.buyer;
-            const createByName = this.params.buyerName;
-            const updateById = this.$store.state.user.id;
-            const updateByName = this.$store.state.user.name;
-            const { code, msg } = await ADD({
-              createById,
-              createByName,
-              updateById,
-              updateByName,
-              ...this.params,
-            });
-            if (code === 200) {
-              this.hide();
-              this.$emit("success");
-            } else {
-              this.$notify.warning({ title: msg });
-            }
-          } catch (err) {
-            //
-          } finally {
-            //
-          }
-        } else {
-          return false;
-        }
-      });
+    async useSubmit(prop) {
+      const { submit } = useMethods();
+      await submit({ _this: this, prop, type: "ADD" });
     },
   },
-  created() {
-    console.log(this);
-  },
+  created() {},
   mounted() {},
   destroyed() {},
 };
 </script>
 <template>
-  <el-dialog :visible.sync="visible" title="期初补录" fullscreen @close="hide">
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-check"
+          @click="useSubmit('ruleForm')"
+        >
+        </el-button>
+      </span>
+    </template>
     <el-form
       ref="ruleForm"
       v-loading="loading"
@@ -165,10 +109,11 @@ export default {
       :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="(column, index) in columns"
+          v-for="(column, index) in formColumns"
           :key="index"
           :span="column.span || 6"
         >
@@ -235,6 +180,7 @@ export default {
               :disabled="column.disabled"
               :clearable="column.clearable"
               :placeholder="column.placeholder"
+              :value-format="column.valueFormat"
               :picker-options="column.pickerOptions"
               style="width: 100%"
             >
@@ -248,14 +194,14 @@ export default {
         </el-col>
       </el-row>
       <el-form-item label-width="0">
-        <el-tabs v-model="tabName" tab-position="left" style="width: 100%">
+        <el-tabs v-model="tabName">
           <el-tab-pane
             v-for="(column, index) in tabColumns"
             :key="index"
             :label="column.title"
             :name="column.key"
           >
-            <el-table :data="params[column.key]" style="width: 100%">
+            <el-table :data="params[column.key]">
               <el-table-column label="序号">
                 <template slot-scope="scope">
                   {{ scope.$index + 1 }}
@@ -337,7 +283,7 @@ export default {
                     circle
                     icon="el-icon-plus"
                     :size="size"
-                    @click="rowAdd(tabName)"
+                    @click="useRowAdd(tabName)"
                   >
                   </el-button>
                 </template>
@@ -346,7 +292,7 @@ export default {
                     circle
                     icon="el-icon-minus"
                     :size="size"
-                    @click.native.prevent="rowDelete(tabName, scope)"
+                    @click.native.prevent="useRowRemove(tabName, scope)"
                   >
                   </el-button>
                 </template>
@@ -355,10 +301,6 @@ export default {
           </el-tab-pane>
         </el-tabs>
       </el-form-item>
-      <el-form-item label-width="0" style="text-align: right">
-        <el-button :size="size" @click="hide">取 消</el-button>
-        <el-button :size="size" @click="submit('ruleForm')"> 新 增 </el-button>
-      </el-form-item>
     </el-form>
-  </el-dialog>
+  </el-drawer>
 </template>

+ 37 - 64
src/views/purchase/contract/see/index.vue

@@ -1,71 +1,33 @@
 <script>
-import { Columns, TabColumns } from "../column";
-import { initDicts, initParams } from "@/utils/init";
-import { ITEM, TABLELIST } from "@/api/business/purchase/contract";
+import Column from "../add/column";
+import useData from "../hooks/use-data";
+import useDicts from "../hooks/use-dicts";
+import useMethods from "../hooks/use-methods";
 
 export default {
-  name: "SeeDialog",
-  dicts: Array.from(
-    new Set([
-      ...initDicts(Columns),
-      ...initDicts(TabColumns.map((item) => item.tableColumns))
-        .flat()
-        .filter((cItem) => cItem.inputType === "Select"),
-    ])
-  ),
+  name: "SeeDrawer",
+  dicts: useDicts(Column),
+  components: {},
   data() {
     return {
-      size: "mini",
-      title: "明细",
-      width: "100%",
       column: 3,
-      visible: false,
-      loading: false,
-      columns: Columns,
-      params: {
-        ...initParams(Columns),
-        contractItemList: [],
-        contractClauseList: [],
-        contractExpenseList: [],
-        contractApplyOrgList: [],
-        contractAgreementList: [],
-      },
-      tabColumns: TabColumns,
-      tabName: "contractItemList",
+      title: "明 细",
+      ...useData(Column),
     };
   },
   computed: {},
   watch: {},
   methods: {
     //
-    setFileList(prop) {
-      return prop.split(";").map((file) => ({
-        url: file,
-        name: file.split("/")[file.split("/").length - 1],
-      }));
+    async open(prop) {
+      const { open, fetchItem } = useMethods();
+      await open({ _this: this });
+      await fetchItem({ _this: this, prop });
     },
     //
-    open(prop) {
-      this.visible = true;
-      this.fetchItem(prop);
-    },
-    // 查 询
-    async fetchItem(prop) {
-      try {
-        this.loading = true;
-        const { code, data } = await ITEM(prop);
-        if (code === 200) {
-          this.params = data;
-          this.tabName = this.tabColumns[0].key;
-        } else {
-          this.$notify.warning({ title: msg });
-        }
-      } catch (err) {
-        // catch
-      } finally {
-        // finally
-        this.loading = false;
-      }
+    async hide() {
+      const { hide } = useMethods();
+      await hide({ _this: this });
     },
   },
   created() {},
@@ -74,11 +36,27 @@ export default {
 };
 </script>
 <template>
-  <el-drawer :visible.sync="visible" :size="width" :title="title">
-    <el-descriptions border :size="size" :column="column" style="margin: 10px">
+  <el-drawer
+    :size="width"
+    :title="title"
+    :show-close="false"
+    :visible.sync="visible"
+  >
+    <template slot="title">
+      <span>{{ title }}</span>
+      <span>
+        <el-button
+          :size="size"
+          circle
+          icon="el-icon-close"
+          @click="hide"
+        ></el-button>
+      </span>
+    </template>
+    <el-descriptions :size="size" :column="column" border style="margin: 10px">
       <el-descriptions-item
         v-if="params[column.key]"
-        v-for="(column, index) in columns"
+        v-for="(column, index) in formColumns"
         :key="index"
         :label="column.title"
         :labelStyle="{ width: '150px' }"
@@ -91,17 +69,12 @@ export default {
           :options="dict.type[column.referName]"
         />
         <span v-else-if="column.inputType === 'Upload'">
-          <dr-file-tag v-model="params[column.key]"></dr-file-tag>
+          <dr-file-preview v-model="params[column.key]"></dr-file-preview>
         </span>
         <span v-else>{{ params[column.key] }}</span>
       </el-descriptions-item>
     </el-descriptions>
-    <el-tabs
-      v-model="tabName"
-      :size="size"
-      tab-position="top"
-      style="margin: 10px"
-    >
+    <el-tabs v-model="tabName" :size="size" style="margin: 10px">
       <el-tab-pane
         v-for="(column, index) in tabColumns"
         :key="index"

+ 33 - 0
src/views/purchase/contract/termination/index.vue

@@ -0,0 +1,33 @@
+<script>
+import useMethods from "../hooks/use-methods";
+
+export default {
+  name: "TerminationDialog",
+  data() {
+    return {};
+  },
+  computed: {},
+  watch: {},
+  methods: {
+    //
+    open(prop) {
+      this.$confirm("是否终止数据项?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info",
+      })
+        .then(async () => {
+          const { termination } = useMethods();
+          await termination({ _this: this, prop });
+        })
+        .catch((err) => {
+          console.error(err);
+        });
+    },
+  },
+  created() {},
+  mounted() {},
+  destroyed() {},
+};
+</script>
+<template></template>

+ 7 - 1
src/views/purchase/purchase-order/add/column.js

@@ -301,7 +301,13 @@ export const Columns = [
     valueFormat: "yyyy-MM-dd",
     isShow:true,
   },
-  { key: "applyPaymentMoney", title: "累计付款申请金额", inputType: "Input", isShow:true,},
+  { 
+    key: "applyPaymentMoney", 
+    title: "累计付款申请金额", 
+    inputType: "Input", 
+    isShow:true,
+    disabled:true,
+  },
   { key: "paymentMoney", title: "累计付款金额", inputType: "Input", isShow:true,},
   { key: "invoiceMoney", title: "发票金额", inputType: "Input",isShow:true, },
   {

+ 6 - 1
src/views/purchase/purchase-order/add/index.vue

@@ -362,7 +362,7 @@ export default {
    async handleTabReferChange(val, source, type) {
 
       // 触发物料参照询价   && source.qty && source.qty != ""
-      if (type == "MATERIAL_PARAM") {
+      if (type == "MATERIAL_PARAM" && source.qty && source.qty != "") {
 
         source['qty'] = 0;
 
@@ -380,6 +380,11 @@ export default {
 
         source['tax'] = 0;
 
+        this.params['qty'] = 0;
+        this.params['originalQty'] = 0;
+        this.params['money'] = 0;
+        this.params['originalMoney'] = 0;
+        this.params['notaxMoney'] = 0;
         source.isDrug = val.materialMedcine.isDrug  == '0' ? 'Y' : 'N';
 
         await this.handleGetPrice();

+ 27 - 6
src/views/purchase/purchase-order/edit/index.vue

@@ -68,12 +68,26 @@ export default {
     },
     // 同步子表物料
     handleSynchronousMaterial(key1, key2) {
+      let _this = this;
       // this.params[key1]-- -> this.params[key2]
-      this.params[key1] && this.params[key1].forEach((item, index) => {
-        this.params[key2][index].material = item.material;
-        this.params[key2][index].materialName = item.materialName;
-        this.params[key2][index].materialCode = item.materialCode;
-      })
+      this.params[key1] &&
+        this.params[key1].forEach((item, index) => {
+          for (const key in item) {
+            if (key in _this.params[key2][index]) {
+              if (
+                key == "material" ||
+                key == "materialName" ||
+                key == "materialCode"
+              ) {
+                _this.params[key2][index].material = item.material;
+                _this.params[key2][index].materialName = item.materialName;
+                _this.params[key2][index].materialCode = item.materialCode;
+              } else {
+                _this.params[key2][index][key] = item[key];
+              }
+            }
+          }
+        });
     },
     // 判断属性是否禁用
    async handleIsForbidden(status,source) {
@@ -218,8 +232,9 @@ export default {
     },
     // 子表参照改变之后
     async handleTabReferChange(val, source, type) {
+      
       // 触发物料参照
-      if (type == "MATERIAL_PARAM") {
+      if (type == "MATERIAL_PARAM" && source.qty && source.qty != "") {
 
         source['qty'] = 0;
 
@@ -237,6 +252,12 @@ export default {
         
         source['tax'] = 0;
 
+        this.params['qty'] = 0;
+        this.params['originalQty'] = 0;
+        this.params['money'] = 0;
+        this.params['originalMoney'] = 0;
+        this.params['notaxMoney'] = 0;
+
         source.isDrug = val.materialMedcine.isDrug  == '0' ? 'Y' : 'N';
         
         await this.handleGetPrice();

+ 7 - 4
src/views/purchase/purchase-order/index.vue

@@ -8,6 +8,7 @@ import {
   initColumns,
   initDicts,
 } from "@/utils/init";
+import { async } from "q";
 
 
 export default {
@@ -255,7 +256,7 @@ export default {
           cancelButtonText: '取消',
           inputPattern: /\s*\S+?/,
           inputErrorMessage: '退回原因不能为空'
-        }).then(({ value }) => {
+        }).then(async ({ value }) => {
 
           let data = {
             id: this.checkedList[0].id,
@@ -267,14 +268,16 @@ export default {
 
           try {
 
-            let { code, msg } = orderApi.documentsReturn(data);
+            let { code, msg } = await orderApi.documentsReturn(data);
 
-            if (code == 200) {
+            if (code === 200) {
 
               this.fetchList(this.params, this.page);
 
             }
-          } catch (error) {}
+          } catch (error) {
+            console.log(error,'error------------');
+          }
         }).catch(() => {   });
       
     },

+ 6 - 1
src/views/purchase/task/first-direct/column.js

@@ -5,7 +5,12 @@ export const TableColumns = [
   { key: "puOrgName", title: "采购组织名称" },
   { key: "customer", title: "客户" },
   { key: "customerName", title: "客户名称" },
-  { key: "priceType", title: "价格类型" },
+  {
+    key: "priceType",
+    title: "价格类型",
+    inputType: "Select",
+    referName: "sys_price_type",
+  },
   { key: "isDistribution", title: "配送价" },
   { key: "effectiveDate", title: "价格生效日期" },
   { key: "endDate", title: "价格失效日期" },

+ 1 - 0
src/views/purchase/task/first-direct/index.vue

@@ -4,6 +4,7 @@ import { initColumns } from "@/utils/init";
 import { FIRSTDIRECT, ADD } from "@/api/business/purchase/task";
 export default {
   name: "FirstDirectPurchaseDialog",
+  dicts: initDicts(TableColumns),
   components: {},
   data() {
     return {

+ 2 - 2
vue.config.js

@@ -37,13 +37,13 @@ module.exports = {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
         // target: `http://172.16.100.107:8080/drp-admin`, //测试
-        target: `http://test-sy.derom.com/drp-admin`, //测试
+        // target: `http://test-sy.derom.com/drp-admin`, //测试
         // target: `http://release-sy.derom.com/drp-admin`, //预发
         // target: `http://sy.derom.com/drp-admin`, //生产
         // target: `http://172.16.63.202:8000/drp-admin`, // D本地
         // target: `http://172.16.62.241:8000/drp-admin`, //笑寒本地
         // target: `http://172.16.13.152:8000/drp-admin`, //豪哥本地
-        // target: `http://172.16.13.47:8000/drp-admin`, //这是一个美女的本地
+        target: `http://172.16.13.47:8000/drp-admin`, //这是一个美女的本地
         // target: `http://172.16.13.113:8000/drp-admin`, //DWT本地
         // target: `http://172.16.13.77:8000/drp-admin`, //TQ本地
         // target: `http://172.16.13.21:8000/drp-admin`, // 雪豹的本地